From 40ee620e51c86c72e3c2b65df71f5f0a4a79797f Mon Sep 17 00:00:00 2001 From: Teddy_Wang Date: Mon, 8 Jun 2020 00:35:10 -0400 Subject: [PATCH 01/99] Added a lint for .map(|x| x) --- CHANGELOG.md | 1 + clippy_lints/src/lib.rs | 5 ++ clippy_lints/src/map_identity.rs | 126 +++++++++++++++++++++++++++++++ src/lintlist/mod.rs | 7 ++ tests/ui/map_flatten.fixed | 1 + tests/ui/map_flatten.rs | 1 + tests/ui/map_flatten.stderr | 4 +- tests/ui/map_identity.fixed | 23 ++++++ tests/ui/map_identity.rs | 25 ++++++ tests/ui/map_identity.stderr | 37 +++++++++ 10 files changed, 228 insertions(+), 2 deletions(-) create mode 100644 clippy_lints/src/map_identity.rs create mode 100644 tests/ui/map_identity.fixed create mode 100644 tests/ui/map_identity.rs create mode 100644 tests/ui/map_identity.stderr diff --git a/CHANGELOG.md b/CHANGELOG.md index adc945a69441d..d6186c319d07d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1508,6 +1508,7 @@ Released 2018-09-13 [`map_clone`]: https://rust-lang.github.io/rust-clippy/master/index.html#map_clone [`map_entry`]: https://rust-lang.github.io/rust-clippy/master/index.html#map_entry [`map_flatten`]: https://rust-lang.github.io/rust-clippy/master/index.html#map_flatten +[`map_identity`]: https://rust-lang.github.io/rust-clippy/master/index.html#map_identity [`map_unwrap_or`]: https://rust-lang.github.io/rust-clippy/master/index.html#map_unwrap_or [`match_as_ref`]: https://rust-lang.github.io/rust-clippy/master/index.html#match_as_ref [`match_bool`]: https://rust-lang.github.io/rust-clippy/master/index.html#match_bool diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index 021fbe932d895..8b5e0b84eb4f7 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -252,6 +252,7 @@ mod main_recursion; mod manual_async_fn; mod manual_non_exhaustive; mod map_clone; +mod map_identity; mod map_unit_fn; mod match_on_vec_items; mod matches; @@ -631,6 +632,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: &manual_async_fn::MANUAL_ASYNC_FN, &manual_non_exhaustive::MANUAL_NON_EXHAUSTIVE, &map_clone::MAP_CLONE, + &map_identity::MAP_IDENTITY, &map_unit_fn::OPTION_MAP_UNIT_FN, &map_unit_fn::RESULT_MAP_UNIT_FN, &match_on_vec_items::MATCH_ON_VEC_ITEMS, @@ -1080,6 +1082,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: }); store.register_early_pass(|| box unnested_or_patterns::UnnestedOrPatterns); store.register_late_pass(|| box macro_use::MacroUseImports::default()); + store.register_late_pass(|| box map_identity::MapIdentity); store.register_group(true, "clippy::restriction", Some("clippy_restriction"), vec![ LintId::of(&arithmetic::FLOAT_ARITHMETIC), @@ -1295,6 +1298,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: LintId::of(&manual_async_fn::MANUAL_ASYNC_FN), LintId::of(&manual_non_exhaustive::MANUAL_NON_EXHAUSTIVE), LintId::of(&map_clone::MAP_CLONE), + LintId::of(&map_identity::MAP_IDENTITY), LintId::of(&map_unit_fn::OPTION_MAP_UNIT_FN), LintId::of(&map_unit_fn::RESULT_MAP_UNIT_FN), LintId::of(&matches::INFALLIBLE_DESTRUCTURING_MATCH), @@ -1573,6 +1577,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: LintId::of(&loops::EXPLICIT_COUNTER_LOOP), LintId::of(&loops::MUT_RANGE_BOUND), LintId::of(&loops::WHILE_LET_LOOP), + LintId::of(&map_identity::MAP_IDENTITY), LintId::of(&map_unit_fn::OPTION_MAP_UNIT_FN), LintId::of(&map_unit_fn::RESULT_MAP_UNIT_FN), LintId::of(&matches::MATCH_AS_REF), diff --git a/clippy_lints/src/map_identity.rs b/clippy_lints/src/map_identity.rs new file mode 100644 index 0000000000000..9bc8f1bec1bc2 --- /dev/null +++ b/clippy_lints/src/map_identity.rs @@ -0,0 +1,126 @@ +use crate::utils::{ + is_adjusted, is_type_diagnostic_item, match_path, match_trait_method, match_var, paths, remove_blocks, + span_lint_and_sugg, +}; +use if_chain::if_chain; +use rustc_errors::Applicability; +use rustc_hir::{Body, Expr, ExprKind, Pat, PatKind, QPath, StmtKind}; +use rustc_lint::{LateContext, LateLintPass}; +use rustc_session::{declare_lint_pass, declare_tool_lint}; + +declare_clippy_lint! { + /// **What it does:** Checks for instances of `map(f)` where `f` is the identity function. + /// + /// **Why is this bad?** It can be written more concisely without the call to `map`. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// + /// ```rust + /// let x = [1, 2, 3]; + /// let y: Vec<_> = x.iter().map(|x| x).map(|x| 2*x).collect(); + /// ``` + /// Use instead: + /// ```rust + /// let x = [1, 2, 3]; + /// let y: Vec<_> = x.iter().map(|x| 2*x).collect(); + /// ``` + pub MAP_IDENTITY, + complexity, + "using iterator.map(|x| x)" +} + +declare_lint_pass!(MapIdentity => [MAP_IDENTITY]); + +impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MapIdentity { + fn check_expr(&mut self, cx: &LateContext<'_, '_>, expr: &Expr<'_>) { + if expr.span.from_expansion() { + return; + } + + if_chain! { + if let Some([caller, func]) = get_map_argument(cx, expr); + if is_expr_identity_function(cx, func); + then { + span_lint_and_sugg( + cx, + MAP_IDENTITY, + expr.span.trim_start(caller.span).unwrap(), + "unnecessary map of the identity function", + "remove the call to `map`", + String::new(), + Applicability::MachineApplicable + ) + } + } + } +} + +/// Returns the arguments passed into map() if the expression is a method call to +/// map(). Otherwise, returns None. +fn get_map_argument<'a>(cx: &LateContext<'_, '_>, expr: &'a Expr<'a>) -> Option<&'a [Expr<'a>]> { + if_chain! { + if let ExprKind::MethodCall(ref method, _, ref args) = expr.kind; + if args.len() == 2 && method.ident.as_str() == "map"; + let caller_ty = cx.tables.expr_ty(&args[0]); + if match_trait_method(cx, expr, &paths::ITERATOR) + || is_type_diagnostic_item(cx, caller_ty, sym!(result_type)) + || is_type_diagnostic_item(cx, caller_ty, sym!(option_type)); + then { + Some(args) + } else { + None + } + } +} + +/// Checks if an expression represents the identity function +/// Only examines closures and `std::convert::identity` +fn is_expr_identity_function(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> bool { + match expr.kind { + ExprKind::Closure(_, _, body_id, _, _) => is_body_identity_function(cx, cx.tcx.hir().body(body_id)), + ExprKind::Path(QPath::Resolved(_, ref path)) => match_path(path, &paths::STD_CONVERT_IDENTITY), + _ => false, + } +} + +/// Checks if a function's body represents the identity function +/// Looks for bodies of the form `|x| x`, `|x| return x`, `|x| { return x }` or `|x| { +/// return x; }` +fn is_body_identity_function(cx: &LateContext<'_, '_>, func: &Body<'_>) -> bool { + let params = func.params; + let body = remove_blocks(&func.value); + + // if there's less/more than one parameter, then it is not the identity function + if params.len() != 1 { + return false; + } + + match body.kind { + ExprKind::Path(QPath::Resolved(None, _)) => match_expr_param(cx, body, params[0].pat), + ExprKind::Ret(Some(ref ret_val)) => match_expr_param(cx, ret_val, params[0].pat), + ExprKind::Block(ref block, _) => { + if_chain! { + if block.stmts.len() == 1; + if let StmtKind::Semi(ref expr) | StmtKind::Expr(ref expr) = block.stmts[0].kind; + if let ExprKind::Ret(Some(ref ret_val)) = expr.kind; + then { + match_expr_param(cx, ret_val, params[0].pat) + } else { + false + } + } + }, + _ => false, + } +} + +/// Returns true iff an expression returns the same thing as a parameter's pattern +fn match_expr_param(cx: &LateContext<'_, '_>, expr: &Expr<'_>, pat: &Pat<'_>) -> bool { + if let PatKind::Binding(_, _, ident, _) = pat.kind { + match_var(expr, ident.name) && !(cx.tables.hir_owner == Some(expr.hir_id.owner) && is_adjusted(cx, expr)) + } else { + false + } +} diff --git a/src/lintlist/mod.rs b/src/lintlist/mod.rs index cac3cc6bdb316..a9cd5469048e4 100644 --- a/src/lintlist/mod.rs +++ b/src/lintlist/mod.rs @@ -1144,6 +1144,13 @@ pub static ref ALL_LINTS: Vec = vec![ deprecation: None, module: "methods", }, + Lint { + name: "map_identity", + group: "complexity", + desc: "using iterator.map(|x| x)", + deprecation: None, + module: "map_identity", + }, Lint { name: "map_unwrap_or", group: "pedantic", diff --git a/tests/ui/map_flatten.fixed b/tests/ui/map_flatten.fixed index 7ac368878ab7e..4171d80f48a3f 100644 --- a/tests/ui/map_flatten.fixed +++ b/tests/ui/map_flatten.fixed @@ -2,6 +2,7 @@ #![warn(clippy::all, clippy::pedantic)] #![allow(clippy::missing_docs_in_private_items)] +#![allow(clippy::map_identity)] fn main() { let _: Vec<_> = vec![5_i8; 6].into_iter().flat_map(|x| 0..x).collect(); diff --git a/tests/ui/map_flatten.rs b/tests/ui/map_flatten.rs index a608601039ce7..16a0fd090ad04 100644 --- a/tests/ui/map_flatten.rs +++ b/tests/ui/map_flatten.rs @@ -2,6 +2,7 @@ #![warn(clippy::all, clippy::pedantic)] #![allow(clippy::missing_docs_in_private_items)] +#![allow(clippy::map_identity)] fn main() { let _: Vec<_> = vec![5_i8; 6].into_iter().map(|x| 0..x).flatten().collect(); diff --git a/tests/ui/map_flatten.stderr b/tests/ui/map_flatten.stderr index 3cf2abd5b6d85..00bc41c15e9b8 100644 --- a/tests/ui/map_flatten.stderr +++ b/tests/ui/map_flatten.stderr @@ -1,5 +1,5 @@ error: called `map(..).flatten()` on an `Iterator`. This is more succinctly expressed by calling `.flat_map(..)` - --> $DIR/map_flatten.rs:7:21 + --> $DIR/map_flatten.rs:8:21 | LL | let _: Vec<_> = vec![5_i8; 6].into_iter().map(|x| 0..x).flatten().collect(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using `flat_map` instead: `vec![5_i8; 6].into_iter().flat_map(|x| 0..x)` @@ -7,7 +7,7 @@ LL | let _: Vec<_> = vec![5_i8; 6].into_iter().map(|x| 0..x).flatten().colle = note: `-D clippy::map-flatten` implied by `-D warnings` error: called `map(..).flatten()` on an `Option`. This is more succinctly expressed by calling `.and_then(..)` - --> $DIR/map_flatten.rs:8:24 + --> $DIR/map_flatten.rs:9:24 | LL | let _: Option<_> = (Some(Some(1))).map(|x| x).flatten(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using `and_then` instead: `(Some(Some(1))).and_then(|x| x)` diff --git a/tests/ui/map_identity.fixed b/tests/ui/map_identity.fixed new file mode 100644 index 0000000000000..4a1452b25f343 --- /dev/null +++ b/tests/ui/map_identity.fixed @@ -0,0 +1,23 @@ +// run-rustfix +#![warn(clippy::map_identity)] +#![allow(clippy::needless_return)] + +fn main() { + let x: [u16; 3] = [1, 2, 3]; + // should lint + let _: Vec<_> = x.iter().map(not_identity).collect(); + let _: Vec<_> = x.iter().collect(); + let _: Option = Some(3); + let _: Result = Ok(-3); + // should not lint + let _: Vec<_> = x.iter().map(|x| 2 * x).collect(); + let _: Vec<_> = x.iter().map(not_identity).map(|x| return x - 4).collect(); + let _: Option = None.map(|x: u8| x - 1); + let _: Result = Err(2.3).map(|x: i8| { + return x + 3; + }); +} + +fn not_identity(x: &u16) -> u16 { + *x +} diff --git a/tests/ui/map_identity.rs b/tests/ui/map_identity.rs new file mode 100644 index 0000000000000..65c7e6e1ea554 --- /dev/null +++ b/tests/ui/map_identity.rs @@ -0,0 +1,25 @@ +// run-rustfix +#![warn(clippy::map_identity)] +#![allow(clippy::needless_return)] + +fn main() { + let x: [u16; 3] = [1, 2, 3]; + // should lint + let _: Vec<_> = x.iter().map(not_identity).map(|x| return x).collect(); + let _: Vec<_> = x.iter().map(std::convert::identity).map(|y| y).collect(); + let _: Option = Some(3).map(|x| x); + let _: Result = Ok(-3).map(|x| { + return x; + }); + // should not lint + let _: Vec<_> = x.iter().map(|x| 2 * x).collect(); + let _: Vec<_> = x.iter().map(not_identity).map(|x| return x - 4).collect(); + let _: Option = None.map(|x: u8| x - 1); + let _: Result = Err(2.3).map(|x: i8| { + return x + 3; + }); +} + +fn not_identity(x: &u16) -> u16 { + *x +} diff --git a/tests/ui/map_identity.stderr b/tests/ui/map_identity.stderr new file mode 100644 index 0000000000000..e4a0320cbda55 --- /dev/null +++ b/tests/ui/map_identity.stderr @@ -0,0 +1,37 @@ +error: unnecessary map of the identity function + --> $DIR/map_identity.rs:8:47 + | +LL | let _: Vec<_> = x.iter().map(not_identity).map(|x| return x).collect(); + | ^^^^^^^^^^^^^^^^^^ help: remove the call to `map` + | + = note: `-D clippy::map-identity` implied by `-D warnings` + +error: unnecessary map of the identity function + --> $DIR/map_identity.rs:9:57 + | +LL | let _: Vec<_> = x.iter().map(std::convert::identity).map(|y| y).collect(); + | ^^^^^^^^^^^ help: remove the call to `map` + +error: unnecessary map of the identity function + --> $DIR/map_identity.rs:9:29 + | +LL | let _: Vec<_> = x.iter().map(std::convert::identity).map(|y| y).collect(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove the call to `map` + +error: unnecessary map of the identity function + --> $DIR/map_identity.rs:10:32 + | +LL | let _: Option = Some(3).map(|x| x); + | ^^^^^^^^^^^ help: remove the call to `map` + +error: unnecessary map of the identity function + --> $DIR/map_identity.rs:11:36 + | +LL | let _: Result = Ok(-3).map(|x| { + | ____________________________________^ +LL | | return x; +LL | | }); + | |______^ help: remove the call to `map` + +error: aborting due to 5 previous errors + From 80bcbf521c7ff95e38a7567432b5519cc18e5b2a Mon Sep 17 00:00:00 2001 From: flip1995 Date: Tue, 23 Jun 2020 17:05:22 +0200 Subject: [PATCH 02/99] Merge commit 'c2c07fa9d095931eb5684a42942a7b573a0c5238' into clippyup --- .github/ISSUE_TEMPLATE.md | 8 - .github/ISSUE_TEMPLATE/blank_issue.md | 4 + .github/ISSUE_TEMPLATE/bug_report.md | 47 ++++ .github/ISSUE_TEMPLATE/config.yml | 5 + .github/ISSUE_TEMPLATE/ice.md | 53 +++++ .github/ISSUE_TEMPLATE/new_lint.md | 35 +++ .github/PULL_REQUEST_TEMPLATE.md | 1 + .github/driver.sh | 12 + clippy_lints/src/consts.rs | 2 +- clippy_lints/src/escape.rs | 2 +- clippy_lints/src/len_zero.rs | 3 +- clippy_lints/src/let_underscore.rs | 2 +- clippy_lints/src/lib.rs | 54 ++--- clippy_lints/src/loops.rs | 14 +- clippy_lints/src/macro_use.rs | 213 ++++++++++++++++-- clippy_lints/src/mem_replace.rs | 82 ++++--- clippy_lints/src/new_without_default.rs | 2 +- .../src/redundant_pattern_matching.rs | 80 +++++-- clippy_lints/src/suspicious_trait_impl.rs | 2 +- .../src/trivially_copy_pass_by_ref.rs | 2 +- clippy_lints/src/types.rs | 58 +---- clippy_lints/src/unnecessary_sort_by.rs | 5 +- clippy_lints/src/unnested_or_patterns.rs | 2 +- clippy_lints/src/utils/author.rs | 5 +- clippy_lints/src/utils/conf.rs | 4 +- clippy_lints/src/utils/hir_utils.rs | 13 +- clippy_lints/src/utils/sugg.rs | 4 +- clippy_lints/src/utils/usage.rs | 2 +- clippy_lints/src/wildcard_imports.rs | 2 +- src/driver.rs | 44 ++-- src/lintlist/mod.rs | 2 +- src/main.rs | 2 + tests/ui/auxiliary/macro_use_helper.rs | 60 +++++ tests/ui/blacklisted_name.rs | 25 +- tests/ui/blacklisted_name.stderr | 72 +++--- tests/ui/crashes/ice-5389.rs | 13 ++ tests/ui/if_same_then_else.rs | 12 + tests/ui/macro_use_imports.fixed | 43 ++++ tests/ui/macro_use_imports.rs | 44 +++- tests/ui/macro_use_imports.stderr | 26 ++- tests/ui/redundant_pattern_matching.fixed | 42 ++++ tests/ui/redundant_pattern_matching.rs | 42 ++++ tests/ui/redundant_pattern_matching.stderr | 56 ++--- ...undant_pattern_matching_const_result.fixed | 46 ++++ ...redundant_pattern_matching_const_result.rs | 52 +++++ ...ndant_pattern_matching_const_result.stderr | 46 ++++ tests/ui/repl_uninit.rs | 6 + tests/ui/repl_uninit.stderr | 19 +- 48 files changed, 1077 insertions(+), 293 deletions(-) delete mode 100644 .github/ISSUE_TEMPLATE.md create mode 100644 .github/ISSUE_TEMPLATE/blank_issue.md create mode 100644 .github/ISSUE_TEMPLATE/bug_report.md create mode 100644 .github/ISSUE_TEMPLATE/config.yml create mode 100644 .github/ISSUE_TEMPLATE/ice.md create mode 100644 .github/ISSUE_TEMPLATE/new_lint.md create mode 100644 tests/ui/auxiliary/macro_use_helper.rs create mode 100644 tests/ui/crashes/ice-5389.rs create mode 100644 tests/ui/macro_use_imports.fixed create mode 100644 tests/ui/redundant_pattern_matching_const_result.fixed create mode 100644 tests/ui/redundant_pattern_matching_const_result.rs create mode 100644 tests/ui/redundant_pattern_matching_const_result.stderr diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md deleted file mode 100644 index 15006a07b44f2..0000000000000 --- a/.github/ISSUE_TEMPLATE.md +++ /dev/null @@ -1,8 +0,0 @@ - diff --git a/.github/ISSUE_TEMPLATE/blank_issue.md b/.github/ISSUE_TEMPLATE/blank_issue.md new file mode 100644 index 0000000000000..9aef3ebe637a1 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/blank_issue.md @@ -0,0 +1,4 @@ +--- +name: Blank Issue +about: Create a blank issue. +--- diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000000000..d8f0c44148cae --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,47 @@ +--- +name: Bug Report +about: Create a bug report for Clippy +labels: L-bug +--- + + +I tried this code: + +```rust + +``` + +I expected to see this happen: *explanation* + +Instead, this happened: *explanation* + +### Meta + +- `cargo clippy -V`: e.g. clippy 0.0.212 (f455e46 2020-06-20) +- `rustc -Vv`: + ``` + rustc 1.46.0-nightly (f455e46ea 2020-06-20) + binary: rustc + commit-hash: f455e46eae1a227d735091091144601b467e1565 + commit-date: 2020-06-20 + host: x86_64-unknown-linux-gnu + release: 1.46.0-nightly + LLVM version: 10.0 + ``` + + +
Backtrace +

+ + ``` + + ``` + +

+
diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000000000..bd7dc0ac95c1f --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,5 @@ +blank_issues_enabled: true +contact_links: + - name: Rust Programming Language Forum + url: https://users.rust-lang.org + about: Please ask and answer questions about Rust here. diff --git a/.github/ISSUE_TEMPLATE/ice.md b/.github/ISSUE_TEMPLATE/ice.md new file mode 100644 index 0000000000000..3abe76bf2c497 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/ice.md @@ -0,0 +1,53 @@ +--- +name: Internal Compiler Error +about: Create a report for an internal compiler error in Clippy. +labels: L-bug, L-crash +--- + + +### Code + +```rust + +``` + +### Meta + +- `cargo clippy -V`: e.g. clippy 0.0.212 (f455e46 2020-06-20) +- `rustc -Vv`: + ``` + rustc 1.46.0-nightly (f455e46ea 2020-06-20) + binary: rustc + commit-hash: f455e46eae1a227d735091091144601b467e1565 + commit-date: 2020-06-20 + host: x86_64-unknown-linux-gnu + release: 1.46.0-nightly + LLVM version: 10.0 + ``` + +### Error output + +``` + +``` + + +
Backtrace +

+ + ``` + + ``` + +

+
diff --git a/.github/ISSUE_TEMPLATE/new_lint.md b/.github/ISSUE_TEMPLATE/new_lint.md new file mode 100644 index 0000000000000..70445d7ef2503 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/new_lint.md @@ -0,0 +1,35 @@ +--- +name: New lint suggestion +about: Suggest a new Clippy lint. +labels: L-lint +--- + +### What it does + +*What does this lint do?* + +### Categories (optional) + +- Kind: *See for list of lint kinds* + +*What benefit of this lint over old code?* + +For example: +- Remove bounce checking inserted by ... +- Remove the need to duplicating/storing/typo ... + +### Drawbacks + +None. + +### Example + +```rust + +``` + +Could be written as: + +```rust + +``` diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 97aa220afea54..137a73630940a 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -28,4 +28,5 @@ Delete this line and everything above before opening your PR. --- +*Please keep the line below* changelog: none diff --git a/.github/driver.sh b/.github/driver.sh index a2e87f5eb3745..2c17c4203ae5c 100644 --- a/.github/driver.sh +++ b/.github/driver.sh @@ -26,4 +26,16 @@ unset CARGO_MANIFEST_DIR sed -e "s,tests/ui,\$DIR," -e "/= help/d" cstring.stderr > normalized.stderr diff normalized.stderr tests/ui/cstring.stderr + +# make sure "clippy-driver --rustc --arg" and "rustc --arg" behave the same +SYSROOT=`rustc --print sysroot` +diff <(LD_LIBRARY_PATH=${SYSROOT}/lib ./target/debug/clippy-driver --rustc --version --verbose) <(rustc --version --verbose) + + +echo "fn main() {}" > target/driver_test.rs +# we can't run 2 rustcs on the same file at the same time +CLIPPY=`LD_LIBRARY_PATH=${SYSROOT}/lib ./target/debug/clippy-driver ./target/driver_test.rs --rustc` +RUSTC=`rustc ./target/driver_test.rs` +diff <($CLIPPY) <($RUSTC) + # TODO: CLIPPY_CONF_DIR / CARGO_MANIFEST_DIR diff --git a/clippy_lints/src/consts.rs b/clippy_lints/src/consts.rs index 22c5acca064e9..550752396c732 100644 --- a/clippy_lints/src/consts.rs +++ b/clippy_lints/src/consts.rs @@ -396,7 +396,7 @@ impl<'c, 'cc> ConstEvalLateContext<'c, 'cc> { let l = self.expr(left)?; let r = self.expr(right); match (l, r) { - (Constant::Int(l), Some(Constant::Int(r))) => match self.tables.expr_ty(left).kind { + (Constant::Int(l), Some(Constant::Int(r))) => match self.tables.expr_ty_opt(left)?.kind { ty::Int(ity) => { let l = sext(self.lcx.tcx, l, ity); let r = sext(self.lcx.tcx, r, ity); diff --git a/clippy_lints/src/escape.rs b/clippy_lints/src/escape.rs index 59af475af175e..77e90eeac4958 100644 --- a/clippy_lints/src/escape.rs +++ b/clippy_lints/src/escape.rs @@ -6,7 +6,7 @@ use rustc_middle::ty::{self, Ty}; use rustc_session::{declare_tool_lint, impl_lint_pass}; use rustc_span::source_map::Span; use rustc_target::abi::LayoutOf; -use rustc_typeck::expr_use_visitor::{ConsumeMode, Delegate, ExprUseVisitor, PlaceWithHirId, PlaceBase}; +use rustc_typeck::expr_use_visitor::{ConsumeMode, Delegate, ExprUseVisitor, PlaceBase, PlaceWithHirId}; use crate::utils::span_lint; diff --git a/clippy_lints/src/len_zero.rs b/clippy_lints/src/len_zero.rs index 13e85fda8ffeb..7838e8e8ab774 100644 --- a/clippy_lints/src/len_zero.rs +++ b/clippy_lints/src/len_zero.rs @@ -211,7 +211,8 @@ fn check_impl_items(cx: &LateContext<'_, '_>, item: &Item<'_>, impl_items: &[Imp } fn check_cmp(cx: &LateContext<'_, '_>, span: Span, method: &Expr<'_>, lit: &Expr<'_>, op: &str, compare_to: u32) { - if let (&ExprKind::MethodCall(ref method_path, _, ref args, _), &ExprKind::Lit(ref lit)) = (&method.kind, &lit.kind) { + if let (&ExprKind::MethodCall(ref method_path, _, ref args, _), &ExprKind::Lit(ref lit)) = (&method.kind, &lit.kind) + { // check if we are in an is_empty() method if let Some(name) = get_item_name(cx, method) { if name.as_str() == "is_empty" { diff --git a/clippy_lints/src/let_underscore.rs b/clippy_lints/src/let_underscore.rs index 710dec8d33fc9..acd628bbaca59 100644 --- a/clippy_lints/src/let_underscore.rs +++ b/clippy_lints/src/let_underscore.rs @@ -35,7 +35,7 @@ declare_clippy_lint! { /// **What it does:** Checks for `let _ = sync_lock` /// /// **Why is this bad?** This statement immediately drops the lock instead of - /// extending it's lifetime to the end of the scope, which is often not intended. + /// extending its lifetime to the end of the scope, which is often not intended. /// To extend lock lifetime to the end of the scope, use an underscore-prefixed /// name instead (i.e. _lock). If you want to explicitly drop the lock, /// `std::mem::drop` conveys your intention better and is less error-prone. diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index cd258c7b506c3..501220f28e5db 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -1,63 +1,44 @@ // error-pattern:cargo-clippy #![feature(bindings_after_at)] -#![feature(box_syntax)] #![feature(box_patterns)] +#![feature(box_syntax)] +#![feature(concat_idents)] +#![feature(crate_visibility_modifier)] +#![feature(drain_filter)] #![feature(or_patterns)] #![feature(rustc_private)] #![feature(stmt_expr_attributes)] -#![allow(clippy::missing_docs_in_private_items, clippy::must_use_candidate)] #![recursion_limit = "512"] -#![warn(rust_2018_idioms, trivial_casts, trivial_numeric_casts)] -#![deny(rustc::internal)] #![cfg_attr(feature = "deny-warnings", deny(warnings))] -#![feature(crate_visibility_modifier)] -#![feature(concat_idents)] -#![feature(drain_filter)] +#![allow(clippy::missing_docs_in_private_items, clippy::must_use_candidate)] +#![warn(trivial_casts, trivial_numeric_casts)] +// warn on lints, that are included in `rust-lang/rust`s bootstrap +#![warn(rust_2018_idioms, unused_lifetimes)] +// warn on rustc internal lints +#![deny(rustc::internal)] // FIXME: switch to something more ergonomic here, once available. // (Currently there is no way to opt into sysroot crates without `extern crate`.) -#[allow(unused_extern_crates)] extern crate rustc_ast; -#[allow(unused_extern_crates)] extern crate rustc_ast_pretty; -#[allow(unused_extern_crates)] extern crate rustc_attr; -#[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_hir; -#[allow(unused_extern_crates)] extern crate rustc_hir_pretty; -#[allow(unused_extern_crates)] extern crate rustc_index; -#[allow(unused_extern_crates)] extern crate rustc_infer; -#[allow(unused_extern_crates)] extern crate rustc_lexer; -#[allow(unused_extern_crates)] extern crate rustc_lint; -#[allow(unused_extern_crates)] extern crate rustc_middle; -#[allow(unused_extern_crates)] extern crate rustc_mir; -#[allow(unused_extern_crates)] extern crate rustc_parse; -#[allow(unused_extern_crates)] extern crate rustc_parse_format; -#[allow(unused_extern_crates)] extern crate rustc_session; -#[allow(unused_extern_crates)] extern crate rustc_span; -#[allow(unused_extern_crates)] extern crate rustc_target; -#[allow(unused_extern_crates)] extern crate rustc_trait_selection; -#[allow(unused_extern_crates)] extern crate rustc_typeck; use rustc_data_structures::fx::FxHashSet; @@ -82,14 +63,10 @@ use rustc_session::Session; /// # Example /// /// ``` -/// # #![feature(rustc_private)] -/// # #[allow(unused_extern_crates)] -/// # extern crate rustc_middle; -/// # #[allow(unused_extern_crates)] -/// # extern crate rustc_session; -/// # #[macro_use] -/// # use clippy_lints::declare_clippy_lint; +/// #![feature(rustc_private)] +/// extern crate rustc_session; /// use rustc_session::declare_tool_lint; +/// use clippy_lints::declare_clippy_lint; /// /// declare_clippy_lint! { /// /// **What it does:** Checks for ... (describe what the lint matches). @@ -1062,7 +1039,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: store.register_early_pass(|| box option_env_unwrap::OptionEnvUnwrap); let warn_on_all_wildcard_imports = conf.warn_on_all_wildcard_imports; store.register_late_pass(move || box wildcard_imports::WildcardImports::new(warn_on_all_wildcard_imports)); - store.register_early_pass(|| box macro_use::MacroUseImports); store.register_late_pass(|| box verbose_file_reads::VerboseFileReads); store.register_late_pass(|| box redundant_pub_crate::RedundantPubCrate::default()); store.register_late_pass(|| box unnamed_address::UnnamedAddress); @@ -1080,6 +1056,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: single_char_binding_names_threshold, }); store.register_early_pass(|| box unnested_or_patterns::UnnestedOrPatterns); + store.register_late_pass(|| box macro_use::MacroUseImports::default()); store.register_group(true, "clippy::restriction", Some("clippy_restriction"), vec![ LintId::of(&arithmetic::FLOAT_ARITHMETIC), @@ -1187,6 +1164,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: LintId::of(&types::OPTION_OPTION), LintId::of(&unicode::NON_ASCII_LITERAL), LintId::of(&unicode::UNICODE_NOT_NFC), + LintId::of(&unnested_or_patterns::UNNESTED_OR_PATTERNS), LintId::of(&unused_self::UNUSED_SELF), LintId::of(&wildcard_imports::ENUM_GLOB_USE), LintId::of(&wildcard_imports::WILDCARD_IMPORTS), @@ -1440,7 +1418,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: LintId::of(&unnamed_address::FN_ADDRESS_COMPARISONS), LintId::of(&unnamed_address::VTABLE_ADDRESS_COMPARISONS), LintId::of(&unnecessary_sort_by::UNNECESSARY_SORT_BY), - LintId::of(&unnested_or_patterns::UNNESTED_OR_PATTERNS), LintId::of(&unsafe_removed_from_name::UNSAFE_REMOVED_FROM_NAME), LintId::of(&unused_io_amount::UNUSED_IO_AMOUNT), LintId::of(&unwrap::PANICKING_UNWRAP), @@ -1624,7 +1601,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: LintId::of(&types::UNNECESSARY_CAST), LintId::of(&types::VEC_BOX), LintId::of(&unnecessary_sort_by::UNNECESSARY_SORT_BY), - LintId::of(&unnested_or_patterns::UNNESTED_OR_PATTERNS), LintId::of(&unwrap::UNNECESSARY_UNWRAP), LintId::of(&useless_conversion::USELESS_CONVERSION), LintId::of(&zero_div_zero::ZERO_DIVIDED_BY_ZERO), diff --git a/clippy_lints/src/loops.rs b/clippy_lints/src/loops.rs index 83093ec51bd90..9c8e8d8fabf4e 100644 --- a/clippy_lints/src/loops.rs +++ b/clippy_lints/src/loops.rs @@ -28,7 +28,7 @@ use rustc_middle::ty::{self, Ty, TyS}; use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::source_map::Span; use rustc_span::symbol::Symbol; -use rustc_typeck::expr_use_visitor::{ConsumeMode, Delegate, ExprUseVisitor, PlaceWithHirId, PlaceBase}; +use rustc_typeck::expr_use_visitor::{ConsumeMode, Delegate, ExprUseVisitor, PlaceBase, PlaceWithHirId}; use std::iter::{once, Iterator}; use std::mem; @@ -1497,7 +1497,7 @@ struct MutatePairDelegate<'a, 'tcx> { span_high: Option, } -impl<'a, 'tcx> Delegate<'tcx> for MutatePairDelegate<'a, 'tcx> { +impl<'tcx> Delegate<'tcx> for MutatePairDelegate<'_, 'tcx> { fn consume(&mut self, _: &PlaceWithHirId<'tcx>, _: ConsumeMode) {} fn borrow(&mut self, cmt: &PlaceWithHirId<'tcx>, bk: ty::BorrowKind) { @@ -1525,7 +1525,7 @@ impl<'a, 'tcx> Delegate<'tcx> for MutatePairDelegate<'a, 'tcx> { } } -impl<'a, 'tcx> MutatePairDelegate<'a, 'tcx> { +impl MutatePairDelegate<'_, '_> { fn mutation_span(&self) -> (Option, Option) { (self.span_low, self.span_high) } @@ -1580,13 +1580,13 @@ fn check_for_mutability(cx: &LateContext<'_, '_>, bound: &Expr<'_>) -> Option ( +fn check_for_mutation<'a, 'tcx>( cx: &LateContext<'a, 'tcx>, body: &Expr<'_>, bound_ids: &[Option], ) -> (Option, Option) { let mut delegate = MutatePairDelegate { - cx: cx, + cx, hir_id_low: bound_ids[0], hir_id_high: bound_ids[1], span_low: None, @@ -2042,7 +2042,7 @@ impl<'a, 'tcx> Visitor<'tcx> for InitializeVisitor<'a, 'tcx> { if self.state == VarState::DontWarn { return; } - if SpanlessEq::new(self.cx).eq_expr(&expr, self.end_expr) { + if expr.hir_id == self.end_expr.hir_id { self.past_loop = true; return; } @@ -2292,7 +2292,7 @@ struct HasBreakOrReturnVisitor { has_break_or_return: bool, } -impl<'a, 'tcx> Visitor<'tcx> for HasBreakOrReturnVisitor { +impl<'tcx> Visitor<'tcx> for HasBreakOrReturnVisitor { type Map = Map<'tcx>; fn visit_expr(&mut self, expr: &'tcx Expr<'_>) { diff --git a/clippy_lints/src/macro_use.rs b/clippy_lints/src/macro_use.rs index b1345d0b751ae..b845b20d2c012 100644 --- a/clippy_lints/src/macro_use.rs +++ b/clippy_lints/src/macro_use.rs @@ -1,10 +1,13 @@ -use crate::utils::{snippet, span_lint_and_sugg}; +use crate::utils::{in_macro, snippet, span_lint_and_sugg}; +use hir::def::{DefKind, Res}; use if_chain::if_chain; use rustc_ast::ast; +use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_errors::Applicability; -use rustc_lint::{EarlyContext, EarlyLintPass}; -use rustc_session::{declare_lint_pass, declare_tool_lint}; -use rustc_span::edition::Edition; +use rustc_hir as hir; +use rustc_lint::{LateContext, LateLintPass, LintContext}; +use rustc_session::{declare_tool_lint, impl_lint_pass}; +use rustc_span::{edition::Edition, Span}; declare_clippy_lint! { /// **What it does:** Checks for `#[macro_use] use...`. @@ -12,7 +15,7 @@ declare_clippy_lint! { /// **Why is this bad?** Since the Rust 2018 edition you can import /// macro's directly, this is considered idiomatic. /// - /// **Known problems:** This lint does not generate an auto-applicable suggestion. + /// **Known problems:** None. /// /// **Example:** /// ```rust @@ -24,29 +27,205 @@ declare_clippy_lint! { "#[macro_use] is no longer needed" } -declare_lint_pass!(MacroUseImports => [MACRO_USE_IMPORTS]); +const BRACKETS: &[char] = &['<', '>']; -impl EarlyLintPass for MacroUseImports { - fn check_item(&mut self, ecx: &EarlyContext<'_>, item: &ast::Item) { +#[derive(Clone, Debug, PartialEq, Eq)] +struct PathAndSpan { + path: String, + span: Span, +} + +/// `MacroRefData` includes the name of the macro +/// and the path from `SourceMap::span_to_filename`. +#[derive(Debug, Clone)] +pub struct MacroRefData { + name: String, + path: String, +} + +impl MacroRefData { + pub fn new(name: String, callee: Span, cx: &LateContext<'_, '_>) -> Self { + let mut path = cx.sess().source_map().span_to_filename(callee).to_string(); + + // std lib paths are <::std::module::file type> + // so remove brackets, space and type. + if path.contains('<') { + path = path.replace(BRACKETS, ""); + } + if path.contains(' ') { + path = path.split(' ').next().unwrap().to_string(); + } + Self { name, path } + } +} + +#[derive(Default)] +#[allow(clippy::module_name_repetitions)] +pub struct MacroUseImports { + /// the actual import path used and the span of the attribute above it. + imports: Vec<(String, Span)>, + /// the span of the macro reference, kept to ensure only one reference is used per macro call. + collected: FxHashSet, + mac_refs: Vec, +} + +impl_lint_pass!(MacroUseImports => [MACRO_USE_IMPORTS]); + +impl MacroUseImports { + fn push_unique_macro(&mut self, cx: &LateContext<'_, '_>, span: Span) { + let call_site = span.source_callsite(); + let name = snippet(cx, cx.sess().source_map().span_until_char(call_site, '!'), "_"); + if let Some(callee) = span.source_callee() { + if !self.collected.contains(&call_site) { + let name = if name.contains("::") { + name.split("::").last().unwrap().to_string() + } else { + name.to_string() + }; + + self.mac_refs.push(MacroRefData::new(name, callee.def_site, cx)); + self.collected.insert(call_site); + } + } + } + + fn push_unique_macro_pat_ty(&mut self, cx: &LateContext<'_, '_>, span: Span) { + let call_site = span.source_callsite(); + let name = snippet(cx, cx.sess().source_map().span_until_char(call_site, '!'), "_"); + if let Some(callee) = span.source_callee() { + if !self.collected.contains(&call_site) { + self.mac_refs + .push(MacroRefData::new(name.to_string(), callee.def_site, cx)); + self.collected.insert(call_site); + } + } + } +} + +impl<'l, 'txc> LateLintPass<'l, 'txc> for MacroUseImports { + fn check_item(&mut self, cx: &LateContext<'_, '_>, item: &hir::Item<'_>) { if_chain! { - if ecx.sess.opts.edition == Edition::Edition2018; - if let ast::ItemKind::Use(use_tree) = &item.kind; + if cx.sess().opts.edition == Edition::Edition2018; + if let hir::ItemKind::Use(path, _kind) = &item.kind; if let Some(mac_attr) = item .attrs .iter() .find(|attr| attr.ident().map(|s| s.to_string()) == Some("macro_use".to_string())); + if let Res::Def(DefKind::Mod, id) = path.res; then { - let msg = "`macro_use` attributes are no longer needed in the Rust 2018 edition"; - let help = format!("use {}::", snippet(ecx, use_tree.span, "_")); + for kid in cx.tcx.item_children(id).iter() { + if let Res::Def(DefKind::Macro(_mac_type), mac_id) = kid.res { + let span = mac_attr.span; + let def_path = cx.tcx.def_path_str(mac_id); + self.imports.push((def_path, span)); + } + } + } else { + if in_macro(item.span) { + self.push_unique_macro_pat_ty(cx, item.span); + } + } + } + } + fn check_attribute(&mut self, cx: &LateContext<'_, '_>, attr: &ast::Attribute) { + if in_macro(attr.span) { + self.push_unique_macro(cx, attr.span); + } + } + fn check_expr(&mut self, cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>) { + if in_macro(expr.span) { + self.push_unique_macro(cx, expr.span); + } + } + fn check_stmt(&mut self, cx: &LateContext<'_, '_>, stmt: &hir::Stmt<'_>) { + if in_macro(stmt.span) { + self.push_unique_macro(cx, stmt.span); + } + } + fn check_pat(&mut self, cx: &LateContext<'_, '_>, pat: &hir::Pat<'_>) { + if in_macro(pat.span) { + self.push_unique_macro_pat_ty(cx, pat.span); + } + } + fn check_ty(&mut self, cx: &LateContext<'_, '_>, ty: &hir::Ty<'_>) { + if in_macro(ty.span) { + self.push_unique_macro_pat_ty(cx, ty.span); + } + } + #[allow(clippy::too_many_lines)] + fn check_crate_post(&mut self, cx: &LateContext<'_, '_>, _krate: &hir::Crate<'_>) { + let mut used = FxHashMap::default(); + let mut check_dup = vec![]; + for (import, span) in &self.imports { + let found_idx = self.mac_refs.iter().position(|mac| import.ends_with(&mac.name)); + + if let Some(idx) = found_idx { + let _ = self.mac_refs.remove(idx); + let seg = import.split("::").collect::>(); + + match seg.as_slice() { + // an empty path is impossible + // a path should always consist of 2 or more segments + [] | [_] => return, + [root, item] => { + if !check_dup.contains(&(*item).to_string()) { + used.entry(((*root).to_string(), span)) + .or_insert_with(Vec::new) + .push((*item).to_string()); + check_dup.push((*item).to_string()); + } + }, + [root, rest @ ..] => { + if rest.iter().all(|item| !check_dup.contains(&(*item).to_string())) { + let filtered = rest + .iter() + .filter_map(|item| { + if check_dup.contains(&(*item).to_string()) { + None + } else { + Some((*item).to_string()) + } + }) + .collect::>(); + used.entry(((*root).to_string(), span)) + .or_insert_with(Vec::new) + .push(filtered.join("::")); + check_dup.extend(filtered); + } else { + let rest = rest.to_vec(); + used.entry(((*root).to_string(), span)) + .or_insert_with(Vec::new) + .push(rest.join("::")); + check_dup.extend(rest.iter().map(ToString::to_string)); + } + }, + } + } + } + + let mut suggestions = vec![]; + for ((root, span), path) in used { + if path.len() == 1 { + suggestions.push((span, format!("{}::{}", root, path[0]))) + } else { + suggestions.push((span, format!("{}::{{{}}}", root, path.join(", ")))) + } + } + + // If mac_refs is not empty we have encountered an import we could not handle + // such as `std::prelude::v1::foo` or some other macro that expands to an import. + if self.mac_refs.is_empty() { + for (span, import) in suggestions { + let help = format!("use {};", import); span_lint_and_sugg( - ecx, + cx, MACRO_USE_IMPORTS, - mac_attr.span, - msg, + *span, + "`macro_use` attributes are no longer needed in the Rust 2018 edition", "remove the attribute and import the macro directly, try", help, - Applicability::HasPlaceholders, - ); + Applicability::MaybeIncorrect, + ) } } } diff --git a/clippy_lints/src/mem_replace.rs b/clippy_lints/src/mem_replace.rs index ab6865bf0f3b7..e2672e02b36da 100644 --- a/clippy_lints/src/mem_replace.rs +++ b/clippy_lints/src/mem_replace.rs @@ -135,33 +135,59 @@ fn check_replace_option_with_none(cx: &LateContext<'_, '_>, src: &Expr<'_>, dest } } -fn check_replace_with_uninit(cx: &LateContext<'_, '_>, src: &Expr<'_>, expr_span: Span) { - if let ExprKind::Call(ref repl_func, ref repl_args) = src.kind { - if_chain! { - if repl_args.is_empty(); - if let ExprKind::Path(ref repl_func_qpath) = repl_func.kind; - if let Some(repl_def_id) = cx.tables.qpath_res(repl_func_qpath, repl_func.hir_id).opt_def_id(); - then { - if cx.tcx.is_diagnostic_item(sym::mem_uninitialized, repl_def_id) { - span_lint_and_help( - cx, - MEM_REPLACE_WITH_UNINIT, - expr_span, - "replacing with `mem::uninitialized()`", - None, - "consider using the `take_mut` crate instead", - ); - } else if cx.tcx.is_diagnostic_item(sym::mem_zeroed, repl_def_id) && - !cx.tables.expr_ty(src).is_primitive() { - span_lint_and_help( - cx, - MEM_REPLACE_WITH_UNINIT, - expr_span, - "replacing with `mem::zeroed()`", - None, - "consider using a default value or the `take_mut` crate instead", - ); - } +fn check_replace_with_uninit(cx: &LateContext<'_, '_>, src: &Expr<'_>, dest: &Expr<'_>, expr_span: Span) { + if_chain! { + // check if replacement is mem::MaybeUninit::uninit().assume_init() + if let Some(method_def_id) = cx.tables.type_dependent_def_id(src.hir_id); + if cx.tcx.is_diagnostic_item(sym::assume_init, method_def_id); + then { + let mut applicability = Applicability::MachineApplicable; + span_lint_and_sugg( + cx, + MEM_REPLACE_WITH_UNINIT, + expr_span, + "replacing with `mem::MaybeUninit::uninit().assume_init()`", + "consider using", + format!( + "std::ptr::read({})", + snippet_with_applicability(cx, dest.span, "", &mut applicability) + ), + applicability, + ); + return; + } + } + + if_chain! { + if let ExprKind::Call(ref repl_func, ref repl_args) = src.kind; + if repl_args.is_empty(); + if let ExprKind::Path(ref repl_func_qpath) = repl_func.kind; + if let Some(repl_def_id) = cx.tables.qpath_res(repl_func_qpath, repl_func.hir_id).opt_def_id(); + then { + if cx.tcx.is_diagnostic_item(sym::mem_uninitialized, repl_def_id) { + let mut applicability = Applicability::MachineApplicable; + span_lint_and_sugg( + cx, + MEM_REPLACE_WITH_UNINIT, + expr_span, + "replacing with `mem::uninitialized()`", + "consider using", + format!( + "std::ptr::read({})", + snippet_with_applicability(cx, dest.span, "", &mut applicability) + ), + applicability, + ); + } else if cx.tcx.is_diagnostic_item(sym::mem_zeroed, repl_def_id) && + !cx.tables.expr_ty(src).is_primitive() { + span_lint_and_help( + cx, + MEM_REPLACE_WITH_UNINIT, + expr_span, + "replacing with `mem::zeroed()`", + None, + "consider using a default value or the `take_mut` crate instead", + ); } } } @@ -209,7 +235,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MemReplace { if let [dest, src] = &**func_args; then { check_replace_option_with_none(cx, src, dest, expr.span); - check_replace_with_uninit(cx, src, expr.span); + check_replace_with_uninit(cx, src, dest, expr.span); check_replace_with_default(cx, src, dest, expr.span); } } diff --git a/clippy_lints/src/new_without_default.rs b/clippy_lints/src/new_without_default.rs index dd236535c18ad..42200385932b0 100644 --- a/clippy_lints/src/new_without_default.rs +++ b/clippy_lints/src/new_without_default.rs @@ -33,7 +33,7 @@ declare_clippy_lint! { /// } /// ``` /// - /// To fix the lint, and a `Default` implementation that delegates to `new`: + /// To fix the lint, add a `Default` implementation that delegates to `new`: /// /// ```ignore /// struct Foo(Bar); diff --git a/clippy_lints/src/redundant_pattern_matching.rs b/clippy_lints/src/redundant_pattern_matching.rs index f16b916441ae8..3c528a295b044 100644 --- a/clippy_lints/src/redundant_pattern_matching.rs +++ b/clippy_lints/src/redundant_pattern_matching.rs @@ -1,10 +1,13 @@ -use crate::utils::{match_qpath, match_trait_method, paths, snippet, span_lint_and_then}; +use crate::utils::{in_constant, match_qpath, match_trait_method, paths, snippet, span_lint_and_then}; use if_chain::if_chain; use rustc_ast::ast::LitKind; use rustc_errors::Applicability; -use rustc_hir::{Arm, Expr, ExprKind, MatchSource, PatKind, QPath}; +use rustc_hir::{Arm, Expr, ExprKind, HirId, MatchSource, PatKind, QPath}; use rustc_lint::{LateContext, LateLintPass}; +use rustc_middle::ty; +use rustc_mir::const_eval::is_const_fn; use rustc_session::{declare_lint_pass, declare_tool_lint}; +use rustc_span::source_map::Symbol; declare_clippy_lint! { /// **What it does:** Lint for redundant pattern matching over `Result` or @@ -64,26 +67,37 @@ fn find_sugg_for_if_let<'a, 'tcx>( arms: &[Arm<'_>], keyword: &'static str, ) { + fn find_suggestion(cx: &LateContext<'_, '_>, hir_id: HirId, path: &QPath<'_>) -> Option<&'static str> { + if match_qpath(path, &paths::RESULT_OK) && can_suggest(cx, hir_id, sym!(result_type), "is_ok") { + return Some("is_ok()"); + } + if match_qpath(path, &paths::RESULT_ERR) && can_suggest(cx, hir_id, sym!(result_type), "is_err") { + return Some("is_err()"); + } + if match_qpath(path, &paths::OPTION_SOME) && can_suggest(cx, hir_id, sym!(option_type), "is_some") { + return Some("is_some()"); + } + if match_qpath(path, &paths::OPTION_NONE) && can_suggest(cx, hir_id, sym!(option_type), "is_none") { + return Some("is_none()"); + } + None + } + + let hir_id = expr.hir_id; let good_method = match arms[0].pat.kind { PatKind::TupleStruct(ref path, ref patterns, _) if patterns.len() == 1 => { if let PatKind::Wild = patterns[0].kind { - if match_qpath(path, &paths::RESULT_OK) { - "is_ok()" - } else if match_qpath(path, &paths::RESULT_ERR) { - "is_err()" - } else if match_qpath(path, &paths::OPTION_SOME) { - "is_some()" - } else { - return; - } + find_suggestion(cx, hir_id, path) } else { - return; + None } }, - - PatKind::Path(ref path) if match_qpath(path, &paths::OPTION_NONE) => "is_none()", - - _ => return, + PatKind::Path(ref path) => find_suggestion(cx, hir_id, path), + _ => None, + }; + let good_method = match good_method { + Some(method) => method, + None => return, }; // check that `while_let_on_iterator` lint does not trigger @@ -128,6 +142,7 @@ fn find_sugg_for_match<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_ if arms.len() == 2 { let node_pair = (&arms[0].pat.kind, &arms[1].pat.kind); + let hir_id = expr.hir_id; let found_good_method = match node_pair { ( PatKind::TupleStruct(ref path_left, ref patterns_left, _), @@ -142,6 +157,8 @@ fn find_sugg_for_match<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_ &paths::RESULT_ERR, "is_ok()", "is_err()", + || can_suggest(cx, hir_id, sym!(result_type), "is_ok"), + || can_suggest(cx, hir_id, sym!(result_type), "is_err"), ) } else { None @@ -160,6 +177,8 @@ fn find_sugg_for_match<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_ &paths::OPTION_NONE, "is_some()", "is_none()", + || can_suggest(cx, hir_id, sym!(option_type), "is_some"), + || can_suggest(cx, hir_id, sym!(option_type), "is_none"), ) } else { None @@ -188,6 +207,7 @@ fn find_sugg_for_match<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_ } } +#[allow(clippy::too_many_arguments)] fn find_good_method_for_match<'a>( arms: &[Arm<'_>], path_left: &QPath<'_>, @@ -196,6 +216,8 @@ fn find_good_method_for_match<'a>( expected_right: &[&str], should_be_left: &'a str, should_be_right: &'a str, + can_suggest_left: impl Fn() -> bool, + can_suggest_right: impl Fn() -> bool, ) -> Option<&'a str> { let body_node_pair = if match_qpath(path_left, expected_left) && match_qpath(path_right, expected_right) { (&(*arms[0].body).kind, &(*arms[1].body).kind) @@ -207,10 +229,32 @@ fn find_good_method_for_match<'a>( match body_node_pair { (ExprKind::Lit(ref lit_left), ExprKind::Lit(ref lit_right)) => match (&lit_left.node, &lit_right.node) { - (LitKind::Bool(true), LitKind::Bool(false)) => Some(should_be_left), - (LitKind::Bool(false), LitKind::Bool(true)) => Some(should_be_right), + (LitKind::Bool(true), LitKind::Bool(false)) if can_suggest_left() => Some(should_be_left), + (LitKind::Bool(false), LitKind::Bool(true)) if can_suggest_right() => Some(should_be_right), _ => None, }, _ => None, } } + +fn can_suggest(cx: &LateContext<'_, '_>, hir_id: HirId, diag_item: Symbol, name: &str) -> bool { + if !in_constant(cx, hir_id) { + return true; + } + + // Avoid suggesting calls to non-`const fn`s in const contexts, see #5697. + cx.tcx + .get_diagnostic_item(diag_item) + .and_then(|def_id| { + cx.tcx.inherent_impls(def_id).iter().find_map(|imp| { + cx.tcx + .associated_items(*imp) + .in_definition_order() + .find_map(|item| match item.kind { + ty::AssocKind::Fn if item.ident.name.as_str() == name => Some(item.def_id), + _ => None, + }) + }) + }) + .map_or(false, |def_id| is_const_fn(cx.tcx, def_id)) +} diff --git a/clippy_lints/src/suspicious_trait_impl.rs b/clippy_lints/src/suspicious_trait_impl.rs index a9e6fa329c0f0..cf71c3144a2eb 100644 --- a/clippy_lints/src/suspicious_trait_impl.rs +++ b/clippy_lints/src/suspicious_trait_impl.rs @@ -184,7 +184,7 @@ struct BinaryExprVisitor { in_binary_expr: bool, } -impl<'a, 'tcx> Visitor<'tcx> for BinaryExprVisitor { +impl<'tcx> Visitor<'tcx> for BinaryExprVisitor { type Map = Map<'tcx>; fn visit_expr(&mut self, expr: &'tcx hir::Expr<'_>) { diff --git a/clippy_lints/src/trivially_copy_pass_by_ref.rs b/clippy_lints/src/trivially_copy_pass_by_ref.rs index 8e0cb94317aff..146ac4b09d5a4 100644 --- a/clippy_lints/src/trivially_copy_pass_by_ref.rs +++ b/clippy_lints/src/trivially_copy_pass_by_ref.rs @@ -58,7 +58,7 @@ pub struct TriviallyCopyPassByRef { limit: u64, } -impl<'a, 'tcx> TriviallyCopyPassByRef { +impl<'tcx> TriviallyCopyPassByRef { pub fn new(limit: Option, target: &SessionConfig) -> Self { let limit = limit.unwrap_or_else(|| { let bit_width = u64::from(target.ptr_width); diff --git a/clippy_lints/src/types.rs b/clippy_lints/src/types.rs index d59a2f1bae031..98de08f79f3d7 100644 --- a/clippy_lints/src/types.rs +++ b/clippy_lints/src/types.rs @@ -1945,16 +1945,12 @@ fn detect_extreme_expr<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_ let which = match (&ty.kind, cv) { (&ty::Bool, Constant::Bool(false)) | (&ty::Uint(_), Constant::Int(0)) => Minimum, - (&ty::Int(ity), Constant::Int(i)) - if i == unsext(cx.tcx, i128::MIN >> (128 - int_bits(cx.tcx, ity)), ity) => - { + (&ty::Int(ity), Constant::Int(i)) if i == unsext(cx.tcx, i128::MIN >> (128 - int_bits(cx.tcx, ity)), ity) => { Minimum }, (&ty::Bool, Constant::Bool(true)) => Maximum, - (&ty::Int(ity), Constant::Int(i)) - if i == unsext(cx.tcx, i128::MAX >> (128 - int_bits(cx.tcx, ity)), ity) => - { + (&ty::Int(ity), Constant::Int(i)) if i == unsext(cx.tcx, i128::MAX >> (128 - int_bits(cx.tcx, ity)), ity) => { Maximum }, (&ty::Uint(uty), Constant::Int(i)) if clip(cx.tcx, u128::MAX, uty) == i => Maximum, @@ -2083,50 +2079,20 @@ fn numeric_cast_precast_bounds<'a>(cx: &LateContext<'_, '_>, expr: &'a Expr<'_>) } match pre_cast_ty.kind { ty::Int(int_ty) => Some(match int_ty { - IntTy::I8 => ( - FullInt::S(i128::from(i8::MIN)), - FullInt::S(i128::from(i8::MAX)), - ), - IntTy::I16 => ( - FullInt::S(i128::from(i16::MIN)), - FullInt::S(i128::from(i16::MAX)), - ), - IntTy::I32 => ( - FullInt::S(i128::from(i32::MIN)), - FullInt::S(i128::from(i32::MAX)), - ), - IntTy::I64 => ( - FullInt::S(i128::from(i64::MIN)), - FullInt::S(i128::from(i64::MAX)), - ), + IntTy::I8 => (FullInt::S(i128::from(i8::MIN)), FullInt::S(i128::from(i8::MAX))), + IntTy::I16 => (FullInt::S(i128::from(i16::MIN)), FullInt::S(i128::from(i16::MAX))), + IntTy::I32 => (FullInt::S(i128::from(i32::MIN)), FullInt::S(i128::from(i32::MAX))), + IntTy::I64 => (FullInt::S(i128::from(i64::MIN)), FullInt::S(i128::from(i64::MAX))), IntTy::I128 => (FullInt::S(i128::MIN), FullInt::S(i128::MAX)), - IntTy::Isize => ( - FullInt::S(isize::MIN as i128), - FullInt::S(isize::MAX as i128), - ), + IntTy::Isize => (FullInt::S(isize::MIN as i128), FullInt::S(isize::MAX as i128)), }), ty::Uint(uint_ty) => Some(match uint_ty { - UintTy::U8 => ( - FullInt::U(u128::from(u8::MIN)), - FullInt::U(u128::from(u8::MAX)), - ), - UintTy::U16 => ( - FullInt::U(u128::from(u16::MIN)), - FullInt::U(u128::from(u16::MAX)), - ), - UintTy::U32 => ( - FullInt::U(u128::from(u32::MIN)), - FullInt::U(u128::from(u32::MAX)), - ), - UintTy::U64 => ( - FullInt::U(u128::from(u64::MIN)), - FullInt::U(u128::from(u64::MAX)), - ), + UintTy::U8 => (FullInt::U(u128::from(u8::MIN)), FullInt::U(u128::from(u8::MAX))), + UintTy::U16 => (FullInt::U(u128::from(u16::MIN)), FullInt::U(u128::from(u16::MAX))), + UintTy::U32 => (FullInt::U(u128::from(u32::MIN)), FullInt::U(u128::from(u32::MAX))), + UintTy::U64 => (FullInt::U(u128::from(u64::MIN)), FullInt::U(u128::from(u64::MAX))), UintTy::U128 => (FullInt::U(u128::MIN), FullInt::U(u128::MAX)), - UintTy::Usize => ( - FullInt::U(usize::MIN as u128), - FullInt::U(usize::MAX as u128), - ), + UintTy::Usize => (FullInt::U(usize::MIN as u128), FullInt::U(usize::MAX as u128)), }), _ => None, } diff --git a/clippy_lints/src/unnecessary_sort_by.rs b/clippy_lints/src/unnecessary_sort_by.rs index e94eebb88e497..6ac6a12529c86 100644 --- a/clippy_lints/src/unnecessary_sort_by.rs +++ b/clippy_lints/src/unnecessary_sort_by.rs @@ -95,7 +95,10 @@ fn mirrored_exprs( // The two exprs are method calls. // Check to see that the function is the same and the arguments are mirrored // This is enough because the receiver of the method is listed in the arguments - (ExprKind::MethodCall(left_segment, _, left_args, _), ExprKind::MethodCall(right_segment, _, right_args, _)) => { + ( + ExprKind::MethodCall(left_segment, _, left_args, _), + ExprKind::MethodCall(right_segment, _, right_args, _), + ) => { left_segment.ident == right_segment.ident && left_args .iter() diff --git a/clippy_lints/src/unnested_or_patterns.rs b/clippy_lints/src/unnested_or_patterns.rs index 8c281126c32bf..4d3682263f14f 100644 --- a/clippy_lints/src/unnested_or_patterns.rs +++ b/clippy_lints/src/unnested_or_patterns.rs @@ -45,7 +45,7 @@ declare_clippy_lint! { /// } /// ``` pub UNNESTED_OR_PATTERNS, - complexity, + pedantic, "unnested or-patterns, e.g., `Foo(Bar) | Foo(Baz) instead of `Foo(Bar | Baz)`" } diff --git a/clippy_lints/src/utils/author.rs b/clippy_lints/src/utils/author.rs index 8b58bbb5e6575..910b665ccb75e 100644 --- a/clippy_lints/src/utils/author.rs +++ b/clippy_lints/src/utils/author.rs @@ -251,7 +251,10 @@ impl<'tcx> Visitor<'tcx> for PrintVisitor { } }, ExprKind::MethodCall(ref _method_name, ref _generics, ref _args, ref _fn_span) => { - println!("MethodCall(ref method_name, ref generics, ref args, ref fn_span) = {};", current); + println!( + "MethodCall(ref method_name, ref generics, ref args, ref fn_span) = {};", + current + ); println!(" // unimplemented: `ExprKind::MethodCall` is not further destructured at the moment"); }, ExprKind::Tup(ref elements) => { diff --git a/clippy_lints/src/utils/conf.rs b/clippy_lints/src/utils/conf.rs index 9e8e0ff30ec6b..c41befbf147b8 100644 --- a/clippy_lints/src/utils/conf.rs +++ b/clippy_lints/src/utils/conf.rs @@ -106,8 +106,8 @@ macro_rules! define_Conf { pub use self::helpers::Conf; define_Conf! { - /// Lint: BLACKLISTED_NAME. The list of blacklisted names to lint about - (blacklisted_names, "blacklisted_names": Vec, ["foo", "bar", "baz", "quux"].iter().map(ToString::to_string).collect()), + /// Lint: BLACKLISTED_NAME. The list of blacklisted names to lint about. NB: `bar` is not here since it has legitimate uses + (blacklisted_names, "blacklisted_names": Vec, ["foo", "baz", "quux"].iter().map(ToString::to_string).collect()), /// Lint: COGNITIVE_COMPLEXITY. The maximum cognitive complexity a function can have (cognitive_complexity_threshold, "cognitive_complexity_threshold": u64, 25), /// DEPRECATED LINT: CYCLOMATIC_COMPLEXITY. Use the Cognitive Complexity lint instead. diff --git a/clippy_lints/src/utils/hir_utils.rs b/clippy_lints/src/utils/hir_utils.rs index 7a84f1c986aa7..9a9aa3f94eb4b 100644 --- a/clippy_lints/src/utils/hir_utils.rs +++ b/clippy_lints/src/utils/hir_utils.rs @@ -309,18 +309,15 @@ fn swap_binop<'a>( rhs: &'a Expr<'a>, ) -> Option<(BinOpKind, &'a Expr<'a>, &'a Expr<'a>)> { match binop { - BinOpKind::Add - | BinOpKind::Mul - | BinOpKind::Eq - | BinOpKind::Ne - | BinOpKind::BitAnd - | BinOpKind::BitXor - | BinOpKind::BitOr => Some((binop, rhs, lhs)), + BinOpKind::Add | BinOpKind::Eq | BinOpKind::Ne | BinOpKind::BitAnd | BinOpKind::BitXor | BinOpKind::BitOr => { + Some((binop, rhs, lhs)) + }, BinOpKind::Lt => Some((BinOpKind::Gt, rhs, lhs)), BinOpKind::Le => Some((BinOpKind::Ge, rhs, lhs)), BinOpKind::Ge => Some((BinOpKind::Le, rhs, lhs)), BinOpKind::Gt => Some((BinOpKind::Lt, rhs, lhs)), - BinOpKind::Shl + BinOpKind::Mul // Not always commutative, e.g. with matrices. See issue #5698 + | BinOpKind::Shl | BinOpKind::Shr | BinOpKind::Rem | BinOpKind::Sub diff --git a/clippy_lints/src/utils/sugg.rs b/clippy_lints/src/utils/sugg.rs index 73758b7eeb7eb..e919b1522d89a 100644 --- a/clippy_lints/src/utils/sugg.rs +++ b/clippy_lints/src/utils/sugg.rs @@ -509,7 +509,7 @@ fn indentation(cx: &T, span: Span) -> Option { } /// Convenience extension trait for `DiagnosticBuilder`. -pub trait DiagnosticBuilderExt<'a, T: LintContext> { +pub trait DiagnosticBuilderExt { /// Suggests to add an attribute to an item. /// /// Correctly handles indentation of the attribute and item. @@ -556,7 +556,7 @@ pub trait DiagnosticBuilderExt<'a, T: LintContext> { fn suggest_remove_item(&mut self, cx: &T, item: Span, msg: &str, applicability: Applicability); } -impl<'a, 'b, 'c, T: LintContext> DiagnosticBuilderExt<'c, T> for rustc_errors::DiagnosticBuilder<'b> { +impl DiagnosticBuilderExt for rustc_errors::DiagnosticBuilder<'_> { fn suggest_item_with_attr( &mut self, cx: &T, diff --git a/clippy_lints/src/utils/usage.rs b/clippy_lints/src/utils/usage.rs index 6a7a1f1ceaaef..0492878fc272f 100644 --- a/clippy_lints/src/utils/usage.rs +++ b/clippy_lints/src/utils/usage.rs @@ -8,7 +8,7 @@ use rustc_lint::LateContext; use rustc_middle::hir::map::Map; use rustc_middle::ty; use rustc_span::symbol::{Ident, Symbol}; -use rustc_typeck::expr_use_visitor::{ConsumeMode, Delegate, ExprUseVisitor, PlaceWithHirId, PlaceBase}; +use rustc_typeck::expr_use_visitor::{ConsumeMode, Delegate, ExprUseVisitor, PlaceBase, PlaceWithHirId}; /// Returns a set of mutated local variable IDs, or `None` if mutations could not be determined. pub fn mutated_variables<'a, 'tcx>(expr: &'tcx Expr<'_>, cx: &'a LateContext<'a, 'tcx>) -> Option> { diff --git a/clippy_lints/src/wildcard_imports.rs b/clippy_lints/src/wildcard_imports.rs index b637253bd0264..79f7705e281e5 100644 --- a/clippy_lints/src/wildcard_imports.rs +++ b/clippy_lints/src/wildcard_imports.rs @@ -36,7 +36,7 @@ declare_clippy_lint! { declare_clippy_lint! { /// **What it does:** Checks for wildcard imports `use _::*`. /// - /// **Why is this bad?** wildcard imports can polute the namespace. This is especially bad if + /// **Why is this bad?** wildcard imports can pollute the namespace. This is especially bad if /// you try to import something through a wildcard, that already has been imported by name from /// a different source: /// diff --git a/src/driver.rs b/src/driver.rs index 4453ae5ce4414..decd3a79cce18 100644 --- a/src/driver.rs +++ b/src/driver.rs @@ -1,15 +1,16 @@ -#![cfg_attr(feature = "deny-warnings", deny(warnings))] #![feature(rustc_private)] +#![cfg_attr(feature = "deny-warnings", deny(warnings))] +// warn on lints, that are included in `rust-lang/rust`s bootstrap +#![warn(rust_2018_idioms, unused_lifetimes)] +// warn on rustc internal lints +#![deny(rustc::internal)] // FIXME: switch to something more ergonomic here, once available. // (Currently there is no way to opt into sysroot crates without `extern crate`.) -#[allow(unused_extern_crates)] +extern crate rustc_data_structures; extern crate rustc_driver; -#[allow(unused_extern_crates)] extern crate rustc_errors; -#[allow(unused_extern_crates)] extern crate rustc_interface; -#[allow(unused_extern_crates)] extern crate rustc_middle; use rustc_interface::interface; @@ -93,7 +94,7 @@ impl rustc_driver::Callbacks for ClippyCallbacks { #[allow(clippy::find_map, clippy::filter_map)] fn describe_lints() { use lintlist::{Level, Lint, ALL_LINTS, LINT_LEVELS}; - use std::collections::HashSet; + use rustc_data_structures::fx::FxHashSet; println!( " @@ -137,7 +138,7 @@ Available lint options: let scoped = |x: &str| format!("clippy::{}", x); - let lint_groups: HashSet<_> = lints.iter().map(|lint| lint.group).collect(); + let lint_groups: FxHashSet<_> = lints.iter().map(|lint| lint.group).collect(); println!("Lint checks provided by clippy:\n"); println!(" {} {:7.7} meaning", padded("name"), "default"); @@ -207,6 +208,7 @@ Usage: Common options: -h, --help Print this message + --rustc Pass all args to rustc -V, --version Print version info and exit Other options are the same as `cargo check`. @@ -297,12 +299,6 @@ pub fn main() { exit(rustc_driver::catch_with_exit_code(move || { let mut orig_args: Vec = env::args().collect(); - if orig_args.iter().any(|a| a == "--version" || a == "-V") { - let version_info = rustc_tools_util::get_version_info!(); - println!("{}", version_info); - exit(0); - } - // Get the sysroot, looking from most specific to this invocation to the least: // - command line // - runtime environment @@ -348,6 +344,28 @@ pub fn main() { .map(|pb| pb.to_string_lossy().to_string()) .expect("need to specify SYSROOT env var during clippy compilation, or use rustup or multirust"); + // make "clippy-driver --rustc" work like a subcommand that passes further args to "rustc" + // for example `clippy-driver --rustc --version` will print the rustc version that clippy-driver + // uses + if let Some(pos) = orig_args.iter().position(|arg| arg == "--rustc") { + orig_args.remove(pos); + orig_args[0] = "rustc".to_string(); + + // if we call "rustc", we need to pass --sysroot here as well + let mut args: Vec = orig_args.clone(); + if !have_sys_root_arg { + args.extend(vec!["--sysroot".into(), sys_root]); + }; + + return rustc_driver::run_compiler(&args, &mut DefaultCallbacks, None, None); + } + + if orig_args.iter().any(|a| a == "--version" || a == "-V") { + let version_info = rustc_tools_util::get_version_info!(); + println!("{}", version_info); + exit(0); + } + // Setting RUSTC_WRAPPER causes Cargo to pass 'rustc' as the first argument. // We're invoking the compiler programmatically, so we ignore this/ let wrapper_mode = orig_args.get(1).map(Path::new).and_then(Path::file_stem) == Some("rustc".as_ref()); diff --git a/src/lintlist/mod.rs b/src/lintlist/mod.rs index cac3cc6bdb316..edceb75518008 100644 --- a/src/lintlist/mod.rs +++ b/src/lintlist/mod.rs @@ -2329,7 +2329,7 @@ pub static ref ALL_LINTS: Vec = vec![ }, Lint { name: "unnested_or_patterns", - group: "complexity", + group: "pedantic", desc: "unnested or-patterns, e.g., `Foo(Bar) | Foo(Baz) instead of `Foo(Bar | Baz)`", deprecation: None, module: "unnested_or_patterns", diff --git a/src/main.rs b/src/main.rs index bc43a34ed5d4a..6739a4cf2245e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,6 @@ #![cfg_attr(feature = "deny-warnings", deny(warnings))] +// warn on lints, that are included in `rust-lang/rust`s bootstrap +#![warn(rust_2018_idioms, unused_lifetimes)] use rustc_tools_util::VersionInfo; use std::env; diff --git a/tests/ui/auxiliary/macro_use_helper.rs b/tests/ui/auxiliary/macro_use_helper.rs new file mode 100644 index 0000000000000..ecb55d8cb48d5 --- /dev/null +++ b/tests/ui/auxiliary/macro_use_helper.rs @@ -0,0 +1,60 @@ +extern crate macro_rules; + +// STMT +#[macro_export] +macro_rules! pub_macro { + () => { + let _ = "hello Mr. Vonnegut"; + }; +} + +pub mod inner { + pub use super::*; + + // RE-EXPORT + // this will stick in `inner` module + pub use macro_rules::foofoo; + pub use macro_rules::try_err; + + pub mod nested { + pub use macro_rules::string_add; + } + + // ITEM + #[macro_export] + macro_rules! inner_mod_macro { + () => { + #[allow(dead_code)] + pub struct Tardis; + }; + } +} + +// EXPR +#[macro_export] +macro_rules! function_macro { + () => { + if true { + } else { + } + }; +} + +// TYPE +#[macro_export] +macro_rules! ty_macro { + () => { + Vec + }; +} + +mod extern_exports { + pub(super) mod private_inner { + #[macro_export] + macro_rules! pub_in_private_macro { + ($name:ident) => { + let $name = String::from("secrets and lies"); + }; + } + } +} diff --git a/tests/ui/blacklisted_name.rs b/tests/ui/blacklisted_name.rs index ca9d8d16b787d..cb15bdd2f1b2d 100644 --- a/tests/ui/blacklisted_name.rs +++ b/tests/ui/blacklisted_name.rs @@ -12,29 +12,34 @@ fn test(foo: ()) {} fn main() { let foo = 42; - let bar = 42; let baz = 42; + let quux = 42; + // Unlike these others, `bar` is actually considered an acceptable name. + // Among many other legitimate uses, bar commonly refers to a period of time in music. + // See https://github.com/rust-lang/rust-clippy/issues/5225. + let bar = 42; - let barb = 42; - let barbaric = 42; + let food = 42; + let foodstuffs = 42; + let bazaar = 42; match (42, Some(1337), Some(0)) { - (foo, Some(bar), baz @ Some(_)) => (), + (foo, Some(baz), quux @ Some(_)) => (), _ => (), } } fn issue_1647(mut foo: u8) { - let mut bar = 0; - if let Some(mut baz) = Some(42) {} + let mut baz = 0; + if let Some(mut quux) = Some(42) {} } fn issue_1647_ref() { - let ref bar = 0; - if let Some(ref baz) = Some(42) {} + let ref baz = 0; + if let Some(ref quux) = Some(42) {} } fn issue_1647_ref_mut() { - let ref mut bar = 0; - if let Some(ref mut baz) = Some(42) {} + let ref mut baz = 0; + if let Some(ref mut quux) = Some(42) {} } diff --git a/tests/ui/blacklisted_name.stderr b/tests/ui/blacklisted_name.stderr index 44123829fb0f6..70dbdaece8b6b 100644 --- a/tests/ui/blacklisted_name.stderr +++ b/tests/ui/blacklisted_name.stderr @@ -12,77 +12,77 @@ error: use of a blacklisted/placeholder name `foo` LL | let foo = 42; | ^^^ -error: use of a blacklisted/placeholder name `bar` +error: use of a blacklisted/placeholder name `baz` --> $DIR/blacklisted_name.rs:15:9 | -LL | let bar = 42; +LL | let baz = 42; | ^^^ -error: use of a blacklisted/placeholder name `baz` +error: use of a blacklisted/placeholder name `quux` --> $DIR/blacklisted_name.rs:16:9 | -LL | let baz = 42; - | ^^^ +LL | let quux = 42; + | ^^^^ error: use of a blacklisted/placeholder name `foo` - --> $DIR/blacklisted_name.rs:22:10 + --> $DIR/blacklisted_name.rs:27:10 | -LL | (foo, Some(bar), baz @ Some(_)) => (), +LL | (foo, Some(baz), quux @ Some(_)) => (), | ^^^ -error: use of a blacklisted/placeholder name `bar` - --> $DIR/blacklisted_name.rs:22:20 +error: use of a blacklisted/placeholder name `baz` + --> $DIR/blacklisted_name.rs:27:20 | -LL | (foo, Some(bar), baz @ Some(_)) => (), +LL | (foo, Some(baz), quux @ Some(_)) => (), | ^^^ -error: use of a blacklisted/placeholder name `baz` - --> $DIR/blacklisted_name.rs:22:26 +error: use of a blacklisted/placeholder name `quux` + --> $DIR/blacklisted_name.rs:27:26 | -LL | (foo, Some(bar), baz @ Some(_)) => (), - | ^^^ +LL | (foo, Some(baz), quux @ Some(_)) => (), + | ^^^^ error: use of a blacklisted/placeholder name `foo` - --> $DIR/blacklisted_name.rs:27:19 + --> $DIR/blacklisted_name.rs:32:19 | LL | fn issue_1647(mut foo: u8) { | ^^^ -error: use of a blacklisted/placeholder name `bar` - --> $DIR/blacklisted_name.rs:28:13 +error: use of a blacklisted/placeholder name `baz` + --> $DIR/blacklisted_name.rs:33:13 | -LL | let mut bar = 0; +LL | let mut baz = 0; | ^^^ -error: use of a blacklisted/placeholder name `baz` - --> $DIR/blacklisted_name.rs:29:21 +error: use of a blacklisted/placeholder name `quux` + --> $DIR/blacklisted_name.rs:34:21 | -LL | if let Some(mut baz) = Some(42) {} - | ^^^ +LL | if let Some(mut quux) = Some(42) {} + | ^^^^ -error: use of a blacklisted/placeholder name `bar` - --> $DIR/blacklisted_name.rs:33:13 +error: use of a blacklisted/placeholder name `baz` + --> $DIR/blacklisted_name.rs:38:13 | -LL | let ref bar = 0; +LL | let ref baz = 0; | ^^^ -error: use of a blacklisted/placeholder name `baz` - --> $DIR/blacklisted_name.rs:34:21 +error: use of a blacklisted/placeholder name `quux` + --> $DIR/blacklisted_name.rs:39:21 | -LL | if let Some(ref baz) = Some(42) {} - | ^^^ +LL | if let Some(ref quux) = Some(42) {} + | ^^^^ -error: use of a blacklisted/placeholder name `bar` - --> $DIR/blacklisted_name.rs:38:17 +error: use of a blacklisted/placeholder name `baz` + --> $DIR/blacklisted_name.rs:43:17 | -LL | let ref mut bar = 0; +LL | let ref mut baz = 0; | ^^^ -error: use of a blacklisted/placeholder name `baz` - --> $DIR/blacklisted_name.rs:39:25 +error: use of a blacklisted/placeholder name `quux` + --> $DIR/blacklisted_name.rs:44:25 | -LL | if let Some(ref mut baz) = Some(42) {} - | ^^^ +LL | if let Some(ref mut quux) = Some(42) {} + | ^^^^ error: aborting due to 14 previous errors diff --git a/tests/ui/crashes/ice-5389.rs b/tests/ui/crashes/ice-5389.rs new file mode 100644 index 0000000000000..de262199004b0 --- /dev/null +++ b/tests/ui/crashes/ice-5389.rs @@ -0,0 +1,13 @@ +#![allow(clippy::explicit_counter_loop)] + +fn main() { + let v = vec![1, 2, 3]; + let mut i = 0; + let max_storage_size = [0; 128 * 1024]; + for item in &v { + bar(i, *item); + i += 1; + } +} + +fn bar(_: usize, _: u32) {} diff --git a/tests/ui/if_same_then_else.rs b/tests/ui/if_same_then_else.rs index 6bbf79edfcf70..9c5fe02f7519b 100644 --- a/tests/ui/if_same_then_else.rs +++ b/tests/ui/if_same_then_else.rs @@ -142,4 +142,16 @@ fn func() { fn f(val: &[u8]) {} +mod issue_5698 { + fn mul_not_always_commutative(x: i32, y: i32) -> i32 { + if x == 42 { + x * y + } else if x == 21 { + y * x + } else { + 0 + } + } +} + fn main() {} diff --git a/tests/ui/macro_use_imports.fixed b/tests/ui/macro_use_imports.fixed new file mode 100644 index 0000000000000..91e34c62160a1 --- /dev/null +++ b/tests/ui/macro_use_imports.fixed @@ -0,0 +1,43 @@ +// compile-flags: --edition 2018 +// aux-build:macro_rules.rs +// aux-build:macro_use_helper.rs +// run-rustfix +// ignore-32bit + +#![allow(unused_imports, unreachable_code, unused_variables, dead_code)] +#![allow(clippy::single_component_path_imports)] +#![warn(clippy::macro_use_imports)] + +#[macro_use] +extern crate macro_use_helper as mac; + +#[macro_use] +extern crate clippy_mini_macro_test as mini_mac; + +mod a { + use mac::{pub_macro, inner_mod_macro, function_macro, ty_macro, pub_in_private_macro}; + use mac; + use mini_mac::ClippyMiniMacroTest; + use mini_mac; + use mac::{inner::foofoo, inner::try_err}; + use mac::inner; + use mac::inner::nested::string_add; + use mac::inner::nested; + + #[derive(ClippyMiniMacroTest)] + struct Test; + + fn test() { + pub_macro!(); + inner_mod_macro!(); + pub_in_private_macro!(_var); + function_macro!(); + let v: ty_macro!() = Vec::default(); + + inner::try_err!(); + inner::foofoo!(); + nested::string_add!(); + } +} + +fn main() {} diff --git a/tests/ui/macro_use_imports.rs b/tests/ui/macro_use_imports.rs index 60c64ee8146e5..9c3c50c5d49f2 100644 --- a/tests/ui/macro_use_imports.rs +++ b/tests/ui/macro_use_imports.rs @@ -1,11 +1,43 @@ -// edition:2018 +// compile-flags: --edition 2018 +// aux-build:macro_rules.rs +// aux-build:macro_use_helper.rs +// run-rustfix +// ignore-32bit + +#![allow(unused_imports, unreachable_code, unused_variables, dead_code)] +#![allow(clippy::single_component_path_imports)] #![warn(clippy::macro_use_imports)] -use std::collections::HashMap; #[macro_use] -use std::prelude; +extern crate macro_use_helper as mac; + +#[macro_use] +extern crate clippy_mini_macro_test as mini_mac; + +mod a { + #[macro_use] + use mac; + #[macro_use] + use mini_mac; + #[macro_use] + use mac::inner; + #[macro_use] + use mac::inner::nested; -fn main() { - let _ = HashMap::::new(); - println!(); + #[derive(ClippyMiniMacroTest)] + struct Test; + + fn test() { + pub_macro!(); + inner_mod_macro!(); + pub_in_private_macro!(_var); + function_macro!(); + let v: ty_macro!() = Vec::default(); + + inner::try_err!(); + inner::foofoo!(); + nested::string_add!(); + } } + +fn main() {} diff --git a/tests/ui/macro_use_imports.stderr b/tests/ui/macro_use_imports.stderr index b5e3dbec57277..f8c86c8d9179f 100644 --- a/tests/ui/macro_use_imports.stderr +++ b/tests/ui/macro_use_imports.stderr @@ -1,10 +1,28 @@ error: `macro_use` attributes are no longer needed in the Rust 2018 edition - --> $DIR/macro_use_imports.rs:5:1 + --> $DIR/macro_use_imports.rs:18:5 | -LL | #[macro_use] - | ^^^^^^^^^^^^ help: remove the attribute and import the macro directly, try: `use std::prelude::` +LL | #[macro_use] + | ^^^^^^^^^^^^ help: remove the attribute and import the macro directly, try: `use mac::{pub_macro, inner_mod_macro, function_macro, ty_macro, pub_in_private_macro};` | = note: `-D clippy::macro-use-imports` implied by `-D warnings` -error: aborting due to previous error +error: `macro_use` attributes are no longer needed in the Rust 2018 edition + --> $DIR/macro_use_imports.rs:20:5 + | +LL | #[macro_use] + | ^^^^^^^^^^^^ help: remove the attribute and import the macro directly, try: `use mini_mac::ClippyMiniMacroTest;` + +error: `macro_use` attributes are no longer needed in the Rust 2018 edition + --> $DIR/macro_use_imports.rs:22:5 + | +LL | #[macro_use] + | ^^^^^^^^^^^^ help: remove the attribute and import the macro directly, try: `use mac::{inner::foofoo, inner::try_err};` + +error: `macro_use` attributes are no longer needed in the Rust 2018 edition + --> $DIR/macro_use_imports.rs:24:5 + | +LL | #[macro_use] + | ^^^^^^^^^^^^ help: remove the attribute and import the macro directly, try: `use mac::inner::nested::string_add;` + +error: aborting due to 4 previous errors diff --git a/tests/ui/redundant_pattern_matching.fixed b/tests/ui/redundant_pattern_matching.fixed index fc8cb0e747c73..6ba5cfb1d7177 100644 --- a/tests/ui/redundant_pattern_matching.fixed +++ b/tests/ui/redundant_pattern_matching.fixed @@ -1,5 +1,7 @@ // run-rustfix +#![feature(const_if_match)] +#![feature(const_loop)] #![warn(clippy::all)] #![warn(clippy::redundant_pattern_matching)] #![allow(clippy::unit_arg, unused_must_use, clippy::needless_bool, deprecated)] @@ -67,6 +69,7 @@ fn main() { takes_bool(x); issue5504(); + issue5697(); let _ = if gen_opt().is_some() { 1 @@ -117,3 +120,42 @@ fn issue5504() { if m!().is_some() {} while m!().is_some() {} } + +// None of these should be linted because none of the suggested methods +// are `const fn` without toggling a feature. +const fn issue5697() { + if let Ok(_) = Ok::(42) {} + + if let Err(_) = Err::(42) {} + + if let Some(_) = Some(42) {} + + if let None = None::<()> {} + + while let Ok(_) = Ok::(10) {} + + while let Err(_) = Ok::(10) {} + + while let Some(_) = Some(42) {} + + while let None = None::<()> {} + + match Ok::(42) { + Ok(_) => true, + Err(_) => false, + }; + + match Err::(42) { + Ok(_) => false, + Err(_) => true, + }; + match Some(42) { + Some(_) => true, + None => false, + }; + + match None::<()> { + Some(_) => false, + None => true, + }; +} diff --git a/tests/ui/redundant_pattern_matching.rs b/tests/ui/redundant_pattern_matching.rs index 51912dade0356..17de66f9ad0eb 100644 --- a/tests/ui/redundant_pattern_matching.rs +++ b/tests/ui/redundant_pattern_matching.rs @@ -1,5 +1,7 @@ // run-rustfix +#![feature(const_if_match)] +#![feature(const_loop)] #![warn(clippy::all)] #![warn(clippy::redundant_pattern_matching)] #![allow(clippy::unit_arg, unused_must_use, clippy::needless_bool, deprecated)] @@ -88,6 +90,7 @@ fn main() { takes_bool(x); issue5504(); + issue5697(); let _ = if let Some(_) = gen_opt() { 1 @@ -138,3 +141,42 @@ fn issue5504() { if let Some(_) = m!() {} while let Some(_) = m!() {} } + +// None of these should be linted because none of the suggested methods +// are `const fn` without toggling a feature. +const fn issue5697() { + if let Ok(_) = Ok::(42) {} + + if let Err(_) = Err::(42) {} + + if let Some(_) = Some(42) {} + + if let None = None::<()> {} + + while let Ok(_) = Ok::(10) {} + + while let Err(_) = Ok::(10) {} + + while let Some(_) = Some(42) {} + + while let None = None::<()> {} + + match Ok::(42) { + Ok(_) => true, + Err(_) => false, + }; + + match Err::(42) { + Ok(_) => false, + Err(_) => true, + }; + match Some(42) { + Some(_) => true, + None => false, + }; + + match None::<()> { + Some(_) => false, + None => true, + }; +} diff --git a/tests/ui/redundant_pattern_matching.stderr b/tests/ui/redundant_pattern_matching.stderr index b58deb7954efe..1b9a4b40a2f02 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:8:12 + --> $DIR/redundant_pattern_matching.rs:10:12 | LL | if let Ok(_) = Ok::(42) {} | -------^^^^^--------------------- help: try this: `if Ok::(42).is_ok()` @@ -7,67 +7,67 @@ 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:10:12 + --> $DIR/redundant_pattern_matching.rs:12:12 | LL | if let Err(_) = Err::(42) {} | -------^^^^^^---------------------- help: try this: `if Err::(42).is_err()` error: redundant pattern matching, consider using `is_none()` - --> $DIR/redundant_pattern_matching.rs:12:12 + --> $DIR/redundant_pattern_matching.rs:14:12 | LL | if let None = None::<()> {} | -------^^^^------------- help: try this: `if None::<()>.is_none()` error: redundant pattern matching, consider using `is_some()` - --> $DIR/redundant_pattern_matching.rs:14:12 + --> $DIR/redundant_pattern_matching.rs:16:12 | LL | if let Some(_) = Some(42) {} | -------^^^^^^^----------- help: try this: `if Some(42).is_some()` error: redundant pattern matching, consider using `is_some()` - --> $DIR/redundant_pattern_matching.rs:16:12 + --> $DIR/redundant_pattern_matching.rs:18:12 | LL | if let Some(_) = Some(42) { | -------^^^^^^^----------- help: try this: `if Some(42).is_some()` error: redundant pattern matching, consider using `is_some()` - --> $DIR/redundant_pattern_matching.rs:22:15 + --> $DIR/redundant_pattern_matching.rs:24:15 | LL | while let Some(_) = Some(42) {} | ----------^^^^^^^----------- help: try this: `while Some(42).is_some()` error: redundant pattern matching, consider using `is_none()` - --> $DIR/redundant_pattern_matching.rs:24:15 + --> $DIR/redundant_pattern_matching.rs:26:15 | LL | while let None = Some(42) {} | ----------^^^^----------- help: try this: `while Some(42).is_none()` error: redundant pattern matching, consider using `is_none()` - --> $DIR/redundant_pattern_matching.rs:26:15 + --> $DIR/redundant_pattern_matching.rs:28:15 | LL | while let None = None::<()> {} | ----------^^^^------------- help: try this: `while None::<()>.is_none()` error: redundant pattern matching, consider using `is_ok()` - --> $DIR/redundant_pattern_matching.rs:28:15 + --> $DIR/redundant_pattern_matching.rs:30:15 | LL | while let Ok(_) = Ok::(10) {} | ----------^^^^^--------------------- help: try this: `while Ok::(10).is_ok()` error: redundant pattern matching, consider using `is_err()` - --> $DIR/redundant_pattern_matching.rs:30:15 + --> $DIR/redundant_pattern_matching.rs:32:15 | LL | while let Err(_) = Ok::(10) {} | ----------^^^^^^--------------------- help: try this: `while Ok::(10).is_err()` error: redundant pattern matching, consider using `is_some()` - --> $DIR/redundant_pattern_matching.rs:33:15 + --> $DIR/redundant_pattern_matching.rs:35:15 | LL | while let Some(_) = v.pop() { | ----------^^^^^^^---------- help: try this: `while v.pop().is_some()` error: redundant pattern matching, consider using `is_ok()` - --> $DIR/redundant_pattern_matching.rs:49:5 + --> $DIR/redundant_pattern_matching.rs:51:5 | LL | / match Ok::(42) { LL | | Ok(_) => true, @@ -76,7 +76,7 @@ LL | | }; | |_____^ help: try this: `Ok::(42).is_ok()` error: redundant pattern matching, consider using `is_err()` - --> $DIR/redundant_pattern_matching.rs:54:5 + --> $DIR/redundant_pattern_matching.rs:56:5 | LL | / match Ok::(42) { LL | | Ok(_) => false, @@ -85,7 +85,7 @@ LL | | }; | |_____^ help: try this: `Ok::(42).is_err()` error: redundant pattern matching, consider using `is_err()` - --> $DIR/redundant_pattern_matching.rs:59:5 + --> $DIR/redundant_pattern_matching.rs:61:5 | LL | / match Err::(42) { LL | | Ok(_) => false, @@ -94,7 +94,7 @@ LL | | }; | |_____^ help: try this: `Err::(42).is_err()` error: redundant pattern matching, consider using `is_ok()` - --> $DIR/redundant_pattern_matching.rs:64:5 + --> $DIR/redundant_pattern_matching.rs:66:5 | LL | / match Err::(42) { LL | | Ok(_) => true, @@ -103,7 +103,7 @@ LL | | }; | |_____^ help: try this: `Err::(42).is_ok()` error: redundant pattern matching, consider using `is_some()` - --> $DIR/redundant_pattern_matching.rs:69:5 + --> $DIR/redundant_pattern_matching.rs:71:5 | LL | / match Some(42) { LL | | Some(_) => true, @@ -112,7 +112,7 @@ LL | | }; | |_____^ help: try this: `Some(42).is_some()` error: redundant pattern matching, consider using `is_none()` - --> $DIR/redundant_pattern_matching.rs:74:5 + --> $DIR/redundant_pattern_matching.rs:76:5 | LL | / match None::<()> { LL | | Some(_) => false, @@ -121,7 +121,7 @@ LL | | }; | |_____^ help: try this: `None::<()>.is_none()` error: redundant pattern matching, consider using `is_none()` - --> $DIR/redundant_pattern_matching.rs:79:13 + --> $DIR/redundant_pattern_matching.rs:81:13 | LL | let _ = match None::<()> { | _____________^ @@ -131,61 +131,61 @@ LL | | }; | |_____^ help: try this: `None::<()>.is_none()` error: redundant pattern matching, consider using `is_ok()` - --> $DIR/redundant_pattern_matching.rs:84:20 + --> $DIR/redundant_pattern_matching.rs:86:20 | LL | let _ = if let Ok(_) = Ok::(4) { true } else { false }; | -------^^^^^--------------------- help: try this: `if Ok::(4).is_ok()` error: redundant pattern matching, consider using `is_some()` - --> $DIR/redundant_pattern_matching.rs:87:20 + --> $DIR/redundant_pattern_matching.rs:89:20 | LL | let x = if let Some(_) = opt { true } else { false }; | -------^^^^^^^------ help: try this: `if opt.is_some()` error: redundant pattern matching, consider using `is_some()` - --> $DIR/redundant_pattern_matching.rs:92:20 + --> $DIR/redundant_pattern_matching.rs:95:20 | LL | let _ = if let Some(_) = gen_opt() { | -------^^^^^^^------------ help: try this: `if gen_opt().is_some()` error: redundant pattern matching, consider using `is_none()` - --> $DIR/redundant_pattern_matching.rs:94:19 + --> $DIR/redundant_pattern_matching.rs:97:19 | LL | } else if let None = gen_opt() { | -------^^^^------------ help: try this: `if gen_opt().is_none()` error: redundant pattern matching, consider using `is_ok()` - --> $DIR/redundant_pattern_matching.rs:96:19 + --> $DIR/redundant_pattern_matching.rs:99:19 | LL | } else if let Ok(_) = gen_res() { | -------^^^^^------------ help: try this: `if gen_res().is_ok()` error: redundant pattern matching, consider using `is_err()` - --> $DIR/redundant_pattern_matching.rs:98:19 + --> $DIR/redundant_pattern_matching.rs:101:19 | LL | } else if let Err(_) = gen_res() { | -------^^^^^^------------ help: try this: `if gen_res().is_err()` error: redundant pattern matching, consider using `is_some()` - --> $DIR/redundant_pattern_matching.rs:131:19 + --> $DIR/redundant_pattern_matching.rs:134:19 | LL | while let Some(_) = r#try!(result_opt()) {} | ----------^^^^^^^----------------------- help: try this: `while r#try!(result_opt()).is_some()` error: redundant pattern matching, consider using `is_some()` - --> $DIR/redundant_pattern_matching.rs:132:16 + --> $DIR/redundant_pattern_matching.rs:135:16 | LL | if let Some(_) = r#try!(result_opt()) {} | -------^^^^^^^----------------------- help: try this: `if r#try!(result_opt()).is_some()` error: redundant pattern matching, consider using `is_some()` - --> $DIR/redundant_pattern_matching.rs:138:12 + --> $DIR/redundant_pattern_matching.rs:141:12 | LL | if let Some(_) = m!() {} | -------^^^^^^^------- help: try this: `if m!().is_some()` error: redundant pattern matching, consider using `is_some()` - --> $DIR/redundant_pattern_matching.rs:139:15 + --> $DIR/redundant_pattern_matching.rs:142:15 | LL | while let Some(_) = m!() {} | ----------^^^^^^^------- help: try this: `while m!().is_some()` diff --git a/tests/ui/redundant_pattern_matching_const_result.fixed b/tests/ui/redundant_pattern_matching_const_result.fixed new file mode 100644 index 0000000000000..c8bc5458067d3 --- /dev/null +++ b/tests/ui/redundant_pattern_matching_const_result.fixed @@ -0,0 +1,46 @@ +// run-rustfix + +#![feature(const_if_match)] +#![feature(const_loop)] +#![feature(const_result)] +#![warn(clippy::redundant_pattern_matching)] +#![allow(unused)] + +// Test that results are linted with the feature enabled. + +const fn issue_5697() { + if Ok::(42).is_ok() {} + + if Err::(42).is_err() {} + + while Ok::(10).is_ok() {} + + while Ok::(10).is_err() {} + + Ok::(42).is_ok(); + + Err::(42).is_err(); + + // These should not be linted until `const_option` is implemented. + // See https://github.com/rust-lang/rust/issues/67441 + + if let Some(_) = Some(42) {} + + if let None = None::<()> {} + + while let Some(_) = Some(42) {} + + while let None = None::<()> {} + + match Some(42) { + Some(_) => true, + None => false, + }; + + match None::<()> { + Some(_) => false, + None => true, + }; +} + +fn main() {} diff --git a/tests/ui/redundant_pattern_matching_const_result.rs b/tests/ui/redundant_pattern_matching_const_result.rs new file mode 100644 index 0000000000000..75f37ec15c622 --- /dev/null +++ b/tests/ui/redundant_pattern_matching_const_result.rs @@ -0,0 +1,52 @@ +// run-rustfix + +#![feature(const_if_match)] +#![feature(const_loop)] +#![feature(const_result)] +#![warn(clippy::redundant_pattern_matching)] +#![allow(unused)] + +// Test that results are linted with the feature enabled. + +const fn issue_5697() { + if let Ok(_) = Ok::(42) {} + + if let Err(_) = Err::(42) {} + + while let Ok(_) = Ok::(10) {} + + while let Err(_) = Ok::(10) {} + + match Ok::(42) { + Ok(_) => true, + Err(_) => false, + }; + + match Err::(42) { + Ok(_) => false, + Err(_) => true, + }; + + // These should not be linted until `const_option` is implemented. + // See https://github.com/rust-lang/rust/issues/67441 + + if let Some(_) = Some(42) {} + + if let None = None::<()> {} + + while let Some(_) = Some(42) {} + + while let None = None::<()> {} + + match Some(42) { + Some(_) => true, + None => false, + }; + + match None::<()> { + Some(_) => false, + None => true, + }; +} + +fn main() {} diff --git a/tests/ui/redundant_pattern_matching_const_result.stderr b/tests/ui/redundant_pattern_matching_const_result.stderr new file mode 100644 index 0000000000000..c32292f0eee8b --- /dev/null +++ b/tests/ui/redundant_pattern_matching_const_result.stderr @@ -0,0 +1,46 @@ +error: redundant pattern matching, consider using `is_ok()` + --> $DIR/redundant_pattern_matching_const_result.rs:12:12 + | +LL | if let Ok(_) = Ok::(42) {} + | -------^^^^^--------------------- help: try this: `if Ok::(42).is_ok()` + | + = note: `-D clippy::redundant-pattern-matching` implied by `-D warnings` + +error: redundant pattern matching, consider using `is_err()` + --> $DIR/redundant_pattern_matching_const_result.rs:14:12 + | +LL | if let Err(_) = Err::(42) {} + | -------^^^^^^---------------------- help: try this: `if Err::(42).is_err()` + +error: redundant pattern matching, consider using `is_ok()` + --> $DIR/redundant_pattern_matching_const_result.rs:16:15 + | +LL | while let Ok(_) = Ok::(10) {} + | ----------^^^^^--------------------- help: try this: `while Ok::(10).is_ok()` + +error: redundant pattern matching, consider using `is_err()` + --> $DIR/redundant_pattern_matching_const_result.rs:18:15 + | +LL | while let Err(_) = Ok::(10) {} + | ----------^^^^^^--------------------- help: try this: `while Ok::(10).is_err()` + +error: redundant pattern matching, consider using `is_ok()` + --> $DIR/redundant_pattern_matching_const_result.rs:20:5 + | +LL | / match Ok::(42) { +LL | | Ok(_) => true, +LL | | Err(_) => false, +LL | | }; + | |_____^ help: try this: `Ok::(42).is_ok()` + +error: redundant pattern matching, consider using `is_err()` + --> $DIR/redundant_pattern_matching_const_result.rs:25:5 + | +LL | / match Err::(42) { +LL | | Ok(_) => false, +LL | | Err(_) => true, +LL | | }; + | |_____^ help: try this: `Err::(42).is_err()` + +error: aborting due to 6 previous errors + diff --git a/tests/ui/repl_uninit.rs b/tests/ui/repl_uninit.rs index 346972b7bb4e0..ad5b8e4857d17 100644 --- a/tests/ui/repl_uninit.rs +++ b/tests/ui/repl_uninit.rs @@ -17,6 +17,12 @@ fn main() { std::mem::forget(mem::replace(&mut v, new_v)); } + unsafe { + let taken_v = mem::replace(&mut v, mem::MaybeUninit::uninit().assume_init()); + let new_v = might_panic(taken_v); + std::mem::forget(mem::replace(&mut v, new_v)); + } + unsafe { let taken_v = mem::replace(&mut v, mem::zeroed()); let new_v = might_panic(taken_v); diff --git a/tests/ui/repl_uninit.stderr b/tests/ui/repl_uninit.stderr index c1f55d7601e5c..09468eeaea4bf 100644 --- a/tests/ui/repl_uninit.stderr +++ b/tests/ui/repl_uninit.stderr @@ -2,26 +2,29 @@ error: replacing with `mem::uninitialized()` --> $DIR/repl_uninit.rs:15:23 | LL | let taken_v = mem::replace(&mut v, mem::uninitialized()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::ptr::read(&mut v)` | = note: `-D clippy::mem-replace-with-uninit` implied by `-D warnings` - = help: consider using the `take_mut` crate instead -error: replacing with `mem::zeroed()` +error: replacing with `mem::MaybeUninit::uninit().assume_init()` --> $DIR/repl_uninit.rs:21:23 | +LL | let taken_v = mem::replace(&mut v, mem::MaybeUninit::uninit().assume_init()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::ptr::read(&mut v)` + +error: replacing with `mem::zeroed()` + --> $DIR/repl_uninit.rs:27:23 + | LL | let taken_v = mem::replace(&mut v, mem::zeroed()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: consider using a default value or the `take_mut` crate instead error: replacing with `mem::uninitialized()` - --> $DIR/repl_uninit.rs:33:28 + --> $DIR/repl_uninit.rs:39:28 | LL | let taken_u = unsafe { mem::replace(uref, mem::uninitialized()) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = help: consider using the `take_mut` crate instead + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::ptr::read(uref)` -error: aborting due to 3 previous errors +error: aborting due to 4 previous errors From fb4f9a0ad7a4656beb01c85b02b3e6ef15d914ec Mon Sep 17 00:00:00 2001 From: Teddy_Wang Date: Tue, 23 Jun 2020 11:40:38 -0400 Subject: [PATCH 03/99] Fix pattern match of ExprKind::MethodCall --- clippy_lints/src/map_identity.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clippy_lints/src/map_identity.rs b/clippy_lints/src/map_identity.rs index 9bc8f1bec1bc2..6607a26b130dd 100644 --- a/clippy_lints/src/map_identity.rs +++ b/clippy_lints/src/map_identity.rs @@ -61,7 +61,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MapIdentity { /// map(). Otherwise, returns None. fn get_map_argument<'a>(cx: &LateContext<'_, '_>, expr: &'a Expr<'a>) -> Option<&'a [Expr<'a>]> { if_chain! { - if let ExprKind::MethodCall(ref method, _, ref args) = expr.kind; + if let ExprKind::MethodCall(ref method, _, ref args, _) = expr.kind; if args.len() == 2 && method.ident.as_str() == "map"; let caller_ty = cx.tables.expr_ty(&args[0]); if match_trait_method(cx, expr, &paths::ITERATOR) From 7c1b3aa0ddb81954a804455ca45fcf09fdb17dd8 Mon Sep 17 00:00:00 2001 From: Ayaz Hafiz Date: Sun, 21 Jun 2020 15:49:56 -0700 Subject: [PATCH 04/99] Record span of `const` kw in GenericParamKind Context: this is needed to fix https://github.com/rust-lang/rustfmt/issues/4263, which currently records the span of a const generic param incorrectly because the location of the `const` kw is not known. I am not sure how to add tests for this; any guidance in how to do so would be appreciated :slightly_smiling_face: --- clippy_lints/src/utils/ast_utils.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clippy_lints/src/utils/ast_utils.rs b/clippy_lints/src/utils/ast_utils.rs index e60e2a81e070b..e19a79dd8dad1 100755 --- a/clippy_lints/src/utils/ast_utils.rs +++ b/clippy_lints/src/utils/ast_utils.rs @@ -476,7 +476,7 @@ pub fn eq_generic_param(l: &GenericParam, r: &GenericParam) -> bool { && match (&l.kind, &r.kind) { (Lifetime, Lifetime) => true, (Type { default: l }, Type { default: r }) => both(l, r, |l, r| eq_ty(l, r)), - (Const { ty: l }, Const { ty: r }) => eq_ty(l, r), + (Const { ty: l, kw_span: _ }, Const { ty: r, kw_span: _ }) => eq_ty(l, r), _ => false, } && over(&l.attrs, &r.attrs, |l, r| eq_attr(l, r)) From 5987c7d4041ce5d72c8412d2ad73fe3b63308b51 Mon Sep 17 00:00:00 2001 From: Eduardo Broto Date: Tue, 9 Jun 2020 22:40:43 +0200 Subject: [PATCH 05/99] cmp_owned: avoid FP when PartialEq is not implemented symmetrically --- clippy_lints/src/misc.rs | 35 ++++++++++++---------- tests/ui/cmp_owned/issue_4874.rs | 51 ++++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+), 15 deletions(-) create mode 100644 tests/ui/cmp_owned/issue_4874.rs diff --git a/clippy_lints/src/misc.rs b/clippy_lints/src/misc.rs index a0947608e6077..1b65a01690d60 100644 --- a/clippy_lints/src/misc.rs +++ b/clippy_lints/src/misc.rs @@ -3,11 +3,11 @@ use rustc_ast::ast::LitKind; use rustc_errors::Applicability; use rustc_hir::intravisit::FnKind; use rustc_hir::{ - def, BinOpKind, BindingAnnotation, Body, Expr, ExprKind, FnDecl, HirId, Mutability, PatKind, Stmt, StmtKind, Ty, - TyKind, UnOp, + self as hir, def, BinOpKind, BindingAnnotation, Body, Expr, ExprKind, FnDecl, HirId, Mutability, PatKind, Stmt, + StmtKind, TyKind, UnOp, }; use rustc_lint::{LateContext, LateLintPass}; -use rustc_middle::ty; +use rustc_middle::ty::{self, Ty}; use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::hygiene::DesugaringKind; use rustc_span::source_map::{ExpnKind, Span}; @@ -571,6 +571,15 @@ fn is_array(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> bool { } fn check_to_owned(cx: &LateContext<'_, '_>, expr: &Expr<'_>, other: &Expr<'_>) { + fn symmetric_partial_eq<'tcx>(cx: &LateContext<'_, 'tcx>, lhs: Ty<'tcx>, rhs: Ty<'tcx>) -> bool { + if let Some(trait_def_id) = cx.tcx.lang_items().eq_trait() { + return implements_trait(cx, lhs, trait_def_id, &[rhs.into()]) + && implements_trait(cx, rhs, trait_def_id, &[lhs.into()]); + } + + false + } + let (arg_ty, snip) = match expr.kind { ExprKind::MethodCall(.., ref args, _) if args.len() == 1 => { if match_trait_method(cx, expr, &paths::TO_STRING) || match_trait_method(cx, expr, &paths::TO_OWNED) { @@ -594,18 +603,14 @@ fn check_to_owned(cx: &LateContext<'_, '_>, expr: &Expr<'_>, other: &Expr<'_>) { }; let other_ty = cx.tables.expr_ty_adjusted(other); - let partial_eq_trait_id = match cx.tcx.lang_items().eq_trait() { - Some(id) => id, - None => return, - }; - let deref_arg_impl_partial_eq_other = arg_ty.builtin_deref(true).map_or(false, |tam| { - implements_trait(cx, tam.ty, partial_eq_trait_id, &[other_ty.into()]) - }); - let arg_impl_partial_eq_deref_other = other_ty.builtin_deref(true).map_or(false, |tam| { - implements_trait(cx, arg_ty, partial_eq_trait_id, &[tam.ty.into()]) - }); - let arg_impl_partial_eq_other = implements_trait(cx, arg_ty, partial_eq_trait_id, &[other_ty.into()]); + let deref_arg_impl_partial_eq_other = arg_ty + .builtin_deref(true) + .map_or(false, |tam| symmetric_partial_eq(cx, tam.ty, other_ty)); + let arg_impl_partial_eq_deref_other = other_ty + .builtin_deref(true) + .map_or(false, |tam| symmetric_partial_eq(cx, arg_ty, tam.ty)); + let arg_impl_partial_eq_other = symmetric_partial_eq(cx, arg_ty, other_ty); if !deref_arg_impl_partial_eq_other && !arg_impl_partial_eq_deref_other && !arg_impl_partial_eq_other { return; @@ -694,7 +699,7 @@ fn non_macro_local(cx: &LateContext<'_, '_>, res: def::Res) -> bool { } } -fn check_cast(cx: &LateContext<'_, '_>, span: Span, e: &Expr<'_>, ty: &Ty<'_>) { +fn check_cast(cx: &LateContext<'_, '_>, span: Span, e: &Expr<'_>, ty: &hir::Ty<'_>) { if_chain! { if let TyKind::Ptr(ref mut_ty) = ty.kind; if let ExprKind::Lit(ref lit) = e.kind; diff --git a/tests/ui/cmp_owned/issue_4874.rs b/tests/ui/cmp_owned/issue_4874.rs new file mode 100644 index 0000000000000..b29c555eb1e2f --- /dev/null +++ b/tests/ui/cmp_owned/issue_4874.rs @@ -0,0 +1,51 @@ +#![allow(clippy::redundant_clone)] // See #5700 + +#[derive(PartialEq)] +struct Foo; + +struct Bar; + +impl std::fmt::Display for Bar { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "bar") + } +} + +// NOTE: PartialEq for T can't be implemented due to the orphan rules +impl PartialEq for Bar +where + T: AsRef + ?Sized, +{ + fn eq(&self, _: &T) -> bool { + true + } +} + +// NOTE: PartialEq for Foo is not implemented +impl PartialEq for Bar { + fn eq(&self, _: &Foo) -> bool { + true + } +} + +impl ToOwned for Bar { + type Owned = Foo; + fn to_owned(&self) -> Foo { + Foo + } +} + +impl std::borrow::Borrow for Foo { + fn borrow(&self) -> &Bar { + static BAR: Bar = Bar; + &BAR + } +} + +fn main() { + let b = Bar {}; + if "Hi" == b.to_string() {} + + let f = Foo {}; + if f == b.to_owned() {} +} From b498e1d71537a79e7aff5378da625aca8b4eef96 Mon Sep 17 00:00:00 2001 From: Eduardo Broto Date: Sat, 13 Jun 2020 00:03:19 +0200 Subject: [PATCH 06/99] cmp_owned: reverse operands if necessary --- clippy_lints/src/misc.rs | 79 ++++++++++------ .../ui/cmp_owned/asymmetric_partial_eq.fixed | 93 +++++++++++++++++++ tests/ui/cmp_owned/asymmetric_partial_eq.rs | 93 +++++++++++++++++++ .../ui/cmp_owned/asymmetric_partial_eq.stderr | 46 +++++++++ tests/ui/cmp_owned/issue_4874.rs | 51 ---------- 5 files changed, 282 insertions(+), 80 deletions(-) create mode 100644 tests/ui/cmp_owned/asymmetric_partial_eq.fixed create mode 100644 tests/ui/cmp_owned/asymmetric_partial_eq.rs create mode 100644 tests/ui/cmp_owned/asymmetric_partial_eq.stderr delete mode 100644 tests/ui/cmp_owned/issue_4874.rs diff --git a/clippy_lints/src/misc.rs b/clippy_lints/src/misc.rs index 1b65a01690d60..76ffe6f6a1c42 100644 --- a/clippy_lints/src/misc.rs +++ b/clippy_lints/src/misc.rs @@ -371,8 +371,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MiscLints { if op.is_comparison() { check_nan(cx, left, expr); check_nan(cx, right, expr); - check_to_owned(cx, left, right); - check_to_owned(cx, right, left); + check_to_owned(cx, left, right, true); + check_to_owned(cx, right, left, false); } if (op == BinOpKind::Eq || op == BinOpKind::Ne) && (is_float(cx, left) || is_float(cx, right)) { if is_allowed(cx, left) || is_allowed(cx, right) { @@ -570,20 +570,30 @@ fn is_array(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> bool { matches!(&walk_ptrs_ty(cx.tables.expr_ty(expr)).kind, ty::Array(_, _)) } -fn check_to_owned(cx: &LateContext<'_, '_>, expr: &Expr<'_>, other: &Expr<'_>) { - fn symmetric_partial_eq<'tcx>(cx: &LateContext<'_, 'tcx>, lhs: Ty<'tcx>, rhs: Ty<'tcx>) -> bool { - if let Some(trait_def_id) = cx.tcx.lang_items().eq_trait() { - return implements_trait(cx, lhs, trait_def_id, &[rhs.into()]) - && implements_trait(cx, rhs, trait_def_id, &[lhs.into()]); +fn check_to_owned(cx: &LateContext<'_, '_>, expr: &Expr<'_>, other: &Expr<'_>, left: bool) { + #[derive(Default)] + struct EqImpl { + ty_eq_other: bool, + other_eq_ty: bool, + } + + impl EqImpl { + fn is_implemented(&self) -> bool { + self.ty_eq_other || self.other_eq_ty } + } - false + fn symmetric_partial_eq<'tcx>(cx: &LateContext<'_, 'tcx>, ty: Ty<'tcx>, other: Ty<'tcx>) -> Option { + cx.tcx.lang_items().eq_trait().map(|def_id| EqImpl { + ty_eq_other: implements_trait(cx, ty, def_id, &[other.into()]), + other_eq_ty: implements_trait(cx, other, def_id, &[ty.into()]), + }) } let (arg_ty, snip) = match expr.kind { ExprKind::MethodCall(.., ref args, _) if args.len() == 1 => { if match_trait_method(cx, expr, &paths::TO_STRING) || match_trait_method(cx, expr, &paths::TO_OWNED) { - (cx.tables.expr_ty_adjusted(&args[0]), snippet(cx, args[0].span, "..")) + (cx.tables.expr_ty(&args[0]), snippet(cx, args[0].span, "..")) } else { return; } @@ -591,7 +601,7 @@ fn check_to_owned(cx: &LateContext<'_, '_>, expr: &Expr<'_>, other: &Expr<'_>) { ExprKind::Call(ref path, ref v) if v.len() == 1 => { if let ExprKind::Path(ref path) = path.kind { if match_qpath(path, &["String", "from_str"]) || match_qpath(path, &["String", "from"]) { - (cx.tables.expr_ty_adjusted(&v[0]), snippet(cx, v[0].span, "..")) + (cx.tables.expr_ty(&v[0]), snippet(cx, v[0].span, "..")) } else { return; } @@ -602,24 +612,19 @@ fn check_to_owned(cx: &LateContext<'_, '_>, expr: &Expr<'_>, other: &Expr<'_>) { _ => return, }; - let other_ty = cx.tables.expr_ty_adjusted(other); + let other_ty = cx.tables.expr_ty(other); - let deref_arg_impl_partial_eq_other = arg_ty - .builtin_deref(true) - .map_or(false, |tam| symmetric_partial_eq(cx, tam.ty, other_ty)); - let arg_impl_partial_eq_deref_other = other_ty + let without_deref = symmetric_partial_eq(cx, arg_ty, other_ty).unwrap_or_default(); + let with_deref = arg_ty .builtin_deref(true) - .map_or(false, |tam| symmetric_partial_eq(cx, arg_ty, tam.ty)); - let arg_impl_partial_eq_other = symmetric_partial_eq(cx, arg_ty, other_ty); + .and_then(|tam| symmetric_partial_eq(cx, tam.ty, other_ty)) + .unwrap_or_default(); - if !deref_arg_impl_partial_eq_other && !arg_impl_partial_eq_deref_other && !arg_impl_partial_eq_other { + if !with_deref.is_implemented() && !without_deref.is_implemented() { return; } - let other_gets_derefed = match other.kind { - ExprKind::Unary(UnOp::UnDeref, _) => true, - _ => false, - }; + let other_gets_derefed = matches!(other.kind, ExprKind::Unary(UnOp::UnDeref, _)); let lint_span = if other_gets_derefed { expr.span.to(other.span) @@ -639,18 +644,34 @@ fn check_to_owned(cx: &LateContext<'_, '_>, expr: &Expr<'_>, other: &Expr<'_>) { return; } - let try_hint = if deref_arg_impl_partial_eq_other { - // suggest deref on the left - format!("*{}", snip) + let expr_snip; + let eq_impl; + if with_deref.is_implemented() { + expr_snip = format!("*{}", snip); + eq_impl = with_deref; } else { - // suggest dropping the to_owned on the left - snip.to_string() + expr_snip = snip.to_string(); + eq_impl = without_deref; }; + let span; + let hint; + if (eq_impl.ty_eq_other && left) || (eq_impl.other_eq_ty && !left) { + span = expr.span; + hint = expr_snip; + } else { + span = expr.span.to(other.span); + if eq_impl.ty_eq_other { + hint = format!("{} == {}", expr_snip, snippet(cx, other.span, "..")); + } else { + hint = format!("{} == {}", snippet(cx, other.span, ".."), expr_snip); + } + } + diag.span_suggestion( - lint_span, + span, "try", - try_hint, + hint, Applicability::MachineApplicable, // snippet ); }, diff --git a/tests/ui/cmp_owned/asymmetric_partial_eq.fixed b/tests/ui/cmp_owned/asymmetric_partial_eq.fixed new file mode 100644 index 0000000000000..3305ac9bf8b6c --- /dev/null +++ b/tests/ui/cmp_owned/asymmetric_partial_eq.fixed @@ -0,0 +1,93 @@ +// run-rustfix +#![allow(unused, clippy::redundant_clone)] // See #5700 + +// Define the types in each module to avoid trait impls leaking between modules. +macro_rules! impl_types { + () => { + #[derive(PartialEq)] + pub struct Owned; + + pub struct Borrowed; + + impl ToOwned for Borrowed { + type Owned = Owned; + fn to_owned(&self) -> Owned { + Owned {} + } + } + + impl std::borrow::Borrow for Owned { + fn borrow(&self) -> &Borrowed { + static VALUE: Borrowed = Borrowed {}; + &VALUE + } + } + }; +} + +// Only Borrowed == Owned is implemented +mod borrowed_eq_owned { + impl_types!(); + + impl PartialEq for Borrowed { + fn eq(&self, _: &Owned) -> bool { + true + } + } + + pub fn compare() { + let owned = Owned {}; + let borrowed = Borrowed {}; + + if borrowed == owned {} + if borrowed == owned {} + } +} + +// Only Owned == Borrowed is implemented +mod owned_eq_borrowed { + impl_types!(); + + impl PartialEq for Owned { + fn eq(&self, _: &Borrowed) -> bool { + true + } + } + + fn compare() { + let owned = Owned {}; + let borrowed = Borrowed {}; + + if owned == borrowed {} + if owned == borrowed {} + } +} + +mod issue_4874 { + impl_types!(); + + // NOTE: PartialEq for T can't be implemented due to the orphan rules + impl PartialEq for Borrowed + where + T: AsRef + ?Sized, + { + fn eq(&self, _: &T) -> bool { + true + } + } + + impl std::fmt::Display for Borrowed { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "borrowed") + } + } + + fn compare() { + let borrowed = Borrowed {}; + + if borrowed == "Hi" {} + if borrowed == "Hi" {} + } +} + +fn main() {} diff --git a/tests/ui/cmp_owned/asymmetric_partial_eq.rs b/tests/ui/cmp_owned/asymmetric_partial_eq.rs new file mode 100644 index 0000000000000..88bc2f51dd662 --- /dev/null +++ b/tests/ui/cmp_owned/asymmetric_partial_eq.rs @@ -0,0 +1,93 @@ +// run-rustfix +#![allow(unused, clippy::redundant_clone)] // See #5700 + +// Define the types in each module to avoid trait impls leaking between modules. +macro_rules! impl_types { + () => { + #[derive(PartialEq)] + pub struct Owned; + + pub struct Borrowed; + + impl ToOwned for Borrowed { + type Owned = Owned; + fn to_owned(&self) -> Owned { + Owned {} + } + } + + impl std::borrow::Borrow for Owned { + fn borrow(&self) -> &Borrowed { + static VALUE: Borrowed = Borrowed {}; + &VALUE + } + } + }; +} + +// Only Borrowed == Owned is implemented +mod borrowed_eq_owned { + impl_types!(); + + impl PartialEq for Borrowed { + fn eq(&self, _: &Owned) -> bool { + true + } + } + + pub fn compare() { + let owned = Owned {}; + let borrowed = Borrowed {}; + + if borrowed.to_owned() == owned {} + if owned == borrowed.to_owned() {} + } +} + +// Only Owned == Borrowed is implemented +mod owned_eq_borrowed { + impl_types!(); + + impl PartialEq for Owned { + fn eq(&self, _: &Borrowed) -> bool { + true + } + } + + fn compare() { + let owned = Owned {}; + let borrowed = Borrowed {}; + + if owned == borrowed.to_owned() {} + if borrowed.to_owned() == owned {} + } +} + +mod issue_4874 { + impl_types!(); + + // NOTE: PartialEq for T can't be implemented due to the orphan rules + impl PartialEq for Borrowed + where + T: AsRef + ?Sized, + { + fn eq(&self, _: &T) -> bool { + true + } + } + + impl std::fmt::Display for Borrowed { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "borrowed") + } + } + + fn compare() { + let borrowed = Borrowed {}; + + if "Hi" == borrowed.to_string() {} + if borrowed.to_string() == "Hi" {} + } +} + +fn main() {} diff --git a/tests/ui/cmp_owned/asymmetric_partial_eq.stderr b/tests/ui/cmp_owned/asymmetric_partial_eq.stderr new file mode 100644 index 0000000000000..43bf8851fc620 --- /dev/null +++ b/tests/ui/cmp_owned/asymmetric_partial_eq.stderr @@ -0,0 +1,46 @@ +error: this creates an owned instance just for comparison + --> $DIR/asymmetric_partial_eq.rs:42:12 + | +LL | if borrowed.to_owned() == owned {} + | ^^^^^^^^^^^^^^^^^^^ help: try: `borrowed` + | + = note: `-D clippy::cmp-owned` implied by `-D warnings` + +error: this creates an owned instance just for comparison + --> $DIR/asymmetric_partial_eq.rs:43:21 + | +LL | if owned == borrowed.to_owned() {} + | ---------^^^^^^^^^^^^^^^^^^^ + | | + | help: try: `borrowed == owned` + +error: this creates an owned instance just for comparison + --> $DIR/asymmetric_partial_eq.rs:61:21 + | +LL | if owned == borrowed.to_owned() {} + | ^^^^^^^^^^^^^^^^^^^ help: try: `borrowed` + +error: this creates an owned instance just for comparison + --> $DIR/asymmetric_partial_eq.rs:62:12 + | +LL | if borrowed.to_owned() == owned {} + | ^^^^^^^^^^^^^^^^^^^--------- + | | + | help: try: `owned == borrowed` + +error: this creates an owned instance just for comparison + --> $DIR/asymmetric_partial_eq.rs:88:20 + | +LL | if "Hi" == borrowed.to_string() {} + | --------^^^^^^^^^^^^^^^^^^^^ + | | + | help: try: `borrowed == "Hi"` + +error: this creates an owned instance just for comparison + --> $DIR/asymmetric_partial_eq.rs:89:12 + | +LL | if borrowed.to_string() == "Hi" {} + | ^^^^^^^^^^^^^^^^^^^^ help: try: `borrowed` + +error: aborting due to 6 previous errors + diff --git a/tests/ui/cmp_owned/issue_4874.rs b/tests/ui/cmp_owned/issue_4874.rs deleted file mode 100644 index b29c555eb1e2f..0000000000000 --- a/tests/ui/cmp_owned/issue_4874.rs +++ /dev/null @@ -1,51 +0,0 @@ -#![allow(clippy::redundant_clone)] // See #5700 - -#[derive(PartialEq)] -struct Foo; - -struct Bar; - -impl std::fmt::Display for Bar { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "bar") - } -} - -// NOTE: PartialEq for T can't be implemented due to the orphan rules -impl PartialEq for Bar -where - T: AsRef + ?Sized, -{ - fn eq(&self, _: &T) -> bool { - true - } -} - -// NOTE: PartialEq for Foo is not implemented -impl PartialEq for Bar { - fn eq(&self, _: &Foo) -> bool { - true - } -} - -impl ToOwned for Bar { - type Owned = Foo; - fn to_owned(&self) -> Foo { - Foo - } -} - -impl std::borrow::Borrow for Foo { - fn borrow(&self) -> &Bar { - static BAR: Bar = Bar; - &BAR - } -} - -fn main() { - let b = Bar {}; - if "Hi" == b.to_string() {} - - let f = Foo {}; - if f == b.to_owned() {} -} From 6bf5434e19ce6d2a501589d1fcbc0d1748c531a6 Mon Sep 17 00:00:00 2001 From: Tim Nielens Date: Wed, 24 Jun 2020 01:01:23 +0200 Subject: [PATCH 07/99] copy_on_clone - add machine applicability --- clippy_lints/src/methods/mod.rs | 2 +- tests/ui/clone_on_copy.fixed | 40 +++++++++++++++++++++ tests/ui/clone_on_copy.rs | 40 +++++++++++++++++++++ tests/ui/clone_on_copy.stderr | 34 ++++++++++++++++++ tests/ui/unnecessary_clone.rs | 25 ------------- tests/ui/unnecessary_clone.stderr | 58 ++++++++----------------------- 6 files changed, 129 insertions(+), 70 deletions(-) create mode 100644 tests/ui/clone_on_copy.fixed create mode 100644 tests/ui/clone_on_copy.rs create mode 100644 tests/ui/clone_on_copy.stderr diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index 214cf0c130f21..74fefa65612f6 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -2041,7 +2041,7 @@ fn lint_clone_on_copy(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, arg: &hir: } span_lint_and_then(cx, CLONE_ON_COPY, expr.span, "using `clone` on a `Copy` type", |diag| { if let Some((text, snip)) = snip { - diag.span_suggestion(expr.span, text, snip, Applicability::Unspecified); + diag.span_suggestion(expr.span, text, snip, Applicability::MachineApplicable); } }); } diff --git a/tests/ui/clone_on_copy.fixed b/tests/ui/clone_on_copy.fixed new file mode 100644 index 0000000000000..1f0ca101757ec --- /dev/null +++ b/tests/ui/clone_on_copy.fixed @@ -0,0 +1,40 @@ +// run-rustfix + +#![allow( + unused, + clippy::redundant_clone, + clippy::deref_addrof, + clippy::no_effect, + clippy::unnecessary_operation +)] + +use std::cell::RefCell; +use std::rc::{self, Rc}; +use std::sync::{self, Arc}; + +fn main() {} + +fn is_ascii(ch: char) -> bool { + ch.is_ascii() +} + +fn clone_on_copy() { + 42; + + vec![1].clone(); // ok, not a Copy type + Some(vec![1]).clone(); // ok, not a Copy type + *(&42); + + let rc = RefCell::new(0); + *rc.borrow(); + + // Issue #4348 + let mut x = 43; + let _ = &x.clone(); // ok, getting a ref + 'a'.clone().make_ascii_uppercase(); // ok, clone and then mutate + is_ascii('z'); + + // Issue #5436 + let mut vec = Vec::new(); + vec.push(42); +} diff --git a/tests/ui/clone_on_copy.rs b/tests/ui/clone_on_copy.rs new file mode 100644 index 0000000000000..ca39a654b4fce --- /dev/null +++ b/tests/ui/clone_on_copy.rs @@ -0,0 +1,40 @@ +// run-rustfix + +#![allow( + unused, + clippy::redundant_clone, + clippy::deref_addrof, + clippy::no_effect, + clippy::unnecessary_operation +)] + +use std::cell::RefCell; +use std::rc::{self, Rc}; +use std::sync::{self, Arc}; + +fn main() {} + +fn is_ascii(ch: char) -> bool { + ch.is_ascii() +} + +fn clone_on_copy() { + 42.clone(); + + vec![1].clone(); // ok, not a Copy type + Some(vec![1]).clone(); // ok, not a Copy type + (&42).clone(); + + 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 + is_ascii('z'.clone()); + + // Issue #5436 + let mut vec = Vec::new(); + vec.push(42.clone()); +} diff --git a/tests/ui/clone_on_copy.stderr b/tests/ui/clone_on_copy.stderr new file mode 100644 index 0000000000000..ec2faf4ab40d2 --- /dev/null +++ b/tests/ui/clone_on_copy.stderr @@ -0,0 +1,34 @@ +error: using `clone` on a `Copy` type + --> $DIR/clone_on_copy.rs:22:5 + | +LL | 42.clone(); + | ^^^^^^^^^^ help: try removing the `clone` call: `42` + | + = note: `-D clippy::clone-on-copy` implied by `-D warnings` + +error: using `clone` on a `Copy` type + --> $DIR/clone_on_copy.rs:26:5 + | +LL | (&42).clone(); + | ^^^^^^^^^^^^^ help: try dereferencing it: `*(&42)` + +error: using `clone` on a `Copy` type + --> $DIR/clone_on_copy.rs:29:5 + | +LL | rc.borrow().clone(); + | ^^^^^^^^^^^^^^^^^^^ help: try dereferencing it: `*rc.borrow()` + +error: using `clone` on a `Copy` type + --> $DIR/clone_on_copy.rs:35:14 + | +LL | is_ascii('z'.clone()); + | ^^^^^^^^^^^ help: try removing the `clone` call: `'z'` + +error: using `clone` on a `Copy` type + --> $DIR/clone_on_copy.rs:39:14 + | +LL | vec.push(42.clone()); + | ^^^^^^^^^^ help: try removing the `clone` call: `42` + +error: aborting due to 5 previous errors + diff --git a/tests/ui/unnecessary_clone.rs b/tests/ui/unnecessary_clone.rs index f1cc5b564c1dc..2c9d4d39e6c7d 100644 --- a/tests/ui/unnecessary_clone.rs +++ b/tests/ui/unnecessary_clone.rs @@ -13,31 +13,6 @@ impl SomeTrait for SomeImpl {} fn main() {} -fn is_ascii(ch: char) -> bool { - ch.is_ascii() -} - -fn clone_on_copy() { - 42.clone(); - - vec![1].clone(); // ok, not a Copy type - Some(vec![1]).clone(); // ok, not a Copy type - (&42).clone(); - - 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 - is_ascii('z'.clone()); - - // Issue #5436 - let mut vec = Vec::new(); - vec.push(42.clone()); -} - fn clone_on_ref_ptr() { let rc = Rc::new(true); let arc = Arc::new(true); diff --git a/tests/ui/unnecessary_clone.stderr b/tests/ui/unnecessary_clone.stderr index 6176a2bc46479..113fab6900954 100644 --- a/tests/ui/unnecessary_clone.stderr +++ b/tests/ui/unnecessary_clone.stderr @@ -1,37 +1,5 @@ -error: using `clone` on a `Copy` type - --> $DIR/unnecessary_clone.rs:21:5 - | -LL | 42.clone(); - | ^^^^^^^^^^ help: try removing the `clone` call: `42` - | - = note: `-D clippy::clone-on-copy` implied by `-D warnings` - -error: using `clone` on a `Copy` type - --> $DIR/unnecessary_clone.rs:25:5 - | -LL | (&42).clone(); - | ^^^^^^^^^^^^^ help: try dereferencing it: `*(&42)` - -error: using `clone` on a `Copy` type - --> $DIR/unnecessary_clone.rs:28:5 - | -LL | rc.borrow().clone(); - | ^^^^^^^^^^^^^^^^^^^ help: try dereferencing it: `*rc.borrow()` - -error: using `clone` on a `Copy` type - --> $DIR/unnecessary_clone.rs:34:14 - | -LL | is_ascii('z'.clone()); - | ^^^^^^^^^^^ help: try removing the `clone` call: `'z'` - -error: using `clone` on a `Copy` type - --> $DIR/unnecessary_clone.rs:38:14 - | -LL | vec.push(42.clone()); - | ^^^^^^^^^^ help: try removing the `clone` call: `42` - error: using `.clone()` on a ref-counted pointer - --> $DIR/unnecessary_clone.rs:48:5 + --> $DIR/unnecessary_clone.rs:23:5 | LL | rc.clone(); | ^^^^^^^^^^ help: try this: `Rc::::clone(&rc)` @@ -39,43 +7,45 @@ 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:51:5 + --> $DIR/unnecessary_clone.rs:26:5 | LL | arc.clone(); | ^^^^^^^^^^^ help: try this: `Arc::::clone(&arc)` error: using `.clone()` on a ref-counted pointer - --> $DIR/unnecessary_clone.rs:54:5 + --> $DIR/unnecessary_clone.rs:29:5 | LL | rcweak.clone(); | ^^^^^^^^^^^^^^ help: try this: `Weak::::clone(&rcweak)` error: using `.clone()` on a ref-counted pointer - --> $DIR/unnecessary_clone.rs:57:5 + --> $DIR/unnecessary_clone.rs:32:5 | LL | arc_weak.clone(); | ^^^^^^^^^^^^^^^^ help: try this: `Weak::::clone(&arc_weak)` error: using `.clone()` on a ref-counted pointer - --> $DIR/unnecessary_clone.rs:61:33 + --> $DIR/unnecessary_clone.rs:36:33 | LL | let _: Arc = x.clone(); | ^^^^^^^^^ help: try this: `Arc::::clone(&x)` error: using `clone` on a `Copy` type - --> $DIR/unnecessary_clone.rs:65:5 + --> $DIR/unnecessary_clone.rs:40:5 | LL | t.clone(); | ^^^^^^^^^ help: try removing the `clone` call: `t` + | + = note: `-D clippy::clone-on-copy` implied by `-D warnings` error: using `clone` on a `Copy` type - --> $DIR/unnecessary_clone.rs:67:5 + --> $DIR/unnecessary_clone.rs:42: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:73:22 + --> $DIR/unnecessary_clone.rs:48:22 | LL | let z: &Vec<_> = y.clone(); | ^^^^^^^^^ @@ -91,13 +61,13 @@ LL | let z: &Vec<_> = <&std::vec::Vec>::clone(y); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: using `clone` on a `Copy` type - --> $DIR/unnecessary_clone.rs:109:20 + --> $DIR/unnecessary_clone.rs:84:20 | LL | let _: E = a.clone(); | ^^^^^^^^^ help: try dereferencing it: `*****a` error: using `clone` on a double-reference; this will copy the reference instead of cloning the inner type - --> $DIR/unnecessary_clone.rs:114:22 + --> $DIR/unnecessary_clone.rs:89:22 | LL | let _ = &mut encoded.clone(); | ^^^^^^^^^^^^^^^ @@ -112,7 +82,7 @@ LL | let _ = &mut <&[u8]>::clone(encoded); | ^^^^^^^^^^^^^^^^^^^^^^^ error: using `clone` on a double-reference; this will copy the reference instead of cloning the inner type - --> $DIR/unnecessary_clone.rs:115:18 + --> $DIR/unnecessary_clone.rs:90:18 | LL | let _ = &encoded.clone(); | ^^^^^^^^^^^^^^^ @@ -126,5 +96,5 @@ help: or try being explicit if you are sure, that you want to clone a reference LL | let _ = &<&[u8]>::clone(encoded); | ^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 16 previous errors +error: aborting due to 11 previous errors From 3e48aaea03aef6e6e7ac678d11995a2a39ba9d99 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 25 Jun 2020 13:19:56 +0200 Subject: [PATCH 08/99] Clean up E0704 error explanation --- src/librustc_error_codes/error_codes/E0704.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/librustc_error_codes/error_codes/E0704.md b/src/librustc_error_codes/error_codes/E0704.md index cde46f52c27d7..c22b274fb223e 100644 --- a/src/librustc_error_codes/error_codes/E0704.md +++ b/src/librustc_error_codes/error_codes/E0704.md @@ -1,6 +1,6 @@ -This error indicates that a incorrect visibility restriction was specified. +An incorrect visibility restriction was specified. -Example of erroneous code: +Erroneous code example: ```compile_fail,E0704 mod foo { @@ -12,6 +12,7 @@ mod foo { To make struct `Bar` only visible in module `foo` the `in` keyword should be used: + ``` mod foo { pub(in crate::foo) struct Bar { From fa0f1d3e5353df04e3d2e68e65810ca1a231c220 Mon Sep 17 00:00:00 2001 From: "Carol (Nichols || Goulding)" Date: Thu, 25 Jun 2020 11:25:21 -0400 Subject: [PATCH 09/99] Change a noun to a verb to make the sentence complete --- clippy_lints/src/await_holding_lock.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clippy_lints/src/await_holding_lock.rs b/clippy_lints/src/await_holding_lock.rs index a88f922d8e03d..8f7e06b32ff02 100644 --- a/clippy_lints/src/await_holding_lock.rs +++ b/clippy_lints/src/await_holding_lock.rs @@ -11,7 +11,7 @@ declare_clippy_lint! { /// non-async-aware MutexGuard. /// /// **Why is this bad?** The Mutex types found in syd::sync and parking_lot - /// are not designed to operator in an async context across await points. + /// are not designed to operate in an async context across await points. /// /// There are two potential solutions. One is to use an asynx-aware Mutex /// type. Many asynchronous foundation crates provide such a Mutex type. The From f5ce0e5fe960d09db01cf912c475cd1a52131120 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Fri, 26 Jun 2020 02:56:23 +0300 Subject: [PATCH 10/99] rustc_lint: only query `typeck_tables_of` when a lint needs it. --- clippy_lints/src/arithmetic.rs | 6 +- clippy_lints/src/assertions_on_constants.rs | 4 +- clippy_lints/src/assign_ops.rs | 6 +- clippy_lints/src/atomic_ordering.rs | 8 +- clippy_lints/src/bit_mask.rs | 2 +- clippy_lints/src/booleans.rs | 6 +- clippy_lints/src/bytecount.rs | 4 +- clippy_lints/src/cognitive_complexity.rs | 2 +- clippy_lints/src/comparison_chain.rs | 2 +- clippy_lints/src/copies.rs | 8 +- clippy_lints/src/default_trait_access.rs | 4 +- clippy_lints/src/dereference.rs | 18 +-- clippy_lints/src/drop_forget_ref.rs | 2 +- clippy_lints/src/duration_subsec.rs | 4 +- clippy_lints/src/entry.rs | 2 +- clippy_lints/src/eq_op.rs | 16 +-- clippy_lints/src/erasing_op.rs | 2 +- clippy_lints/src/escape.rs | 2 +- clippy_lints/src/eta_reduction.rs | 6 +- clippy_lints/src/eval_order_dependence.rs | 8 +- clippy_lints/src/float_literal.rs | 2 +- clippy_lints/src/floating_point_arithmetic.rs | 24 ++-- clippy_lints/src/format.rs | 4 +- clippy_lints/src/get_last_with_len.rs | 2 +- clippy_lints/src/identity_op.rs | 8 +- clippy_lints/src/if_let_mutex.rs | 2 +- clippy_lints/src/if_let_some_result.rs | 2 +- clippy_lints/src/implicit_return.rs | 2 +- clippy_lints/src/implicit_saturating_sub.rs | 4 +- clippy_lints/src/indexing_slicing.rs | 8 +- clippy_lints/src/infinite_iter.rs | 7 +- clippy_lints/src/integer_division.rs | 2 +- clippy_lints/src/large_stack_arrays.rs | 2 +- clippy_lints/src/len_zero.rs | 2 +- clippy_lints/src/let_and_return.rs | 4 +- clippy_lints/src/let_if_seq.rs | 2 +- clippy_lints/src/let_underscore.rs | 4 +- clippy_lints/src/lifetimes.rs | 2 +- clippy_lints/src/loops.rs | 34 +++--- clippy_lints/src/map_clone.rs | 6 +- clippy_lints/src/map_unit_fn.rs | 8 +- clippy_lints/src/match_on_vec_items.rs | 4 +- clippy_lints/src/matches.rs | 26 ++-- clippy_lints/src/mem_discriminant.rs | 4 +- clippy_lints/src/mem_forget.rs | 2 +- clippy_lints/src/mem_replace.rs | 10 +- .../src/methods/bind_instead_of_map.rs | 2 +- .../src/methods/inefficient_to_string.rs | 4 +- .../methods/manual_saturating_arithmetic.rs | 4 +- clippy_lints/src/methods/mod.rs | 111 +++++++++--------- .../src/methods/option_map_unwrap_or.rs | 4 +- .../src/methods/unnecessary_filter_map.rs | 2 +- clippy_lints/src/minmax.rs | 29 +++-- clippy_lints/src/misc.rs | 18 +-- clippy_lints/src/modulo_arithmetic.rs | 6 +- clippy_lints/src/mut_key.rs | 2 +- clippy_lints/src/mut_mut.rs | 2 +- clippy_lints/src/mut_reference.rs | 6 +- clippy_lints/src/mutable_debug_assertion.rs | 2 +- clippy_lints/src/mutex_atomic.rs | 2 +- clippy_lints/src/needless_bool.rs | 2 +- clippy_lints/src/needless_borrow.rs | 6 +- clippy_lints/src/needless_pass_by_value.rs | 10 +- clippy_lints/src/needless_update.rs | 2 +- clippy_lints/src/neg_cmp_op_on_partial_ord.rs | 2 +- clippy_lints/src/neg_multiply.rs | 4 +- clippy_lints/src/no_effect.rs | 10 +- clippy_lints/src/non_copy_const.rs | 6 +- clippy_lints/src/open_options.rs | 4 +- .../src/overflow_check_conditional.rs | 8 +- clippy_lints/src/path_buf_push_overwrite.rs | 2 +- clippy_lints/src/ptr_offset_with_cast.rs | 4 +- clippy_lints/src/question_mark.rs | 6 +- clippy_lints/src/ranges.rs | 6 +- clippy_lints/src/regex.rs | 6 +- clippy_lints/src/shadow.rs | 2 +- clippy_lints/src/strings.rs | 2 +- clippy_lints/src/swap.rs | 2 +- clippy_lints/src/temporary_assignment.rs | 2 +- clippy_lints/src/to_digit_is_some.rs | 4 +- clippy_lints/src/trait_bounds.rs | 2 +- clippy_lints/src/transmute.rs | 6 +- clippy_lints/src/transmuting_null.rs | 2 +- clippy_lints/src/try_err.rs | 4 +- clippy_lints/src/types.rs | 36 +++--- clippy_lints/src/unnamed_address.rs | 12 +- clippy_lints/src/unnecessary_sort_by.rs | 2 +- clippy_lints/src/unwrap.rs | 2 +- clippy_lints/src/useless_conversion.rs | 18 +-- clippy_lints/src/utils/higher.rs | 4 +- clippy_lints/src/utils/hir_utils.rs | 4 +- clippy_lints/src/utils/inspector.rs | 6 +- clippy_lints/src/utils/internal_lints.rs | 6 +- clippy_lints/src/utils/mod.rs | 16 +-- clippy_lints/src/utils/usage.rs | 2 +- clippy_lints/src/vec.rs | 6 +- clippy_lints/src/vec_resize_to_zero.rs | 2 +- clippy_lints/src/verbose_file_reads.rs | 4 +- clippy_lints/src/zero_div_zero.rs | 4 +- doc/common_tools_writing_lints.md | 16 +-- 100 files changed, 361 insertions(+), 366 deletions(-) diff --git a/clippy_lints/src/arithmetic.rs b/clippy_lints/src/arithmetic.rs index 6cbe10a5352d1..cc09b99cf1dd1 100644 --- a/clippy_lints/src/arithmetic.rs +++ b/clippy_lints/src/arithmetic.rs @@ -86,7 +86,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Arithmetic { _ => (), } - let (l_ty, r_ty) = (cx.tables.expr_ty(l), cx.tables.expr_ty(r)); + let (l_ty, r_ty) = (cx.tables().expr_ty(l), cx.tables().expr_ty(r)); if l_ty.peel_refs().is_integral() && r_ty.peel_refs().is_integral() { span_lint(cx, INTEGER_ARITHMETIC, expr.span, "integer arithmetic detected"); self.expr_span = Some(expr.span); @@ -96,8 +96,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Arithmetic { } }, hir::ExprKind::Unary(hir::UnOp::UnNeg, arg) => { - let ty = cx.tables.expr_ty(arg); - if constant_simple(cx, cx.tables, expr).is_none() { + let ty = cx.tables().expr_ty(arg); + if constant_simple(cx, cx.tables(), expr).is_none() { if ty.is_integral() { span_lint(cx, INTEGER_ARITHMETIC, expr.span, "integer arithmetic detected"); self.expr_span = Some(expr.span); diff --git a/clippy_lints/src/assertions_on_constants.rs b/clippy_lints/src/assertions_on_constants.rs index f8a8fdcd3aa35..c4536b57f8a99 100644 --- a/clippy_lints/src/assertions_on_constants.rs +++ b/clippy_lints/src/assertions_on_constants.rs @@ -72,7 +72,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for AssertionsOnConstants { } if_chain! { if let ExprKind::Unary(_, ref lit) = e.kind; - if let Some((Constant::Bool(is_true), _)) = constant(cx, cx.tables, lit); + if let Some((Constant::Bool(is_true), _)) = constant(cx, cx.tables(), lit); if is_true; then { lint_true(true); @@ -121,7 +121,7 @@ fn match_assert_with_message<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx E if let ExprKind::DropTemps(ref expr) = expr.kind; if let ExprKind::Unary(UnOp::UnNot, ref expr) = expr.kind; // bind the first argument of the `assert!` macro - if let Some((Constant::Bool(is_true), _)) = constant(cx, cx.tables, expr); + if let Some((Constant::Bool(is_true), _)) = constant(cx, cx.tables(), expr); // arm 1 pattern if let PatKind::Lit(ref lit_expr) = arms[0].pat.kind; if let ExprKind::Lit(ref lit) = lit_expr.kind; diff --git a/clippy_lints/src/assign_ops.rs b/clippy_lints/src/assign_ops.rs index 13e61fe98bac1..51a7647d3208f 100644 --- a/clippy_lints/src/assign_ops.rs +++ b/clippy_lints/src/assign_ops.rs @@ -82,8 +82,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for AssignOps { hir::ExprKind::Assign(assignee, e, _) => { if let hir::ExprKind::Binary(op, l, r) = &e.kind { let lint = |assignee: &hir::Expr<'_>, rhs: &hir::Expr<'_>| { - let ty = cx.tables.expr_ty(assignee); - let rty = cx.tables.expr_ty(rhs); + let ty = cx.tables().expr_ty(assignee); + let rty = cx.tables().expr_ty(rhs); macro_rules! ops { ($op:expr, $cx:expr, @@ -167,7 +167,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for AssignOps { // a = b commutative_op a // Limited to primitive type as these ops are know to be commutative if SpanlessEq::new(cx).ignore_fn().eq_expr(assignee, r) - && cx.tables.expr_ty(assignee).is_primitive_ty() + && cx.tables().expr_ty(assignee).is_primitive_ty() { match op.node { hir::BinOpKind::Add diff --git a/clippy_lints/src/atomic_ordering.rs b/clippy_lints/src/atomic_ordering.rs index fca9aaaff9dce..65e1e2c519c26 100644 --- a/clippy_lints/src/atomic_ordering.rs +++ b/clippy_lints/src/atomic_ordering.rs @@ -53,7 +53,7 @@ const ATOMIC_TYPES: [&str; 12] = [ ]; fn type_is_atomic(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> bool { - if let ty::Adt(&ty::AdtDef { did, .. }, _) = cx.tables.expr_ty(expr).kind { + if let ty::Adt(&ty::AdtDef { did, .. }, _) = cx.tables().expr_ty(expr).kind { ATOMIC_TYPES .iter() .any(|ty| match_def_path(cx, did, &["core", "sync", "atomic", ty])) @@ -76,7 +76,7 @@ fn check_atomic_load_store(cx: &LateContext<'_, '_>, expr: &Expr<'_>) { if method == "load" || method == "store"; let ordering_arg = if method == "load" { &args[1] } else { &args[2] }; if let ExprKind::Path(ref ordering_qpath) = ordering_arg.kind; - if let Some(ordering_def_id) = cx.tables.qpath_res(ordering_qpath, ordering_arg.hir_id).opt_def_id(); + if let Some(ordering_def_id) = cx.tables().qpath_res(ordering_qpath, ordering_arg.hir_id).opt_def_id(); then { if method == "load" && match_ordering_def_path(cx, ordering_def_id, &["Release", "AcqRel"]) { @@ -107,12 +107,12 @@ fn check_memory_fence(cx: &LateContext<'_, '_>, expr: &Expr<'_>) { if_chain! { if let ExprKind::Call(ref func, ref args) = expr.kind; if let ExprKind::Path(ref func_qpath) = func.kind; - if let Some(def_id) = cx.tables.qpath_res(func_qpath, func.hir_id).opt_def_id(); + if let Some(def_id) = cx.tables().qpath_res(func_qpath, func.hir_id).opt_def_id(); if ["fence", "compiler_fence"] .iter() .any(|func| match_def_path(cx, def_id, &["core", "sync", "atomic", func])); if let ExprKind::Path(ref ordering_qpath) = &args[0].kind; - if let Some(ordering_def_id) = cx.tables.qpath_res(ordering_qpath, args[0].hir_id).opt_def_id(); + if let Some(ordering_def_id) = cx.tables().qpath_res(ordering_qpath, args[0].hir_id).opt_def_id(); if match_ordering_def_path(cx, ordering_def_id, &["Relaxed"]); then { span_lint_and_help( diff --git a/clippy_lints/src/bit_mask.rs b/clippy_lints/src/bit_mask.rs index ccb62cb038fd0..a53f3249b85b6 100644 --- a/clippy_lints/src/bit_mask.rs +++ b/clippy_lints/src/bit_mask.rs @@ -319,7 +319,7 @@ fn check_ineffective_gt(cx: &LateContext<'_, '_>, span: Span, m: u128, c: u128, } fn fetch_int_literal(cx: &LateContext<'_, '_>, lit: &Expr<'_>) -> Option { - match constant(cx, cx.tables, lit)?.0 { + match constant(cx, cx.tables(), lit)?.0 { Constant::Int(n) => Some(n), _ => None, } diff --git a/clippy_lints/src/booleans.rs b/clippy_lints/src/booleans.rs index f92c564543b89..cc399a1f8a009 100644 --- a/clippy_lints/src/booleans.rs +++ b/clippy_lints/src/booleans.rs @@ -248,7 +248,7 @@ fn simplify_not(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> Option { }) }, ExprKind::MethodCall(path, _, args, _) if args.len() == 1 => { - let type_of_receiver = cx.tables.expr_ty(&args[0]); + let type_of_receiver = cx.tables().expr_ty(&args[0]); if !is_type_diagnostic_item(cx, type_of_receiver, sym!(option_type)) && !is_type_diagnostic_item(cx, type_of_receiver, sym!(result_type)) { @@ -450,7 +450,7 @@ impl<'a, 'tcx> Visitor<'tcx> for NonminimalBoolVisitor<'a, 'tcx> { self.bool_expr(e) }, ExprKind::Unary(UnOp::UnNot, inner) => { - if self.cx.tables.node_types()[inner.hir_id].is_bool() { + if self.cx.tables().node_types()[inner.hir_id].is_bool() { self.bool_expr(e); } else { walk_expr(self, e); @@ -465,7 +465,7 @@ impl<'a, 'tcx> Visitor<'tcx> for NonminimalBoolVisitor<'a, 'tcx> { } fn implements_ord<'a, 'tcx>(cx: &'a LateContext<'a, 'tcx>, expr: &Expr<'_>) -> bool { - let ty = cx.tables.expr_ty(expr); + let ty = cx.tables().expr_ty(expr); get_trait_def_id(cx, &paths::ORD).map_or(false, |id| implements_trait(cx, ty, id, &[])) } diff --git a/clippy_lints/src/bytecount.rs b/clippy_lints/src/bytecount.rs index 531531a654d0e..c00bb23069bf4 100644 --- a/clippy_lints/src/bytecount.rs +++ b/clippy_lints/src/bytecount.rs @@ -53,7 +53,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ByteCount { if let ExprKind::Binary(ref op, ref l, ref r) = body.value.kind; if op.node == BinOpKind::Eq; if match_type(cx, - walk_ptrs_ty(cx.tables.expr_ty(&filter_args[0])), + walk_ptrs_ty(cx.tables().expr_ty(&filter_args[0])), &paths::SLICE_ITER); then { let needle = match get_path_name(l) { @@ -63,7 +63,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ByteCount { _ => { return; } } }; - if ty::Uint(UintTy::U8) != walk_ptrs_ty(cx.tables.expr_ty(needle)).kind { + if ty::Uint(UintTy::U8) != walk_ptrs_ty(cx.tables().expr_ty(needle)).kind { return; } let haystack = if let ExprKind::MethodCall(ref path, _, ref args, _) = diff --git a/clippy_lints/src/cognitive_complexity.rs b/clippy_lints/src/cognitive_complexity.rs index 3ba72e84fa827..78e509d2ecd83 100644 --- a/clippy_lints/src/cognitive_complexity.rs +++ b/clippy_lints/src/cognitive_complexity.rs @@ -60,7 +60,7 @@ impl CognitiveComplexity { let mut helper = CCHelper { cc: 1, returns: 0 }; helper.visit_expr(expr); let CCHelper { cc, returns } = helper; - let ret_ty = cx.tables.node_type(expr.hir_id); + let ret_ty = cx.tables().node_type(expr.hir_id); let ret_adjust = if is_type_diagnostic_item(cx, ret_ty, sym!(result_type)) { returns } else { diff --git a/clippy_lints/src/comparison_chain.rs b/clippy_lints/src/comparison_chain.rs index 93e29edcaa58f..9c0d33f928015 100644 --- a/clippy_lints/src/comparison_chain.rs +++ b/clippy_lints/src/comparison_chain.rs @@ -99,7 +99,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ComparisonChain { } // Check that the type being compared implements `core::cmp::Ord` - let ty = cx.tables.expr_ty(lhs1); + let ty = cx.tables().expr_ty(lhs1); let is_ord = get_trait_def_id(cx, &paths::ORD).map_or(false, |id| implements_trait(cx, ty, id, &[])); if !is_ord { diff --git a/clippy_lints/src/copies.rs b/clippy_lints/src/copies.rs index b6d50bdfa1466..efd4a31f55960 100644 --- a/clippy_lints/src/copies.rs +++ b/clippy_lints/src/copies.rs @@ -192,7 +192,7 @@ fn lint_same_then_else(cx: &LateContext<'_, '_>, blocks: &[&Block<'_>]) { /// Implementation of `IFS_SAME_COND`. fn lint_same_cond(cx: &LateContext<'_, '_>, conds: &[&Expr<'_>]) { let hash: &dyn Fn(&&Expr<'_>) -> u64 = &|expr| -> u64 { - let mut h = SpanlessHash::new(cx, cx.tables); + let mut h = SpanlessHash::new(cx, cx.tables()); h.hash_expr(expr); h.finish() }; @@ -215,7 +215,7 @@ fn lint_same_cond(cx: &LateContext<'_, '_>, conds: &[&Expr<'_>]) { /// Implementation of `SAME_FUNCTIONS_IN_IF_CONDITION`. fn lint_same_fns_in_if_cond(cx: &LateContext<'_, '_>, conds: &[&Expr<'_>]) { let hash: &dyn Fn(&&Expr<'_>) -> u64 = &|expr| -> u64 { - let mut h = SpanlessHash::new(cx, cx.tables); + let mut h = SpanlessHash::new(cx, cx.tables()); h.hash_expr(expr); h.finish() }; @@ -251,7 +251,7 @@ fn lint_match_arms<'tcx>(cx: &LateContext<'_, 'tcx>, expr: &Expr<'_>) { if let ExprKind::Match(_, ref arms, MatchSource::Normal) = expr.kind { let hash = |&(_, arm): &(usize, &Arm<'_>)| -> u64 { - let mut h = SpanlessHash::new(cx, cx.tables); + let mut h = SpanlessHash::new(cx, cx.tables()); h.hash_expr(&arm.body); h.finish() }; @@ -320,7 +320,7 @@ fn bindings<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, pat: &Pat<'_>) -> FxHashMap { if let Entry::Vacant(v) = map.entry(ident.name) { - v.insert(cx.tables.pat_ty(pat)); + v.insert(cx.tables().pat_ty(pat)); } if let Some(ref as_pat) = *as_pat { bindings_impl(cx, as_pat, map); diff --git a/clippy_lints/src/default_trait_access.rs b/clippy_lints/src/default_trait_access.rs index 635d609c38289..69ae509fb23e9 100644 --- a/clippy_lints/src/default_trait_access.rs +++ b/clippy_lints/src/default_trait_access.rs @@ -36,7 +36,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for DefaultTraitAccess { if let ExprKind::Call(ref path, ..) = expr.kind; if !any_parent_is_automatically_derived(cx.tcx, expr.hir_id); if let ExprKind::Path(ref qpath) = path.kind; - if let Some(def_id) = cx.tables.qpath_res(qpath, path.hir_id).opt_def_id(); + if let Some(def_id) = cx.tables().qpath_res(qpath, path.hir_id).opt_def_id(); if match_def_path(cx, def_id, &paths::DEFAULT_TRAIT_METHOD); then { match qpath { @@ -54,7 +54,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for DefaultTraitAccess { // TODO: Work out a way to put "whatever the imported way of referencing // this type in this file" rather than a fully-qualified type. - let expr_ty = cx.tables.expr_ty(expr); + let expr_ty = cx.tables().expr_ty(expr); if let ty::Adt(..) = expr_ty.kind { let replacement = format!("{}::default()", expr_ty); span_lint_and_sugg( diff --git a/clippy_lints/src/dereference.rs b/clippy_lints/src/dereference.rs index 1cd30ae2c6381..1c6cc93690096 100644 --- a/clippy_lints/src/dereference.rs +++ b/clippy_lints/src/dereference.rs @@ -73,12 +73,9 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Dereferencing { fn lint_deref(cx: &LateContext<'_, '_>, method_name: &str, call_expr: &Expr<'_>, var_span: Span, expr_span: Span) { match method_name { "deref" => { - if cx - .tcx - .lang_items() - .deref_trait() - .map_or(false, |id| implements_trait(cx, cx.tables.expr_ty(&call_expr), id, &[])) - { + if cx.tcx.lang_items().deref_trait().map_or(false, |id| { + implements_trait(cx, cx.tables().expr_ty(&call_expr), id, &[]) + }) { span_lint_and_sugg( cx, EXPLICIT_DEREF_METHODS, @@ -91,12 +88,9 @@ fn lint_deref(cx: &LateContext<'_, '_>, method_name: &str, call_expr: &Expr<'_>, } }, "deref_mut" => { - if cx - .tcx - .lang_items() - .deref_mut_trait() - .map_or(false, |id| implements_trait(cx, cx.tables.expr_ty(&call_expr), id, &[])) - { + if cx.tcx.lang_items().deref_mut_trait().map_or(false, |id| { + implements_trait(cx, cx.tables().expr_ty(&call_expr), id, &[]) + }) { span_lint_and_sugg( cx, EXPLICIT_DEREF_METHODS, diff --git a/clippy_lints/src/drop_forget_ref.rs b/clippy_lints/src/drop_forget_ref.rs index 9de9056c14029..014873eb13255 100644 --- a/clippy_lints/src/drop_forget_ref.rs +++ b/clippy_lints/src/drop_forget_ref.rs @@ -119,7 +119,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for DropForgetRef { let lint; let msg; let arg = &args[0]; - let arg_ty = cx.tables.expr_ty(arg); + let arg_ty = cx.tables().expr_ty(arg); if let ty::Ref(..) = arg_ty.kind { if match_def_path(cx, def_id, &paths::DROP) { diff --git a/clippy_lints/src/duration_subsec.rs b/clippy_lints/src/duration_subsec.rs index 7171dcef968c1..5eb320ceca247 100644 --- a/clippy_lints/src/duration_subsec.rs +++ b/clippy_lints/src/duration_subsec.rs @@ -43,8 +43,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for DurationSubsec { if_chain! { if let ExprKind::Binary(Spanned { node: BinOpKind::Div, .. }, ref left, ref right) = expr.kind; if let ExprKind::MethodCall(ref method_path, _ , ref args, _) = left.kind; - if match_type(cx, walk_ptrs_ty(cx.tables.expr_ty(&args[0])), &paths::DURATION); - if let Some((Constant::Int(divisor), _)) = constant(cx, cx.tables, right); + if match_type(cx, walk_ptrs_ty(cx.tables().expr_ty(&args[0])), &paths::DURATION); + if let Some((Constant::Int(divisor), _)) = constant(cx, cx.tables(), right); then { let suggested_fn = match (method_path.ident.as_str().as_ref(), divisor) { ("subsec_micros", 1_000) | ("subsec_nanos", 1_000_000) => "subsec_millis", diff --git a/clippy_lints/src/entry.rs b/clippy_lints/src/entry.rs index f625058b6703c..e37e23b8944d7 100644 --- a/clippy_lints/src/entry.rs +++ b/clippy_lints/src/entry.rs @@ -109,7 +109,7 @@ fn check_cond<'a, 'tcx, 'b>( if let ExprKind::AddrOf(BorrowKind::Ref, _, ref key) = params[1].kind; then { let map = ¶ms[0]; - let obj_ty = walk_ptrs_ty(cx.tables.expr_ty(map)); + let obj_ty = walk_ptrs_ty(cx.tables().expr_ty(map)); return if match_type(cx, obj_ty, &paths::BTREEMAP) { Some(("BTreeMap", map, key)) diff --git a/clippy_lints/src/eq_op.rs b/clippy_lints/src/eq_op.rs index d7819d737ea04..98757624a13b5 100644 --- a/clippy_lints/src/eq_op.rs +++ b/clippy_lints/src/eq_op.rs @@ -103,8 +103,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for EqOp { (&ExprKind::Lit(..), _) | (_, &ExprKind::Lit(..)) => {}, // &foo == &bar (&ExprKind::AddrOf(BorrowKind::Ref, _, ref l), &ExprKind::AddrOf(BorrowKind::Ref, _, ref r)) => { - let lty = cx.tables.expr_ty(l); - let rty = cx.tables.expr_ty(r); + let lty = cx.tables().expr_ty(l); + let rty = cx.tables().expr_ty(r); let lcpy = is_copy(cx, lty); let rcpy = is_copy(cx, rty); // either operator autorefs or both args are copyable @@ -126,7 +126,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for EqOp { ) } else if lcpy && !rcpy - && implements_trait(cx, lty, trait_id, &[cx.tables.expr_ty(right).into()]) + && implements_trait(cx, lty, trait_id, &[cx.tables().expr_ty(right).into()]) { span_lint_and_then( cx, @@ -145,7 +145,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for EqOp { ) } else if !lcpy && rcpy - && implements_trait(cx, cx.tables.expr_ty(left), trait_id, &[rty.into()]) + && implements_trait(cx, cx.tables().expr_ty(left), trait_id, &[rty.into()]) { span_lint_and_then( cx, @@ -166,10 +166,10 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for EqOp { }, // &foo == bar (&ExprKind::AddrOf(BorrowKind::Ref, _, ref l), _) => { - let lty = cx.tables.expr_ty(l); + let lty = cx.tables().expr_ty(l); let lcpy = is_copy(cx, lty); if (requires_ref || lcpy) - && implements_trait(cx, lty, trait_id, &[cx.tables.expr_ty(right).into()]) + && implements_trait(cx, lty, trait_id, &[cx.tables().expr_ty(right).into()]) { span_lint_and_then( cx, @@ -190,10 +190,10 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for EqOp { }, // foo == &bar (_, &ExprKind::AddrOf(BorrowKind::Ref, _, ref r)) => { - let rty = cx.tables.expr_ty(r); + let rty = cx.tables().expr_ty(r); let rcpy = is_copy(cx, rty); if (requires_ref || rcpy) - && implements_trait(cx, cx.tables.expr_ty(left), trait_id, &[rty.into()]) + && implements_trait(cx, cx.tables().expr_ty(left), trait_id, &[rty.into()]) { span_lint_and_then(cx, OP_REF, e.span, "taken reference of right operand", |diag| { let rsnip = snippet(cx, r.span, "...").to_string(); diff --git a/clippy_lints/src/erasing_op.rs b/clippy_lints/src/erasing_op.rs index 3ff0506e28d00..804a9c1904b73 100644 --- a/clippy_lints/src/erasing_op.rs +++ b/clippy_lints/src/erasing_op.rs @@ -48,7 +48,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ErasingOp { } fn check(cx: &LateContext<'_, '_>, e: &Expr<'_>, span: Span) { - if let Some(Constant::Int(0)) = constant_simple(cx, cx.tables, e) { + if let Some(Constant::Int(0)) = constant_simple(cx, cx.tables(), e) { span_lint( cx, ERASING_OP, diff --git a/clippy_lints/src/escape.rs b/clippy_lints/src/escape.rs index 77e90eeac4958..bb74f193a48e7 100644 --- a/clippy_lints/src/escape.rs +++ b/clippy_lints/src/escape.rs @@ -84,7 +84,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for BoxedLocal { let fn_def_id = cx.tcx.hir().local_def_id(hir_id); cx.tcx.infer_ctxt().enter(|infcx| { - ExprUseVisitor::new(&mut v, &infcx, fn_def_id, cx.param_env, cx.tables).consume_body(body); + ExprUseVisitor::new(&mut v, &infcx, fn_def_id, cx.param_env, cx.tables()).consume_body(body); }); for node in v.set { diff --git a/clippy_lints/src/eta_reduction.rs b/clippy_lints/src/eta_reduction.rs index a889856de2742..0ac8b95de8d61 100644 --- a/clippy_lints/src/eta_reduction.rs +++ b/clippy_lints/src/eta_reduction.rs @@ -97,7 +97,7 @@ fn check_closure(cx: &LateContext<'_, '_>, expr: &Expr<'_>) { // Are the expression or the arguments type-adjusted? Then we need the closure if !(is_adjusted(cx, ex) || args.iter().any(|arg| is_adjusted(cx, arg))); - let fn_ty = cx.tables.expr_ty(caller); + let fn_ty = cx.tables().expr_ty(caller); if matches!(fn_ty.kind, ty::FnDef(_, _) | ty::FnPtr(_) | ty::Closure(_, _)); @@ -128,7 +128,7 @@ fn check_closure(cx: &LateContext<'_, '_>, expr: &Expr<'_>) { // Are the expression or the arguments type-adjusted? Then we need the closure if !(is_adjusted(cx, ex) || args.iter().skip(1).any(|arg| is_adjusted(cx, arg))); - let method_def_id = cx.tables.type_dependent_def_id(ex.hir_id).unwrap(); + let method_def_id = cx.tables().type_dependent_def_id(ex.hir_id).unwrap(); if !type_is_unsafe_function(cx, cx.tcx.type_of(method_def_id)); if compare_inputs(&mut iter_input_pats(decl, body), &mut args.iter()); @@ -153,7 +153,7 @@ fn check_closure(cx: &LateContext<'_, '_>, expr: &Expr<'_>) { /// Tries to determine the type for universal function call to be used instead of the closure fn get_ufcs_type_name(cx: &LateContext<'_, '_>, method_def_id: def_id::DefId, self_arg: &Expr<'_>) -> Option { let expected_type_of_self = &cx.tcx.fn_sig(method_def_id).inputs_and_output().skip_binder()[0]; - let actual_type_of_self = &cx.tables.node_type(self_arg.hir_id); + let actual_type_of_self = &cx.tables().node_type(self_arg.hir_id); if let Some(trait_id) = cx.tcx.trait_of_item(method_def_id) { if match_borrow_depth(expected_type_of_self, &actual_type_of_self) diff --git a/clippy_lints/src/eval_order_dependence.rs b/clippy_lints/src/eval_order_dependence.rs index 74144fb299de2..04af6c2c1f85d 100644 --- a/clippy_lints/src/eval_order_dependence.rs +++ b/clippy_lints/src/eval_order_dependence.rs @@ -75,7 +75,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for EvalOrderDependence { if let ExprKind::Path(ref qpath) = lhs.kind { if let QPath::Resolved(_, ref path) = *qpath { if path.segments.len() == 1 { - if let def::Res::Local(var) = cx.tables.qpath_res(qpath, lhs.hir_id) { + if let def::Res::Local(var) = cx.tables().qpath_res(qpath, lhs.hir_id) { let mut visitor = ReadVisitor { cx, var, @@ -137,7 +137,7 @@ impl<'a, 'tcx> Visitor<'tcx> for DivergenceVisitor<'a, 'tcx> { match e.kind { ExprKind::Continue(_) | ExprKind::Break(_, _) | ExprKind::Ret(_) => self.report_diverging_sub_expr(e), ExprKind::Call(ref func, _) => { - let typ = self.cx.tables.expr_ty(func); + let typ = self.cx.tables().expr_ty(func); match typ.kind { ty::FnDef(..) | ty::FnPtr(_) => { let sig = typ.fn_sig(self.cx.tcx); @@ -149,7 +149,7 @@ impl<'a, 'tcx> Visitor<'tcx> for DivergenceVisitor<'a, 'tcx> { } }, ExprKind::MethodCall(..) => { - let borrowed_table = self.cx.tables; + let borrowed_table = self.cx.tables(); if borrowed_table.expr_ty(e).is_never() { self.report_diverging_sub_expr(e); } @@ -309,7 +309,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ReadVisitor<'a, 'tcx> { if_chain! { if let QPath::Resolved(None, ref path) = *qpath; if path.segments.len() == 1; - if let def::Res::Local(local_id) = self.cx.tables.qpath_res(qpath, expr.hir_id); + if let def::Res::Local(local_id) = self.cx.tables().qpath_res(qpath, expr.hir_id); if local_id == self.var; // Check that this is a read, not a write. if !is_in_assignment_position(self.cx, expr); diff --git a/clippy_lints/src/float_literal.rs b/clippy_lints/src/float_literal.rs index 4c604cd01075e..cd3d443ec58ef 100644 --- a/clippy_lints/src/float_literal.rs +++ b/clippy_lints/src/float_literal.rs @@ -61,7 +61,7 @@ declare_lint_pass!(FloatLiteral => [EXCESSIVE_PRECISION, LOSSY_FLOAT_LITERAL]); impl<'a, 'tcx> LateLintPass<'a, 'tcx> for FloatLiteral { fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx hir::Expr<'_>) { if_chain! { - let ty = cx.tables.expr_ty(expr); + let ty = cx.tables().expr_ty(expr); if let ty::Float(fty) = ty.kind; if let hir::ExprKind::Lit(ref lit) = expr.kind; if let LitKind::Float(sym, lit_float_ty) = lit.node; diff --git a/clippy_lints/src/floating_point_arithmetic.rs b/clippy_lints/src/floating_point_arithmetic.rs index ad4f66c52c2c8..76713cb1afc41 100644 --- a/clippy_lints/src/floating_point_arithmetic.rs +++ b/clippy_lints/src/floating_point_arithmetic.rs @@ -112,7 +112,7 @@ declare_lint_pass!(FloatingPointArithmetic => [ // Returns the specialized log method for a given base if base is constant // and is one of 2, 10 and e fn get_specialized_log_method(cx: &LateContext<'_, '_>, base: &Expr<'_>) -> Option<&'static str> { - if let Some((value, _)) = constant(cx, cx.tables, base) { + if let Some((value, _)) = constant(cx, cx.tables(), base) { if F32(2.0) == value || F64(2.0) == value { return Some("log2"); } else if F32(10.0) == value || F64(10.0) == value { @@ -136,7 +136,7 @@ fn prepare_receiver_sugg<'a>(cx: &LateContext<'_, '_>, mut expr: &'a Expr<'a>) - if_chain! { // if the expression is a float literal and it is unsuffixed then // add a suffix so the suggestion is valid and unambiguous - if let ty::Float(float_ty) = cx.tables.expr_ty(expr).kind; + if let ty::Float(float_ty) = cx.tables().expr_ty(expr).kind; if let ExprKind::Lit(lit) = &expr.kind; if let ast::LitKind::Float(sym, ast::LitFloatType::Unsuffixed) = lit.node; then { @@ -188,7 +188,7 @@ fn check_ln1p(cx: &LateContext<'_, '_>, expr: &Expr<'_>, args: &[Expr<'_>]) { rhs, ) = &args[0].kind { - let recv = match (constant(cx, cx.tables, lhs), constant(cx, cx.tables, rhs)) { + let recv = match (constant(cx, cx.tables(), lhs), constant(cx, cx.tables(), rhs)) { (Some((value, _)), _) if F32(1.0) == value || F64(1.0) == value => rhs, (_, Some((value, _))) if F32(1.0) == value || F64(1.0) == value => lhs, _ => return, @@ -233,7 +233,7 @@ fn get_integer_from_float_constant(value: &Constant) -> Option { fn check_powf(cx: &LateContext<'_, '_>, expr: &Expr<'_>, args: &[Expr<'_>]) { // Check receiver - if let Some((value, _)) = constant(cx, cx.tables, &args[0]) { + if let Some((value, _)) = constant(cx, cx.tables(), &args[0]) { let method = if F32(f32_consts::E) == value || F64(f64_consts::E) == value { "exp" } else if F32(2.0) == value || F64(2.0) == value { @@ -254,7 +254,7 @@ fn check_powf(cx: &LateContext<'_, '_>, expr: &Expr<'_>, args: &[Expr<'_>]) { } // Check argument - if let Some((value, _)) = constant(cx, cx.tables, &args[1]) { + if let Some((value, _)) = constant(cx, cx.tables(), &args[1]) { let (lint, help, suggestion) = if F32(1.0 / 2.0) == value || F64(1.0 / 2.0) == value { ( SUBOPTIMAL_FLOPS, @@ -298,11 +298,11 @@ fn check_powf(cx: &LateContext<'_, '_>, expr: &Expr<'_>, args: &[Expr<'_>]) { fn check_expm1(cx: &LateContext<'_, '_>, expr: &Expr<'_>) { if_chain! { if let ExprKind::Binary(Spanned { node: BinOpKind::Sub, .. }, ref lhs, ref rhs) = expr.kind; - if cx.tables.expr_ty(lhs).is_floating_point(); - if let Some((value, _)) = constant(cx, cx.tables, rhs); + if cx.tables().expr_ty(lhs).is_floating_point(); + if let Some((value, _)) = constant(cx, cx.tables(), rhs); if F32(1.0) == value || F64(1.0) == value; if let ExprKind::MethodCall(ref path, _, ref method_args, _) = lhs.kind; - if cx.tables.expr_ty(&method_args[0]).is_floating_point(); + if cx.tables().expr_ty(&method_args[0]).is_floating_point(); if path.ident.name.as_str() == "exp"; then { span_lint_and_sugg( @@ -324,8 +324,8 @@ fn check_expm1(cx: &LateContext<'_, '_>, expr: &Expr<'_>) { fn is_float_mul_expr<'a>(cx: &LateContext<'_, '_>, expr: &'a Expr<'a>) -> Option<(&'a Expr<'a>, &'a Expr<'a>)> { if_chain! { if let ExprKind::Binary(Spanned { node: BinOpKind::Mul, .. }, ref lhs, ref rhs) = &expr.kind; - if cx.tables.expr_ty(lhs).is_floating_point(); - if cx.tables.expr_ty(rhs).is_floating_point(); + if cx.tables().expr_ty(lhs).is_floating_point(); + if cx.tables().expr_ty(rhs).is_floating_point(); then { return Some((lhs, rhs)); } @@ -404,7 +404,7 @@ fn are_exprs_equal(cx: &LateContext<'_, '_>, expr1: &Expr<'_>, expr2: &Expr<'_>) /// Returns true iff expr is some zero literal fn is_zero(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> bool { - match constant_simple(cx, cx.tables, expr) { + match constant_simple(cx, cx.tables(), expr) { Some(Constant::Int(i)) => i == 0, Some(Constant::F32(f)) => f == 0.0, Some(Constant::F64(f)) => f == 0.0, @@ -482,7 +482,7 @@ fn check_custom_abs(cx: &LateContext<'_, '_>, expr: &Expr<'_>) { impl<'a, 'tcx> LateLintPass<'a, 'tcx> for FloatingPointArithmetic { fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) { if let ExprKind::MethodCall(ref path, _, args, _) = &expr.kind { - let recv_ty = cx.tables.expr_ty(&args[0]); + let recv_ty = cx.tables().expr_ty(&args[0]); if recv_ty.is_floating_point() { match &*path.ident.name.as_str() { diff --git a/clippy_lints/src/format.rs b/clippy_lints/src/format.rs index 4cae5ca2c4326..58cf0027ea4d4 100644 --- a/clippy_lints/src/format.rs +++ b/clippy_lints/src/format.rs @@ -88,13 +88,13 @@ fn on_argumentv1_new<'a, 'tcx>( // matches `core::fmt::Display::fmt` if args.len() == 2; if let ExprKind::Path(ref qpath) = args[1].kind; - if let Some(did) = cx.tables.qpath_res(qpath, args[1].hir_id).opt_def_id(); + if let Some(did) = cx.tables().qpath_res(qpath, args[1].hir_id).opt_def_id(); if match_def_path(cx, did, &paths::DISPLAY_FMT_METHOD); // check `(arg0,)` in match block if let PatKind::Tuple(ref pats, None) = arms[0].pat.kind; if pats.len() == 1; then { - let ty = walk_ptrs_ty(cx.tables.pat_ty(&pats[0])); + let ty = walk_ptrs_ty(cx.tables().pat_ty(&pats[0])); if ty.kind != rustc_middle::ty::Str && !is_type_diagnostic_item(cx, ty, sym!(string_type)) { return None; } diff --git a/clippy_lints/src/get_last_with_len.rs b/clippy_lints/src/get_last_with_len.rs index 3629ba623ce43..57a7fbb565679 100644 --- a/clippy_lints/src/get_last_with_len.rs +++ b/clippy_lints/src/get_last_with_len.rs @@ -54,7 +54,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for GetLastWithLen { // Argument 0 (the struct we're calling the method on) is a vector if let Some(struct_calling_on) = args.get(0); - let struct_ty = cx.tables.expr_ty(struct_calling_on); + let struct_ty = cx.tables().expr_ty(struct_calling_on); if is_type_diagnostic_item(cx, struct_ty, sym!(vec_type)); // Argument to "get" is a subtraction diff --git a/clippy_lints/src/identity_op.rs b/clippy_lints/src/identity_op.rs index 78e07d25f67c5..1c25e050997ea 100644 --- a/clippy_lints/src/identity_op.rs +++ b/clippy_lints/src/identity_op.rs @@ -62,8 +62,8 @@ fn is_allowed(cx: &LateContext<'_, '_>, cmp: BinOp, left: &Expr<'_>, right: &Exp // `1 << 0` is a common pattern in bit manipulation code if_chain! { if let BinOpKind::Shl = cmp.node; - if let Some(Constant::Int(0)) = constant_simple(cx, cx.tables, right); - if let Some(Constant::Int(1)) = constant_simple(cx, cx.tables, left); + if let Some(Constant::Int(0)) = constant_simple(cx, cx.tables(), right); + if let Some(Constant::Int(1)) = constant_simple(cx, cx.tables(), left); then { return true; } @@ -74,8 +74,8 @@ fn is_allowed(cx: &LateContext<'_, '_>, cmp: BinOp, left: &Expr<'_>, right: &Exp #[allow(clippy::cast_possible_wrap)] fn check(cx: &LateContext<'_, '_>, e: &Expr<'_>, m: i8, span: Span, arg: Span) { - if let Some(Constant::Int(v)) = constant_simple(cx, cx.tables, e) { - let check = match cx.tables.expr_ty(e).kind { + if let Some(Constant::Int(v)) = constant_simple(cx, cx.tables(), e) { + let check = match cx.tables().expr_ty(e).kind { ty::Int(ity) => unsext(cx.tcx, -1_i128, ity), ty::Uint(uty) => clip(cx.tcx, !0, uty), _ => return, diff --git a/clippy_lints/src/if_let_mutex.rs b/clippy_lints/src/if_let_mutex.rs index 04d17c91d63c1..e357c7b3b2eb2 100644 --- a/clippy_lints/src/if_let_mutex.rs +++ b/clippy_lints/src/if_let_mutex.rs @@ -149,7 +149,7 @@ fn is_mutex_lock_call<'a>(cx: &LateContext<'a, '_>, expr: &'a Expr<'_>) -> Optio if_chain! { if let ExprKind::MethodCall(path, _span, args, _) = &expr.kind; if path.ident.to_string() == "lock"; - let ty = cx.tables.expr_ty(&args[0]); + let ty = cx.tables().expr_ty(&args[0]); if is_type_diagnostic_item(cx, ty, sym!(mutex_type)); then { Some(&args[0]) diff --git a/clippy_lints/src/if_let_some_result.rs b/clippy_lints/src/if_let_some_result.rs index 6a1fcdd1ce445..3f1ae9b86d387 100644 --- a/clippy_lints/src/if_let_some_result.rs +++ b/clippy_lints/src/if_let_some_result.rs @@ -45,7 +45,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for OkIfLet { if let ExprKind::MethodCall(_, ok_span, ref result_types, _) = op.kind; //check is expr.ok() has type Result.ok(, _) if let PatKind::TupleStruct(QPath::Resolved(_, ref x), ref y, _) = body[0].pat.kind; //get operation if method_chain_args(op, &["ok"]).is_some(); //test to see if using ok() methoduse std::marker::Sized; - if is_type_diagnostic_item(cx, cx.tables.expr_ty(&result_types[0]), sym!(result_type)); + if is_type_diagnostic_item(cx, cx.tables().expr_ty(&result_types[0]), sym!(result_type)); if rustc_hir_pretty::to_string(rustc_hir_pretty::NO_ANN, |s| s.print_path(x, false)) == "Some"; then { diff --git a/clippy_lints/src/implicit_return.rs b/clippy_lints/src/implicit_return.rs index c4308fd26a302..5a0531ff749e9 100644 --- a/clippy_lints/src/implicit_return.rs +++ b/clippy_lints/src/implicit_return.rs @@ -108,7 +108,7 @@ fn expr_match(cx: &LateContext<'_, '_>, expr: &Expr<'_>) { ExprKind::Call(expr, ..) => { if_chain! { if let ExprKind::Path(qpath) = &expr.kind; - if let Some(path_def_id) = cx.tables.qpath_res(qpath, expr.hir_id).opt_def_id(); + if let Some(path_def_id) = cx.tables().qpath_res(qpath, expr.hir_id).opt_def_id(); if match_def_path(cx, path_def_id, &BEGIN_PANIC) || match_def_path(cx, path_def_id, &BEGIN_PANIC_FMT); then { } diff --git a/clippy_lints/src/implicit_saturating_sub.rs b/clippy_lints/src/implicit_saturating_sub.rs index fdaf37e5e08fa..1a6cb0b0c566e 100644 --- a/clippy_lints/src/implicit_saturating_sub.rs +++ b/clippy_lints/src/implicit_saturating_sub.rs @@ -81,7 +81,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ImplicitSaturatingSub { }; // Check if the variable in the condition statement is an integer - if !cx.tables.expr_ty(cond_var).is_integral() { + if !cx.tables().expr_ty(cond_var).is_integral() { return; } @@ -93,7 +93,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ImplicitSaturatingSub { ExprKind::Lit(ref cond_lit) => { // Check if the constant is zero if let LitKind::Int(0, _) = cond_lit.node { - if cx.tables.expr_ty(cond_left).is_signed() { + if cx.tables().expr_ty(cond_left).is_signed() { } else { print_lint_and_sugg(cx, &var_name, expr); }; diff --git a/clippy_lints/src/indexing_slicing.rs b/clippy_lints/src/indexing_slicing.rs index c5808dd540b6f..c5e4abc94a8a6 100644 --- a/clippy_lints/src/indexing_slicing.rs +++ b/clippy_lints/src/indexing_slicing.rs @@ -88,7 +88,7 @@ declare_lint_pass!(IndexingSlicing => [INDEXING_SLICING, OUT_OF_BOUNDS_INDEXING] impl<'a, 'tcx> LateLintPass<'a, 'tcx> for IndexingSlicing { fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) { if let ExprKind::Index(ref array, ref index) = &expr.kind { - let ty = cx.tables.expr_ty(array); + let ty = cx.tables().expr_ty(array); if let Some(range) = higher::range(cx, index) { // Ranged indexes, i.e., &x[n..m], &x[n..], &x[..n] and &x[..] if let ty::Array(_, s) = ty.kind { @@ -143,7 +143,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for IndexingSlicing { // Catchall non-range index, i.e., [n] or [n << m] if let ty::Array(..) = ty.kind { // Index is a constant uint. - if let Some(..) = constant(cx, cx.tables, index) { + if let Some(..) = constant(cx, cx.tables(), index) { // Let rustc's `const_err` lint handle constant `usize` indexing on arrays. return; } @@ -169,14 +169,14 @@ fn to_const_range<'a, 'tcx>( range: higher::Range<'_>, array_size: u128, ) -> (Option, Option) { - let s = range.start.map(|expr| constant(cx, cx.tables, expr).map(|(c, _)| c)); + let s = range.start.map(|expr| constant(cx, cx.tables(), expr).map(|(c, _)| c)); let start = match s { Some(Some(Constant::Int(x))) => Some(x), Some(_) => None, None => Some(0), }; - let e = range.end.map(|expr| constant(cx, cx.tables, expr).map(|(c, _)| c)); + let e = range.end.map(|expr| constant(cx, cx.tables(), expr).map(|(c, _)| c)); let end = match e { Some(Some(Constant::Int(x))) => { if range.limits == RangeLimits::Closed { diff --git a/clippy_lints/src/infinite_iter.rs b/clippy_lints/src/infinite_iter.rs index a860a9def2422..38f086c9221fe 100644 --- a/clippy_lints/src/infinite_iter.rs +++ b/clippy_lints/src/infinite_iter.rs @@ -230,13 +230,14 @@ fn complete_infinite_iter(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> Finitene } } if method.ident.name == sym!(last) && args.len() == 1 { - let not_double_ended = get_trait_def_id(cx, &paths::DOUBLE_ENDED_ITERATOR) - .map_or(false, |id| !implements_trait(cx, cx.tables.expr_ty(&args[0]), id, &[])); + let not_double_ended = get_trait_def_id(cx, &paths::DOUBLE_ENDED_ITERATOR).map_or(false, |id| { + !implements_trait(cx, cx.tables().expr_ty(&args[0]), id, &[]) + }); if not_double_ended { return is_infinite(cx, &args[0]); } } else if method.ident.name == sym!(collect) { - let ty = cx.tables.expr_ty(expr); + let ty = cx.tables().expr_ty(expr); if INFINITE_COLLECTORS.iter().any(|path| match_type(cx, ty, path)) { return is_infinite(cx, &args[0]); } diff --git a/clippy_lints/src/integer_division.rs b/clippy_lints/src/integer_division.rs index d537ef3f3238e..83ae1c1a971e1 100644 --- a/clippy_lints/src/integer_division.rs +++ b/clippy_lints/src/integer_division.rs @@ -50,7 +50,7 @@ fn is_integer_division<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx hir::Ex if let hir::ExprKind::Binary(binop, left, right) = &expr.kind; if let hir::BinOpKind::Div = &binop.node; then { - let (left_ty, right_ty) = (cx.tables.expr_ty(left), cx.tables.expr_ty(right)); + let (left_ty, right_ty) = (cx.tables().expr_ty(left), cx.tables().expr_ty(right)); return left_ty.is_integral() && right_ty.is_integral(); } } diff --git a/clippy_lints/src/large_stack_arrays.rs b/clippy_lints/src/large_stack_arrays.rs index deb57db167896..0301f263489f4 100644 --- a/clippy_lints/src/large_stack_arrays.rs +++ b/clippy_lints/src/large_stack_arrays.rs @@ -42,7 +42,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for LargeStackArrays { fn check_expr(&mut self, cx: &LateContext<'_, '_>, expr: &Expr<'_>) { if_chain! { if let ExprKind::Repeat(_, _) = expr.kind; - if let ty::Array(element_type, cst) = cx.tables.expr_ty(expr).kind; + if let ty::Array(element_type, cst) = cx.tables().expr_ty(expr).kind; if let ConstKind::Value(val) = cst.val; if let ConstValue::Scalar(element_count) = val; if let Ok(element_count) = element_count.to_machine_usize(&cx.tcx); diff --git a/clippy_lints/src/len_zero.rs b/clippy_lints/src/len_zero.rs index 7838e8e8ab774..e17297e969516 100644 --- a/clippy_lints/src/len_zero.rs +++ b/clippy_lints/src/len_zero.rs @@ -300,7 +300,7 @@ fn has_is_empty(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> bool { return false; } - let ty = &walk_ptrs_ty(cx.tables.expr_ty(expr)); + let ty = &walk_ptrs_ty(cx.tables().expr_ty(expr)); match ty.kind { ty::Dynamic(ref tt, ..) => { if let Some(principal) = tt.principal() { diff --git a/clippy_lints/src/let_and_return.rs b/clippy_lints/src/let_and_return.rs index 6d3fb317bcfc5..299202981b1f3 100644 --- a/clippy_lints/src/let_and_return.rs +++ b/clippy_lints/src/let_and_return.rs @@ -100,14 +100,14 @@ struct BorrowVisitor<'a, 'tcx> { impl BorrowVisitor<'_, '_> { fn fn_def_id(&self, expr: &Expr<'_>) -> Option { match &expr.kind { - ExprKind::MethodCall(..) => self.cx.tables.type_dependent_def_id(expr.hir_id), + ExprKind::MethodCall(..) => self.cx.tables().type_dependent_def_id(expr.hir_id), ExprKind::Call( Expr { kind: ExprKind::Path(qpath), .. }, .., - ) => self.cx.tables.qpath_res(qpath, expr.hir_id).opt_def_id(), + ) => self.cx.tables().qpath_res(qpath, expr.hir_id).opt_def_id(), _ => None, } } diff --git a/clippy_lints/src/let_if_seq.rs b/clippy_lints/src/let_if_seq.rs index e097f40f87e47..7b03812b82260 100644 --- a/clippy_lints/src/let_if_seq.rs +++ b/clippy_lints/src/let_if_seq.rs @@ -73,7 +73,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for LetIfSeq { then { let span = stmt.span.to(if_.span); - let has_interior_mutability = !cx.tables.node_type(canonical_id).is_freeze( + let has_interior_mutability = !cx.tables().node_type(canonical_id).is_freeze( cx.tcx.at(span), cx.param_env, ); diff --git a/clippy_lints/src/let_underscore.rs b/clippy_lints/src/let_underscore.rs index acd628bbaca59..0864bbe0f9127 100644 --- a/clippy_lints/src/let_underscore.rs +++ b/clippy_lints/src/let_underscore.rs @@ -76,7 +76,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for LetUnderscore { if let PatKind::Wild = local.pat.kind; if let Some(ref init) = local.init; then { - let init_ty = cx.tables.expr_ty(init); + let init_ty = cx.tables().expr_ty(init); let contains_sync_guard = init_ty.walk().any(|inner| match inner.unpack() { GenericArgKind::Type(inner_ty) => { SYNC_GUARD_PATHS.iter().any(|path| match_type(cx, inner_ty, path)) @@ -94,7 +94,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for LetUnderscore { "consider using an underscore-prefixed named \ binding or dropping explicitly with `std::mem::drop`" ) - } else if is_must_use_ty(cx, cx.tables.expr_ty(init)) { + } else if is_must_use_ty(cx, cx.tables().expr_ty(init)) { span_lint_and_help( cx, LET_UNDERSCORE_MUST_USE, diff --git a/clippy_lints/src/lifetimes.rs b/clippy_lints/src/lifetimes.rs index 318d0b69d57b7..6840e82d4bf1b 100644 --- a/clippy_lints/src/lifetimes.rs +++ b/clippy_lints/src/lifetimes.rs @@ -343,7 +343,7 @@ impl<'v, 't> RefVisitor<'v, 't> { }) { let hir_id = ty.hir_id; - match self.cx.tables.qpath_res(qpath, hir_id) { + match self.cx.tables().qpath_res(qpath, hir_id) { Res::Def(DefKind::TyAlias | DefKind::Struct, def_id) => { let generics = self.cx.tcx.generics_of(def_id); for _ in generics.params.as_slice() { diff --git a/clippy_lints/src/loops.rs b/clippy_lints/src/loops.rs index 9c8e8d8fabf4e..18b979176a0a0 100644 --- a/clippy_lints/src/loops.rs +++ b/clippy_lints/src/loops.rs @@ -535,7 +535,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Loops { if_chain! { if let ExprKind::MethodCall(..) | ExprKind::Call(..) = iter_expr.kind; if let Some(iter_def_id) = get_trait_def_id(cx, &paths::ITERATOR); - if implements_trait(cx, cx.tables.expr_ty(iter_expr), iter_def_id, &[]); + if implements_trait(cx, cx.tables().expr_ty(iter_expr), iter_def_id, &[]); then { return; } @@ -985,8 +985,8 @@ fn detect_manual_memcpy<'a, 'tcx>( if_chain! { if let ExprKind::Index(seqexpr_left, idx_left) = lhs.kind; if let ExprKind::Index(seqexpr_right, idx_right) = rhs.kind; - if is_slice_like(cx, cx.tables.expr_ty(seqexpr_left)) - && is_slice_like(cx, cx.tables.expr_ty(seqexpr_right)); + if is_slice_like(cx, cx.tables().expr_ty(seqexpr_left)) + && is_slice_like(cx, cx.tables().expr_ty(seqexpr_right)); if let Some(offset_left) = get_offset(cx, &idx_left, canonical_id); if let Some(offset_right) = get_offset(cx, &idx_right, canonical_id); @@ -1254,8 +1254,8 @@ fn check_for_loop_arg(cx: &LateContext<'_, '_>, pat: &Pat<'_>, arg: &Expr<'_>, e lint_iter_method(cx, args, arg, method_name); } } else if method_name == "into_iter" && match_trait_method(cx, arg, &paths::INTO_ITERATOR) { - let receiver_ty = cx.tables.expr_ty(&args[0]); - let receiver_ty_adjusted = cx.tables.expr_ty_adjusted(&args[0]); + let receiver_ty = cx.tables().expr_ty(&args[0]); + let receiver_ty_adjusted = cx.tables().expr_ty_adjusted(&args[0]); if TyS::same_type(receiver_ty, receiver_ty_adjusted) { let mut applicability = Applicability::MachineApplicable; let object = snippet_with_applicability(cx, args[0].span, "_", &mut applicability); @@ -1300,7 +1300,7 @@ fn check_for_loop_arg(cx: &LateContext<'_, '_>, pat: &Pat<'_>, arg: &Expr<'_>, e /// Checks for `for` loops over `Option`s and `Result`s. fn check_arg_type(cx: &LateContext<'_, '_>, pat: &Pat<'_>, arg: &Expr<'_>) { - let ty = cx.tables.expr_ty(arg); + let ty = cx.tables().expr_ty(arg); if is_type_diagnostic_item(cx, ty, sym!(option_type)) { span_lint_and_help( cx, @@ -1405,7 +1405,7 @@ fn check_for_loop_explicit_counter<'a, 'tcx>( /// actual `Iterator` that the loop uses. fn make_iterator_snippet(cx: &LateContext<'_, '_>, arg: &Expr<'_>, applic_ref: &mut Applicability) -> String { let impls_iterator = get_trait_def_id(cx, &paths::ITERATOR) - .map_or(false, |id| implements_trait(cx, cx.tables.expr_ty(arg), id, &[])); + .map_or(false, |id| implements_trait(cx, cx.tables().expr_ty(arg), id, &[])); if impls_iterator { format!( "{}", @@ -1416,7 +1416,7 @@ fn make_iterator_snippet(cx: &LateContext<'_, '_>, arg: &Expr<'_>, applic_ref: & // (&mut x).into_iter() ==> x.iter_mut() match &arg.kind { ExprKind::AddrOf(BorrowKind::Ref, mutability, arg_inner) - if has_iter_method(cx, cx.tables.expr_ty(&arg_inner)).is_some() => + if has_iter_method(cx, cx.tables().expr_ty(&arg_inner)).is_some() => { let meth_name = match mutability { Mutability::Mut => "iter_mut", @@ -1449,7 +1449,7 @@ fn check_for_loop_over_map_kv<'a, 'tcx>( if let PatKind::Tuple(ref pat, _) = pat.kind { if pat.len() == 2 { let arg_span = arg.span; - let (new_pat_span, kind, ty, mutbl) = match cx.tables.expr_ty(arg).kind { + let (new_pat_span, kind, ty, mutbl) = match cx.tables().expr_ty(arg).kind { ty::Ref(_, ty, mutbl) => match (&pat[0].kind, &pat[1].kind) { (key, _) if pat_is_wild(key, body) => (pat[1].span, "value", ty, mutbl), (_, value) if pat_is_wild(value, body) => (pat[0].span, "key", ty, Mutability::Not), @@ -1594,7 +1594,7 @@ fn check_for_mutation<'a, 'tcx>( }; let def_id = body.hir_id.owner.to_def_id(); cx.tcx.infer_ctxt().enter(|infcx| { - ExprUseVisitor::new(&mut delegate, &infcx, def_id.expect_local(), cx.param_env, cx.tables).walk_expr(body); + ExprUseVisitor::new(&mut delegate, &infcx, def_id.expect_local(), cx.param_env, cx.tables()).walk_expr(body); }); delegate.mutation_span() } @@ -1688,7 +1688,7 @@ impl<'a, 'tcx> VarVisitor<'a, 'tcx> { if index_used_directly { self.indexed_directly.insert( seqvar.segments[0].ident.name, - (Some(extent), self.cx.tables.node_type(seqexpr.hir_id)), + (Some(extent), self.cx.tables().node_type(seqexpr.hir_id)), ); } return false; // no need to walk further *on the variable* @@ -1700,7 +1700,7 @@ impl<'a, 'tcx> VarVisitor<'a, 'tcx> { if index_used_directly { self.indexed_directly.insert( seqvar.segments[0].ident.name, - (None, self.cx.tables.node_type(seqexpr.hir_id)), + (None, self.cx.tables().node_type(seqexpr.hir_id)), ); } return false; // no need to walk further *on the variable* @@ -1768,7 +1768,7 @@ impl<'a, 'tcx> Visitor<'tcx> for VarVisitor<'a, 'tcx> { ExprKind::Call(ref f, args) => { self.visit_expr(f); for expr in args { - let ty = self.cx.tables.expr_ty_adjusted(expr); + let ty = self.cx.tables().expr_ty_adjusted(expr); self.prefer_mutable = false; if let ty::Ref(_, _, mutbl) = ty.kind { if mutbl == Mutability::Mut { @@ -1779,7 +1779,7 @@ impl<'a, 'tcx> Visitor<'tcx> for VarVisitor<'a, 'tcx> { } }, ExprKind::MethodCall(_, _, args, _) => { - let def_id = self.cx.tables.type_dependent_def_id(expr.hir_id).unwrap(); + let def_id = self.cx.tables().type_dependent_def_id(expr.hir_id).unwrap(); for (ty, expr) in self.cx.tcx.fn_sig(def_id).inputs().skip_binder().iter().zip(args) { self.prefer_mutable = false; if let ty::Ref(_, _, mutbl) = ty.kind { @@ -1866,7 +1866,7 @@ impl<'a, 'tcx> Visitor<'tcx> for VarUsedAfterLoopVisitor<'a, 'tcx> { fn is_ref_iterable_type(cx: &LateContext<'_, '_>, e: &Expr<'_>) -> bool { // no walk_ptrs_ty: calling iter() on a reference can make sense because it // will allow further borrows afterwards - let ty = cx.tables.expr_ty(e); + let ty = cx.tables().expr_ty(e); is_iterable_array(ty, cx) || is_type_diagnostic_item(cx, ty, sym!(vec_type)) || match_type(cx, ty, &paths::LINKED_LIST) || @@ -2241,7 +2241,7 @@ fn path_name(e: &Expr<'_>) -> Option { } fn check_infinite_loop<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, cond: &'tcx Expr<'_>, expr: &'tcx Expr<'_>) { - if constant(cx, cx.tables, cond).is_some() { + if constant(cx, cx.tables(), cond).is_some() { // A pure constant condition (e.g., `while false`) is not linted. return; } @@ -2377,7 +2377,7 @@ fn check_needless_collect<'a, 'tcx>(expr: &'tcx Expr<'_>, cx: &LateContext<'a, ' if let Some(ref generic_args) = chain_method.args; if let Some(GenericArg::Type(ref ty)) = generic_args.args.get(0); then { - let ty = cx.tables.node_type(ty.hir_id); + let ty = cx.tables().node_type(ty.hir_id); if is_type_diagnostic_item(cx, ty, sym!(vec_type)) || is_type_diagnostic_item(cx, ty, sym!(vecdeque_type)) || match_type(cx, ty, &paths::BTREEMAP) || diff --git a/clippy_lints/src/map_clone.rs b/clippy_lints/src/map_clone.rs index 8f4fdc685ef38..9109de9458f1c 100644 --- a/clippy_lints/src/map_clone.rs +++ b/clippy_lints/src/map_clone.rs @@ -52,7 +52,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MapClone { if let hir::ExprKind::MethodCall(ref method, _, ref args, _) = e.kind; if args.len() == 2; if method.ident.as_str() == "map"; - let ty = cx.tables.expr_ty(&args[0]); + let ty = cx.tables().expr_ty(&args[0]); if is_type_diagnostic_item(cx, ty, sym!(option_type)) || match_trait_method(cx, e, &paths::ITERATOR); if let hir::ExprKind::Closure(_, _, body_id, _, _) = args[1].kind; let closure_body = cx.tcx.hir().body(body_id); @@ -70,7 +70,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MapClone { match closure_expr.kind { hir::ExprKind::Unary(hir::UnOp::UnDeref, ref inner) => { if ident_eq(name, inner) { - if let ty::Ref(.., Mutability::Not) = cx.tables.expr_ty(inner).kind { + if let ty::Ref(.., Mutability::Not) = cx.tables().expr_ty(inner).kind { lint(cx, e.span, args[0].span, true); } } @@ -79,7 +79,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MapClone { if ident_eq(name, &obj[0]) && method.ident.as_str() == "clone" && match_trait_method(cx, closure_expr, &paths::CLONE_TRAIT) { - let obj_ty = cx.tables.expr_ty(&obj[0]); + let obj_ty = cx.tables().expr_ty(&obj[0]); if let ty::Ref(_, ty, _) = obj_ty.kind { let copy = is_copy(cx, ty); lint(cx, e.span, args[0].span, copy); diff --git a/clippy_lints/src/map_unit_fn.rs b/clippy_lints/src/map_unit_fn.rs index 8f4b674c04f49..a4550f707ee22 100644 --- a/clippy_lints/src/map_unit_fn.rs +++ b/clippy_lints/src/map_unit_fn.rs @@ -101,7 +101,7 @@ fn is_unit_type(ty: Ty<'_>) -> bool { } fn is_unit_function(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>) -> bool { - let ty = cx.tables.expr_ty(expr); + let ty = cx.tables().expr_ty(expr); if let ty::FnDef(id, _) = ty.kind { if let Some(fn_type) = cx.tcx.fn_sig(id).no_bound_vars() { @@ -112,7 +112,7 @@ fn is_unit_function(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>) -> bool { } fn is_unit_expression(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>) -> bool { - is_unit_type(cx.tables.expr_ty(expr)) + is_unit_type(cx.tables().expr_ty(expr)) } /// The expression inside a closure may or may not have surrounding braces and @@ -205,9 +205,9 @@ fn suggestion_msg(function_type: &str, map_type: &str) -> String { fn lint_map_unit_fn(cx: &LateContext<'_, '_>, stmt: &hir::Stmt<'_>, expr: &hir::Expr<'_>, map_args: &[hir::Expr<'_>]) { let var_arg = &map_args[0]; - let (map_type, variant, lint) = if is_type_diagnostic_item(cx, cx.tables.expr_ty(var_arg), sym!(option_type)) { + let (map_type, variant, lint) = if is_type_diagnostic_item(cx, cx.tables().expr_ty(var_arg), sym!(option_type)) { ("Option", "Some", OPTION_MAP_UNIT_FN) - } else if is_type_diagnostic_item(cx, cx.tables.expr_ty(var_arg), sym!(result_type)) { + } else if is_type_diagnostic_item(cx, cx.tables().expr_ty(var_arg), sym!(result_type)) { ("Result", "Ok", RESULT_MAP_UNIT_FN) } else { return; diff --git a/clippy_lints/src/match_on_vec_items.rs b/clippy_lints/src/match_on_vec_items.rs index ee69628e9f052..4a025e0621f96 100644 --- a/clippy_lints/src/match_on_vec_items.rs +++ b/clippy_lints/src/match_on_vec_items.rs @@ -88,13 +88,13 @@ fn is_vec_indexing<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'tcx>) } fn is_vector(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> bool { - let ty = cx.tables.expr_ty(expr); + let ty = cx.tables().expr_ty(expr); let ty = walk_ptrs_ty(ty); is_type_diagnostic_item(cx, ty, sym!(vec_type)) } fn is_full_range(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> bool { - let ty = cx.tables.expr_ty(expr); + let ty = cx.tables().expr_ty(expr); let ty = walk_ptrs_ty(ty); match_type(cx, ty, &utils::paths::RANGE_FULL) } diff --git a/clippy_lints/src/matches.rs b/clippy_lints/src/matches.rs index 6d7af45a47224..0c91d8885d924 100644 --- a/clippy_lints/src/matches.rs +++ b/clippy_lints/src/matches.rs @@ -540,7 +540,7 @@ fn check_single_match(cx: &LateContext<'_, '_>, ex: &Expr<'_>, arms: &[Arm<'_>], // allow match arms with just expressions return; }; - let ty = cx.tables.expr_ty(ex); + let ty = cx.tables().expr_ty(ex); if ty.kind != ty::Bool || is_allowed(cx, MATCH_BOOL, ex.hir_id) { check_single_match_single_pattern(cx, ex, arms, expr, els); check_single_match_opt_like(cx, ex, arms, expr, ty, els); @@ -632,7 +632,7 @@ fn check_single_match_opt_like( fn check_match_bool(cx: &LateContext<'_, '_>, ex: &Expr<'_>, arms: &[Arm<'_>], expr: &Expr<'_>) { // Type of expression is `bool`. - if cx.tables.expr_ty(ex).kind == ty::Bool { + if cx.tables().expr_ty(ex).kind == ty::Bool { span_lint_and_then( cx, MATCH_BOOL, @@ -695,8 +695,8 @@ fn check_match_bool(cx: &LateContext<'_, '_>, ex: &Expr<'_>, arms: &[Arm<'_>], e } fn check_overlapping_arms<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, ex: &'tcx Expr<'_>, arms: &'tcx [Arm<'_>]) { - if arms.len() >= 2 && cx.tables.expr_ty(ex).is_integral() { - let ranges = all_ranges(cx, arms, cx.tables.expr_ty(ex)); + if arms.len() >= 2 && cx.tables().expr_ty(ex).is_integral() { + let ranges = all_ranges(cx, arms, cx.tables().expr_ty(ex)); let type_ranges = type_ranges(&ranges); if !type_ranges.is_empty() { if let Some((start, end)) = overlapping(&type_ranges) { @@ -714,7 +714,7 @@ fn check_overlapping_arms<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, ex: &'tcx Expr<' } fn check_wild_err_arm(cx: &LateContext<'_, '_>, ex: &Expr<'_>, arms: &[Arm<'_>]) { - let ex_ty = walk_ptrs_ty(cx.tables.expr_ty(ex)); + let ex_ty = walk_ptrs_ty(cx.tables().expr_ty(ex)); if is_type_diagnostic_item(cx, ex_ty, sym!(result_type)) { for arm in arms { if let PatKind::TupleStruct(ref path, ref inner, _) = arm.pat.kind { @@ -755,7 +755,7 @@ fn check_wild_err_arm(cx: &LateContext<'_, '_>, ex: &Expr<'_>, arms: &[Arm<'_>]) } fn check_wild_enum_match(cx: &LateContext<'_, '_>, ex: &Expr<'_>, arms: &[Arm<'_>]) { - let ty = cx.tables.expr_ty(ex); + let ty = cx.tables().expr_ty(ex); if !ty.is_enum() { // If there isn't a nice closed set of possible values that can be conveniently enumerated, // don't complain about not enumerating the mall. @@ -935,8 +935,8 @@ fn check_match_as_ref(cx: &LateContext<'_, '_>, ex: &Expr<'_>, arms: &[Arm<'_>], "as_mut" }; - let output_ty = cx.tables.expr_ty(expr); - let input_ty = cx.tables.expr_ty(ex); + let output_ty = cx.tables().expr_ty(expr); + let input_ty = cx.tables().expr_ty(ex); let cast = if_chain! { if let ty::Adt(_, substs) = input_ty.kind; @@ -1006,13 +1006,13 @@ fn check_match_single_binding<'a>(cx: &LateContext<'_, 'a>, ex: &Expr<'a>, arms: match match_body.kind { ExprKind::Block(block, _) => { // macro + expr_ty(body) == () - if block.span.from_expansion() && cx.tables.expr_ty(&match_body).is_unit() { + if block.span.from_expansion() && cx.tables().expr_ty(&match_body).is_unit() { snippet_body.push(';'); } }, _ => { // expr_ty(body) == () - if cx.tables.expr_ty(&match_body).is_unit() { + if cx.tables().expr_ty(&match_body).is_unit() { snippet_body.push(';'); } }, @@ -1111,11 +1111,11 @@ fn all_ranges<'a, 'tcx>( { if let PatKind::Range(ref lhs, ref rhs, range_end) = pat.kind { let lhs = match lhs { - Some(lhs) => constant(cx, cx.tables, lhs)?.0, + Some(lhs) => constant(cx, cx.tables(), lhs)?.0, None => miri_to_const(ty.numeric_min_val(cx.tcx)?)?, }; let rhs = match rhs { - Some(rhs) => constant(cx, cx.tables, rhs)?.0, + Some(rhs) => constant(cx, cx.tables(), rhs)?.0, None => miri_to_const(ty.numeric_max_val(cx.tcx)?)?, }; let rhs = match range_end { @@ -1129,7 +1129,7 @@ fn all_ranges<'a, 'tcx>( } if let PatKind::Lit(ref value) = pat.kind { - let value = constant(cx, cx.tables, value)?.0; + let value = constant(cx, cx.tables(), value)?.0; return Some(SpannedRange { span: pat.span, node: (value.clone(), Bound::Included(value)), diff --git a/clippy_lints/src/mem_discriminant.rs b/clippy_lints/src/mem_discriminant.rs index 3f953655670cf..d315c5ef89a88 100644 --- a/clippy_lints/src/mem_discriminant.rs +++ b/clippy_lints/src/mem_discriminant.rs @@ -35,10 +35,10 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MemDiscriminant { if let ExprKind::Call(ref func, ref func_args) = expr.kind; // is `mem::discriminant` if let ExprKind::Path(ref func_qpath) = func.kind; - if let Some(def_id) = cx.tables.qpath_res(func_qpath, func.hir_id).opt_def_id(); + if let Some(def_id) = cx.tables().qpath_res(func_qpath, func.hir_id).opt_def_id(); if match_def_path(cx, def_id, &paths::MEM_DISCRIMINANT); // type is non-enum - let ty_param = cx.tables.node_substs(func.hir_id).type_at(0); + let ty_param = cx.tables().node_substs(func.hir_id).type_at(0); if !ty_param.is_enum(); then { diff --git a/clippy_lints/src/mem_forget.rs b/clippy_lints/src/mem_forget.rs index c6ddc5de63b0e..1821bd9135f98 100644 --- a/clippy_lints/src/mem_forget.rs +++ b/clippy_lints/src/mem_forget.rs @@ -31,7 +31,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MemForget { if let ExprKind::Path(ref qpath) = path_expr.kind { if let Some(def_id) = qpath_res(cx, qpath, path_expr.hir_id).opt_def_id() { if match_def_path(cx, def_id, &paths::MEM_FORGET) { - let forgot_ty = cx.tables.expr_ty(&args[0]); + let forgot_ty = cx.tables().expr_ty(&args[0]); if forgot_ty.ty_adt_def().map_or(false, |def| def.has_dtor(cx.tcx)) { span_lint(cx, MEM_FORGET, e.span, "usage of `mem::forget` on `Drop` type"); diff --git a/clippy_lints/src/mem_replace.rs b/clippy_lints/src/mem_replace.rs index e2672e02b36da..16d31fc8346ea 100644 --- a/clippy_lints/src/mem_replace.rs +++ b/clippy_lints/src/mem_replace.rs @@ -138,7 +138,7 @@ fn check_replace_option_with_none(cx: &LateContext<'_, '_>, src: &Expr<'_>, dest fn check_replace_with_uninit(cx: &LateContext<'_, '_>, src: &Expr<'_>, dest: &Expr<'_>, expr_span: Span) { if_chain! { // check if replacement is mem::MaybeUninit::uninit().assume_init() - if let Some(method_def_id) = cx.tables.type_dependent_def_id(src.hir_id); + if let Some(method_def_id) = cx.tables().type_dependent_def_id(src.hir_id); if cx.tcx.is_diagnostic_item(sym::assume_init, method_def_id); then { let mut applicability = Applicability::MachineApplicable; @@ -162,7 +162,7 @@ fn check_replace_with_uninit(cx: &LateContext<'_, '_>, src: &Expr<'_>, dest: &Ex if let ExprKind::Call(ref repl_func, ref repl_args) = src.kind; if repl_args.is_empty(); if let ExprKind::Path(ref repl_func_qpath) = repl_func.kind; - if let Some(repl_def_id) = cx.tables.qpath_res(repl_func_qpath, repl_func.hir_id).opt_def_id(); + if let Some(repl_def_id) = cx.tables().qpath_res(repl_func_qpath, repl_func.hir_id).opt_def_id(); then { if cx.tcx.is_diagnostic_item(sym::mem_uninitialized, repl_def_id) { let mut applicability = Applicability::MachineApplicable; @@ -179,7 +179,7 @@ fn check_replace_with_uninit(cx: &LateContext<'_, '_>, src: &Expr<'_>, dest: &Ex applicability, ); } else if cx.tcx.is_diagnostic_item(sym::mem_zeroed, repl_def_id) && - !cx.tables.expr_ty(src).is_primitive() { + !cx.tables().expr_ty(src).is_primitive() { span_lint_and_help( cx, MEM_REPLACE_WITH_UNINIT, @@ -198,7 +198,7 @@ fn check_replace_with_default(cx: &LateContext<'_, '_>, src: &Expr<'_>, dest: &E if_chain! { if !in_external_macro(cx.tcx.sess, expr_span); if let ExprKind::Path(ref repl_func_qpath) = repl_func.kind; - if let Some(repl_def_id) = cx.tables.qpath_res(repl_func_qpath, repl_func.hir_id).opt_def_id(); + if let Some(repl_def_id) = cx.tables().qpath_res(repl_func_qpath, repl_func.hir_id).opt_def_id(); if match_def_path(cx, repl_def_id, &paths::DEFAULT_TRAIT_METHOD); then { span_lint_and_then( @@ -230,7 +230,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MemReplace { // Check that `expr` is a call to `mem::replace()` if let ExprKind::Call(ref func, ref func_args) = expr.kind; if let ExprKind::Path(ref func_qpath) = func.kind; - if let Some(def_id) = cx.tables.qpath_res(func_qpath, func.hir_id).opt_def_id(); + if let Some(def_id) = cx.tables().qpath_res(func_qpath, func.hir_id).opt_def_id(); if match_def_path(cx, def_id, &paths::MEM_REPLACE); if let [dest, src] = &**func_args; then { diff --git a/clippy_lints/src/methods/bind_instead_of_map.rs b/clippy_lints/src/methods/bind_instead_of_map.rs index 32e86637569ed..092702c8b8c7b 100644 --- a/clippy_lints/src/methods/bind_instead_of_map.rs +++ b/clippy_lints/src/methods/bind_instead_of_map.rs @@ -157,7 +157,7 @@ pub(crate) trait BindInsteadOfMap { /// Lint use of `_.and_then(|x| Some(y))` for `Option`s fn lint(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, args: &[hir::Expr<'_>]) { - if !match_type(cx, cx.tables.expr_ty(&args[0]), Self::TYPE_QPATH) { + if !match_type(cx, cx.tables().expr_ty(&args[0]), Self::TYPE_QPATH) { return; } diff --git a/clippy_lints/src/methods/inefficient_to_string.rs b/clippy_lints/src/methods/inefficient_to_string.rs index 06138ab9783c3..d29b9adcb7d43 100644 --- a/clippy_lints/src/methods/inefficient_to_string.rs +++ b/clippy_lints/src/methods/inefficient_to_string.rs @@ -11,9 +11,9 @@ use rustc_middle::ty::{self, Ty}; /// Checks for the `INEFFICIENT_TO_STRING` lint pub fn lint<'tcx>(cx: &LateContext<'_, 'tcx>, expr: &hir::Expr<'_>, arg: &hir::Expr<'_>, arg_ty: Ty<'tcx>) { if_chain! { - if let Some(to_string_meth_did) = cx.tables.type_dependent_def_id(expr.hir_id); + if let Some(to_string_meth_did) = cx.tables().type_dependent_def_id(expr.hir_id); if match_def_path(cx, to_string_meth_did, &paths::TO_STRING_METHOD); - if let Some(substs) = cx.tables.node_substs_opt(expr.hir_id); + if let Some(substs) = cx.tables().node_substs_opt(expr.hir_id); let self_ty = substs.type_at(0); let (deref_self_ty, deref_count) = walk_ptrs_ty_depth(self_ty); if deref_count >= 1; diff --git a/clippy_lints/src/methods/manual_saturating_arithmetic.rs b/clippy_lints/src/methods/manual_saturating_arithmetic.rs index 4f5c06e785c23..eb02314f4680a 100644 --- a/clippy_lints/src/methods/manual_saturating_arithmetic.rs +++ b/clippy_lints/src/methods/manual_saturating_arithmetic.rs @@ -11,7 +11,7 @@ pub fn lint(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, args: &[&[hir::Expr< let arith_lhs = &args[1][0]; let arith_rhs = &args[1][1]; - let ty = cx.tables.expr_ty(arith_lhs); + let ty = cx.tables().expr_ty(arith_lhs); if !ty.is_integral() { return; } @@ -101,7 +101,7 @@ fn is_min_or_max<'tcx>(cx: &LateContext<'_, 'tcx>, expr: &hir::Expr<'_>) -> Opti } } - let ty = cx.tables.expr_ty(expr); + let ty = cx.tables().expr_ty(expr); let ty_str = ty.to_string(); // `std::T::MAX` `std::T::MIN` constants diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index f25a9782813bb..c4e707ecf03ad 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -1433,7 +1433,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Methods { lint_or_fun_call(cx, expr, *method_span, &method_call.ident.as_str(), args); lint_expect_fun_call(cx, expr, *method_span, &method_call.ident.as_str(), args); - let self_ty = cx.tables.expr_ty_adjusted(&args[0]); + let self_ty = cx.tables().expr_ty_adjusted(&args[0]); if args.len() == 1 && method_call.ident.name == sym!(clone) { lint_clone_on_copy(cx, expr, &args[0], self_ty); lint_clone_on_ref_ptr(cx, expr, &args[0]); @@ -1639,7 +1639,7 @@ fn lint_or_fun_call<'a, 'tcx>( if let hir::ExprKind::Path(ref qpath) = fun.kind; let path = &*last_path_segment(qpath).ident.as_str(); if ["default", "new"].contains(&path); - let arg_ty = cx.tables.expr_ty(arg); + let arg_ty = cx.tables().expr_ty(arg); if let Some(default_trait_id) = get_trait_def_id(cx, &paths::DEFAULT_TRAIT); if implements_trait(cx, arg_ty, default_trait_id, &[]); @@ -1679,7 +1679,7 @@ fn lint_or_fun_call<'a, 'tcx>( ) { if let hir::ExprKind::MethodCall(ref path, _, ref args, _) = &arg.kind { if path.ident.as_str() == "len" { - let ty = walk_ptrs_ty(cx.tables.expr_ty(&args[0])); + let ty = walk_ptrs_ty(cx.tables().expr_ty(&args[0])); match ty.kind { ty::Slice(_) | ty::Array(_, _) => return, @@ -1707,7 +1707,7 @@ fn lint_or_fun_call<'a, 'tcx>( if { finder.visit_expr(&arg); finder.found }; if !contains_return(&arg); - let self_ty = cx.tables.expr_ty(self_expr); + let self_ty = cx.tables().expr_ty(self_expr); if let Some(&(_, fn_has_arguments, poss, suffix)) = know_types.iter().find(|&&i| match_type(cx, self_ty, i.0)); @@ -1786,7 +1786,7 @@ fn lint_expect_fun_call( if call_args.len() == 1 && (method_name.ident.name == sym!(as_str) || method_name.ident.name == sym!(as_ref)) && { - let arg_type = cx.tables.expr_ty(&call_args[0]); + let arg_type = cx.tables().expr_ty(&call_args[0]); let base_type = walk_ptrs_ty(arg_type); base_type.kind == ty::Str || is_type_diagnostic_item(cx, base_type, sym!(string_type)) } @@ -1805,7 +1805,7 @@ fn lint_expect_fun_call( // Only `&'static str` or `String` can be used directly in the `panic!`. Other types should be // converted to string. fn requires_to_string(cx: &LateContext<'_, '_>, arg: &hir::Expr<'_>) -> bool { - let arg_ty = cx.tables.expr_ty(arg); + let arg_ty = cx.tables().expr_ty(arg); if is_type_diagnostic_item(cx, arg_ty, sym!(string_type)) { return false; } @@ -1824,7 +1824,7 @@ fn lint_expect_fun_call( hir::ExprKind::Lit(_) => true, hir::ExprKind::Call(fun, _) => { if let hir::ExprKind::Path(ref p) = fun.kind { - match cx.tables.qpath_res(p, fun.hir_id) { + match cx.tables().qpath_res(p, fun.hir_id) { hir::def::Res::Def(hir::def::DefKind::Fn | hir::def::DefKind::AssocFn, def_id) => matches!( cx.tcx.fn_sig(def_id).output().skip_binder().kind, ty::Ref(ty::ReStatic, ..) @@ -1835,13 +1835,16 @@ fn lint_expect_fun_call( false } }, - hir::ExprKind::MethodCall(..) => cx.tables.type_dependent_def_id(arg.hir_id).map_or(false, |method_id| { - matches!( - cx.tcx.fn_sig(method_id).output().skip_binder().kind, - ty::Ref(ty::ReStatic, ..) - ) - }), - hir::ExprKind::Path(ref p) => match cx.tables.qpath_res(p, arg.hir_id) { + hir::ExprKind::MethodCall(..) => cx + .tables() + .type_dependent_def_id(arg.hir_id) + .map_or(false, |method_id| { + matches!( + cx.tcx.fn_sig(method_id).output().skip_binder().kind, + ty::Ref(ty::ReStatic, ..) + ) + }), + hir::ExprKind::Path(ref p) => match cx.tables().qpath_res(p, arg.hir_id) { hir::def::Res::Def(hir::def::DefKind::Const | hir::def::DefKind::Static, _) => true, _ => false, }, @@ -1888,7 +1891,7 @@ fn lint_expect_fun_call( return; } - let receiver_type = cx.tables.expr_ty_adjusted(&args[0]); + let receiver_type = cx.tables().expr_ty_adjusted(&args[0]); let closure_args = if is_type_diagnostic_item(cx, receiver_type, sym!(option_type)) { "||" } else if is_type_diagnostic_item(cx, receiver_type, sym!(result_type)) { @@ -1954,7 +1957,7 @@ fn lint_expect_fun_call( /// Checks for the `CLONE_ON_COPY` lint. fn lint_clone_on_copy(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, arg: &hir::Expr<'_>, arg_ty: Ty<'_>) { - let ty = cx.tables.expr_ty(expr); + let ty = cx.tables().expr_ty(expr); if let ty::Ref(_, inner, _) = arg_ty.kind { if let ty::Ref(_, innermost, _) = inner.kind { span_lint_and_then( @@ -2018,11 +2021,11 @@ fn lint_clone_on_copy(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, arg: &hir: } // x.clone() might have dereferenced x, possibly through Deref impls - if cx.tables.expr_ty(arg) == ty { + if cx.tables().expr_ty(arg) == ty { snip = Some(("try removing the `clone` call", format!("{}", snippet))); } else { let deref_count = cx - .tables + .tables() .expr_adjustments(arg) .iter() .filter(|adj| { @@ -2048,7 +2051,7 @@ fn lint_clone_on_copy(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, arg: &hir: } fn lint_clone_on_ref_ptr(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, arg: &hir::Expr<'_>) { - let obj_ty = walk_ptrs_ty(cx.tables.expr_ty(arg)); + let obj_ty = walk_ptrs_ty(cx.tables().expr_ty(arg)); if let ty::Adt(_, subst) = obj_ty.kind { let caller_type = if is_type_diagnostic_item(cx, obj_ty, sym::Rc) { @@ -2082,7 +2085,7 @@ fn lint_string_extend(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, args: &[hi let arg = &args[1]; if let Some(arglists) = method_chain_args(arg, &["chars"]) { let target = &arglists[0][0]; - let self_ty = walk_ptrs_ty(cx.tables.expr_ty(target)); + let self_ty = walk_ptrs_ty(cx.tables().expr_ty(target)); let ref_str = if self_ty.kind == ty::Str { "" } else if is_type_diagnostic_item(cx, self_ty, sym!(string_type)) { @@ -2110,7 +2113,7 @@ fn lint_string_extend(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, args: &[hi } fn lint_extend(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, args: &[hir::Expr<'_>]) { - let obj_ty = walk_ptrs_ty(cx.tables.expr_ty(&args[0])); + let obj_ty = walk_ptrs_ty(cx.tables().expr_ty(&args[0])); if is_type_diagnostic_item(cx, obj_ty, sym!(string_type)) { lint_string_extend(cx, expr, args); } @@ -2118,7 +2121,7 @@ fn lint_extend(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, args: &[hir::Expr fn lint_cstring_as_ptr(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, source: &hir::Expr<'_>, unwrap: &hir::Expr<'_>) { if_chain! { - let source_type = cx.tables.expr_ty(source); + let source_type = cx.tables().expr_ty(source); if let ty::Adt(def, substs) = source_type.kind; if cx.tcx.is_diagnostic_item(sym!(result_type), def.did); if match_type(cx, substs.type_at(0), &paths::CSTRING); @@ -2142,8 +2145,8 @@ fn lint_iter_cloned_collect<'a, 'tcx>( iter_args: &'tcx [hir::Expr<'_>], ) { if_chain! { - if is_type_diagnostic_item(cx, cx.tables.expr_ty(expr), sym!(vec_type)); - if let Some(slice) = derefs_to_slice(cx, &iter_args[0], cx.tables.expr_ty(&iter_args[0])); + if is_type_diagnostic_item(cx, cx.tables().expr_ty(expr), sym!(vec_type)); + if let Some(slice) = derefs_to_slice(cx, &iter_args[0], cx.tables().expr_ty(&iter_args[0])); if let Some(to_replace) = expr.span.trim_start(slice.span.source_callsite()); then { @@ -2250,7 +2253,7 @@ fn lint_unnecessary_fold(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, fold_ar fn lint_step_by<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &hir::Expr<'_>, args: &'tcx [hir::Expr<'_>]) { if match_trait_method(cx, expr, &paths::ITERATOR) { - if let Some((Constant::Int(0), _)) = constant(cx, cx.tables, &args[1]) { + if let Some((Constant::Int(0), _)) = constant(cx, cx.tables(), &args[1]) { span_lint( cx, ITERATOR_STEP_BY_ZERO, @@ -2274,7 +2277,7 @@ fn lint_iter_next<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx hir::Expr<'_ parent_expr_opt = get_parent_expr(cx, parent_expr); } - if derefs_to_slice(cx, caller_expr, cx.tables.expr_ty(caller_expr)).is_some() { + if derefs_to_slice(cx, caller_expr, cx.tables().expr_ty(caller_expr)).is_some() { // caller is a Slice if_chain! { if let hir::ExprKind::Index(ref caller_var, ref index_expr) = &caller_expr.kind; @@ -2295,8 +2298,8 @@ fn lint_iter_next<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx hir::Expr<'_ ); } } - } else if is_type_diagnostic_item(cx, cx.tables.expr_ty(caller_expr), sym!(vec_type)) - || matches!(&walk_ptrs_ty(cx.tables.expr_ty(caller_expr)).kind, ty::Array(_, _)) + } else if is_type_diagnostic_item(cx, cx.tables().expr_ty(caller_expr), sym!(vec_type)) + || matches!(&walk_ptrs_ty(cx.tables().expr_ty(caller_expr)).kind, ty::Array(_, _)) { // caller is a Vec or an Array let mut applicability = Applicability::MachineApplicable; @@ -2323,11 +2326,11 @@ fn lint_iter_nth<'a, 'tcx>( ) { let iter_args = nth_and_iter_args[1]; let mut_str = if is_mut { "_mut" } else { "" }; - let caller_type = if derefs_to_slice(cx, &iter_args[0], cx.tables.expr_ty(&iter_args[0])).is_some() { + let caller_type = if derefs_to_slice(cx, &iter_args[0], cx.tables().expr_ty(&iter_args[0])).is_some() { "slice" - } else if is_type_diagnostic_item(cx, cx.tables.expr_ty(&iter_args[0]), sym!(vec_type)) { + } else if is_type_diagnostic_item(cx, cx.tables().expr_ty(&iter_args[0]), sym!(vec_type)) { "Vec" - } else if is_type_diagnostic_item(cx, cx.tables.expr_ty(&iter_args[0]), sym!(vecdeque_type)) { + } else if is_type_diagnostic_item(cx, cx.tables().expr_ty(&iter_args[0]), sym!(vecdeque_type)) { "VecDeque" } else { let nth_args = nth_and_iter_args[0]; @@ -2348,7 +2351,7 @@ fn lint_iter_nth<'a, 'tcx>( fn lint_iter_nth_zero<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &hir::Expr<'_>, nth_args: &'tcx [hir::Expr<'_>]) { if_chain! { if match_trait_method(cx, expr, &paths::ITERATOR); - if let Some((Constant::Int(0), _)) = constant(cx, cx.tables, &nth_args[1]); + if let Some((Constant::Int(0), _)) = constant(cx, cx.tables(), &nth_args[1]); then { let mut applicability = Applicability::MachineApplicable; span_lint_and_sugg( @@ -2373,7 +2376,7 @@ fn lint_get_unwrap<'a, 'tcx>( // Note: we don't want to lint `get_mut().unwrap` for `HashMap` or `BTreeMap`, // because they do not implement `IndexMut` let mut applicability = Applicability::MachineApplicable; - let expr_ty = cx.tables.expr_ty(&get_args[0]); + let expr_ty = cx.tables().expr_ty(&get_args[0]); let get_args_str = if get_args.len() > 1 { snippet_with_applicability(cx, get_args[1].span, "_", &mut applicability) } else { @@ -2479,7 +2482,7 @@ fn derefs_to_slice<'a, 'tcx>( } if let hir::ExprKind::MethodCall(ref path, _, ref args, _) = expr.kind { - if path.ident.name == sym!(iter) && may_slice(cx, cx.tables.expr_ty(&args[0])) { + if path.ident.name == sym!(iter) && may_slice(cx, cx.tables().expr_ty(&args[0])) { Some(&args[0]) } else { None @@ -2502,7 +2505,7 @@ fn derefs_to_slice<'a, 'tcx>( /// lint use of `unwrap()` for `Option`s and `Result`s fn lint_unwrap(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, unwrap_args: &[hir::Expr<'_>]) { - let obj_ty = walk_ptrs_ty(cx.tables.expr_ty(&unwrap_args[0])); + let obj_ty = walk_ptrs_ty(cx.tables().expr_ty(&unwrap_args[0])); let mess = if is_type_diagnostic_item(cx, obj_ty, sym!(option_type)) { Some((UNWRAP_USED, "an Option", "None")) @@ -2530,7 +2533,7 @@ fn lint_unwrap(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, unwrap_args: &[hi /// lint use of `expect()` for `Option`s and `Result`s fn lint_expect(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, expect_args: &[hir::Expr<'_>]) { - let obj_ty = walk_ptrs_ty(cx.tables.expr_ty(&expect_args[0])); + let obj_ty = walk_ptrs_ty(cx.tables().expr_ty(&expect_args[0])); let mess = if is_type_diagnostic_item(cx, obj_ty, sym!(option_type)) { Some((EXPECT_USED, "an Option", "None")) @@ -2556,8 +2559,8 @@ fn lint_expect(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, expect_args: &[hi fn lint_ok_expect(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, ok_args: &[hir::Expr<'_>]) { if_chain! { // lint if the caller of `ok()` is a `Result` - if is_type_diagnostic_item(cx, cx.tables.expr_ty(&ok_args[0]), sym!(result_type)); - let result_type = cx.tables.expr_ty(&ok_args[0]); + if is_type_diagnostic_item(cx, cx.tables().expr_ty(&ok_args[0]), sym!(result_type)); + let result_type = cx.tables().expr_ty(&ok_args[0]); if let Some(error_type) = get_error_type(cx, result_type); if has_debug_impl(error_type, cx); @@ -2595,7 +2598,7 @@ fn lint_map_flatten<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx hir::Expr< } // lint if caller of `.map().flatten()` is an Option - if is_type_diagnostic_item(cx, cx.tables.expr_ty(&map_args[0]), sym!(option_type)) { + if is_type_diagnostic_item(cx, cx.tables().expr_ty(&map_args[0]), sym!(option_type)) { let msg = "called `map(..).flatten()` on an `Option`. \ This is more succinctly expressed by calling `.and_then(..)`"; let self_snippet = snippet(cx, map_args[0].span, ".."); @@ -2621,8 +2624,8 @@ fn lint_map_unwrap_or_else<'a, 'tcx>( unwrap_args: &'tcx [hir::Expr<'_>], ) { // lint if the caller of `map()` is an `Option` - let is_option = is_type_diagnostic_item(cx, cx.tables.expr_ty(&map_args[0]), sym!(option_type)); - let is_result = is_type_diagnostic_item(cx, cx.tables.expr_ty(&map_args[0]), sym!(result_type)); + let is_option = is_type_diagnostic_item(cx, cx.tables().expr_ty(&map_args[0]), sym!(option_type)); + let is_result = is_type_diagnostic_item(cx, cx.tables().expr_ty(&map_args[0]), sym!(result_type)); if is_option || is_result { // Don't make a suggestion that may fail to compile due to mutably borrowing @@ -2676,8 +2679,8 @@ fn lint_map_or_none<'a, 'tcx>( expr: &'tcx hir::Expr<'_>, map_or_args: &'tcx [hir::Expr<'_>], ) { - let is_option = is_type_diagnostic_item(cx, cx.tables.expr_ty(&map_or_args[0]), sym!(option_type)); - let is_result = is_type_diagnostic_item(cx, cx.tables.expr_ty(&map_or_args[0]), sym!(result_type)); + let is_option = is_type_diagnostic_item(cx, cx.tables().expr_ty(&map_or_args[0]), sym!(option_type)); + let is_result = is_type_diagnostic_item(cx, cx.tables().expr_ty(&map_or_args[0]), sym!(result_type)); // There are two variants of this `map_or` lint: // (1) using `map_or` as an adapter from `Result` to `Option` @@ -3042,7 +3045,7 @@ fn lint_chars_cmp( if segment.ident.name == sym!(Some); then { let mut applicability = Applicability::MachineApplicable; - let self_ty = walk_ptrs_ty(cx.tables.expr_ty_adjusted(&args[0][0])); + let self_ty = walk_ptrs_ty(cx.tables().expr_ty_adjusted(&args[0][0])); if self_ty.kind != ty::Str { return false; @@ -3174,8 +3177,8 @@ fn lint_asref(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, call_name: &str, a if match_trait_method(cx, expr, &paths::ASREF_TRAIT) || match_trait_method(cx, expr, &paths::ASMUT_TRAIT) { // check if the type after `as_ref` or `as_mut` is the same as before let recvr = &as_ref_args[0]; - let rcv_ty = cx.tables.expr_ty(recvr); - let res_ty = cx.tables.expr_ty(expr); + let rcv_ty = cx.tables().expr_ty(recvr); + let res_ty = cx.tables().expr_ty(expr); let (base_res_ty, res_depth) = walk_ptrs_ty_depth(res_ty); let (base_rcv_ty, rcv_depth) = walk_ptrs_ty_depth(rcv_ty); if base_rcv_ty == base_res_ty && rcv_depth >= res_depth { @@ -3244,7 +3247,7 @@ fn lint_maybe_uninit(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, outer: &hir if args.is_empty(); if let hir::ExprKind::Path(ref path) = callee.kind; if match_qpath(path, &paths::MEM_MAYBEUNINIT_UNINIT); - if !is_maybe_uninit_ty_valid(cx, cx.tables.expr_ty_adjusted(outer)); + if !is_maybe_uninit_ty_valid(cx, cx.tables().expr_ty_adjusted(outer)); then { span_lint( cx, @@ -3286,7 +3289,7 @@ fn lint_option_as_ref_deref<'a, 'tcx>( ) { let same_mutability = |m| (is_mut && m == &hir::Mutability::Mut) || (!is_mut && m == &hir::Mutability::Not); - let option_ty = cx.tables.expr_ty(&as_ref_args[0]); + let option_ty = cx.tables().expr_ty(&as_ref_args[0]); if !is_type_diagnostic_item(cx, option_ty, sym!(option_type)) { return; } @@ -3314,12 +3317,12 @@ fn lint_option_as_ref_deref<'a, 'tcx>( if_chain! { if args.len() == 1; if let hir::ExprKind::Path(qpath) = &args[0].kind; - if let hir::def::Res::Local(local_id) = cx.tables.qpath_res(qpath, args[0].hir_id); + if let hir::def::Res::Local(local_id) = cx.tables().qpath_res(qpath, args[0].hir_id); if closure_body.params[0].pat.hir_id == local_id; - let adj = cx.tables.expr_adjustments(&args[0]).iter().map(|x| &x.kind).collect::>(); + let adj = cx.tables().expr_adjustments(&args[0]).iter().map(|x| &x.kind).collect::>(); if let [ty::adjustment::Adjust::Deref(None), ty::adjustment::Adjust::Borrow(_)] = *adj; then { - let method_did = cx.tables.type_dependent_def_id(closure_expr.hir_id).unwrap(); + let method_did = cx.tables().type_dependent_def_id(closure_expr.hir_id).unwrap(); deref_aliases.iter().any(|path| match_def_path(cx, method_did, path)) } else { false @@ -3331,7 +3334,7 @@ fn lint_option_as_ref_deref<'a, 'tcx>( if let hir::ExprKind::Unary(hir::UnOp::UnDeref, ref inner1) = inner.kind; if let hir::ExprKind::Unary(hir::UnOp::UnDeref, ref inner2) = inner1.kind; if let hir::ExprKind::Path(ref qpath) = inner2.kind; - if let hir::def::Res::Local(local_id) = cx.tables.qpath_res(qpath, inner2.hir_id); + if let hir::def::Res::Local(local_id) = cx.tables().qpath_res(qpath, inner2.hir_id); then { closure_body.params[0].pat.hir_id == local_id } else { @@ -3614,7 +3617,7 @@ fn contains_return(expr: &hir::Expr<'_>) -> bool { fn check_pointer_offset(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, args: &[hir::Expr<'_>]) { if_chain! { if args.len() == 2; - if let ty::RawPtr(ty::TypeAndMut { ref ty, .. }) = cx.tables.expr_ty(&args[0]).kind; + if let ty::RawPtr(ty::TypeAndMut { ref ty, .. }) = cx.tables().expr_ty(&args[0]).kind; if let Ok(layout) = cx.tcx.layout_of(cx.param_env.and(ty)); if layout.is_zst(); then { @@ -3624,7 +3627,7 @@ fn check_pointer_offset(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, args: &[ } fn lint_filetype_is_file(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, args: &[hir::Expr<'_>]) { - let ty = cx.tables.expr_ty(&args[0]); + let ty = cx.tables().expr_ty(&args[0]); if !match_type(cx, ty, &paths::FILE_TYPE) { return; diff --git a/clippy_lints/src/methods/option_map_unwrap_or.rs b/clippy_lints/src/methods/option_map_unwrap_or.rs index 20c60ef33189d..7f4529a5870ac 100644 --- a/clippy_lints/src/methods/option_map_unwrap_or.rs +++ b/clippy_lints/src/methods/option_map_unwrap_or.rs @@ -20,8 +20,8 @@ pub(super) fn lint<'a, 'tcx>( map_span: Span, ) { // lint if the caller of `map()` is an `Option` - if is_type_diagnostic_item(cx, cx.tables.expr_ty(&map_args[0]), sym!(option_type)) { - if !is_copy(cx, cx.tables.expr_ty(&unwrap_args[1])) { + if is_type_diagnostic_item(cx, cx.tables().expr_ty(&map_args[0]), sym!(option_type)) { + if !is_copy(cx, cx.tables().expr_ty(&unwrap_args[1])) { // Do not lint if the `map` argument uses identifiers in the `map` // argument that are also used in the `unwrap_or` argument diff --git a/clippy_lints/src/methods/unnecessary_filter_map.rs b/clippy_lints/src/methods/unnecessary_filter_map.rs index 41c9ce7cda3e6..88243a88d9dd7 100644 --- a/clippy_lints/src/methods/unnecessary_filter_map.rs +++ b/clippy_lints/src/methods/unnecessary_filter_map.rs @@ -65,7 +65,7 @@ fn check_expression<'a, 'tcx>( if match_qpath(path, &paths::OPTION_SOME) { if_chain! { if let hir::ExprKind::Path(path) = &args[0].kind; - if let Res::Local(ref local) = cx.tables.qpath_res(path, args[0].hir_id); + if let Res::Local(ref local) = cx.tables().qpath_res(path, args[0].hir_id); then { if arg_id == *local { return (false, false) diff --git a/clippy_lints/src/minmax.rs b/clippy_lints/src/minmax.rs index b02c993de526b..8e6f3925d6605 100644 --- a/clippy_lints/src/minmax.rs +++ b/clippy_lints/src/minmax.rs @@ -36,7 +36,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MinMaxPass { } match ( outer_max, - Constant::partial_cmp(cx.tcx, cx.tables.expr_ty(ie), &outer_c, &inner_c), + Constant::partial_cmp(cx.tcx, cx.tables().expr_ty(ie), &outer_c, &inner_c), ) { (_, None) | (MinMax::Max, Some(Ordering::Less)) | (MinMax::Min, Some(Ordering::Greater)) => (), _ => { @@ -62,15 +62,18 @@ enum MinMax { fn min_max<'a>(cx: &LateContext<'_, '_>, expr: &'a Expr<'a>) -> Option<(MinMax, Constant, &'a Expr<'a>)> { if let ExprKind::Call(ref path, ref args) = expr.kind { if let ExprKind::Path(ref qpath) = path.kind { - cx.tables.qpath_res(qpath, path.hir_id).opt_def_id().and_then(|def_id| { - if match_def_path(cx, def_id, &paths::CMP_MIN) { - fetch_const(cx, args, MinMax::Min) - } else if match_def_path(cx, def_id, &paths::CMP_MAX) { - fetch_const(cx, args, MinMax::Max) - } else { - None - } - }) + cx.tables() + .qpath_res(qpath, path.hir_id) + .opt_def_id() + .and_then(|def_id| { + if match_def_path(cx, def_id, &paths::CMP_MIN) { + fetch_const(cx, args, MinMax::Min) + } else if match_def_path(cx, def_id, &paths::CMP_MAX) { + fetch_const(cx, args, MinMax::Max) + } else { + None + } + }) } else { None } @@ -87,14 +90,14 @@ fn fetch_const<'a>( if args.len() != 2 { return None; } - if let Some(c) = constant_simple(cx, cx.tables, &args[0]) { - if constant_simple(cx, cx.tables, &args[1]).is_none() { + if let Some(c) = constant_simple(cx, cx.tables(), &args[0]) { + if constant_simple(cx, cx.tables(), &args[1]).is_none() { // otherwise ignore Some((m, c, &args[1])) } else { None } - } else if let Some(c) = constant_simple(cx, cx.tables, &args[1]) { + } else if let Some(c) = constant_simple(cx, cx.tables(), &args[1]) { Some((m, c, &args[0])) } else { None diff --git a/clippy_lints/src/misc.rs b/clippy_lints/src/misc.rs index a0947608e6077..99cd864cae4e3 100644 --- a/clippy_lints/src/misc.rs +++ b/clippy_lints/src/misc.rs @@ -436,7 +436,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MiscLints { binding != "_result" && // FIXME: #944 is_used(cx, expr) && // don't lint if the declaration is in a macro - non_macro_local(cx, cx.tables.qpath_res(qpath, expr.hir_id)) + non_macro_local(cx, cx.tables().qpath_res(qpath, expr.hir_id)) { Some(binding) } else { @@ -496,7 +496,7 @@ fn get_lint_and_message( fn check_nan(cx: &LateContext<'_, '_>, expr: &Expr<'_>, cmp_expr: &Expr<'_>) { if_chain! { if !in_constant(cx, cmp_expr.hir_id); - if let Some((value, _)) = constant(cx, cx.tables, expr); + if let Some((value, _)) = constant(cx, cx.tables(), expr); then { let needs_lint = match value { Constant::F32(num) => num.is_nan(), @@ -517,7 +517,7 @@ fn check_nan(cx: &LateContext<'_, '_>, expr: &Expr<'_>, cmp_expr: &Expr<'_>) { } fn is_named_constant<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) -> bool { - if let Some((_, res)) = constant(cx, cx.tables, expr) { + if let Some((_, res)) = constant(cx, cx.tables(), expr) { res } else { false @@ -525,7 +525,7 @@ fn is_named_constant<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) } fn is_allowed<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) -> bool { - match constant(cx, cx.tables, expr) { + match constant(cx, cx.tables(), expr) { Some((Constant::F32(f), _)) => f == 0.0 || f.is_infinite(), Some((Constant::F64(f), _)) => f == 0.0 || f.is_infinite(), Some((Constant::Vec(vec), _)) => vec.iter().all(|f| match f { @@ -557,7 +557,7 @@ fn is_signum(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> bool { } fn is_float(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> bool { - let value = &walk_ptrs_ty(cx.tables.expr_ty(expr)).kind; + let value = &walk_ptrs_ty(cx.tables().expr_ty(expr)).kind; if let ty::Array(arr_ty, _) = value { return matches!(arr_ty.kind, ty::Float(_)); @@ -567,14 +567,14 @@ fn is_float(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> bool { } fn is_array(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> bool { - matches!(&walk_ptrs_ty(cx.tables.expr_ty(expr)).kind, ty::Array(_, _)) + matches!(&walk_ptrs_ty(cx.tables().expr_ty(expr)).kind, ty::Array(_, _)) } fn check_to_owned(cx: &LateContext<'_, '_>, expr: &Expr<'_>, other: &Expr<'_>) { let (arg_ty, snip) = match expr.kind { ExprKind::MethodCall(.., ref args, _) if args.len() == 1 => { if match_trait_method(cx, expr, &paths::TO_STRING) || match_trait_method(cx, expr, &paths::TO_OWNED) { - (cx.tables.expr_ty_adjusted(&args[0]), snippet(cx, args[0].span, "..")) + (cx.tables().expr_ty_adjusted(&args[0]), snippet(cx, args[0].span, "..")) } else { return; } @@ -582,7 +582,7 @@ fn check_to_owned(cx: &LateContext<'_, '_>, expr: &Expr<'_>, other: &Expr<'_>) { ExprKind::Call(ref path, ref v) if v.len() == 1 => { if let ExprKind::Path(ref path) = path.kind { if match_qpath(path, &["String", "from_str"]) || match_qpath(path, &["String", "from"]) { - (cx.tables.expr_ty_adjusted(&v[0]), snippet(cx, v[0].span, "..")) + (cx.tables().expr_ty_adjusted(&v[0]), snippet(cx, v[0].span, "..")) } else { return; } @@ -593,7 +593,7 @@ fn check_to_owned(cx: &LateContext<'_, '_>, expr: &Expr<'_>, other: &Expr<'_>) { _ => return, }; - let other_ty = cx.tables.expr_ty_adjusted(other); + let other_ty = cx.tables().expr_ty_adjusted(other); let partial_eq_trait_id = match cx.tcx.lang_items().eq_trait() { Some(id) => id, None => return, diff --git a/clippy_lints/src/modulo_arithmetic.rs b/clippy_lints/src/modulo_arithmetic.rs index 4ca90455bc4d1..f76e4721e1f63 100644 --- a/clippy_lints/src/modulo_arithmetic.rs +++ b/clippy_lints/src/modulo_arithmetic.rs @@ -37,8 +37,8 @@ struct OperandInfo { } fn analyze_operand(operand: &Expr<'_>, cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> Option { - match constant(cx, cx.tables, operand) { - Some((Constant::Int(v), _)) => match cx.tables.expr_ty(expr).kind { + match constant(cx, cx.tables(), operand) { + Some((Constant::Int(v), _)) => match cx.tables().expr_ty(expr).kind { ty::Int(ity) => { let value = sext(cx.tcx, v, ity); return Some(OperandInfo { @@ -106,7 +106,7 @@ fn check_const_operands<'a, 'tcx>( } fn check_non_const_operands<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>, operand: &Expr<'_>) { - let operand_type = cx.tables.expr_ty(operand); + let operand_type = cx.tables().expr_ty(operand); if might_have_negative_value(operand_type) { span_lint_and_then( cx, diff --git a/clippy_lints/src/mut_key.rs b/clippy_lints/src/mut_key.rs index 93569a04f7a3a..755b196c698c2 100644 --- a/clippy_lints/src/mut_key.rs +++ b/clippy_lints/src/mut_key.rs @@ -76,7 +76,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MutableKeyType { if let hir::PatKind::Wild = local.pat.kind { return; } - check_ty(cx, local.span, cx.tables.pat_ty(&*local.pat)); + check_ty(cx, local.span, cx.tables().pat_ty(&*local.pat)); } } diff --git a/clippy_lints/src/mut_mut.rs b/clippy_lints/src/mut_mut.rs index f7a20a74b85e2..6aa77b4df83aa 100644 --- a/clippy_lints/src/mut_mut.rs +++ b/clippy_lints/src/mut_mut.rs @@ -69,7 +69,7 @@ impl<'a, 'tcx> intravisit::Visitor<'tcx> for MutVisitor<'a, 'tcx> { expr.span, "generally you want to avoid `&mut &mut _` if possible", ); - } else if let ty::Ref(_, _, hir::Mutability::Mut) = self.cx.tables.expr_ty(e).kind { + } else if let ty::Ref(_, _, hir::Mutability::Mut) = self.cx.tables().expr_ty(e).kind { span_lint( self.cx, MUT_MUT, diff --git a/clippy_lints/src/mut_reference.rs b/clippy_lints/src/mut_reference.rs index 7fcf15f8acbe8..dbe257069c3e2 100644 --- a/clippy_lints/src/mut_reference.rs +++ b/clippy_lints/src/mut_reference.rs @@ -37,14 +37,14 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnnecessaryMutPassed { check_arguments( cx, arguments, - cx.tables.expr_ty(fn_expr), + cx.tables().expr_ty(fn_expr), &rustc_hir_pretty::to_string(rustc_hir_pretty::NO_ANN, |s| s.print_qpath(path, false)), ); } }, ExprKind::MethodCall(ref path, _, ref arguments, _) => { - let def_id = cx.tables.type_dependent_def_id(e.hir_id).unwrap(); - let substs = cx.tables.node_substs(e.hir_id); + let def_id = cx.tables().type_dependent_def_id(e.hir_id).unwrap(); + let substs = cx.tables().node_substs(e.hir_id); let method_type = cx.tcx.type_of(def_id).subst(cx.tcx, substs); check_arguments(cx, arguments, method_type, &path.ident.as_str()) }, diff --git a/clippy_lints/src/mutable_debug_assertion.rs b/clippy_lints/src/mutable_debug_assertion.rs index 119e0905ff442..45db5140711ad 100644 --- a/clippy_lints/src/mutable_debug_assertion.rs +++ b/clippy_lints/src/mutable_debug_assertion.rs @@ -135,7 +135,7 @@ impl<'a, 'tcx> Visitor<'tcx> for MutArgVisitor<'a, 'tcx> { return; }, ExprKind::Path(_) => { - if let Some(adj) = self.cx.tables.adjustments().get(expr.hir_id) { + if let Some(adj) = self.cx.tables().adjustments().get(expr.hir_id) { if adj .iter() .any(|a| matches!(a.target.kind, ty::Ref(_, _, Mutability::Mut))) diff --git a/clippy_lints/src/mutex_atomic.rs b/clippy_lints/src/mutex_atomic.rs index 78b15afc5a7fa..c227dc54f2939 100644 --- a/clippy_lints/src/mutex_atomic.rs +++ b/clippy_lints/src/mutex_atomic.rs @@ -66,7 +66,7 @@ declare_lint_pass!(Mutex => [MUTEX_ATOMIC, MUTEX_INTEGER]); impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Mutex { fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) { - let ty = cx.tables.expr_ty(expr); + let ty = cx.tables().expr_ty(expr); if let ty::Adt(_, subst) = ty.kind { if is_type_diagnostic_item(cx, ty, sym!(mutex_type)) { let mutex_param = subst.type_at(0); diff --git a/clippy_lints/src/needless_bool.rs b/clippy_lints/src/needless_bool.rs index 15b129fa09802..653f9e2ae8625 100644 --- a/clippy_lints/src/needless_bool.rs +++ b/clippy_lints/src/needless_bool.rs @@ -229,7 +229,7 @@ fn check_comparison<'a, 'tcx>( use self::Expression::{Bool, Other}; if let ExprKind::Binary(op, ref left_side, ref right_side) = e.kind { - let (l_ty, r_ty) = (cx.tables.expr_ty(left_side), cx.tables.expr_ty(right_side)); + let (l_ty, r_ty) = (cx.tables().expr_ty(left_side), cx.tables().expr_ty(right_side)); if l_ty.is_bool() && r_ty.is_bool() { let mut applicability = Applicability::MachineApplicable; diff --git a/clippy_lints/src/needless_borrow.rs b/clippy_lints/src/needless_borrow.rs index 5880d1d610206..6bb06defb7034 100644 --- a/clippy_lints/src/needless_borrow.rs +++ b/clippy_lints/src/needless_borrow.rs @@ -46,8 +46,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessBorrow { return; } if let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Not, ref inner) = e.kind { - if let ty::Ref(..) = cx.tables.expr_ty(inner).kind { - for adj3 in cx.tables.expr_adjustments(e).windows(3) { + if let ty::Ref(..) = cx.tables().expr_ty(inner).kind { + for adj3 in cx.tables().expr_adjustments(e).windows(3) { if let [Adjustment { kind: Adjust::Deref(_), .. }, Adjustment { @@ -85,7 +85,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessBorrow { } if_chain! { if let PatKind::Binding(BindingAnnotation::Ref, .., name, _) = pat.kind; - if let ty::Ref(_, tam, mutbl) = cx.tables.pat_ty(pat).kind; + if let ty::Ref(_, tam, mutbl) = cx.tables().pat_ty(pat).kind; if mutbl == Mutability::Not; if let ty::Ref(_, _, mutbl) = tam.kind; // only lint immutable refs, because borrowed `&mut T` cannot be moved out diff --git a/clippy_lints/src/needless_pass_by_value.rs b/clippy_lints/src/needless_pass_by_value.rs index ca87deac9891c..6954f0cc683f1 100644 --- a/clippy_lints/src/needless_pass_by_value.rs +++ b/clippy_lints/src/needless_pass_by_value.rs @@ -135,7 +135,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessPassByValue { } = { let mut ctx = MovedVariablesCtxt::default(); cx.tcx.infer_ctxt().enter(|infcx| { - euv::ExprUseVisitor::new(&mut ctx, &infcx, fn_def_id, cx.param_env, cx.tables).consume_body(body); + euv::ExprUseVisitor::new(&mut ctx, &infcx, fn_def_id, cx.param_env, cx.tables()).consume_body(body); }); ctx }; @@ -173,13 +173,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessPassByValue { !preds.is_empty() && { let ty_empty_region = cx.tcx.mk_imm_ref(cx.tcx.lifetimes.re_root_empty, ty); preds.iter().all(|t| { - let ty_params = &t - .skip_binder() - .trait_ref - .substs - .iter() - .skip(1) - .collect::>(); + let ty_params = &t.skip_binder().trait_ref.substs.iter().skip(1).collect::>(); implements_trait(cx, ty_empty_region, t.def_id(), ty_params) }) }, diff --git a/clippy_lints/src/needless_update.rs b/clippy_lints/src/needless_update.rs index d866bab2f642c..9b556dbb8540e 100644 --- a/clippy_lints/src/needless_update.rs +++ b/clippy_lints/src/needless_update.rs @@ -47,7 +47,7 @@ declare_lint_pass!(NeedlessUpdate => [NEEDLESS_UPDATE]); impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessUpdate { fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) { if let ExprKind::Struct(_, ref fields, Some(ref base)) = expr.kind { - let ty = cx.tables.expr_ty(expr); + let ty = cx.tables().expr_ty(expr); if let ty::Adt(def, _) = ty.kind { if fields.len() == def.non_enum_variant().fields.len() { span_lint( diff --git a/clippy_lints/src/neg_cmp_op_on_partial_ord.rs b/clippy_lints/src/neg_cmp_op_on_partial_ord.rs index 54536ed57d3e9..0f56daa3659e8 100644 --- a/clippy_lints/src/neg_cmp_op_on_partial_ord.rs +++ b/clippy_lints/src/neg_cmp_op_on_partial_ord.rs @@ -56,7 +56,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NoNegCompOpForPartialOrd { then { - let ty = cx.tables.expr_ty(left); + let ty = cx.tables().expr_ty(left); let implements_ord = { if let Some(id) = utils::get_trait_def_id(cx, &paths::ORD) { diff --git a/clippy_lints/src/neg_multiply.rs b/clippy_lints/src/neg_multiply.rs index 4681e990df88a..a9ce01b67b097 100644 --- a/clippy_lints/src/neg_multiply.rs +++ b/clippy_lints/src/neg_multiply.rs @@ -44,8 +44,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NegMultiply { fn check_mul(cx: &LateContext<'_, '_>, span: Span, lit: &Expr<'_>, exp: &Expr<'_>) { if_chain! { if let ExprKind::Lit(ref l) = lit.kind; - if let Constant::Int(1) = consts::lit_to_constant(&l.node, cx.tables.expr_ty_opt(lit)); - if cx.tables.expr_ty(exp).is_integral(); + if let Constant::Int(1) = consts::lit_to_constant(&l.node, cx.tables().expr_ty_opt(lit)); + if cx.tables().expr_ty(exp).is_integral(); then { span_lint(cx, NEG_MULTIPLY, span, "Negation by multiplying with `-1`"); } diff --git a/clippy_lints/src/no_effect.rs b/clippy_lints/src/no_effect.rs index 2eacd3c80c486..5fdc656580f29 100644 --- a/clippy_lints/src/no_effect.rs +++ b/clippy_lints/src/no_effect.rs @@ -48,7 +48,7 @@ fn has_no_effect(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> bool { } match expr.kind { ExprKind::Lit(..) | ExprKind::Closure(..) => true, - ExprKind::Path(..) => !has_drop(cx, cx.tables.expr_ty(expr)), + ExprKind::Path(..) => !has_drop(cx, cx.tables().expr_ty(expr)), ExprKind::Index(ref a, ref b) | ExprKind::Binary(_, ref a, ref b) => { has_no_effect(cx, a) && has_no_effect(cx, b) }, @@ -61,7 +61,7 @@ fn has_no_effect(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> bool { | ExprKind::AddrOf(_, _, ref inner) | ExprKind::Box(ref inner) => has_no_effect(cx, inner), ExprKind::Struct(_, ref fields, ref base) => { - !has_drop(cx, cx.tables.expr_ty(expr)) + !has_drop(cx, cx.tables().expr_ty(expr)) && fields.iter().all(|field| has_no_effect(cx, &field.expr)) && base.as_ref().map_or(true, |base| has_no_effect(cx, base)) }, @@ -70,7 +70,7 @@ fn has_no_effect(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> bool { let res = qpath_res(cx, qpath, callee.hir_id); match res { Res::Def(DefKind::Struct | DefKind::Variant | DefKind::Ctor(..), ..) => { - !has_drop(cx, cx.tables.expr_ty(expr)) && args.iter().all(|arg| has_no_effect(cx, arg)) + !has_drop(cx, cx.tables().expr_ty(expr)) && args.iter().all(|arg| has_no_effect(cx, arg)) }, _ => false, } @@ -137,7 +137,7 @@ fn reduce_expression<'a>(cx: &LateContext<'_, '_>, expr: &'a Expr<'a>) -> Option | ExprKind::AddrOf(_, _, ref inner) | ExprKind::Box(ref inner) => reduce_expression(cx, inner).or_else(|| Some(vec![inner])), ExprKind::Struct(_, ref fields, ref base) => { - if has_drop(cx, cx.tables.expr_ty(expr)) { + if has_drop(cx, cx.tables().expr_ty(expr)) { None } else { Some(fields.iter().map(|f| &f.expr).chain(base).map(Deref::deref).collect()) @@ -148,7 +148,7 @@ fn reduce_expression<'a>(cx: &LateContext<'_, '_>, expr: &'a Expr<'a>) -> Option let res = qpath_res(cx, qpath, callee.hir_id); match res { Res::Def(DefKind::Struct | DefKind::Variant | DefKind::Ctor(..), ..) - if !has_drop(cx, cx.tables.expr_ty(expr)) => + if !has_drop(cx, cx.tables().expr_ty(expr)) => { Some(args.iter().collect()) }, diff --git a/clippy_lints/src/non_copy_const.rs b/clippy_lints/src/non_copy_const.rs index 230dfd2ebf566..21d7a7439f25c 100644 --- a/clippy_lints/src/non_copy_const.rs +++ b/clippy_lints/src/non_copy_const.rs @@ -237,13 +237,13 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NonCopyConst { } let ty = if needs_check_adjustment { - let adjustments = cx.tables.expr_adjustments(dereferenced_expr); + let adjustments = cx.tables().expr_adjustments(dereferenced_expr); if let Some(i) = adjustments.iter().position(|adj| match adj.kind { Adjust::Borrow(_) | Adjust::Deref(_) => true, _ => false, }) { if i == 0 { - cx.tables.expr_ty(dereferenced_expr) + cx.tables().expr_ty(dereferenced_expr) } else { adjustments[i - 1].target } @@ -252,7 +252,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NonCopyConst { return; } } else { - cx.tables.expr_ty(dereferenced_expr) + cx.tables().expr_ty(dereferenced_expr) }; verify_ty_bound(cx, ty, Source::Expr { expr: expr.span }); diff --git a/clippy_lints/src/open_options.rs b/clippy_lints/src/open_options.rs index 2d4629b683f05..2467a14cea12f 100644 --- a/clippy_lints/src/open_options.rs +++ b/clippy_lints/src/open_options.rs @@ -30,7 +30,7 @@ declare_lint_pass!(OpenOptions => [NONSENSICAL_OPEN_OPTIONS]); impl<'a, 'tcx> LateLintPass<'a, 'tcx> for OpenOptions { fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr<'_>) { if let ExprKind::MethodCall(ref path, _, ref arguments, _) = e.kind { - let obj_ty = walk_ptrs_ty(cx.tables.expr_ty(&arguments[0])); + let obj_ty = walk_ptrs_ty(cx.tables().expr_ty(&arguments[0])); if path.ident.name == sym!(open) && match_type(cx, obj_ty, &paths::OPEN_OPTIONS) { let mut options = Vec::new(); get_open_options(cx, &arguments[0], &mut options); @@ -58,7 +58,7 @@ enum OpenOption { fn get_open_options(cx: &LateContext<'_, '_>, argument: &Expr<'_>, options: &mut Vec<(OpenOption, Argument)>) { if let ExprKind::MethodCall(ref path, _, ref arguments, _) = argument.kind { - let obj_ty = walk_ptrs_ty(cx.tables.expr_ty(&arguments[0])); + let obj_ty = walk_ptrs_ty(cx.tables().expr_ty(&arguments[0])); // Only proceed if this is a call on some object of type std::fs::OpenOptions if match_type(cx, obj_ty, &paths::OPEN_OPTIONS) && arguments.len() >= 2 { diff --git a/clippy_lints/src/overflow_check_conditional.rs b/clippy_lints/src/overflow_check_conditional.rs index b90fdc232e72c..5984b09120d0e 100644 --- a/clippy_lints/src/overflow_check_conditional.rs +++ b/clippy_lints/src/overflow_check_conditional.rs @@ -36,8 +36,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for OverflowCheckConditional { if let ExprKind::Path(QPath::Resolved(_, ref path2)) = ident2.kind; if let ExprKind::Path(QPath::Resolved(_, ref path3)) = second.kind; if eq(&path1.segments[0], &path3.segments[0]) || eq(&path2.segments[0], &path3.segments[0]); - if cx.tables.expr_ty(ident1).is_integral(); - if cx.tables.expr_ty(ident2).is_integral(); + if cx.tables().expr_ty(ident1).is_integral(); + if cx.tables().expr_ty(ident2).is_integral(); then { if let BinOpKind::Lt = op.node { if let BinOpKind::Add = op2.node { @@ -61,8 +61,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for OverflowCheckConditional { if let ExprKind::Path(QPath::Resolved(_, ref path2)) = ident2.kind; if let ExprKind::Path(QPath::Resolved(_, ref path3)) = first.kind; if eq(&path1.segments[0], &path3.segments[0]) || eq(&path2.segments[0], &path3.segments[0]); - if cx.tables.expr_ty(ident1).is_integral(); - if cx.tables.expr_ty(ident2).is_integral(); + if cx.tables().expr_ty(ident1).is_integral(); + if cx.tables().expr_ty(ident2).is_integral(); then { if let BinOpKind::Gt = op.node { if let BinOpKind::Add = op2.node { diff --git a/clippy_lints/src/path_buf_push_overwrite.rs b/clippy_lints/src/path_buf_push_overwrite.rs index 88ad1e0914f25..f26a5258782a7 100644 --- a/clippy_lints/src/path_buf_push_overwrite.rs +++ b/clippy_lints/src/path_buf_push_overwrite.rs @@ -46,7 +46,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for PathBufPushOverwrite { if let ExprKind::MethodCall(ref path, _, ref args, _) = expr.kind; if path.ident.name == sym!(push); if args.len() == 2; - if match_type(cx, walk_ptrs_ty(cx.tables.expr_ty(&args[0])), &paths::PATH_BUF); + if match_type(cx, walk_ptrs_ty(cx.tables().expr_ty(&args[0])), &paths::PATH_BUF); if let Some(get_index_arg) = args.get(1); if let ExprKind::Lit(ref lit) = get_index_arg.kind; if let LitKind::Str(ref path_lit, _) = lit.node; diff --git a/clippy_lints/src/ptr_offset_with_cast.rs b/clippy_lints/src/ptr_offset_with_cast.rs index d23d7e59b73fc..b35a7e64bff27 100644 --- a/clippy_lints/src/ptr_offset_with_cast.rs +++ b/clippy_lints/src/ptr_offset_with_cast.rs @@ -105,12 +105,12 @@ fn expr_as_ptr_offset_call<'a, 'tcx>( // Is the type of the expression a usize? fn is_expr_ty_usize<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &Expr<'_>) -> bool { - cx.tables.expr_ty(expr) == cx.tcx.types.usize + cx.tables().expr_ty(expr) == cx.tcx.types.usize } // Is the type of the expression a raw pointer? fn is_expr_ty_raw_ptr<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &Expr<'_>) -> bool { - cx.tables.expr_ty(expr).is_unsafe_ptr() + cx.tables().expr_ty(expr).is_unsafe_ptr() } fn build_suggestion<'a, 'tcx>( diff --git a/clippy_lints/src/question_mark.rs b/clippy_lints/src/question_mark.rs index d8a73f8054bca..4a6395da01c99 100644 --- a/clippy_lints/src/question_mark.rs +++ b/clippy_lints/src/question_mark.rs @@ -135,13 +135,13 @@ impl QuestionMark { } fn moves_by_default(cx: &LateContext<'_, '_>, expression: &Expr<'_>) -> bool { - let expr_ty = cx.tables.expr_ty(expression); + let expr_ty = cx.tables().expr_ty(expression); !expr_ty.is_copy_modulo_regions(cx.tcx.at(expression.span), cx.param_env) } fn is_option(cx: &LateContext<'_, '_>, expression: &Expr<'_>) -> bool { - let expr_ty = cx.tables.expr_ty(expression); + let expr_ty = cx.tables().expr_ty(expression); is_type_diagnostic_item(cx, expr_ty, sym!(option_type)) } @@ -158,7 +158,7 @@ impl QuestionMark { ExprKind::Ret(Some(ref expr)) => Self::expression_returns_none(cx, expr), ExprKind::Path(ref qp) => { if let Res::Def(DefKind::Ctor(def::CtorOf::Variant, def::CtorKind::Const), def_id) = - cx.tables.qpath_res(qp, expression.hir_id) + cx.tables().qpath_res(qp, expression.hir_id) { return match_def_path(cx, def_id, &paths::OPTION_NONE); } diff --git a/clippy_lints/src/ranges.rs b/clippy_lints/src/ranges.rs index fcd02a196e7bf..43ef236a92420 100644 --- a/clippy_lints/src/ranges.rs +++ b/clippy_lints/src/ranges.rs @@ -272,10 +272,10 @@ fn check_reversed_empty_range(cx: &LateContext<'_, '_>, expr: &Expr<'_>) { if_chain! { if let Some(higher::Range { start: Some(start), end: Some(end), limits }) = higher::range(cx, expr); - let ty = cx.tables.expr_ty(start); + let ty = cx.tables().expr_ty(start); if let ty::Int(_) | ty::Uint(_) = ty.kind; - if let Some((start_idx, _)) = constant(cx, cx.tables, start); - if let Some((end_idx, _)) = constant(cx, cx.tables, end); + if let Some((start_idx, _)) = constant(cx, cx.tables(), start); + if let Some((end_idx, _)) = constant(cx, cx.tables(), end); if let Some(ordering) = Constant::partial_cmp(cx.tcx, ty, &start_idx, &end_idx); if is_empty_range(limits, ordering); then { diff --git a/clippy_lints/src/regex.rs b/clippy_lints/src/regex.rs index a2c35c4267344..9c54c3cbac02b 100644 --- a/clippy_lints/src/regex.rs +++ b/clippy_lints/src/regex.rs @@ -82,7 +82,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Regex { if_chain! { if self.last.is_none(); if let Some(ref expr) = block.expr; - if match_type(cx, cx.tables.expr_ty(expr), &paths::REGEX); + if match_type(cx, cx.tables().expr_ty(expr), &paths::REGEX); if let Some(span) = is_expn_of(expr.span, "regex"); then { if !self.spans.contains(&span) { @@ -111,7 +111,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Regex { if let ExprKind::Call(ref fun, ref args) = expr.kind; if let ExprKind::Path(ref qpath) = fun.kind; if args.len() == 1; - if let Some(def_id) = cx.tables.qpath_res(qpath, fun.hir_id).opt_def_id(); + if let Some(def_id) = cx.tables().qpath_res(qpath, fun.hir_id).opt_def_id(); then { if match_def_path(cx, def_id, &paths::REGEX_NEW) || match_def_path(cx, def_id, &paths::REGEX_BUILDER_NEW) { @@ -140,7 +140,7 @@ fn str_span(base: Span, c: regex_syntax::ast::Span, offset: u16) -> Span { } fn const_str<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, e: &'tcx Expr<'_>) -> Option { - constant(cx, cx.tables, e).and_then(|(c, _)| match c { + constant(cx, cx.tables(), e).and_then(|(c, _)| match c { Constant::Str(s) => Some(s), _ => None, }) diff --git a/clippy_lints/src/shadow.rs b/clippy_lints/src/shadow.rs index 68c36f9189184..4780249bcb8e3 100644 --- a/clippy_lints/src/shadow.rs +++ b/clippy_lints/src/shadow.rs @@ -164,7 +164,7 @@ fn check_local<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, local: &'tcx Local<'_>, bin } fn is_binding(cx: &LateContext<'_, '_>, pat_id: HirId) -> bool { - let var_ty = cx.tables.node_type_opt(pat_id); + let var_ty = cx.tables().node_type_opt(pat_id); if let Some(var_ty) = var_ty { match var_ty.kind { ty::Adt(..) => false, diff --git a/clippy_lints/src/strings.rs b/clippy_lints/src/strings.rs index d8e4bff3d702a..ef66850358e57 100644 --- a/clippy_lints/src/strings.rs +++ b/clippy_lints/src/strings.rs @@ -134,7 +134,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for StringAdd { } fn is_string(cx: &LateContext<'_, '_>, e: &Expr<'_>) -> bool { - is_type_diagnostic_item(cx, walk_ptrs_ty(cx.tables.expr_ty(e)), sym!(string_type)) + is_type_diagnostic_item(cx, walk_ptrs_ty(cx.tables().expr_ty(e)), sym!(string_type)) } fn is_add(cx: &LateContext<'_, '_>, src: &Expr<'_>, target: &Expr<'_>) -> bool { diff --git a/clippy_lints/src/swap.rs b/clippy_lints/src/swap.rs index c52e6a643f2a2..7fdc872c01f54 100644 --- a/clippy_lints/src/swap.rs +++ b/clippy_lints/src/swap.rs @@ -194,7 +194,7 @@ fn check_for_slice<'a>(cx: &LateContext<'_, '_>, lhs1: &'a Expr<'_>, lhs2: &'a E if let ExprKind::Index(ref lhs1, ref idx1) = lhs1.kind { if let ExprKind::Index(ref lhs2, ref idx2) = lhs2.kind { if SpanlessEq::new(cx).ignore_fn().eq_expr(lhs1, lhs2) { - let ty = walk_ptrs_ty(cx.tables.expr_ty(lhs1)); + let ty = walk_ptrs_ty(cx.tables().expr_ty(lhs1)); if matches!(ty.kind, ty::Slice(_)) || matches!(ty.kind, ty::Array(_, _)) diff --git a/clippy_lints/src/temporary_assignment.rs b/clippy_lints/src/temporary_assignment.rs index bbb883aaf3287..f2bbf19bea92f 100644 --- a/clippy_lints/src/temporary_assignment.rs +++ b/clippy_lints/src/temporary_assignment.rs @@ -26,7 +26,7 @@ fn is_temporary(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> bool { match &expr.kind { ExprKind::Struct(..) | ExprKind::Tup(..) => true, ExprKind::Path(qpath) => { - if let Res::Def(DefKind::Const, ..) = cx.tables.qpath_res(qpath, expr.hir_id) { + if let Res::Def(DefKind::Const, ..) = cx.tables().qpath_res(qpath, expr.hir_id) { true } else { false diff --git a/clippy_lints/src/to_digit_is_some.rs b/clippy_lints/src/to_digit_is_some.rs index 4f132c6db76fa..1efba3580fef0 100644 --- a/clippy_lints/src/to_digit_is_some.rs +++ b/clippy_lints/src/to_digit_is_some.rs @@ -43,7 +43,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ToDigitIsSome { if_chain! { if let [char_arg, radix_arg] = &**to_digit_args; if to_digits_path.ident.name.as_str() == "to_digit"; - let char_arg_ty = cx.tables.expr_ty_adjusted(char_arg); + let char_arg_ty = cx.tables().expr_ty_adjusted(char_arg); if char_arg_ty.kind == ty::Char; then { Some((true, char_arg, radix_arg)) @@ -56,7 +56,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ToDigitIsSome { if_chain! { if let [char_arg, radix_arg] = &**to_digit_args; if let hir::ExprKind::Path(to_digits_path) = &to_digits_call.kind; - if let to_digits_call_res = cx.tables.qpath_res(to_digits_path, to_digits_call.hir_id); + if let to_digits_call_res = cx.tables().qpath_res(to_digits_path, to_digits_call.hir_id); if let Some(to_digits_def_id) = to_digits_call_res.opt_def_id(); if match_def_path(cx, to_digits_def_id, &["core", "char", "methods", "", "to_digit"]); then { diff --git a/clippy_lints/src/trait_bounds.rs b/clippy_lints/src/trait_bounds.rs index 67121729663c6..1b233b8302f93 100644 --- a/clippy_lints/src/trait_bounds.rs +++ b/clippy_lints/src/trait_bounds.rs @@ -37,7 +37,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TraitBounds { return; } let hash = |ty| -> u64 { - let mut hasher = SpanlessHash::new(cx, cx.tables); + let mut hasher = SpanlessHash::new(cx, cx.tables()); hasher.hash_ty(ty); hasher.finish() }; diff --git a/clippy_lints/src/transmute.rs b/clippy_lints/src/transmute.rs index 1869638f6ffb1..9b1344949470a 100644 --- a/clippy_lints/src/transmute.rs +++ b/clippy_lints/src/transmute.rs @@ -299,11 +299,11 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Transmute { if_chain! { if let ExprKind::Call(ref path_expr, ref args) = e.kind; if let ExprKind::Path(ref qpath) = path_expr.kind; - if let Some(def_id) = cx.tables.qpath_res(qpath, path_expr.hir_id).opt_def_id(); + if let Some(def_id) = cx.tables().qpath_res(qpath, path_expr.hir_id).opt_def_id(); if match_def_path(cx, def_id, &paths::TRANSMUTE); then { - let from_ty = cx.tables.expr_ty(&args[0]); - let to_ty = cx.tables.expr_ty(e); + let from_ty = cx.tables().expr_ty(&args[0]); + let to_ty = cx.tables().expr_ty(e); match (&from_ty.kind, &to_ty.kind) { _ if from_ty == to_ty => span_lint( diff --git a/clippy_lints/src/transmuting_null.rs b/clippy_lints/src/transmuting_null.rs index 1d0332c580500..3351488a45c4d 100644 --- a/clippy_lints/src/transmuting_null.rs +++ b/clippy_lints/src/transmuting_null.rs @@ -44,7 +44,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TransmutingNull { then { // Catching transmute over constants that resolve to `null`. - let mut const_eval_context = constant_context(cx, cx.tables); + let mut const_eval_context = constant_context(cx, cx.tables()); if_chain! { if let ExprKind::Path(ref _qpath) = args[0].kind; let x = const_eval_context.expr(&args[0]); diff --git a/clippy_lints/src/try_err.rs b/clippy_lints/src/try_err.rs index 7018fa6804ba7..e129dd84d15a6 100644 --- a/clippy_lints/src/try_err.rs +++ b/clippy_lints/src/try_err.rs @@ -68,7 +68,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TryErr { if let Some(return_type) = find_err_return_type(cx, &expr.kind); then { - let err_type = cx.tables.expr_ty(err_arg); + let err_type = cx.tables().expr_ty(err_arg); let origin_snippet = if err_arg.span.from_expansion() { snippet_with_macro_callsite(cx, err_arg.span, "_") } else { @@ -114,7 +114,7 @@ fn find_err_return_type_arm<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, arm: &'tcx Arm if match_qpath(from_error_fn, &paths::TRY_FROM_ERROR); if let Some(from_error_arg) = from_error_args.get(0); then { - Some(cx.tables.expr_ty(from_error_arg)) + Some(cx.tables().expr_ty(from_error_arg)) } else { None } diff --git a/clippy_lints/src/types.rs b/clippy_lints/src/types.rs index 98de08f79f3d7..ecfb6ee2a7de9 100644 --- a/clippy_lints/src/types.rs +++ b/clippy_lints/src/types.rs @@ -603,7 +603,7 @@ declare_lint_pass!(LetUnitValue => [LET_UNIT_VALUE]); 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.kind { - if is_unit(cx.tables.pat_ty(&local.pat)) { + if is_unit(cx.tables().pat_ty(&local.pat)) { if in_external_macro(cx.sess(), stmt.span) || local.pat.span.from_expansion() { return; } @@ -688,7 +688,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnitCmp { if let ExpnKind::Macro(MacroKind::Bang, symbol) = callee.kind { if let ExprKind::Binary(ref cmp, ref left, _) = expr.kind { let op = cmp.node; - if op.is_comparison() && is_unit(cx.tables.expr_ty(left)) { + if op.is_comparison() && is_unit(cx.tables().expr_ty(left)) { let result = match &*symbol.as_str() { "assert_eq" | "debug_assert_eq" => "succeed", "assert_ne" | "debug_assert_ne" => "fail", @@ -712,7 +712,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnitCmp { } if let ExprKind::Binary(ref cmp, ref left, _) = expr.kind { let op = cmp.node; - if op.is_comparison() && is_unit(cx.tables.expr_ty(left)) { + if op.is_comparison() && is_unit(cx.tables().expr_ty(left)) { let result = match op { BinOpKind::Eq | BinOpKind::Le | BinOpKind::Ge => "true", _ => "false", @@ -782,7 +782,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnitArg { let args_to_recover = args .iter() .filter(|arg| { - if is_unit(cx.tables.expr_ty(arg)) && !is_unit_literal(arg) { + if is_unit(cx.tables().expr_ty(arg)) && !is_unit_literal(arg) { if let ExprKind::Match(.., MatchSource::TryDesugar) = &arg.kind { false } else { @@ -1250,7 +1250,7 @@ fn check_loss_of_sign(cx: &LateContext<'_, '_>, expr: &Expr<'_>, op: &Expr<'_>, } // don't lint for positive constants - let const_val = constant(cx, &cx.tables, op); + let const_val = constant(cx, &cx.tables(), op); if_chain! { if let Some((const_val, _)) = const_val; if let Constant::Int(n) = const_val; @@ -1416,7 +1416,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Casts { return; } if let ExprKind::Cast(ref ex, _) = expr.kind { - let (cast_from, cast_to) = (cx.tables.expr_ty(ex), cx.tables.expr_ty(expr)); + let (cast_from, cast_to) = (cx.tables().expr_ty(ex), cx.tables().expr_ty(expr)); lint_fn_to_numeric_cast(cx, expr, ex, cast_from, cast_to); if let ExprKind::Lit(ref lit) = ex.kind { if_chain! { @@ -1804,7 +1804,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for CharLitAsU8 { if let ExprKind::Cast(e, _) = &expr.kind; if let ExprKind::Lit(l) = &e.kind; if let LitKind::Char(c) = l.node; - if ty::Uint(UintTy::U8) == cx.tables.expr_ty(expr).kind; + if ty::Uint(UintTy::U8) == cx.tables().expr_ty(expr).kind; then { let mut applicability = Applicability::MachineApplicable; let snippet = snippet_with_applicability(cx, e.span, "'x'", &mut applicability); @@ -1880,8 +1880,8 @@ enum AbsurdComparisonResult { fn is_cast_between_fixed_and_target<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'tcx>) -> bool { if let ExprKind::Cast(ref cast_exp, _) = expr.kind { - let precast_ty = cx.tables.expr_ty(cast_exp); - let cast_ty = cx.tables.expr_ty(expr); + let precast_ty = cx.tables().expr_ty(cast_exp); + let cast_ty = cx.tables().expr_ty(expr); return is_isize_or_usize(precast_ty) != is_isize_or_usize(cast_ty); } @@ -1901,7 +1901,7 @@ fn detect_absurd_comparison<'a, 'tcx>( // absurd comparison only makes sense on primitive types // primitive types don't implement comparison operators with each other - if cx.tables.expr_ty(lhs) != cx.tables.expr_ty(rhs) { + if cx.tables().expr_ty(lhs) != cx.tables().expr_ty(rhs) { return None; } @@ -1939,9 +1939,9 @@ fn detect_absurd_comparison<'a, 'tcx>( fn detect_extreme_expr<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) -> Option> { use crate::types::ExtremeType::{Maximum, Minimum}; - let ty = cx.tables.expr_ty(expr); + let ty = cx.tables().expr_ty(expr); - let cv = constant(cx, cx.tables, expr)?.0; + let cv = constant(cx, cx.tables(), expr)?.0; let which = match (&ty.kind, cv) { (&ty::Bool, Constant::Bool(false)) | (&ty::Uint(_), Constant::Int(0)) => Minimum, @@ -2071,8 +2071,8 @@ impl Ord for FullInt { fn numeric_cast_precast_bounds<'a>(cx: &LateContext<'_, '_>, expr: &'a Expr<'_>) -> Option<(FullInt, FullInt)> { if let ExprKind::Cast(ref cast_exp, _) = expr.kind { - let pre_cast_ty = cx.tables.expr_ty(cast_exp); - let cast_ty = cx.tables.expr_ty(expr); + let pre_cast_ty = cx.tables().expr_ty(cast_exp); + let cast_ty = cx.tables().expr_ty(expr); // if it's a cast from i32 to u32 wrapping will invalidate all these checks if cx.layout_of(pre_cast_ty).ok().map(|l| l.size) == cx.layout_of(cast_ty).ok().map(|l| l.size) { return None; @@ -2102,9 +2102,9 @@ fn numeric_cast_precast_bounds<'a>(cx: &LateContext<'_, '_>, expr: &'a Expr<'_>) } fn node_as_const_fullint<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) -> Option { - let val = constant(cx, cx.tables, expr)?.0; + let val = constant(cx, cx.tables(), expr)?.0; if let Constant::Int(const_int) = val { - match cx.tables.expr_ty(expr).kind { + match cx.tables().expr_ty(expr).kind { ty::Int(ity) => Some(FullInt::S(sext(cx.tcx, const_int, ity))), ty::Uint(_) => Some(FullInt::U(const_int)), _ => None, @@ -2499,7 +2499,7 @@ impl<'a, 'b, 'tcx> ImplicitHasherConstructorVisitor<'a, 'b, 'tcx> { fn new(cx: &'a LateContext<'a, 'tcx>, target: &'b ImplicitHasherType<'tcx>) -> Self { Self { cx, - body: cx.tables, + body: cx.tables(), target, suggestions: BTreeMap::new(), } @@ -2608,7 +2608,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for RefToMut { if let TyKind::Ptr(MutTy { mutbl: Mutability::Mut, .. }) = t.kind; if let ExprKind::Cast(e, t) = &e.kind; if let TyKind::Ptr(MutTy { mutbl: Mutability::Not, .. }) = t.kind; - if let ty::Ref(..) = cx.tables.node_type(e.hir_id).kind; + if let ty::Ref(..) = cx.tables().node_type(e.hir_id).kind; then { span_lint( cx, diff --git a/clippy_lints/src/unnamed_address.rs b/clippy_lints/src/unnamed_address.rs index 4e077b95b5c68..53e47f09ae55c 100644 --- a/clippy_lints/src/unnamed_address.rs +++ b/clippy_lints/src/unnamed_address.rs @@ -65,14 +65,14 @@ impl LateLintPass<'_, '_> for UnnamedAddress { } fn is_trait_ptr(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> bool { - match cx.tables.expr_ty_adjusted(expr).kind { + match cx.tables().expr_ty_adjusted(expr).kind { ty::RawPtr(ty::TypeAndMut { ty, .. }) => ty.is_trait(), _ => false, } } fn is_fn_def(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> bool { - if let ty::FnDef(..) = cx.tables.expr_ty(expr).kind { + if let ty::FnDef(..) = cx.tables().expr_ty(expr).kind { true } else { false @@ -98,11 +98,11 @@ impl LateLintPass<'_, '_> for UnnamedAddress { if_chain! { if let ExprKind::Call(ref func, [ref _left, ref _right]) = expr.kind; if let ExprKind::Path(ref func_qpath) = func.kind; - if let Some(def_id) = cx.tables.qpath_res(func_qpath, func.hir_id).opt_def_id(); + if let Some(def_id) = cx.tables().qpath_res(func_qpath, func.hir_id).opt_def_id(); if match_def_path(cx, def_id, &paths::PTR_EQ) || match_def_path(cx, def_id, &paths::RC_PTR_EQ) || match_def_path(cx, def_id, &paths::ARC_PTR_EQ); - let ty_param = cx.tables.node_substs(func.hir_id).type_at(0); + let ty_param = cx.tables().node_substs(func.hir_id).type_at(0); if ty_param.is_trait(); then { span_lint_and_help( @@ -119,8 +119,8 @@ impl LateLintPass<'_, '_> for UnnamedAddress { if_chain! { if let ExprKind::Binary(binop, ref left, ref right) = expr.kind; if is_comparison(binop.node); - if cx.tables.expr_ty_adjusted(left).is_fn_ptr() && - cx.tables.expr_ty_adjusted(right).is_fn_ptr(); + if cx.tables().expr_ty_adjusted(left).is_fn_ptr() && + cx.tables().expr_ty_adjusted(right).is_fn_ptr(); if is_fn_def(cx, left) || is_fn_def(cx, right); then { span_lint( diff --git a/clippy_lints/src/unnecessary_sort_by.rs b/clippy_lints/src/unnecessary_sort_by.rs index 6ac6a12529c86..bb68e50b33195 100644 --- a/clippy_lints/src/unnecessary_sort_by.rs +++ b/clippy_lints/src/unnecessary_sort_by.rs @@ -177,7 +177,7 @@ fn detect_lint(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> Option if let name = name_ident.ident.name.to_ident_string(); if name == "sort_by" || name == "sort_unstable_by"; if let [vec, Expr { kind: ExprKind::Closure(_, _, closure_body_id, _, _), .. }] = args; - if utils::match_type(cx, &cx.tables.expr_ty(vec), &paths::VEC); + if utils::match_type(cx, &cx.tables().expr_ty(vec), &paths::VEC); if let closure_body = cx.tcx.hir().body(*closure_body_id); if let &[ Param { pat: Pat { kind: PatKind::Binding(_, _, left_ident, _), .. }, ..}, diff --git a/clippy_lints/src/unwrap.rs b/clippy_lints/src/unwrap.rs index a6c7b5d405cda..be55982f90556 100644 --- a/clippy_lints/src/unwrap.rs +++ b/clippy_lints/src/unwrap.rs @@ -114,7 +114,7 @@ fn collect_unwrap_info<'a, 'tcx>( if_chain! { if let ExprKind::MethodCall(method_name, _, args, _) = &expr.kind; if let ExprKind::Path(QPath::Resolved(None, path)) = &args[0].kind; - let ty = cx.tables.expr_ty(&args[0]); + let ty = cx.tables().expr_ty(&args[0]); let name = method_name.ident.as_str(); if is_relevant_option_call(cx, ty, &name) || is_relevant_result_call(cx, ty, &name); then { diff --git a/clippy_lints/src/useless_conversion.rs b/clippy_lints/src/useless_conversion.rs index 78d249482d53d..5d150ad4f03e4 100644 --- a/clippy_lints/src/useless_conversion.rs +++ b/clippy_lints/src/useless_conversion.rs @@ -63,8 +63,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UselessConversion { ExprKind::MethodCall(ref name, .., ref args, _) => { if match_trait_method(cx, e, &paths::INTO) && &*name.ident.as_str() == "into" { - let a = cx.tables.expr_ty(e); - let b = cx.tables.expr_ty(&args[0]); + let a = cx.tables().expr_ty(e); + let b = cx.tables().expr_ty(&args[0]); if TyS::same_type(a, b) { let sugg = snippet_with_macro_callsite(cx, args[0].span, "").to_string(); span_lint_and_sugg( @@ -79,8 +79,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UselessConversion { } } if match_trait_method(cx, e, &paths::INTO_ITERATOR) && &*name.ident.as_str() == "into_iter" { - let a = cx.tables.expr_ty(e); - let b = cx.tables.expr_ty(&args[0]); + let a = cx.tables().expr_ty(e); + let b = cx.tables().expr_ty(&args[0]); if TyS::same_type(a, b) { let sugg = snippet(cx, args[0].span, "").into_owned(); span_lint_and_sugg( @@ -96,8 +96,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UselessConversion { } if match_trait_method(cx, e, &paths::TRY_INTO_TRAIT) && &*name.ident.as_str() == "try_into" { if_chain! { - let a = cx.tables.expr_ty(e); - let b = cx.tables.expr_ty(&args[0]); + let a = cx.tables().expr_ty(e); + let b = cx.tables().expr_ty(&args[0]); if is_type_diagnostic_item(cx, a, sym!(result_type)); if let ty::Adt(_, substs) = a.kind; if let Some(a_type) = substs.types().next(); @@ -121,9 +121,9 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UselessConversion { if_chain! { if args.len() == 1; if let ExprKind::Path(ref qpath) = path.kind; - if let Some(def_id) = cx.tables.qpath_res(qpath, path.hir_id).opt_def_id(); - let a = cx.tables.expr_ty(e); - let b = cx.tables.expr_ty(&args[0]); + if let Some(def_id) = cx.tables().qpath_res(qpath, path.hir_id).opt_def_id(); + let a = cx.tables().expr_ty(e); + let b = cx.tables().expr_ty(&args[0]); then { if_chain! { diff --git a/clippy_lints/src/utils/higher.rs b/clippy_lints/src/utils/higher.rs index 33fba7df8d336..0e78f35a1290a 100644 --- a/clippy_lints/src/utils/higher.rs +++ b/clippy_lints/src/utils/higher.rs @@ -56,7 +56,7 @@ pub fn range<'a, 'b, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'b hir::Expr<'_>) Some(expr) } - let def_path = match cx.tables.expr_ty(expr).kind { + let def_path = match cx.tables().expr_ty(expr).kind { ty::Adt(def, _) => cx.tcx.def_path(def.did), _ => return None, }; @@ -262,7 +262,7 @@ pub fn vec_macro<'e>(cx: &LateContext<'_, '_>, expr: &'e hir::Expr<'_>) -> Optio if let hir::ExprKind::Call(ref fun, ref args) = expr.kind; if let hir::ExprKind::Path(ref qpath) = fun.kind; if is_expn_of(fun.span, "vec").is_some(); - if let Some(fun_def_id) = cx.tables.qpath_res(qpath, fun.hir_id).opt_def_id(); + if let Some(fun_def_id) = cx.tables().qpath_res(qpath, fun.hir_id).opt_def_id(); then { return if match_def_path(cx, fun_def_id, &paths::VEC_FROM_ELEM) && args.len() == 2 { // `vec![elem; size]` case diff --git a/clippy_lints/src/utils/hir_utils.rs b/clippy_lints/src/utils/hir_utils.rs index 9a9aa3f94eb4b..a74ab18a063b2 100644 --- a/clippy_lints/src/utils/hir_utils.rs +++ b/clippy_lints/src/utils/hir_utils.rs @@ -32,7 +32,7 @@ impl<'a, 'tcx> SpanlessEq<'a, 'tcx> { pub fn new(cx: &'a LateContext<'a, 'tcx>) -> Self { Self { cx, - tables: cx.tables, + tables: cx.tables(), ignore_fn: false, } } @@ -40,7 +40,7 @@ impl<'a, 'tcx> SpanlessEq<'a, 'tcx> { pub fn ignore_fn(self) -> Self { Self { cx: self.cx, - tables: self.cx.tables, + tables: self.cx.tables(), ignore_fn: true, } } diff --git a/clippy_lints/src/utils/inspector.rs b/clippy_lints/src/utils/inspector.rs index afde971f9df4e..3f5659c3d8c0f 100644 --- a/clippy_lints/src/utils/inspector.rs +++ b/clippy_lints/src/utils/inspector.rs @@ -114,7 +114,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for DeepCodeInspector { } match stmt.kind { hir::StmtKind::Local(ref local) => { - println!("local variable of type {}", cx.tables.node_type(local.hir_id)); + println!("local variable of type {}", cx.tables().node_type(local.hir_id)); println!("pattern:"); print_pat(cx, &local.pat, 0); if let Some(ref e) = local.init { @@ -144,8 +144,8 @@ fn has_attr(sess: &Session, attrs: &[Attribute]) -> bool { fn print_expr(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, indent: usize) { let ind = " ".repeat(indent); println!("{}+", ind); - println!("{}ty: {}", ind, cx.tables.expr_ty(expr)); - println!("{}adjustments: {:?}", ind, cx.tables.adjustments().get(expr.hir_id)); + println!("{}ty: {}", ind, cx.tables().expr_ty(expr)); + println!("{}adjustments: {:?}", ind, cx.tables().adjustments().get(expr.hir_id)); match expr.kind { hir::ExprKind::Box(ref e) => { println!("{}Box", ind); diff --git a/clippy_lints/src/utils/internal_lints.rs b/clippy_lints/src/utils/internal_lints.rs index 89e2bcdd7935d..38468181d0261 100644 --- a/clippy_lints/src/utils/internal_lints.rs +++ b/clippy_lints/src/utils/internal_lints.rs @@ -347,7 +347,7 @@ fn is_lint_ref_type<'tcx>(cx: &LateContext<'_, 'tcx>, ty: &Ty<'_>) -> bool { ) = ty.kind { if let TyKind::Path(ref path) = inner.kind { - if let Res::Def(DefKind::Struct, def_id) = cx.tables.qpath_res(path, inner.hir_id) { + if let Res::Def(DefKind::Struct, def_id) = cx.tables().qpath_res(path, inner.hir_id) { return match_def_path(cx, def_id, &paths::LINT); } } @@ -405,7 +405,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for CompilerLintFunctions { if let ExprKind::MethodCall(ref path, _, ref args, _) = expr.kind; let fn_name = path.ident; if let Some(sugg) = self.map.get(&*fn_name.as_str()); - let ty = walk_ptrs_ty(cx.tables.expr_ty(&args[0])); + let ty = walk_ptrs_ty(cx.tables().expr_ty(&args[0])); if match_type(cx, ty, &paths::EARLY_CONTEXT) || match_type(cx, ty, &paths::LATE_CONTEXT); then { @@ -438,7 +438,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for OuterExpnDataPass { let args = arg_lists[1]; if args.len() == 1; let self_arg = &args[0]; - let self_ty = walk_ptrs_ty(cx.tables.expr_ty(self_arg)); + let self_ty = walk_ptrs_ty(cx.tables().expr_ty(self_arg)); if match_type(cx, self_ty, &paths::SYNTAX_CONTEXT); then { span_lint_and_sugg( diff --git a/clippy_lints/src/utils/mod.rs b/clippy_lints/src/utils/mod.rs index 6d4c6c6ce1cea..69ec4b7ad6d18 100644 --- a/clippy_lints/src/utils/mod.rs +++ b/clippy_lints/src/utils/mod.rs @@ -151,7 +151,7 @@ pub fn is_type_diagnostic_item(cx: &LateContext<'_, '_>, ty: Ty<'_>, diag_item: /// Checks if the method call given in `expr` belongs to the given trait. pub fn match_trait_method(cx: &LateContext<'_, '_>, expr: &Expr<'_>, path: &[&str]) -> bool { - let def_id = cx.tables.type_dependent_def_id(expr.hir_id).unwrap(); + let def_id = cx.tables().type_dependent_def_id(expr.hir_id).unwrap(); let trt_id = cx.tcx.trait_of_item(def_id); if let Some(trt_id) = trt_id { match_def_path(cx, trt_id, path) @@ -824,7 +824,7 @@ pub fn is_integer_literal(expr: &Expr<'_>, value: u128) -> bool { /// See `rustc_middle::ty::adjustment::Adjustment` and `rustc_typeck::check::coercion` for more /// information on adjustments and coercions. pub fn is_adjusted(cx: &LateContext<'_, '_>, e: &Expr<'_>) -> bool { - cx.tables.adjustments().get(e.hir_id).is_some() + cx.tables().adjustments().get(e.hir_id).is_some() } /// Returns the pre-expansion span if is this comes from an expansion of the @@ -898,7 +898,7 @@ pub fn is_copy<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, ty: Ty<'tcx>) -> bool { pub fn is_ctor_or_promotable_const_function(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> bool { if let ExprKind::Call(ref fun, _) = expr.kind { if let ExprKind::Path(ref qp) = fun.kind { - let res = cx.tables.qpath_res(qp, fun.hir_id); + let res = cx.tables().qpath_res(qp, fun.hir_id); return match res { def::Res::Def(DefKind::Variant | DefKind::Ctor(..), ..) => true, def::Res::Def(_, def_id) => cx.tcx.is_promotable_const_fn(def_id), @@ -914,7 +914,7 @@ pub fn is_ctor_or_promotable_const_function(cx: &LateContext<'_, '_>, expr: &Exp pub fn is_refutable(cx: &LateContext<'_, '_>, pat: &Pat<'_>) -> bool { fn is_enum_variant(cx: &LateContext<'_, '_>, qpath: &QPath<'_>, id: HirId) -> bool { matches!( - cx.tables.qpath_res(qpath, id), + cx.tables().qpath_res(qpath, id), def::Res::Def(DefKind::Variant, ..) | Res::Def(DefKind::Ctor(def::CtorOf::Variant, _), _) ) } @@ -941,7 +941,7 @@ pub fn is_refutable(cx: &LateContext<'_, '_>, pat: &Pat<'_>) -> bool { is_enum_variant(cx, qpath, pat.hir_id) || are_refutable(cx, pats.iter().map(|pat| &**pat)) }, PatKind::Slice(ref head, ref middle, ref tail) => { - match &cx.tables.node_type(pat.hir_id).kind { + match &cx.tables().node_type(pat.hir_id).kind { ty::Slice(..) => { // [..] is the only irrefutable slice pattern. !head.is_empty() || middle.is_none() || !tail.is_empty() @@ -1190,7 +1190,7 @@ pub fn match_function_call<'a, 'tcx>( if_chain! { if let ExprKind::Call(ref fun, ref args) = expr.kind; if let ExprKind::Path(ref qpath) = fun.kind; - if let Some(fun_def_id) = cx.tables.qpath_res(qpath, fun.hir_id).opt_def_id(); + if let Some(fun_def_id) = cx.tables().qpath_res(qpath, fun.hir_id).opt_def_id(); if match_def_path(cx, fun_def_id, path); then { return Some(&args) @@ -1317,14 +1317,14 @@ pub fn is_must_use_func_call(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> bool let did = match expr.kind { ExprKind::Call(ref path, _) => if_chain! { if let ExprKind::Path(ref qpath) = path.kind; - if let def::Res::Def(_, did) = cx.tables.qpath_res(qpath, path.hir_id); + if let def::Res::Def(_, did) = cx.tables().qpath_res(qpath, path.hir_id); then { Some(did) } else { None } }, - ExprKind::MethodCall(_, _, _, _) => cx.tables.type_dependent_def_id(expr.hir_id), + ExprKind::MethodCall(_, _, _, _) => cx.tables().type_dependent_def_id(expr.hir_id), _ => None, }; diff --git a/clippy_lints/src/utils/usage.rs b/clippy_lints/src/utils/usage.rs index 0492878fc272f..d280fe4ab4e02 100644 --- a/clippy_lints/src/utils/usage.rs +++ b/clippy_lints/src/utils/usage.rs @@ -18,7 +18,7 @@ pub fn mutated_variables<'a, 'tcx>(expr: &'tcx Expr<'_>, cx: &'a LateContext<'a, }; let def_id = expr.hir_id.owner.to_def_id(); cx.tcx.infer_ctxt().enter(|infcx| { - ExprUseVisitor::new(&mut delegate, &infcx, def_id.expect_local(), cx.param_env, cx.tables).walk_expr(expr); + ExprUseVisitor::new(&mut delegate, &infcx, def_id.expect_local(), cx.param_env, cx.tables()).walk_expr(expr); }); if delegate.skip { diff --git a/clippy_lints/src/vec.rs b/clippy_lints/src/vec.rs index a8d4c7620b1ef..080785b177d65 100644 --- a/clippy_lints/src/vec.rs +++ b/clippy_lints/src/vec.rs @@ -37,7 +37,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UselessVec { fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) { // search for `&vec![_]` expressions where the adjusted type is `&[_]` if_chain! { - if let ty::Ref(_, ty, _) = cx.tables.expr_ty_adjusted(expr).kind; + if let ty::Ref(_, ty, _) = cx.tables().expr_ty_adjusted(expr).kind; if let ty::Slice(..) = ty.kind; if let ExprKind::AddrOf(BorrowKind::Ref, _, ref addressee) = expr.kind; if let Some(vec_args) = higher::vec_macro(cx, addressee); @@ -50,7 +50,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UselessVec { if_chain! { if let Some((_, arg, _)) = higher::for_loop(expr); if let Some(vec_args) = higher::vec_macro(cx, arg); - if is_copy(cx, vec_type(cx.tables.expr_ty_adjusted(arg))); + if is_copy(cx, vec_type(cx.tables().expr_ty_adjusted(arg))); then { // report the error around the `vec!` not inside `:` let span = arg.span @@ -70,7 +70,7 @@ fn check_vec_macro<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, vec_args: &higher::VecA let mut applicability = Applicability::MachineApplicable; let snippet = match *vec_args { higher::VecArgs::Repeat(elem, len) => { - if constant(cx, cx.tables, len).is_some() { + if constant(cx, cx.tables(), len).is_some() { format!( "&[{}; {}]", snippet_with_applicability(cx, elem.span, "elem", &mut applicability), diff --git a/clippy_lints/src/vec_resize_to_zero.rs b/clippy_lints/src/vec_resize_to_zero.rs index 55758efa32e67..bb315e64e5de1 100644 --- a/clippy_lints/src/vec_resize_to_zero.rs +++ b/clippy_lints/src/vec_resize_to_zero.rs @@ -32,7 +32,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for VecResizeToZero { fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) { if_chain! { if let hir::ExprKind::MethodCall(path_segment, _, ref args, _) = expr.kind; - if let Some(method_def_id) = cx.tables.type_dependent_def_id(expr.hir_id); + if let Some(method_def_id) = cx.tables().type_dependent_def_id(expr.hir_id); if match_def_path(cx, method_def_id, &paths::VEC_RESIZE) && args.len() == 3; if let ExprKind::Lit(Spanned { node: LitKind::Int(0, _), .. }) = args[1].kind; if let ExprKind::Lit(Spanned { node: LitKind::Int(..), .. }) = args[2].kind; diff --git a/clippy_lints/src/verbose_file_reads.rs b/clippy_lints/src/verbose_file_reads.rs index 6d420d491c50f..85f9208457448 100644 --- a/clippy_lints/src/verbose_file_reads.rs +++ b/clippy_lints/src/verbose_file_reads.rs @@ -62,7 +62,7 @@ fn is_file_read_to_end<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'t if let ExprKind::MethodCall(method_name, _, exprs, _) = expr.kind; if method_name.ident.as_str() == "read_to_end"; if let ExprKind::Path(QPath::Resolved(None, _)) = &exprs[0].kind; - let ty = cx.tables.expr_ty(&exprs[0]); + let ty = cx.tables().expr_ty(&exprs[0]); if match_type(cx, ty, &paths::FILE); then { return true @@ -76,7 +76,7 @@ fn is_file_read_to_string<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr if let ExprKind::MethodCall(method_name, _, exprs, _) = expr.kind; if method_name.ident.as_str() == "read_to_string"; if let ExprKind::Path(QPath::Resolved(None, _)) = &exprs[0].kind; - let ty = cx.tables.expr_ty(&exprs[0]); + let ty = cx.tables().expr_ty(&exprs[0]); if match_type(cx, ty, &paths::FILE); then { return true diff --git a/clippy_lints/src/zero_div_zero.rs b/clippy_lints/src/zero_div_zero.rs index 0820385e01bb5..f0cf17c3b9549 100644 --- a/clippy_lints/src/zero_div_zero.rs +++ b/clippy_lints/src/zero_div_zero.rs @@ -36,8 +36,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ZeroDiv { // TODO - constant_simple does not fold many operations involving floats. // That's probably fine for this lint - it's pretty unlikely that someone would // do something like 0.0/(2.0 - 2.0), but it would be nice to warn on that case too. - if let Some(lhs_value) = constant_simple(cx, cx.tables, left); - if let Some(rhs_value) = constant_simple(cx, cx.tables, right); + if let Some(lhs_value) = constant_simple(cx, cx.tables(), left); + if let Some(rhs_value) = constant_simple(cx, cx.tables(), right); if Constant::F32(0.0) == lhs_value || Constant::F64(0.0) == lhs_value; if Constant::F32(0.0) == rhs_value || Constant::F64(0.0) == rhs_value; then { diff --git a/doc/common_tools_writing_lints.md b/doc/common_tools_writing_lints.md index dbc434505947d..d06e359bc7aa5 100644 --- a/doc/common_tools_writing_lints.md +++ b/doc/common_tools_writing_lints.md @@ -19,11 +19,11 @@ Useful Rustc dev guide links: Sometimes you may want to retrieve the type `Ty` of an expression `Expr`, for example to answer following questions: - which type does this expression correspond to (using its [`TyKind`][TyKind])? -- is it a sized type? +- is it a sized type? - is it a primitive type? - does it implement a trait? -This operation is performed using the [`expr_ty()`][expr_ty] method from the [`TypeckTables`][TypeckTables] struct, +This operation is performed using the [`expr_ty()`][expr_ty] method from the [`TypeckTables`][TypeckTables] struct, that gives you access to the underlying structure [`TyS`][TyS]. Example of use: @@ -31,7 +31,7 @@ Example of use: impl LateLintPass<'_, '_> for MyStructLint { fn check_expr(&mut self, cx: &LateContext<'_, '_>, expr: &Expr<'_>) { // Get type of `expr` - let ty = cx.tables.expr_ty(expr); + let ty = cx.tables().expr_ty(expr); // Match its kind to enter its type match ty.kind { ty::Adt(adt_def, _) if adt_def.is_struct() => println!("Our `expr` is a struct!"), @@ -41,14 +41,14 @@ impl LateLintPass<'_, '_> for MyStructLint { } ``` -Similarly in [`TypeckTables`][TypeckTables] methods, you have the [`pat_ty()`][pat_ty] method +Similarly in [`TypeckTables`][TypeckTables] methods, you have the [`pat_ty()`][pat_ty] method to retrieve a type from a pattern. Two noticeable items here: -- `cx` is the lint context [`LateContext`][LateContext]. - The two most useful data structures in this context are `tcx` and `tables`, +- `cx` is the lint context [`LateContext`][LateContext]. + The two most useful data structures in this context are `tcx` and `tables`, allowing us to jump to type definitions and other compilation stages such as HIR. -- `tables` is [`TypeckTables`][TypeckTables] and is created by type checking step, +- `tables` is [`TypeckTables`][TypeckTables] and is created by type checking step, it includes useful information such as types of expressions, ways to resolve methods and so on. # Checking if an expr is calling a specific method @@ -87,7 +87,7 @@ impl LateLintPass<'_, '_> for MyStructLint { } // 2. Using type context `TyCtxt` - let ty = cx.tables.expr_ty(expr); + let ty = cx.tables().expr_ty(expr); if cx.tcx.lang_items() // we are looking for the `DefId` of `Drop` trait in lang items .drop_trait() From 3c5ee3300f6c88f3d984d62ce704d17b7432f29c Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Thu, 25 Jun 2020 17:43:48 -0700 Subject: [PATCH 11/99] Update tests --- tests/ui/redundant_pattern_matching.fixed | 2 - tests/ui/redundant_pattern_matching.rs | 2 - tests/ui/redundant_pattern_matching.stderr | 56 +++++++++---------- ...undant_pattern_matching_const_result.fixed | 2 - ...redundant_pattern_matching_const_result.rs | 2 - ...ndant_pattern_matching_const_result.stderr | 12 ++-- 6 files changed, 34 insertions(+), 42 deletions(-) diff --git a/tests/ui/redundant_pattern_matching.fixed b/tests/ui/redundant_pattern_matching.fixed index 6ba5cfb1d7177..8b4e2d21331cd 100644 --- a/tests/ui/redundant_pattern_matching.fixed +++ b/tests/ui/redundant_pattern_matching.fixed @@ -1,7 +1,5 @@ // run-rustfix -#![feature(const_if_match)] -#![feature(const_loop)] #![warn(clippy::all)] #![warn(clippy::redundant_pattern_matching)] #![allow(clippy::unit_arg, unused_must_use, clippy::needless_bool, deprecated)] diff --git a/tests/ui/redundant_pattern_matching.rs b/tests/ui/redundant_pattern_matching.rs index 17de66f9ad0eb..b0904e41b6f43 100644 --- a/tests/ui/redundant_pattern_matching.rs +++ b/tests/ui/redundant_pattern_matching.rs @@ -1,7 +1,5 @@ // run-rustfix -#![feature(const_if_match)] -#![feature(const_loop)] #![warn(clippy::all)] #![warn(clippy::redundant_pattern_matching)] #![allow(clippy::unit_arg, unused_must_use, clippy::needless_bool, deprecated)] diff --git a/tests/ui/redundant_pattern_matching.stderr b/tests/ui/redundant_pattern_matching.stderr index 1b9a4b40a2f02..51a6f4350d32c 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:10:12 + --> $DIR/redundant_pattern_matching.rs:8:12 | LL | if let Ok(_) = Ok::(42) {} | -------^^^^^--------------------- help: try this: `if Ok::(42).is_ok()` @@ -7,67 +7,67 @@ 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:12:12 + --> $DIR/redundant_pattern_matching.rs:10:12 | LL | if let Err(_) = Err::(42) {} | -------^^^^^^---------------------- help: try this: `if Err::(42).is_err()` error: redundant pattern matching, consider using `is_none()` - --> $DIR/redundant_pattern_matching.rs:14:12 + --> $DIR/redundant_pattern_matching.rs:12:12 | LL | if let None = None::<()> {} | -------^^^^------------- help: try this: `if None::<()>.is_none()` error: redundant pattern matching, consider using `is_some()` - --> $DIR/redundant_pattern_matching.rs:16:12 + --> $DIR/redundant_pattern_matching.rs:14:12 | LL | if let Some(_) = Some(42) {} | -------^^^^^^^----------- help: try this: `if Some(42).is_some()` error: redundant pattern matching, consider using `is_some()` - --> $DIR/redundant_pattern_matching.rs:18:12 + --> $DIR/redundant_pattern_matching.rs:16:12 | LL | if let Some(_) = Some(42) { | -------^^^^^^^----------- help: try this: `if Some(42).is_some()` error: redundant pattern matching, consider using `is_some()` - --> $DIR/redundant_pattern_matching.rs:24:15 + --> $DIR/redundant_pattern_matching.rs:22:15 | LL | while let Some(_) = Some(42) {} | ----------^^^^^^^----------- help: try this: `while Some(42).is_some()` error: redundant pattern matching, consider using `is_none()` - --> $DIR/redundant_pattern_matching.rs:26:15 + --> $DIR/redundant_pattern_matching.rs:24:15 | LL | while let None = Some(42) {} | ----------^^^^----------- help: try this: `while Some(42).is_none()` error: redundant pattern matching, consider using `is_none()` - --> $DIR/redundant_pattern_matching.rs:28:15 + --> $DIR/redundant_pattern_matching.rs:26:15 | LL | while let None = None::<()> {} | ----------^^^^------------- help: try this: `while None::<()>.is_none()` error: redundant pattern matching, consider using `is_ok()` - --> $DIR/redundant_pattern_matching.rs:30:15 + --> $DIR/redundant_pattern_matching.rs:28:15 | LL | while let Ok(_) = Ok::(10) {} | ----------^^^^^--------------------- help: try this: `while Ok::(10).is_ok()` error: redundant pattern matching, consider using `is_err()` - --> $DIR/redundant_pattern_matching.rs:32:15 + --> $DIR/redundant_pattern_matching.rs:30:15 | LL | while let Err(_) = Ok::(10) {} | ----------^^^^^^--------------------- help: try this: `while Ok::(10).is_err()` error: redundant pattern matching, consider using `is_some()` - --> $DIR/redundant_pattern_matching.rs:35:15 + --> $DIR/redundant_pattern_matching.rs:33:15 | LL | while let Some(_) = v.pop() { | ----------^^^^^^^---------- help: try this: `while v.pop().is_some()` error: redundant pattern matching, consider using `is_ok()` - --> $DIR/redundant_pattern_matching.rs:51:5 + --> $DIR/redundant_pattern_matching.rs:49:5 | LL | / match Ok::(42) { LL | | Ok(_) => true, @@ -76,7 +76,7 @@ LL | | }; | |_____^ help: try this: `Ok::(42).is_ok()` error: redundant pattern matching, consider using `is_err()` - --> $DIR/redundant_pattern_matching.rs:56:5 + --> $DIR/redundant_pattern_matching.rs:54:5 | LL | / match Ok::(42) { LL | | Ok(_) => false, @@ -85,7 +85,7 @@ LL | | }; | |_____^ help: try this: `Ok::(42).is_err()` error: redundant pattern matching, consider using `is_err()` - --> $DIR/redundant_pattern_matching.rs:61:5 + --> $DIR/redundant_pattern_matching.rs:59:5 | LL | / match Err::(42) { LL | | Ok(_) => false, @@ -94,7 +94,7 @@ LL | | }; | |_____^ help: try this: `Err::(42).is_err()` error: redundant pattern matching, consider using `is_ok()` - --> $DIR/redundant_pattern_matching.rs:66:5 + --> $DIR/redundant_pattern_matching.rs:64:5 | LL | / match Err::(42) { LL | | Ok(_) => true, @@ -103,7 +103,7 @@ LL | | }; | |_____^ help: try this: `Err::(42).is_ok()` error: redundant pattern matching, consider using `is_some()` - --> $DIR/redundant_pattern_matching.rs:71:5 + --> $DIR/redundant_pattern_matching.rs:69:5 | LL | / match Some(42) { LL | | Some(_) => true, @@ -112,7 +112,7 @@ LL | | }; | |_____^ help: try this: `Some(42).is_some()` error: redundant pattern matching, consider using `is_none()` - --> $DIR/redundant_pattern_matching.rs:76:5 + --> $DIR/redundant_pattern_matching.rs:74:5 | LL | / match None::<()> { LL | | Some(_) => false, @@ -121,7 +121,7 @@ LL | | }; | |_____^ help: try this: `None::<()>.is_none()` error: redundant pattern matching, consider using `is_none()` - --> $DIR/redundant_pattern_matching.rs:81:13 + --> $DIR/redundant_pattern_matching.rs:79:13 | LL | let _ = match None::<()> { | _____________^ @@ -131,61 +131,61 @@ LL | | }; | |_____^ help: try this: `None::<()>.is_none()` error: redundant pattern matching, consider using `is_ok()` - --> $DIR/redundant_pattern_matching.rs:86:20 + --> $DIR/redundant_pattern_matching.rs:84:20 | LL | let _ = if let Ok(_) = Ok::(4) { true } else { false }; | -------^^^^^--------------------- help: try this: `if Ok::(4).is_ok()` error: redundant pattern matching, consider using `is_some()` - --> $DIR/redundant_pattern_matching.rs:89:20 + --> $DIR/redundant_pattern_matching.rs:87:20 | LL | let x = if let Some(_) = opt { true } else { false }; | -------^^^^^^^------ help: try this: `if opt.is_some()` error: redundant pattern matching, consider using `is_some()` - --> $DIR/redundant_pattern_matching.rs:95:20 + --> $DIR/redundant_pattern_matching.rs:93:20 | LL | let _ = if let Some(_) = gen_opt() { | -------^^^^^^^------------ help: try this: `if gen_opt().is_some()` error: redundant pattern matching, consider using `is_none()` - --> $DIR/redundant_pattern_matching.rs:97:19 + --> $DIR/redundant_pattern_matching.rs:95:19 | LL | } else if let None = gen_opt() { | -------^^^^------------ help: try this: `if gen_opt().is_none()` error: redundant pattern matching, consider using `is_ok()` - --> $DIR/redundant_pattern_matching.rs:99:19 + --> $DIR/redundant_pattern_matching.rs:97:19 | LL | } else if let Ok(_) = gen_res() { | -------^^^^^------------ help: try this: `if gen_res().is_ok()` error: redundant pattern matching, consider using `is_err()` - --> $DIR/redundant_pattern_matching.rs:101:19 + --> $DIR/redundant_pattern_matching.rs:99:19 | LL | } else if let Err(_) = gen_res() { | -------^^^^^^------------ help: try this: `if gen_res().is_err()` error: redundant pattern matching, consider using `is_some()` - --> $DIR/redundant_pattern_matching.rs:134:19 + --> $DIR/redundant_pattern_matching.rs:132:19 | LL | while let Some(_) = r#try!(result_opt()) {} | ----------^^^^^^^----------------------- help: try this: `while r#try!(result_opt()).is_some()` error: redundant pattern matching, consider using `is_some()` - --> $DIR/redundant_pattern_matching.rs:135:16 + --> $DIR/redundant_pattern_matching.rs:133:16 | LL | if let Some(_) = r#try!(result_opt()) {} | -------^^^^^^^----------------------- help: try this: `if r#try!(result_opt()).is_some()` error: redundant pattern matching, consider using `is_some()` - --> $DIR/redundant_pattern_matching.rs:141:12 + --> $DIR/redundant_pattern_matching.rs:139:12 | LL | if let Some(_) = m!() {} | -------^^^^^^^------- help: try this: `if m!().is_some()` error: redundant pattern matching, consider using `is_some()` - --> $DIR/redundant_pattern_matching.rs:142:15 + --> $DIR/redundant_pattern_matching.rs:140:15 | LL | while let Some(_) = m!() {} | ----------^^^^^^^------- help: try this: `while m!().is_some()` diff --git a/tests/ui/redundant_pattern_matching_const_result.fixed b/tests/ui/redundant_pattern_matching_const_result.fixed index c8bc5458067d3..8a81e92f04a73 100644 --- a/tests/ui/redundant_pattern_matching_const_result.fixed +++ b/tests/ui/redundant_pattern_matching_const_result.fixed @@ -1,7 +1,5 @@ // run-rustfix -#![feature(const_if_match)] -#![feature(const_loop)] #![feature(const_result)] #![warn(clippy::redundant_pattern_matching)] #![allow(unused)] diff --git a/tests/ui/redundant_pattern_matching_const_result.rs b/tests/ui/redundant_pattern_matching_const_result.rs index 75f37ec15c622..1cd515441d13a 100644 --- a/tests/ui/redundant_pattern_matching_const_result.rs +++ b/tests/ui/redundant_pattern_matching_const_result.rs @@ -1,7 +1,5 @@ // run-rustfix -#![feature(const_if_match)] -#![feature(const_loop)] #![feature(const_result)] #![warn(clippy::redundant_pattern_matching)] #![allow(unused)] diff --git a/tests/ui/redundant_pattern_matching_const_result.stderr b/tests/ui/redundant_pattern_matching_const_result.stderr index c32292f0eee8b..8ecd72158d33c 100644 --- a/tests/ui/redundant_pattern_matching_const_result.stderr +++ b/tests/ui/redundant_pattern_matching_const_result.stderr @@ -1,5 +1,5 @@ error: redundant pattern matching, consider using `is_ok()` - --> $DIR/redundant_pattern_matching_const_result.rs:12:12 + --> $DIR/redundant_pattern_matching_const_result.rs:10:12 | LL | if let Ok(_) = Ok::(42) {} | -------^^^^^--------------------- help: try this: `if 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_const_result.rs:14:12 + --> $DIR/redundant_pattern_matching_const_result.rs:12:12 | LL | if let Err(_) = Err::(42) {} | -------^^^^^^---------------------- help: try this: `if Err::(42).is_err()` error: redundant pattern matching, consider using `is_ok()` - --> $DIR/redundant_pattern_matching_const_result.rs:16:15 + --> $DIR/redundant_pattern_matching_const_result.rs:14:15 | LL | while let Ok(_) = Ok::(10) {} | ----------^^^^^--------------------- help: try this: `while Ok::(10).is_ok()` error: redundant pattern matching, consider using `is_err()` - --> $DIR/redundant_pattern_matching_const_result.rs:18:15 + --> $DIR/redundant_pattern_matching_const_result.rs:16:15 | LL | while let Err(_) = Ok::(10) {} | ----------^^^^^^--------------------- help: try this: `while Ok::(10).is_err()` error: redundant pattern matching, consider using `is_ok()` - --> $DIR/redundant_pattern_matching_const_result.rs:20:5 + --> $DIR/redundant_pattern_matching_const_result.rs:18: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_const_result.rs:25:5 + --> $DIR/redundant_pattern_matching_const_result.rs:23:5 | LL | / match Err::(42) { LL | | Ok(_) => false, From 9448ed4c1f8b586c9c90a78c12afc4c826041d5a Mon Sep 17 00:00:00 2001 From: Dario Gonzalez Date: Mon, 29 Jun 2020 09:07:33 -0700 Subject: [PATCH 12/99] Obviate #[allow(improper_ctypes_definitions)] Modifies the return type for `fn entry` so that allowing improper_ctypes_definitions is no longer necessary. This change is derived from a similar pattern in `libstd/sys/sgx/abi/usercalls/raw.rs` with `UsercallReturn`. --- src/libstd/sys/sgx/abi/mod.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/libstd/sys/sgx/abi/mod.rs b/src/libstd/sys/sgx/abi/mod.rs index 5ef26d4cc4dc6..b0693b63a48fd 100644 --- a/src/libstd/sys/sgx/abi/mod.rs +++ b/src/libstd/sys/sgx/abi/mod.rs @@ -17,6 +17,9 @@ pub mod usercalls; #[cfg(not(test))] global_asm!(include_str!("entry.S")); +#[repr(C)] +struct EntryReturn(u64, u64); + #[cfg(not(test))] #[no_mangle] unsafe extern "C" fn tcs_init(secondary: bool) { @@ -56,8 +59,7 @@ unsafe extern "C" fn tcs_init(secondary: bool) { // able to specify this #[cfg(not(test))] #[no_mangle] -#[allow(improper_ctypes_definitions)] -extern "C" fn entry(p1: u64, p2: u64, p3: u64, secondary: bool, p4: u64, p5: u64) -> (u64, u64) { +extern "C" fn entry(p1: u64, p2: u64, p3: u64, secondary: bool, p4: u64, p5: u64) -> EntryReturn { // FIXME: how to support TLS in library mode? let tls = Box::new(tls::Tls::new()); let _tls_guard = unsafe { tls.activate() }; @@ -65,7 +67,7 @@ extern "C" fn entry(p1: u64, p2: u64, p3: u64, secondary: bool, p4: u64, p5: u64 if secondary { super::thread::Thread::entry(); - (0, 0) + EntryReturn(0, 0) } else { extern "C" { fn main(argc: isize, argv: *const *const u8) -> isize; From dfecaef91478e1b529962bad3c8dffe0a95f9450 Mon Sep 17 00:00:00 2001 From: Azhng Date: Wed, 24 Jun 2020 16:33:31 -0400 Subject: [PATCH 13/99] typeck: adding type information to projection This commit modifies the Place as follow: * remove 'ty' from ProjectionKind * add type information into to Projection * replace 'ty' in Place with 'base_ty' * introduce 'ty()' in `Place` to return the final type of the `Place` * introduce `ty_before_projection()` in `Place` to return the type of a `Place` before i'th projection is applied Closes https://github.com/rust-lang/project-rfc-2229/issues/5 --- clippy_lints/src/escape.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clippy_lints/src/escape.rs b/clippy_lints/src/escape.rs index 59af475af175e..fcb574e437481 100644 --- a/clippy_lints/src/escape.rs +++ b/clippy_lints/src/escape.rs @@ -150,7 +150,7 @@ impl<'a, 'tcx> Delegate<'tcx> for EscapeDelegate<'a, 'tcx> { return; } - if is_non_trait_box(cmt.place.ty) && !self.is_large_box(cmt.place.ty) { + if is_non_trait_box(cmt.place.ty()) && !self.is_large_box(cmt.place.ty()) { self.set.insert(cmt.hir_id); } return; From ab649c920e18929c8f2b3399178bcfd1ecdcdd3e Mon Sep 17 00:00:00 2001 From: flip1995 Date: Tue, 30 Jun 2020 16:19:42 +0200 Subject: [PATCH 14/99] Disable chrono integration test --- .github/workflows/clippy_bors.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/clippy_bors.yml b/.github/workflows/clippy_bors.yml index 0c80394f03e3c..fd0cd7a1890bd 100644 --- a/.github/workflows/clippy_bors.yml +++ b/.github/workflows/clippy_bors.yml @@ -240,7 +240,8 @@ jobs: - 'Geal/nom' - 'rust-lang/stdarch' - 'serde-rs/serde' - - 'chronotope/chrono' + # FIXME: chrono currently cannot be compiled with `--all-targets` + # - 'chronotope/chrono' - 'hyperium/hyper' - 'rust-random/rand' - 'rust-lang/futures-rs' From 814349f9418b3d247e2e3cc952877e510f824fdd Mon Sep 17 00:00:00 2001 From: Eduardo Broto Date: Fri, 26 Jun 2020 10:52:14 +0200 Subject: [PATCH 15/99] Lint enabling the whole restriction group --- CHANGELOG.md | 1 + clippy_lints/src/attrs.rs | 95 +++++++++++++++++++++++++++------------ clippy_lints/src/lib.rs | 3 ++ src/lintlist/mod.rs | 7 +++ tests/ui/attrs.rs | 6 +++ tests/ui/attrs.stderr | 33 ++++++++++++-- 6 files changed, 113 insertions(+), 32 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d6186c319d07d..b88044d6ce84c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1352,6 +1352,7 @@ Released 2018-09-13 [`bad_bit_mask`]: https://rust-lang.github.io/rust-clippy/master/index.html#bad_bit_mask [`bind_instead_of_map`]: https://rust-lang.github.io/rust-clippy/master/index.html#bind_instead_of_map [`blacklisted_name`]: https://rust-lang.github.io/rust-clippy/master/index.html#blacklisted_name +[`blanket_clippy_restriction_lints`]: https://rust-lang.github.io/rust-clippy/master/index.html#blanket_clippy_restriction_lints [`blocks_in_if_conditions`]: https://rust-lang.github.io/rust-clippy/master/index.html#blocks_in_if_conditions [`bool_comparison`]: https://rust-lang.github.io/rust-clippy/master/index.html#bool_comparison [`borrow_interior_mutable_const`]: https://rust-lang.github.io/rust-clippy/master/index.html#borrow_interior_mutable_const diff --git a/clippy_lints/src/attrs.rs b/clippy_lints/src/attrs.rs index 41f125d48398f..dd4dffda0f970 100644 --- a/clippy_lints/src/attrs.rs +++ b/clippy_lints/src/attrs.rs @@ -2,8 +2,8 @@ use crate::reexport::Name; use crate::utils::{ - first_line_of_span, is_present_in_source, match_def_path, paths, snippet_opt, span_lint, span_lint_and_sugg, - span_lint_and_then, without_block_comments, + first_line_of_span, is_present_in_source, match_def_path, paths, snippet_opt, span_lint, span_lint_and_help, + span_lint_and_sugg, span_lint_and_then, without_block_comments, }; use if_chain::if_chain; use rustc_ast::ast::{AttrKind, AttrStyle, Attribute, Lit, LitKind, MetaItemKind, NestedMetaItem}; @@ -17,7 +17,7 @@ use rustc_middle::lint::in_external_macro; use rustc_middle::ty; use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::source_map::Span; -use rustc_span::symbol::Symbol; +use rustc_span::symbol::{Symbol, SymbolStr}; use semver::Version; static UNIX_SYSTEMS: &[&str] = &[ @@ -182,6 +182,29 @@ declare_clippy_lint! { "unknown_lints for scoped Clippy lints" } +declare_clippy_lint! { + /// **What it does:** Checks for `warn`/`deny`/`forbid` attributes targeting the whole clippy::restriction category. + /// + /// **Why is this bad?** Restriction lints sometimes are in contrast with other lints or even go against idiomatic rust. + /// These lints should only be enabled on a lint-by-lint basis and with careful consideration. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// Bad: + /// ```rust + /// #![deny(clippy::restriction)] + /// ``` + /// + /// Good: + /// ```rust + /// #![deny(clippy::as_conversions)] + /// ``` + pub BLANKET_CLIPPY_RESTRICTION_LINTS, + correctness, + "enabling the complete restriction group" +} + declare_clippy_lint! { /// **What it does:** Checks for `#[cfg_attr(rustfmt, rustfmt_skip)]` and suggests to replace it /// with `#[rustfmt::skip]`. @@ -249,15 +272,17 @@ declare_lint_pass!(Attributes => [ DEPRECATED_SEMVER, USELESS_ATTRIBUTE, UNKNOWN_CLIPPY_LINTS, + BLANKET_CLIPPY_RESTRICTION_LINTS, ]); impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Attributes { fn check_attribute(&mut self, cx: &LateContext<'a, 'tcx>, attr: &'tcx Attribute) { if let Some(items) = &attr.meta_item_list() { if let Some(ident) = attr.ident() { - match &*ident.as_str() { + let ident = &*ident.as_str(); + match ident { "allow" | "warn" | "deny" | "forbid" => { - check_clippy_lint_names(cx, items); + check_clippy_lint_names(cx, ident, items); }, _ => {}, } @@ -363,38 +388,43 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Attributes { } } -#[allow(clippy::single_match_else)] -fn check_clippy_lint_names(cx: &LateContext<'_, '_>, items: &[NestedMetaItem]) { - let lint_store = cx.lints(); - for lint in items { +fn check_clippy_lint_names(cx: &LateContext<'_, '_>, ident: &str, items: &[NestedMetaItem]) { + fn extract_name(lint: &NestedMetaItem) -> Option { if_chain! { if let Some(meta_item) = lint.meta_item(); if meta_item.path.segments.len() > 1; if let tool_name = meta_item.path.segments[0].ident; if tool_name.as_str() == "clippy"; - let name = meta_item.path.segments.last().unwrap().ident.name; - if let CheckLintNameResult::Tool(Err((None, _))) = lint_store.check_lint_name( - &name.as_str(), - Some(tool_name.name), - ); + let lint_name = meta_item.path.segments.last().unwrap().ident.name; then { + return Some(lint_name.as_str()); + } + } + None + } + + let lint_store = cx.lints(); + for lint in items { + if let Some(lint_name) = extract_name(lint) { + if let CheckLintNameResult::Tool(Err((None, _))) = + lint_store.check_lint_name(&lint_name, Some(sym!(clippy))) + { span_lint_and_then( cx, UNKNOWN_CLIPPY_LINTS, lint.span(), - &format!("unknown clippy lint: clippy::{}", name), + &format!("unknown clippy lint: clippy::{}", lint_name), |diag| { - let name_lower = name.as_str().to_lowercase(); - let symbols = lint_store.get_lints().iter().map( - |l| Symbol::intern(&l.name_lower()) - ).collect::>(); - let sugg = find_best_match_for_name( - symbols.iter(), - &format!("clippy::{}", name_lower), - None, - ); - if name.as_str().chars().any(char::is_uppercase) - && lint_store.find_lints(&format!("clippy::{}", name_lower)).is_ok() { + let name_lower = lint_name.to_lowercase(); + let symbols = lint_store + .get_lints() + .iter() + .map(|l| Symbol::intern(&l.name_lower())) + .collect::>(); + let sugg = find_best_match_for_name(symbols.iter(), &format!("clippy::{}", name_lower), None); + if lint_name.chars().any(char::is_uppercase) + && lint_store.find_lints(&format!("clippy::{}", name_lower)).is_ok() + { diag.span_suggestion( lint.span(), "lowercase the lint name", @@ -409,10 +439,19 @@ fn check_clippy_lint_names(cx: &LateContext<'_, '_>, items: &[NestedMetaItem]) { Applicability::MachineApplicable, ); } - } + }, + ); + } else if lint_name == "restriction" && ident != "allow" { + span_lint_and_help( + cx, + BLANKET_CLIPPY_RESTRICTION_LINTS, + lint.span(), + "restriction lints are not meant to be all enabled", + None, + "try enabling only the lints you really need", ); } - }; + } } } diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index 756b6b9a8a464..24eb492ee72a4 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -474,6 +474,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: &assign_ops::ASSIGN_OP_PATTERN, &assign_ops::MISREFACTORED_ASSIGN_OP, &atomic_ordering::INVALID_ATOMIC_ORDERING, + &attrs::BLANKET_CLIPPY_RESTRICTION_LINTS, &attrs::DEPRECATED_CFG_ATTR, &attrs::DEPRECATED_SEMVER, &attrs::EMPTY_LINE_AFTER_OUTER_ATTR, @@ -1189,6 +1190,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: LintId::of(&assign_ops::ASSIGN_OP_PATTERN), LintId::of(&assign_ops::MISREFACTORED_ASSIGN_OP), LintId::of(&atomic_ordering::INVALID_ATOMIC_ORDERING), + LintId::of(&attrs::BLANKET_CLIPPY_RESTRICTION_LINTS), LintId::of(&attrs::DEPRECATED_CFG_ATTR), LintId::of(&attrs::DEPRECATED_SEMVER), LintId::of(&attrs::MISMATCHED_TARGET_OS), @@ -1614,6 +1616,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: store.register_group(true, "clippy::correctness", Some("clippy_correctness"), vec![ LintId::of(&approx_const::APPROX_CONSTANT), LintId::of(&atomic_ordering::INVALID_ATOMIC_ORDERING), + LintId::of(&attrs::BLANKET_CLIPPY_RESTRICTION_LINTS), LintId::of(&attrs::DEPRECATED_SEMVER), LintId::of(&attrs::MISMATCHED_TARGET_OS), LintId::of(&attrs::USELESS_ATTRIBUTE), diff --git a/src/lintlist/mod.rs b/src/lintlist/mod.rs index 5a43a1a07d24b..8d27e6282f135 100644 --- a/src/lintlist/mod.rs +++ b/src/lintlist/mod.rs @@ -80,6 +80,13 @@ pub static ref ALL_LINTS: Vec = vec![ deprecation: None, module: "blacklisted_name", }, + Lint { + name: "blanket_clippy_restriction_lints", + group: "correctness", + desc: "enabling the complete restriction group", + deprecation: None, + module: "attrs", + }, Lint { name: "blocks_in_if_conditions", group: "style", diff --git a/tests/ui/attrs.rs b/tests/ui/attrs.rs index 91b65a43be77f..908d063729f45 100644 --- a/tests/ui/attrs.rs +++ b/tests/ui/attrs.rs @@ -1,5 +1,11 @@ #![warn(clippy::inline_always, clippy::deprecated_semver)] #![allow(clippy::assertions_on_constants)] +// Test that the whole restriction group is not enabled +#![warn(clippy::restriction)] +#![deny(clippy::restriction)] +#![forbid(clippy::restriction)] +#![allow(clippy::missing_docs_in_private_items, clippy::panic, clippy::unreachable)] + #[inline(always)] fn test_attr_lint() { assert!(true) diff --git a/tests/ui/attrs.stderr b/tests/ui/attrs.stderr index 39ddf6f226d95..adceb4b6369e9 100644 --- a/tests/ui/attrs.stderr +++ b/tests/ui/attrs.stderr @@ -1,5 +1,5 @@ error: you have declared `#[inline(always)]` on `test_attr_lint`. This is usually a bad idea - --> $DIR/attrs.rs:3:1 + --> $DIR/attrs.rs:9:1 | LL | #[inline(always)] | ^^^^^^^^^^^^^^^^^ @@ -7,7 +7,7 @@ LL | #[inline(always)] = note: `-D clippy::inline-always` implied by `-D warnings` error: the since field must contain a semver-compliant version - --> $DIR/attrs.rs:23:14 + --> $DIR/attrs.rs:29:14 | LL | #[deprecated(since = "forever")] | ^^^^^^^^^^^^^^^^^ @@ -15,10 +15,35 @@ LL | #[deprecated(since = "forever")] = note: `-D clippy::deprecated-semver` implied by `-D warnings` error: the since field must contain a semver-compliant version - --> $DIR/attrs.rs:26:14 + --> $DIR/attrs.rs:32:14 | LL | #[deprecated(since = "1")] | ^^^^^^^^^^^ -error: aborting due to 3 previous errors +error: restriction lints are not meant to be all enabled + --> $DIR/attrs.rs:4:9 + | +LL | #![warn(clippy::restriction)] + | ^^^^^^^^^^^^^^^^^^^ + | + = note: `#[deny(clippy::blanket_clippy_restriction_lints)]` on by default + = help: try enabling only the lints you really need + +error: restriction lints are not meant to be all enabled + --> $DIR/attrs.rs:5:9 + | +LL | #![deny(clippy::restriction)] + | ^^^^^^^^^^^^^^^^^^^ + | + = help: try enabling only the lints you really need + +error: restriction lints are not meant to be all enabled + --> $DIR/attrs.rs:6:11 + | +LL | #![forbid(clippy::restriction)] + | ^^^^^^^^^^^^^^^^^^^ + | + = help: try enabling only the lints you really need + +error: aborting due to 6 previous errors From c5d8f530e0625f14c5b4bedebdf0dc53064310c9 Mon Sep 17 00:00:00 2001 From: Eduardo Broto Date: Sat, 27 Jun 2020 21:49:34 +0200 Subject: [PATCH 16/99] Move blanket_clippy_restriction_lints to "style" --- clippy_lints/src/attrs.rs | 2 +- clippy_lints/src/lib.rs | 2 +- src/lintlist/mod.rs | 2 +- tests/ui/attrs.stderr | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/clippy_lints/src/attrs.rs b/clippy_lints/src/attrs.rs index dd4dffda0f970..bb9d8be5daee0 100644 --- a/clippy_lints/src/attrs.rs +++ b/clippy_lints/src/attrs.rs @@ -201,7 +201,7 @@ declare_clippy_lint! { /// #![deny(clippy::as_conversions)] /// ``` pub BLANKET_CLIPPY_RESTRICTION_LINTS, - correctness, + style, "enabling the complete restriction group" } diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index 24eb492ee72a4..50116a95612e8 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -1443,6 +1443,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: store.register_group(true, "clippy::style", Some("clippy_style"), vec![ LintId::of(&assertions_on_constants::ASSERTIONS_ON_CONSTANTS), LintId::of(&assign_ops::ASSIGN_OP_PATTERN), + LintId::of(&attrs::BLANKET_CLIPPY_RESTRICTION_LINTS), LintId::of(&attrs::UNKNOWN_CLIPPY_LINTS), LintId::of(&bit_mask::VERBOSE_BIT_MASK), LintId::of(&blacklisted_name::BLACKLISTED_NAME), @@ -1616,7 +1617,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: store.register_group(true, "clippy::correctness", Some("clippy_correctness"), vec![ LintId::of(&approx_const::APPROX_CONSTANT), LintId::of(&atomic_ordering::INVALID_ATOMIC_ORDERING), - LintId::of(&attrs::BLANKET_CLIPPY_RESTRICTION_LINTS), LintId::of(&attrs::DEPRECATED_SEMVER), LintId::of(&attrs::MISMATCHED_TARGET_OS), LintId::of(&attrs::USELESS_ATTRIBUTE), diff --git a/src/lintlist/mod.rs b/src/lintlist/mod.rs index 8d27e6282f135..5119fb4033728 100644 --- a/src/lintlist/mod.rs +++ b/src/lintlist/mod.rs @@ -82,7 +82,7 @@ pub static ref ALL_LINTS: Vec = vec![ }, Lint { name: "blanket_clippy_restriction_lints", - group: "correctness", + group: "style", desc: "enabling the complete restriction group", deprecation: None, module: "attrs", diff --git a/tests/ui/attrs.stderr b/tests/ui/attrs.stderr index adceb4b6369e9..ef4b89eaa6dee 100644 --- a/tests/ui/attrs.stderr +++ b/tests/ui/attrs.stderr @@ -26,7 +26,7 @@ error: restriction lints are not meant to be all enabled LL | #![warn(clippy::restriction)] | ^^^^^^^^^^^^^^^^^^^ | - = note: `#[deny(clippy::blanket_clippy_restriction_lints)]` on by default + = note: `-D clippy::blanket-clippy-restriction-lints` implied by `-D warnings` = help: try enabling only the lints you really need error: restriction lints are not meant to be all enabled From bff6c435ef597071410af5d136916231f310c64c Mon Sep 17 00:00:00 2001 From: Eduardo Broto Date: Wed, 1 Jul 2020 00:15:21 +0200 Subject: [PATCH 17/99] Require `or_patterns` to suggest nesting them --- clippy_lints/src/unnested_or_patterns.rs | 4 ++-- tests/ui/unnested_or_patterns3.rs | 6 ++++++ 2 files changed, 8 insertions(+), 2 deletions(-) create mode 100644 tests/ui/unnested_or_patterns3.rs diff --git a/clippy_lints/src/unnested_or_patterns.rs b/clippy_lints/src/unnested_or_patterns.rs index 4d3682263f14f..169a486d1eb94 100644 --- a/clippy_lints/src/unnested_or_patterns.rs +++ b/clippy_lints/src/unnested_or_patterns.rs @@ -72,8 +72,8 @@ impl EarlyLintPass for UnnestedOrPatterns { } fn lint_unnested_or_patterns(cx: &EarlyContext<'_>, pat: &Pat) { - if !cx.sess.opts.unstable_features.is_nightly_build() { - // User cannot do `#![feature(or_patterns)]`, so bail. + if !cx.sess.features_untracked().or_patterns { + // Do not suggest nesting the patterns if the feature `or_patterns` is not enabled. return; } diff --git a/tests/ui/unnested_or_patterns3.rs b/tests/ui/unnested_or_patterns3.rs new file mode 100644 index 0000000000000..6bd35057bfad1 --- /dev/null +++ b/tests/ui/unnested_or_patterns3.rs @@ -0,0 +1,6 @@ +#![warn(clippy::unnested_or_patterns)] + +// Test that `unnested_or_patterns` does not trigger without enabling `or_patterns` +fn main() { + if let (0, 1) | (0, 2) | (0, 3) = (0, 0) {} +} From 5b9c2ff9ccebbc9ddb646c6f868f9972ccc64f4f Mon Sep 17 00:00:00 2001 From: Michael Wright Date: Wed, 1 Jul 2020 07:30:03 +0200 Subject: [PATCH 18/99] Fix multiple_crate_versions error Fix the versions of packages in the multiple_crate_versions ui test by checking in the Cargo.lock for the test package. `ansi_term 0.11` depends on `winapi ^0.3.4`. This means means that the expected stderr for this test would have to be updated whenever `winapi 0.3` is updated otherwise. --- .../multiple_crate_versions/fail/Cargo.lock | 109 ++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 tests/ui-cargo/multiple_crate_versions/fail/Cargo.lock diff --git a/tests/ui-cargo/multiple_crate_versions/fail/Cargo.lock b/tests/ui-cargo/multiple_crate_versions/fail/Cargo.lock new file mode 100644 index 0000000000000..7e96aa36feb45 --- /dev/null +++ b/tests/ui-cargo/multiple_crate_versions/fail/Cargo.lock @@ -0,0 +1,109 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "ansi_term" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" +dependencies = [ + "winapi 0.3.9", +] + +[[package]] +name = "bitflags" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4efd02e230a02e18f92fc2735f44597385ed02ad8f831e7c1c1156ee5e1ab3a5" + +[[package]] +name = "cfg-if" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" + +[[package]] +name = "ctrlc" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "653abc99aa905f693d89df4797fadc08085baee379db92be9f2496cefe8a6f2c" +dependencies = [ + "kernel32-sys", + "nix", + "winapi 0.2.8", +] + +[[package]] +name = "kernel32-sys" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" +dependencies = [ + "winapi 0.2.8", + "winapi-build", +] + +[[package]] +name = "libc" +version = "0.2.71" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9457b06509d27052635f90d6466700c65095fdf75409b3fbdd903e988b886f49" + +[[package]] +name = "multiple_crate_versions" +version = "0.1.0" +dependencies = [ + "ansi_term", + "ctrlc", +] + +[[package]] +name = "nix" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2c5afeb0198ec7be8569d666644b574345aad2e95a53baf3a532da3e0f3fb32" +dependencies = [ + "bitflags", + "cfg-if", + "libc", + "void", +] + +[[package]] +name = "void" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" + +[[package]] +name = "winapi" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-build" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" From d347d0cf59d0a502361db873d900f4587c6e34de Mon Sep 17 00:00:00 2001 From: Philipp Hansch Date: Wed, 1 Jul 2020 12:36:36 +0200 Subject: [PATCH 19/99] Deprecate regex_macro lint --- clippy_lints/src/deprecated_lints.rs | 10 ++++- clippy_lints/src/lib.rs | 9 +++-- clippy_lints/src/regex.rs | 57 ++-------------------------- clippy_lints/src/utils/paths.rs | 1 - src/lintlist/mod.rs | 7 ---- tests/ui/deprecated.rs | 1 + tests/ui/deprecated.stderr | 8 +++- tests/ui/regex.rs | 2 +- 8 files changed, 26 insertions(+), 69 deletions(-) diff --git a/clippy_lints/src/deprecated_lints.rs b/clippy_lints/src/deprecated_lints.rs index 6e8ca647dd7ae..818d8188a787a 100644 --- a/clippy_lints/src/deprecated_lints.rs +++ b/clippy_lints/src/deprecated_lints.rs @@ -153,5 +153,13 @@ declare_deprecated_lint! { /// /// **Deprecation reason:** Associated-constants are now preferred. pub REPLACE_CONSTS, - "associated-constants `MIN`/`MAX` of integers are prefer to `{min,max}_value()` and module constants" + "associated-constants `MIN`/`MAX` of integers are prefered to `{min,max}_value()` and module constants" +} + +declare_deprecated_lint! { + /// **What it does:** Nothing. This lint has been deprecated. + /// + /// **Deprecation reason:** The regex! macro does not exist anymore. + pub REGEX_MACRO, + "the regex! macro has been removed from the regex crate in 2018" } diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index 50116a95612e8..d31a597b66ac6 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -460,7 +460,11 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: ); store.register_removed( "clippy::replace_consts", - "associated-constants `MIN`/`MAX` of integers are prefer to `{min,max}_value()` and module constants", + "associated-constants `MIN`/`MAX` of integers are prefered to `{min,max}_value()` and module constants", + ); + store.register_removed( + "clippy::regex_macro", + "the regex! macro has been removed from the regex crate in 2018", ); // end deprecated lints, do not remove this comment, it’s used in `update_lints` @@ -755,7 +759,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: &reference::DEREF_ADDROF, &reference::REF_IN_DEREF, ®ex::INVALID_REGEX, - ®ex::REGEX_MACRO, ®ex::TRIVIAL_REGEX, &returns::NEEDLESS_RETURN, &returns::UNUSED_UNIT, @@ -1380,7 +1383,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: LintId::of(&reference::DEREF_ADDROF), LintId::of(&reference::REF_IN_DEREF), LintId::of(®ex::INVALID_REGEX), - LintId::of(®ex::REGEX_MACRO), LintId::of(®ex::TRIVIAL_REGEX), LintId::of(&returns::NEEDLESS_RETURN), LintId::of(&returns::UNUSED_UNIT), @@ -1517,7 +1519,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: LintId::of(&redundant_field_names::REDUNDANT_FIELD_NAMES), LintId::of(&redundant_pattern_matching::REDUNDANT_PATTERN_MATCHING), LintId::of(&redundant_static_lifetimes::REDUNDANT_STATIC_LIFETIMES), - LintId::of(®ex::REGEX_MACRO), LintId::of(®ex::TRIVIAL_REGEX), LintId::of(&returns::NEEDLESS_RETURN), LintId::of(&returns::UNUSED_UNIT), diff --git a/clippy_lints/src/regex.rs b/clippy_lints/src/regex.rs index 9c54c3cbac02b..7405edbcd1966 100644 --- a/clippy_lints/src/regex.rs +++ b/clippy_lints/src/regex.rs @@ -1,9 +1,9 @@ use crate::consts::{constant, Constant}; -use crate::utils::{is_expn_of, match_def_path, match_type, paths, span_lint, span_lint_and_help}; +use crate::utils::{match_def_path, paths, span_lint, span_lint_and_help}; use if_chain::if_chain; use rustc_ast::ast::{LitKind, StrStyle}; use rustc_data_structures::fx::FxHashSet; -use rustc_hir::{Block, BorrowKind, Crate, Expr, ExprKind, HirId}; +use rustc_hir::{BorrowKind, Expr, ExprKind, HirId}; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::{declare_tool_lint, impl_lint_pass}; use rustc_span::source_map::{BytePos, Span}; @@ -46,66 +46,15 @@ declare_clippy_lint! { "trivial regular expressions" } -declare_clippy_lint! { - /// **What it does:** Checks for usage of `regex!(_)` which (as of now) is - /// usually slower than `Regex::new(_)` unless called in a loop (which is a bad - /// idea anyway). - /// - /// **Why is this bad?** Performance, at least for now. The macro version is - /// likely to catch up long-term, but for now the dynamic version is faster. - /// - /// **Known problems:** None. - /// - /// **Example:** - /// ```ignore - /// regex!("foo|bar") - /// ``` - pub REGEX_MACRO, - style, - "use of `regex!(_)` instead of `Regex::new(_)`" -} - #[derive(Clone, Default)] pub struct Regex { spans: FxHashSet, last: Option, } -impl_lint_pass!(Regex => [INVALID_REGEX, REGEX_MACRO, TRIVIAL_REGEX]); +impl_lint_pass!(Regex => [INVALID_REGEX, TRIVIAL_REGEX]); impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Regex { - fn check_crate(&mut self, _: &LateContext<'a, 'tcx>, _: &'tcx Crate<'_>) { - self.spans.clear(); - } - - fn check_block(&mut self, cx: &LateContext<'a, 'tcx>, block: &'tcx Block<'_>) { - if_chain! { - if self.last.is_none(); - if let Some(ref expr) = block.expr; - if match_type(cx, cx.tables().expr_ty(expr), &paths::REGEX); - if let Some(span) = is_expn_of(expr.span, "regex"); - then { - if !self.spans.contains(&span) { - span_lint( - cx, - REGEX_MACRO, - span, - "`regex!(_)` found. \ - Please use `Regex::new(_)`, which is faster for now." - ); - self.spans.insert(span); - } - self.last = Some(block.hir_id); - } - } - } - - fn check_block_post(&mut self, _: &LateContext<'a, 'tcx>, block: &'tcx Block<'_>) { - if self.last.map_or(false, |id| block.hir_id == id) { - self.last = None; - } - } - fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) { if_chain! { if let ExprKind::Call(ref fun, ref args) = expr.kind; diff --git a/clippy_lints/src/utils/paths.rs b/clippy_lints/src/utils/paths.rs index 3b7e9739211b0..4c3462802e921 100644 --- a/clippy_lints/src/utils/paths.rs +++ b/clippy_lints/src/utils/paths.rs @@ -98,7 +98,6 @@ pub const RANGE_TO_STD: [&str; 3] = ["std", "ops", "RangeTo"]; pub const RC: [&str; 3] = ["alloc", "rc", "Rc"]; pub const RC_PTR_EQ: [&str; 4] = ["alloc", "rc", "Rc", "ptr_eq"]; pub const RECEIVER: [&str; 4] = ["std", "sync", "mpsc", "Receiver"]; -pub const REGEX: [&str; 3] = ["regex", "re_unicode", "Regex"]; pub const REGEX_BUILDER_NEW: [&str; 5] = ["regex", "re_builder", "unicode", "RegexBuilder", "new"]; pub const REGEX_BYTES_BUILDER_NEW: [&str; 5] = ["regex", "re_builder", "bytes", "RegexBuilder", "new"]; pub const REGEX_BYTES_NEW: [&str; 4] = ["regex", "re_bytes", "Regex", "new"]; diff --git a/src/lintlist/mod.rs b/src/lintlist/mod.rs index 5119fb4033728..a2998d7413047 100644 --- a/src/lintlist/mod.rs +++ b/src/lintlist/mod.rs @@ -1865,13 +1865,6 @@ pub static ref ALL_LINTS: Vec = vec![ deprecation: None, module: "reference", }, - Lint { - name: "regex_macro", - group: "style", - desc: "use of `regex!(_)` instead of `Regex::new(_)`", - deprecation: None, - module: "regex", - }, Lint { name: "rest_pat_in_fully_bound_structs", group: "restriction", diff --git a/tests/ui/deprecated.rs b/tests/ui/deprecated.rs index 188a641aa1af2..3eefb232780f1 100644 --- a/tests/ui/deprecated.rs +++ b/tests/ui/deprecated.rs @@ -7,5 +7,6 @@ #[warn(clippy::invalid_ref)] #[warn(clippy::into_iter_on_array)] #[warn(clippy::unused_label)] +#[warn(clippy::regex_macro)] fn main() {} diff --git a/tests/ui/deprecated.stderr b/tests/ui/deprecated.stderr index a4efe3d15a952..a80e2bf31feb6 100644 --- a/tests/ui/deprecated.stderr +++ b/tests/ui/deprecated.stderr @@ -54,11 +54,17 @@ error: lint `clippy::unused_label` has been removed: `this lint has been uplifte LL | #[warn(clippy::unused_label)] | ^^^^^^^^^^^^^^^^^^^^ +error: lint `clippy::regex_macro` has been removed: `the regex! macro has been removed from the regex crate in 2018` + --> $DIR/deprecated.rs:10:8 + | +LL | #[warn(clippy::regex_macro)] + | ^^^^^^^^^^^^^^^^^^^ + error: lint `clippy::str_to_string` has been removed: `using `str::to_string` is common even today and specialization will likely happen soon` --> $DIR/deprecated.rs:1:8 | LL | #[warn(clippy::str_to_string)] | ^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 10 previous errors +error: aborting due to 11 previous errors diff --git a/tests/ui/regex.rs b/tests/ui/regex.rs index b523fa5b711ae..9767e5bf76a85 100644 --- a/tests/ui/regex.rs +++ b/tests/ui/regex.rs @@ -1,5 +1,5 @@ #![allow(unused)] -#![warn(clippy::invalid_regex, clippy::trivial_regex, clippy::regex_macro)] +#![warn(clippy::invalid_regex, clippy::trivial_regex)] extern crate regex; From 590e07bbc2d2cba6377476c6b8442400327ff579 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Fri, 26 Jun 2020 05:55:23 +0300 Subject: [PATCH 20/99] rustc_lint: avoid using TypeckTables::empty for LateContext. --- clippy_lints/src/atomic_ordering.rs | 6 +-- clippy_lints/src/copies.rs | 6 +-- clippy_lints/src/default_trait_access.rs | 2 +- clippy_lints/src/eval_order_dependence.rs | 4 +- clippy_lints/src/format.rs | 2 +- clippy_lints/src/implicit_return.rs | 2 +- clippy_lints/src/let_and_return.rs | 2 +- clippy_lints/src/lifetimes.rs | 2 +- clippy_lints/src/map_unit_fn.rs | 8 ++-- clippy_lints/src/mem_discriminant.rs | 2 +- clippy_lints/src/mem_replace.rs | 6 +-- clippy_lints/src/methods/mod.rs | 8 ++-- .../src/methods/unnecessary_filter_map.rs | 2 +- clippy_lints/src/misc.rs | 2 +- clippy_lints/src/question_mark.rs | 2 +- clippy_lints/src/regex.rs | 2 +- clippy_lints/src/temporary_assignment.rs | 2 +- clippy_lints/src/to_digit_is_some.rs | 2 +- clippy_lints/src/trait_bounds.rs | 2 +- clippy_lints/src/transmute.rs | 2 +- clippy_lints/src/types.rs | 11 ++--- clippy_lints/src/unnamed_address.rs | 2 +- clippy_lints/src/useless_conversion.rs | 2 +- clippy_lints/src/utils/higher.rs | 2 +- clippy_lints/src/utils/hir_utils.rs | 46 ++++++++++--------- clippy_lints/src/utils/internal_lints.rs | 2 +- clippy_lints/src/utils/mod.rs | 8 ++-- 27 files changed, 70 insertions(+), 69 deletions(-) diff --git a/clippy_lints/src/atomic_ordering.rs b/clippy_lints/src/atomic_ordering.rs index 65e1e2c519c26..1115ba1bf922d 100644 --- a/clippy_lints/src/atomic_ordering.rs +++ b/clippy_lints/src/atomic_ordering.rs @@ -76,7 +76,7 @@ fn check_atomic_load_store(cx: &LateContext<'_, '_>, expr: &Expr<'_>) { if method == "load" || method == "store"; let ordering_arg = if method == "load" { &args[1] } else { &args[2] }; if let ExprKind::Path(ref ordering_qpath) = ordering_arg.kind; - if let Some(ordering_def_id) = cx.tables().qpath_res(ordering_qpath, ordering_arg.hir_id).opt_def_id(); + if let Some(ordering_def_id) = cx.qpath_res(ordering_qpath, ordering_arg.hir_id).opt_def_id(); then { if method == "load" && match_ordering_def_path(cx, ordering_def_id, &["Release", "AcqRel"]) { @@ -107,12 +107,12 @@ fn check_memory_fence(cx: &LateContext<'_, '_>, expr: &Expr<'_>) { if_chain! { if let ExprKind::Call(ref func, ref args) = expr.kind; if let ExprKind::Path(ref func_qpath) = func.kind; - if let Some(def_id) = cx.tables().qpath_res(func_qpath, func.hir_id).opt_def_id(); + if let Some(def_id) = cx.qpath_res(func_qpath, func.hir_id).opt_def_id(); if ["fence", "compiler_fence"] .iter() .any(|func| match_def_path(cx, def_id, &["core", "sync", "atomic", func])); if let ExprKind::Path(ref ordering_qpath) = &args[0].kind; - if let Some(ordering_def_id) = cx.tables().qpath_res(ordering_qpath, args[0].hir_id).opt_def_id(); + if let Some(ordering_def_id) = cx.qpath_res(ordering_qpath, args[0].hir_id).opt_def_id(); if match_ordering_def_path(cx, ordering_def_id, &["Relaxed"]); then { span_lint_and_help( diff --git a/clippy_lints/src/copies.rs b/clippy_lints/src/copies.rs index efd4a31f55960..8cc69c806aa99 100644 --- a/clippy_lints/src/copies.rs +++ b/clippy_lints/src/copies.rs @@ -192,7 +192,7 @@ fn lint_same_then_else(cx: &LateContext<'_, '_>, blocks: &[&Block<'_>]) { /// Implementation of `IFS_SAME_COND`. fn lint_same_cond(cx: &LateContext<'_, '_>, conds: &[&Expr<'_>]) { let hash: &dyn Fn(&&Expr<'_>) -> u64 = &|expr| -> u64 { - let mut h = SpanlessHash::new(cx, cx.tables()); + let mut h = SpanlessHash::new(cx); h.hash_expr(expr); h.finish() }; @@ -215,7 +215,7 @@ fn lint_same_cond(cx: &LateContext<'_, '_>, conds: &[&Expr<'_>]) { /// Implementation of `SAME_FUNCTIONS_IN_IF_CONDITION`. fn lint_same_fns_in_if_cond(cx: &LateContext<'_, '_>, conds: &[&Expr<'_>]) { let hash: &dyn Fn(&&Expr<'_>) -> u64 = &|expr| -> u64 { - let mut h = SpanlessHash::new(cx, cx.tables()); + let mut h = SpanlessHash::new(cx); h.hash_expr(expr); h.finish() }; @@ -251,7 +251,7 @@ fn lint_match_arms<'tcx>(cx: &LateContext<'_, 'tcx>, expr: &Expr<'_>) { if let ExprKind::Match(_, ref arms, MatchSource::Normal) = expr.kind { let hash = |&(_, arm): &(usize, &Arm<'_>)| -> u64 { - let mut h = SpanlessHash::new(cx, cx.tables()); + let mut h = SpanlessHash::new(cx); h.hash_expr(&arm.body); h.finish() }; diff --git a/clippy_lints/src/default_trait_access.rs b/clippy_lints/src/default_trait_access.rs index 69ae509fb23e9..a918c72fb275e 100644 --- a/clippy_lints/src/default_trait_access.rs +++ b/clippy_lints/src/default_trait_access.rs @@ -36,7 +36,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for DefaultTraitAccess { if let ExprKind::Call(ref path, ..) = expr.kind; if !any_parent_is_automatically_derived(cx.tcx, expr.hir_id); if let ExprKind::Path(ref qpath) = path.kind; - if let Some(def_id) = cx.tables().qpath_res(qpath, path.hir_id).opt_def_id(); + if let Some(def_id) = cx.qpath_res(qpath, path.hir_id).opt_def_id(); if match_def_path(cx, def_id, &paths::DEFAULT_TRAIT_METHOD); then { match qpath { diff --git a/clippy_lints/src/eval_order_dependence.rs b/clippy_lints/src/eval_order_dependence.rs index 04af6c2c1f85d..31fe7382e46de 100644 --- a/clippy_lints/src/eval_order_dependence.rs +++ b/clippy_lints/src/eval_order_dependence.rs @@ -75,7 +75,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for EvalOrderDependence { if let ExprKind::Path(ref qpath) = lhs.kind { if let QPath::Resolved(_, ref path) = *qpath { if path.segments.len() == 1 { - if let def::Res::Local(var) = cx.tables().qpath_res(qpath, lhs.hir_id) { + if let def::Res::Local(var) = cx.qpath_res(qpath, lhs.hir_id) { let mut visitor = ReadVisitor { cx, var, @@ -309,7 +309,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ReadVisitor<'a, 'tcx> { if_chain! { if let QPath::Resolved(None, ref path) = *qpath; if path.segments.len() == 1; - if let def::Res::Local(local_id) = self.cx.tables().qpath_res(qpath, expr.hir_id); + if let def::Res::Local(local_id) = self.cx.qpath_res(qpath, expr.hir_id); if local_id == self.var; // Check that this is a read, not a write. if !is_in_assignment_position(self.cx, expr); diff --git a/clippy_lints/src/format.rs b/clippy_lints/src/format.rs index 58cf0027ea4d4..dc8795e3d11eb 100644 --- a/clippy_lints/src/format.rs +++ b/clippy_lints/src/format.rs @@ -88,7 +88,7 @@ fn on_argumentv1_new<'a, 'tcx>( // matches `core::fmt::Display::fmt` if args.len() == 2; if let ExprKind::Path(ref qpath) = args[1].kind; - if let Some(did) = cx.tables().qpath_res(qpath, args[1].hir_id).opt_def_id(); + if let Some(did) = cx.qpath_res(qpath, args[1].hir_id).opt_def_id(); if match_def_path(cx, did, &paths::DISPLAY_FMT_METHOD); // check `(arg0,)` in match block if let PatKind::Tuple(ref pats, None) = arms[0].pat.kind; diff --git a/clippy_lints/src/implicit_return.rs b/clippy_lints/src/implicit_return.rs index 5a0531ff749e9..b43babc1de879 100644 --- a/clippy_lints/src/implicit_return.rs +++ b/clippy_lints/src/implicit_return.rs @@ -108,7 +108,7 @@ fn expr_match(cx: &LateContext<'_, '_>, expr: &Expr<'_>) { ExprKind::Call(expr, ..) => { if_chain! { if let ExprKind::Path(qpath) = &expr.kind; - if let Some(path_def_id) = cx.tables().qpath_res(qpath, expr.hir_id).opt_def_id(); + if let Some(path_def_id) = cx.qpath_res(qpath, expr.hir_id).opt_def_id(); if match_def_path(cx, path_def_id, &BEGIN_PANIC) || match_def_path(cx, path_def_id, &BEGIN_PANIC_FMT); then { } diff --git a/clippy_lints/src/let_and_return.rs b/clippy_lints/src/let_and_return.rs index 299202981b1f3..7d338cfa86f9f 100644 --- a/clippy_lints/src/let_and_return.rs +++ b/clippy_lints/src/let_and_return.rs @@ -107,7 +107,7 @@ impl BorrowVisitor<'_, '_> { .. }, .., - ) => self.cx.tables().qpath_res(qpath, expr.hir_id).opt_def_id(), + ) => self.cx.qpath_res(qpath, expr.hir_id).opt_def_id(), _ => None, } } diff --git a/clippy_lints/src/lifetimes.rs b/clippy_lints/src/lifetimes.rs index 6840e82d4bf1b..c0d8c1127b9d3 100644 --- a/clippy_lints/src/lifetimes.rs +++ b/clippy_lints/src/lifetimes.rs @@ -343,7 +343,7 @@ impl<'v, 't> RefVisitor<'v, 't> { }) { let hir_id = ty.hir_id; - match self.cx.tables().qpath_res(qpath, hir_id) { + match self.cx.qpath_res(qpath, hir_id) { Res::Def(DefKind::TyAlias | DefKind::Struct, def_id) => { let generics = self.cx.tcx.generics_of(def_id); for _ in generics.params.as_slice() { diff --git a/clippy_lints/src/map_unit_fn.rs b/clippy_lints/src/map_unit_fn.rs index a4550f707ee22..90d4a34a19a29 100644 --- a/clippy_lints/src/map_unit_fn.rs +++ b/clippy_lints/src/map_unit_fn.rs @@ -160,10 +160,10 @@ fn reduce_unit_expression<'a>(cx: &LateContext<'_, '_>, expr: &'a hir::Expr<'_>) } } -fn unit_closure<'a, 'tcx>( - cx: &LateContext<'a, 'tcx>, - expr: &'a hir::Expr<'a>, -) -> Option<(&'tcx hir::Param<'tcx>, &'a hir::Expr<'a>)> { +fn unit_closure<'tcx>( + cx: &LateContext<'_, 'tcx>, + expr: &hir::Expr<'_>, +) -> Option<(&'tcx hir::Param<'tcx>, &'tcx hir::Expr<'tcx>)> { if let hir::ExprKind::Closure(_, ref decl, inner_expr_id, _, _) = expr.kind { let body = cx.tcx.hir().body(inner_expr_id); let body_expr = &body.value; diff --git a/clippy_lints/src/mem_discriminant.rs b/clippy_lints/src/mem_discriminant.rs index d315c5ef89a88..8a665a6e1fad3 100644 --- a/clippy_lints/src/mem_discriminant.rs +++ b/clippy_lints/src/mem_discriminant.rs @@ -35,7 +35,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MemDiscriminant { if let ExprKind::Call(ref func, ref func_args) = expr.kind; // is `mem::discriminant` if let ExprKind::Path(ref func_qpath) = func.kind; - if let Some(def_id) = cx.tables().qpath_res(func_qpath, func.hir_id).opt_def_id(); + if let Some(def_id) = cx.qpath_res(func_qpath, func.hir_id).opt_def_id(); if match_def_path(cx, def_id, &paths::MEM_DISCRIMINANT); // type is non-enum let ty_param = cx.tables().node_substs(func.hir_id).type_at(0); diff --git a/clippy_lints/src/mem_replace.rs b/clippy_lints/src/mem_replace.rs index 16d31fc8346ea..703f91f8ac028 100644 --- a/clippy_lints/src/mem_replace.rs +++ b/clippy_lints/src/mem_replace.rs @@ -162,7 +162,7 @@ fn check_replace_with_uninit(cx: &LateContext<'_, '_>, src: &Expr<'_>, dest: &Ex if let ExprKind::Call(ref repl_func, ref repl_args) = src.kind; if repl_args.is_empty(); if let ExprKind::Path(ref repl_func_qpath) = repl_func.kind; - if let Some(repl_def_id) = cx.tables().qpath_res(repl_func_qpath, repl_func.hir_id).opt_def_id(); + if let Some(repl_def_id) = cx.qpath_res(repl_func_qpath, repl_func.hir_id).opt_def_id(); then { if cx.tcx.is_diagnostic_item(sym::mem_uninitialized, repl_def_id) { let mut applicability = Applicability::MachineApplicable; @@ -198,7 +198,7 @@ fn check_replace_with_default(cx: &LateContext<'_, '_>, src: &Expr<'_>, dest: &E if_chain! { if !in_external_macro(cx.tcx.sess, expr_span); if let ExprKind::Path(ref repl_func_qpath) = repl_func.kind; - if let Some(repl_def_id) = cx.tables().qpath_res(repl_func_qpath, repl_func.hir_id).opt_def_id(); + if let Some(repl_def_id) = cx.qpath_res(repl_func_qpath, repl_func.hir_id).opt_def_id(); if match_def_path(cx, repl_def_id, &paths::DEFAULT_TRAIT_METHOD); then { span_lint_and_then( @@ -230,7 +230,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MemReplace { // Check that `expr` is a call to `mem::replace()` if let ExprKind::Call(ref func, ref func_args) = expr.kind; if let ExprKind::Path(ref func_qpath) = func.kind; - if let Some(def_id) = cx.tables().qpath_res(func_qpath, func.hir_id).opt_def_id(); + if let Some(def_id) = cx.qpath_res(func_qpath, func.hir_id).opt_def_id(); if match_def_path(cx, def_id, &paths::MEM_REPLACE); if let [dest, src] = &**func_args; then { diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index c4e707ecf03ad..7018a2f403976 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -1824,7 +1824,7 @@ fn lint_expect_fun_call( hir::ExprKind::Lit(_) => true, hir::ExprKind::Call(fun, _) => { if let hir::ExprKind::Path(ref p) = fun.kind { - match cx.tables().qpath_res(p, fun.hir_id) { + match cx.qpath_res(p, fun.hir_id) { hir::def::Res::Def(hir::def::DefKind::Fn | hir::def::DefKind::AssocFn, def_id) => matches!( cx.tcx.fn_sig(def_id).output().skip_binder().kind, ty::Ref(ty::ReStatic, ..) @@ -1844,7 +1844,7 @@ fn lint_expect_fun_call( ty::Ref(ty::ReStatic, ..) ) }), - hir::ExprKind::Path(ref p) => match cx.tables().qpath_res(p, arg.hir_id) { + hir::ExprKind::Path(ref p) => match cx.qpath_res(p, arg.hir_id) { hir::def::Res::Def(hir::def::DefKind::Const | hir::def::DefKind::Static, _) => true, _ => false, }, @@ -3317,7 +3317,7 @@ fn lint_option_as_ref_deref<'a, 'tcx>( if_chain! { if args.len() == 1; if let hir::ExprKind::Path(qpath) = &args[0].kind; - if let hir::def::Res::Local(local_id) = cx.tables().qpath_res(qpath, args[0].hir_id); + if let hir::def::Res::Local(local_id) = cx.qpath_res(qpath, args[0].hir_id); if closure_body.params[0].pat.hir_id == local_id; let adj = cx.tables().expr_adjustments(&args[0]).iter().map(|x| &x.kind).collect::>(); if let [ty::adjustment::Adjust::Deref(None), ty::adjustment::Adjust::Borrow(_)] = *adj; @@ -3334,7 +3334,7 @@ fn lint_option_as_ref_deref<'a, 'tcx>( if let hir::ExprKind::Unary(hir::UnOp::UnDeref, ref inner1) = inner.kind; if let hir::ExprKind::Unary(hir::UnOp::UnDeref, ref inner2) = inner1.kind; if let hir::ExprKind::Path(ref qpath) = inner2.kind; - if let hir::def::Res::Local(local_id) = cx.tables().qpath_res(qpath, inner2.hir_id); + if let hir::def::Res::Local(local_id) = cx.qpath_res(qpath, inner2.hir_id); then { closure_body.params[0].pat.hir_id == local_id } else { diff --git a/clippy_lints/src/methods/unnecessary_filter_map.rs b/clippy_lints/src/methods/unnecessary_filter_map.rs index 88243a88d9dd7..8a3df85c91bff 100644 --- a/clippy_lints/src/methods/unnecessary_filter_map.rs +++ b/clippy_lints/src/methods/unnecessary_filter_map.rs @@ -65,7 +65,7 @@ fn check_expression<'a, 'tcx>( if match_qpath(path, &paths::OPTION_SOME) { if_chain! { if let hir::ExprKind::Path(path) = &args[0].kind; - if let Res::Local(ref local) = cx.tables().qpath_res(path, args[0].hir_id); + if let Res::Local(ref local) = cx.qpath_res(path, args[0].hir_id); then { if arg_id == *local { return (false, false) diff --git a/clippy_lints/src/misc.rs b/clippy_lints/src/misc.rs index 99cd864cae4e3..fcd77088b88eb 100644 --- a/clippy_lints/src/misc.rs +++ b/clippy_lints/src/misc.rs @@ -436,7 +436,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MiscLints { binding != "_result" && // FIXME: #944 is_used(cx, expr) && // don't lint if the declaration is in a macro - non_macro_local(cx, cx.tables().qpath_res(qpath, expr.hir_id)) + non_macro_local(cx, cx.qpath_res(qpath, expr.hir_id)) { Some(binding) } else { diff --git a/clippy_lints/src/question_mark.rs b/clippy_lints/src/question_mark.rs index 4a6395da01c99..a77e104bb8f0f 100644 --- a/clippy_lints/src/question_mark.rs +++ b/clippy_lints/src/question_mark.rs @@ -158,7 +158,7 @@ impl QuestionMark { ExprKind::Ret(Some(ref expr)) => Self::expression_returns_none(cx, expr), ExprKind::Path(ref qp) => { if let Res::Def(DefKind::Ctor(def::CtorOf::Variant, def::CtorKind::Const), def_id) = - cx.tables().qpath_res(qp, expression.hir_id) + cx.qpath_res(qp, expression.hir_id) { return match_def_path(cx, def_id, &paths::OPTION_NONE); } diff --git a/clippy_lints/src/regex.rs b/clippy_lints/src/regex.rs index 9c54c3cbac02b..0b56ef02a844b 100644 --- a/clippy_lints/src/regex.rs +++ b/clippy_lints/src/regex.rs @@ -111,7 +111,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Regex { if let ExprKind::Call(ref fun, ref args) = expr.kind; if let ExprKind::Path(ref qpath) = fun.kind; if args.len() == 1; - if let Some(def_id) = cx.tables().qpath_res(qpath, fun.hir_id).opt_def_id(); + if let Some(def_id) = cx.qpath_res(qpath, fun.hir_id).opt_def_id(); then { if match_def_path(cx, def_id, &paths::REGEX_NEW) || match_def_path(cx, def_id, &paths::REGEX_BUILDER_NEW) { diff --git a/clippy_lints/src/temporary_assignment.rs b/clippy_lints/src/temporary_assignment.rs index f2bbf19bea92f..bc282e4bd987c 100644 --- a/clippy_lints/src/temporary_assignment.rs +++ b/clippy_lints/src/temporary_assignment.rs @@ -26,7 +26,7 @@ fn is_temporary(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> bool { match &expr.kind { ExprKind::Struct(..) | ExprKind::Tup(..) => true, ExprKind::Path(qpath) => { - if let Res::Def(DefKind::Const, ..) = cx.tables().qpath_res(qpath, expr.hir_id) { + if let Res::Def(DefKind::Const, ..) = cx.qpath_res(qpath, expr.hir_id) { true } else { false diff --git a/clippy_lints/src/to_digit_is_some.rs b/clippy_lints/src/to_digit_is_some.rs index 1efba3580fef0..4f943eeaeebc7 100644 --- a/clippy_lints/src/to_digit_is_some.rs +++ b/clippy_lints/src/to_digit_is_some.rs @@ -56,7 +56,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ToDigitIsSome { if_chain! { if let [char_arg, radix_arg] = &**to_digit_args; if let hir::ExprKind::Path(to_digits_path) = &to_digits_call.kind; - if let to_digits_call_res = cx.tables().qpath_res(to_digits_path, to_digits_call.hir_id); + if let to_digits_call_res = cx.qpath_res(to_digits_path, to_digits_call.hir_id); if let Some(to_digits_def_id) = to_digits_call_res.opt_def_id(); if match_def_path(cx, to_digits_def_id, &["core", "char", "methods", "", "to_digit"]); then { diff --git a/clippy_lints/src/trait_bounds.rs b/clippy_lints/src/trait_bounds.rs index 1b233b8302f93..c3e4eb05eb4ed 100644 --- a/clippy_lints/src/trait_bounds.rs +++ b/clippy_lints/src/trait_bounds.rs @@ -37,7 +37,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TraitBounds { return; } let hash = |ty| -> u64 { - let mut hasher = SpanlessHash::new(cx, cx.tables()); + let mut hasher = SpanlessHash::new(cx); hasher.hash_ty(ty); hasher.finish() }; diff --git a/clippy_lints/src/transmute.rs b/clippy_lints/src/transmute.rs index 9b1344949470a..6ef4b8dcfc194 100644 --- a/clippy_lints/src/transmute.rs +++ b/clippy_lints/src/transmute.rs @@ -299,7 +299,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Transmute { if_chain! { if let ExprKind::Call(ref path_expr, ref args) = e.kind; if let ExprKind::Path(ref qpath) = path_expr.kind; - if let Some(def_id) = cx.tables().qpath_res(qpath, path_expr.hir_id).opt_def_id(); + if let Some(def_id) = cx.qpath_res(qpath, path_expr.hir_id).opt_def_id(); if match_def_path(cx, def_id, &paths::TRANSMUTE); then { let from_ty = cx.tables().expr_ty(&args[0]); diff --git a/clippy_lints/src/types.rs b/clippy_lints/src/types.rs index ecfb6ee2a7de9..74db29e4f1d50 100644 --- a/clippy_lints/src/types.rs +++ b/clippy_lints/src/types.rs @@ -2490,7 +2490,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ImplicitHasherTypeVisitor<'a, 'tcx> { /// Looks for default-hasher-dependent constructors like `HashMap::new`. struct ImplicitHasherConstructorVisitor<'a, 'b, 'tcx> { cx: &'a LateContext<'a, 'tcx>, - body: &'a TypeckTables<'tcx>, + maybe_typeck_tables: Option<&'tcx TypeckTables<'tcx>>, target: &'b ImplicitHasherType<'tcx>, suggestions: BTreeMap, } @@ -2499,7 +2499,7 @@ impl<'a, 'b, 'tcx> ImplicitHasherConstructorVisitor<'a, 'b, 'tcx> { fn new(cx: &'a LateContext<'a, 'tcx>, target: &'b ImplicitHasherType<'tcx>) -> Self { Self { cx, - body: cx.tables(), + maybe_typeck_tables: cx.maybe_typeck_tables(), target, suggestions: BTreeMap::new(), } @@ -2510,10 +2510,9 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for ImplicitHasherConstructorVisitor<'a, 'b, 't type Map = Map<'tcx>; fn visit_body(&mut self, body: &'tcx Body<'_>) { - let prev_body = self.body; - self.body = self.cx.tcx.body_tables(body.id()); + let old_maybe_typeck_tables = self.maybe_typeck_tables.replace(self.cx.tcx.body_tables(body.id())); walk_body(self, body); - self.body = prev_body; + self.maybe_typeck_tables = old_maybe_typeck_tables; } fn visit_expr(&mut self, e: &'tcx Expr<'_>) { @@ -2522,7 +2521,7 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for ImplicitHasherConstructorVisitor<'a, 'b, 't if let ExprKind::Path(QPath::TypeRelative(ref ty, ref method)) = fun.kind; if let TyKind::Path(QPath::Resolved(None, ty_path)) = ty.kind; then { - if !TyS::same_type(self.target.ty(), self.body.expr_ty(e)) { + if !TyS::same_type(self.target.ty(), self.maybe_typeck_tables.unwrap().expr_ty(e)) { return; } diff --git a/clippy_lints/src/unnamed_address.rs b/clippy_lints/src/unnamed_address.rs index 53e47f09ae55c..0efbf68dcd842 100644 --- a/clippy_lints/src/unnamed_address.rs +++ b/clippy_lints/src/unnamed_address.rs @@ -98,7 +98,7 @@ impl LateLintPass<'_, '_> for UnnamedAddress { if_chain! { if let ExprKind::Call(ref func, [ref _left, ref _right]) = expr.kind; if let ExprKind::Path(ref func_qpath) = func.kind; - if let Some(def_id) = cx.tables().qpath_res(func_qpath, func.hir_id).opt_def_id(); + if let Some(def_id) = cx.qpath_res(func_qpath, func.hir_id).opt_def_id(); if match_def_path(cx, def_id, &paths::PTR_EQ) || match_def_path(cx, def_id, &paths::RC_PTR_EQ) || match_def_path(cx, def_id, &paths::ARC_PTR_EQ); diff --git a/clippy_lints/src/useless_conversion.rs b/clippy_lints/src/useless_conversion.rs index 5d150ad4f03e4..ad5ecc0c02679 100644 --- a/clippy_lints/src/useless_conversion.rs +++ b/clippy_lints/src/useless_conversion.rs @@ -121,7 +121,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UselessConversion { if_chain! { if args.len() == 1; if let ExprKind::Path(ref qpath) = path.kind; - if let Some(def_id) = cx.tables().qpath_res(qpath, path.hir_id).opt_def_id(); + if let Some(def_id) = cx.qpath_res(qpath, path.hir_id).opt_def_id(); let a = cx.tables().expr_ty(e); let b = cx.tables().expr_ty(&args[0]); diff --git a/clippy_lints/src/utils/higher.rs b/clippy_lints/src/utils/higher.rs index 0e78f35a1290a..9502d85e6ee98 100644 --- a/clippy_lints/src/utils/higher.rs +++ b/clippy_lints/src/utils/higher.rs @@ -262,7 +262,7 @@ pub fn vec_macro<'e>(cx: &LateContext<'_, '_>, expr: &'e hir::Expr<'_>) -> Optio if let hir::ExprKind::Call(ref fun, ref args) = expr.kind; if let hir::ExprKind::Path(ref qpath) = fun.kind; if is_expn_of(fun.span, "vec").is_some(); - if let Some(fun_def_id) = cx.tables().qpath_res(qpath, fun.hir_id).opt_def_id(); + if let Some(fun_def_id) = cx.qpath_res(qpath, fun.hir_id).opt_def_id(); then { return if match_def_path(cx, fun_def_id, &paths::VEC_FROM_ELEM) && args.len() == 2 { // `vec![elem; size]` case diff --git a/clippy_lints/src/utils/hir_utils.rs b/clippy_lints/src/utils/hir_utils.rs index a74ab18a063b2..bf1017d76ec63 100644 --- a/clippy_lints/src/utils/hir_utils.rs +++ b/clippy_lints/src/utils/hir_utils.rs @@ -22,7 +22,7 @@ use std::hash::Hash; pub struct SpanlessEq<'a, 'tcx> { /// Context used to evaluate constant expressions. cx: &'a LateContext<'a, 'tcx>, - tables: &'a TypeckTables<'tcx>, + maybe_typeck_tables: Option<&'tcx TypeckTables<'tcx>>, /// If is true, never consider as equal expressions containing function /// calls. ignore_fn: bool, @@ -32,16 +32,15 @@ impl<'a, 'tcx> SpanlessEq<'a, 'tcx> { pub fn new(cx: &'a LateContext<'a, 'tcx>) -> Self { Self { cx, - tables: cx.tables(), + maybe_typeck_tables: cx.maybe_typeck_tables(), ignore_fn: false, } } pub fn ignore_fn(self) -> Self { Self { - cx: self.cx, - tables: self.cx.tables(), ignore_fn: true, + ..self } } @@ -72,12 +71,14 @@ impl<'a, 'tcx> SpanlessEq<'a, 'tcx> { return false; } - if let (Some(l), Some(r)) = ( - constant_simple(self.cx, self.tables, left), - constant_simple(self.cx, self.tables, right), - ) { - if l == r { - return true; + if let Some(tables) = self.maybe_typeck_tables { + if let (Some(l), Some(r)) = ( + constant_simple(self.cx, tables, left), + constant_simple(self.cx, tables, right), + ) { + if l == r { + return true; + } } } @@ -271,18 +272,18 @@ impl<'a, 'tcx> SpanlessEq<'a, 'tcx> { match (left, right) { (&TyKind::Slice(ref l_vec), &TyKind::Slice(ref r_vec)) => self.eq_ty(l_vec, r_vec), (&TyKind::Array(ref lt, ref ll_id), &TyKind::Array(ref rt, ref rl_id)) => { - let full_table = self.tables; + let old_maybe_typeck_tables = self.maybe_typeck_tables; let mut celcx = constant_context(self.cx, self.cx.tcx.body_tables(ll_id.body)); - self.tables = self.cx.tcx.body_tables(ll_id.body); + self.maybe_typeck_tables = Some(self.cx.tcx.body_tables(ll_id.body)); let ll = celcx.expr(&self.cx.tcx.hir().body(ll_id.body).value); let mut celcx = constant_context(self.cx, self.cx.tcx.body_tables(rl_id.body)); - self.tables = self.cx.tcx.body_tables(rl_id.body); + self.maybe_typeck_tables = Some(self.cx.tcx.body_tables(rl_id.body)); let rl = celcx.expr(&self.cx.tcx.hir().body(rl_id.body).value); let eq_ty = self.eq_ty(lt, rt); - self.tables = full_table; + self.maybe_typeck_tables = old_maybe_typeck_tables; eq_ty && ll == rl }, (&TyKind::Ptr(ref l_mut), &TyKind::Ptr(ref r_mut)) => { @@ -347,15 +348,15 @@ pub fn over(left: &[X], right: &[X], mut eq_fn: impl FnMut(&X, &X) -> bool) - pub struct SpanlessHash<'a, 'tcx> { /// Context used to evaluate constant expressions. cx: &'a LateContext<'a, 'tcx>, - tables: &'a TypeckTables<'tcx>, + maybe_typeck_tables: Option<&'tcx TypeckTables<'tcx>>, s: StableHasher, } impl<'a, 'tcx> SpanlessHash<'a, 'tcx> { - pub fn new(cx: &'a LateContext<'a, 'tcx>, tables: &'a TypeckTables<'tcx>) -> Self { + pub fn new(cx: &'a LateContext<'a, 'tcx>) -> Self { Self { cx, - tables, + maybe_typeck_tables: cx.maybe_typeck_tables(), s: StableHasher::new(), } } @@ -384,7 +385,9 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> { #[allow(clippy::many_single_char_names, clippy::too_many_lines)] pub fn hash_expr(&mut self, e: &Expr<'_>) { - let simple_const = constant_simple(self.cx, self.tables, e); + let simple_const = self + .maybe_typeck_tables + .and_then(|tables| constant_simple(self.cx, tables, e)); // const hashing may result in the same hash as some unrelated node, so add a sort of // discriminant depending on which path we're choosing next @@ -599,7 +602,7 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> { self.hash_name(path.ident.name); }, } - // self.cx.tables.qpath_res(p, id).hash(&mut self.s); + // self.maybe_typeck_tables.unwrap().qpath_res(p, id).hash(&mut self.s); } pub fn hash_path(&mut self, p: &Path<'_>) { @@ -728,9 +731,8 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> { pub fn hash_body(&mut self, body_id: BodyId) { // swap out TypeckTables when hashing a body - let old_tables = self.tables; - self.tables = self.cx.tcx.body_tables(body_id); + let old_maybe_typeck_tables = self.maybe_typeck_tables.replace(self.cx.tcx.body_tables(body_id)); self.hash_expr(&self.cx.tcx.hir().body(body_id).value); - self.tables = old_tables; + self.maybe_typeck_tables = old_maybe_typeck_tables; } } diff --git a/clippy_lints/src/utils/internal_lints.rs b/clippy_lints/src/utils/internal_lints.rs index 38468181d0261..ca947e9241f0f 100644 --- a/clippy_lints/src/utils/internal_lints.rs +++ b/clippy_lints/src/utils/internal_lints.rs @@ -347,7 +347,7 @@ fn is_lint_ref_type<'tcx>(cx: &LateContext<'_, 'tcx>, ty: &Ty<'_>) -> bool { ) = ty.kind { if let TyKind::Path(ref path) = inner.kind { - if let Res::Def(DefKind::Struct, def_id) = cx.tables().qpath_res(path, inner.hir_id) { + if let Res::Def(DefKind::Struct, def_id) = cx.qpath_res(path, inner.hir_id) { return match_def_path(cx, def_id, &paths::LINT); } } diff --git a/clippy_lints/src/utils/mod.rs b/clippy_lints/src/utils/mod.rs index 69ec4b7ad6d18..8be9ba2c3c244 100644 --- a/clippy_lints/src/utils/mod.rs +++ b/clippy_lints/src/utils/mod.rs @@ -898,7 +898,7 @@ pub fn is_copy<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, ty: Ty<'tcx>) -> bool { pub fn is_ctor_or_promotable_const_function(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> bool { if let ExprKind::Call(ref fun, _) = expr.kind { if let ExprKind::Path(ref qp) = fun.kind { - let res = cx.tables().qpath_res(qp, fun.hir_id); + let res = cx.qpath_res(qp, fun.hir_id); return match res { def::Res::Def(DefKind::Variant | DefKind::Ctor(..), ..) => true, def::Res::Def(_, def_id) => cx.tcx.is_promotable_const_fn(def_id), @@ -914,7 +914,7 @@ pub fn is_ctor_or_promotable_const_function(cx: &LateContext<'_, '_>, expr: &Exp pub fn is_refutable(cx: &LateContext<'_, '_>, pat: &Pat<'_>) -> bool { fn is_enum_variant(cx: &LateContext<'_, '_>, qpath: &QPath<'_>, id: HirId) -> bool { matches!( - cx.tables().qpath_res(qpath, id), + cx.qpath_res(qpath, id), def::Res::Def(DefKind::Variant, ..) | Res::Def(DefKind::Ctor(def::CtorOf::Variant, _), _) ) } @@ -1190,7 +1190,7 @@ pub fn match_function_call<'a, 'tcx>( if_chain! { if let ExprKind::Call(ref fun, ref args) = expr.kind; if let ExprKind::Path(ref qpath) = fun.kind; - if let Some(fun_def_id) = cx.tables().qpath_res(qpath, fun.hir_id).opt_def_id(); + if let Some(fun_def_id) = cx.qpath_res(qpath, fun.hir_id).opt_def_id(); if match_def_path(cx, fun_def_id, path); then { return Some(&args) @@ -1317,7 +1317,7 @@ pub fn is_must_use_func_call(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> bool let did = match expr.kind { ExprKind::Call(ref path, _) => if_chain! { if let ExprKind::Path(ref qpath) = path.kind; - if let def::Res::Def(_, did) = cx.tables().qpath_res(qpath, path.hir_id); + if let def::Res::Def(_, did) = cx.qpath_res(qpath, path.hir_id); then { Some(did) } else { From bddb266089deb0cb879caeff1bb9aa860746e062 Mon Sep 17 00:00:00 2001 From: David Wood Date: Thu, 2 Jul 2020 14:13:39 +0100 Subject: [PATCH 21/99] typeck: check for infer before type impls trait This commit checks that the target type of the cast (an error related to which is being reported) does not have types to be inferred before checking if it implements the `From` trait. Signed-off-by: David Wood --- src/librustc_typeck/check/cast.rs | 1 + src/test/ui/issues/issue-73886.rs | 6 ++++++ src/test/ui/issues/issue-73886.stderr | 15 +++++++++++++++ 3 files changed, 22 insertions(+) create mode 100644 src/test/ui/issues/issue-73886.rs create mode 100644 src/test/ui/issues/issue-73886.stderr diff --git a/src/librustc_typeck/check/cast.rs b/src/librustc_typeck/check/cast.rs index 1ea7bf25ef2ed..8948e5a3e00db 100644 --- a/src/librustc_typeck/check/cast.rs +++ b/src/librustc_typeck/check/cast.rs @@ -387,6 +387,7 @@ impl<'a, 'tcx> CastCheck<'tcx> { // Check for infer types because cases like `Option<{integer}>` would // panic otherwise. if !expr_ty.has_infer_types() + && !ty.has_infer_types() && fcx.tcx.type_implements_trait(( from_trait, ty, diff --git a/src/test/ui/issues/issue-73886.rs b/src/test/ui/issues/issue-73886.rs new file mode 100644 index 0000000000000..2f1ec8c6d6227 --- /dev/null +++ b/src/test/ui/issues/issue-73886.rs @@ -0,0 +1,6 @@ +fn main() { + let _ = &&[0] as &[_]; + //~^ ERROR non-primitive cast: `&&[i32; 1]` as `&[_]` + let _ = 7u32 as Option<_>; + //~^ ERROR non-primitive cast: `u32` as `std::option::Option<_>` +} diff --git a/src/test/ui/issues/issue-73886.stderr b/src/test/ui/issues/issue-73886.stderr new file mode 100644 index 0000000000000..e8ab7db6b82c2 --- /dev/null +++ b/src/test/ui/issues/issue-73886.stderr @@ -0,0 +1,15 @@ +error[E0605]: non-primitive cast: `&&[i32; 1]` as `&[_]` + --> $DIR/issue-73886.rs:2:13 + | +LL | let _ = &&[0] as &[_]; + | ^^^^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object + +error[E0605]: non-primitive cast: `u32` as `std::option::Option<_>` + --> $DIR/issue-73886.rs:4:13 + | +LL | let _ = 7u32 as Option<_>; + | ^^^^^^^^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0605`. From 30c046ede47ea45a772d2656b0365a4807263bca Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Thu, 25 Jun 2020 23:41:36 +0300 Subject: [PATCH 22/99] Use 'tcx for references to AccessLevels wherever possible. --- clippy_lints/src/approx_const.rs | 8 +- clippy_lints/src/arithmetic.rs | 10 +- clippy_lints/src/assertions_on_constants.rs | 6 +- clippy_lints/src/assign_ops.rs | 8 +- clippy_lints/src/atomic_ordering.rs | 12 +- clippy_lints/src/attrs.rs | 26 +-- clippy_lints/src/await_holding_lock.rs | 8 +- clippy_lints/src/bit_mask.rs | 14 +- clippy_lints/src/blacklisted_name.rs | 4 +- clippy_lints/src/blocks_in_if_conditions.rs | 6 +- clippy_lints/src/booleans.rs | 18 +- clippy_lints/src/bytecount.rs | 4 +- clippy_lints/src/cargo_common_metadata.rs | 6 +- clippy_lints/src/checked_conversions.rs | 10 +- clippy_lints/src/cognitive_complexity.rs | 12 +- clippy_lints/src/comparison_chain.rs | 4 +- clippy_lints/src/consts.rs | 26 +-- clippy_lints/src/copies.rs | 16 +- clippy_lints/src/copy_iterator.rs | 4 +- clippy_lints/src/default_trait_access.rs | 4 +- clippy_lints/src/dereference.rs | 6 +- clippy_lints/src/derive.rs | 20 +- clippy_lints/src/doc.rs | 26 +-- clippy_lints/src/double_comparison.rs | 8 +- clippy_lints/src/drop_bounds.rs | 10 +- clippy_lints/src/drop_forget_ref.rs | 4 +- clippy_lints/src/duration_subsec.rs | 4 +- clippy_lints/src/empty_enum.rs | 4 +- clippy_lints/src/entry.rs | 11 +- clippy_lints/src/enum_clike.rs | 4 +- clippy_lints/src/eq_op.rs | 4 +- clippy_lints/src/erasing_op.rs | 6 +- clippy_lints/src/escape.rs | 6 +- clippy_lints/src/eta_reduction.rs | 10 +- clippy_lints/src/eval_order_dependence.rs | 12 +- clippy_lints/src/exit.rs | 4 +- clippy_lints/src/explicit_write.rs | 4 +- clippy_lints/src/fallible_impl_from.rs | 8 +- clippy_lints/src/float_literal.rs | 4 +- clippy_lints/src/floating_point_arithmetic.rs | 32 +-- clippy_lints/src/format.rs | 14 +- clippy_lints/src/functions.rs | 38 ++-- clippy_lints/src/future_not_send.rs | 4 +- clippy_lints/src/get_last_with_len.rs | 4 +- clippy_lints/src/identity_op.rs | 8 +- clippy_lints/src/if_let_mutex.rs | 22 +- clippy_lints/src/if_let_some_result.rs | 4 +- clippy_lints/src/implicit_return.rs | 8 +- clippy_lints/src/implicit_saturating_sub.rs | 8 +- clippy_lints/src/indexing_slicing.rs | 8 +- clippy_lints/src/infinite_iter.rs | 8 +- clippy_lints/src/inherent_impl.rs | 6 +- clippy_lints/src/inherent_to_string.rs | 6 +- clippy_lints/src/inline_fn_without_body.rs | 6 +- clippy_lints/src/integer_division.rs | 6 +- clippy_lints/src/large_const_arrays.rs | 4 +- clippy_lints/src/large_enum_variant.rs | 4 +- clippy_lints/src/large_stack_arrays.rs | 4 +- clippy_lints/src/len_zero.rs | 28 +-- clippy_lints/src/let_and_return.rs | 8 +- clippy_lints/src/let_if_seq.rs | 12 +- clippy_lints/src/let_underscore.rs | 4 +- clippy_lints/src/lifetimes.rs | 26 +-- clippy_lints/src/loops.rs | 90 ++++---- clippy_lints/src/macro_use.rs | 22 +- clippy_lints/src/main_recursion.rs | 6 +- clippy_lints/src/manual_async_fn.rs | 10 +- clippy_lints/src/map_clone.rs | 8 +- clippy_lints/src/map_unit_fn.rs | 16 +- clippy_lints/src/match_on_vec_items.rs | 10 +- clippy_lints/src/matches.rs | 40 ++-- clippy_lints/src/mem_discriminant.rs | 4 +- clippy_lints/src/mem_forget.rs | 4 +- clippy_lints/src/mem_replace.rs | 10 +- .../src/methods/bind_instead_of_map.rs | 8 +- .../src/methods/inefficient_to_string.rs | 4 +- .../methods/manual_saturating_arithmetic.rs | 4 +- clippy_lints/src/methods/mod.rs | 194 ++++++++---------- .../src/methods/option_map_unwrap_or.rs | 8 +- .../src/methods/unnecessary_filter_map.rs | 12 +- clippy_lints/src/minmax.rs | 12 +- clippy_lints/src/misc.rs | 28 +-- clippy_lints/src/missing_const_for_fn.rs | 6 +- clippy_lints/src/missing_doc.rs | 26 +-- clippy_lints/src/missing_inline.rs | 10 +- clippy_lints/src/modulo_arithmetic.rs | 12 +- clippy_lints/src/multiple_crate_versions.rs | 4 +- clippy_lints/src/mut_key.rs | 16 +- clippy_lints/src/mut_mut.rs | 8 +- clippy_lints/src/mut_reference.rs | 11 +- clippy_lints/src/mutable_debug_assertion.rs | 10 +- clippy_lints/src/mutex_atomic.rs | 4 +- clippy_lints/src/needless_bool.rs | 12 +- clippy_lints/src/needless_borrow.rs | 10 +- clippy_lints/src/needless_borrowed_ref.rs | 4 +- clippy_lints/src/needless_pass_by_value.rs | 4 +- clippy_lints/src/needless_update.rs | 4 +- clippy_lints/src/neg_cmp_op_on_partial_ord.rs | 4 +- clippy_lints/src/neg_multiply.rs | 6 +- clippy_lints/src/new_without_default.rs | 4 +- clippy_lints/src/no_effect.rs | 8 +- clippy_lints/src/non_copy_const.rs | 12 +- clippy_lints/src/open_options.rs | 8 +- .../src/overflow_check_conditional.rs | 4 +- clippy_lints/src/panic_unimplemented.rs | 6 +- clippy_lints/src/partialeq_ne_impl.rs | 4 +- clippy_lints/src/path_buf_push_overwrite.rs | 4 +- clippy_lints/src/ptr.rs | 12 +- clippy_lints/src/ptr_offset_with_cast.rs | 18 +- clippy_lints/src/question_mark.rs | 14 +- clippy_lints/src/ranges.rs | 18 +- clippy_lints/src/redundant_clone.rs | 16 +- .../src/redundant_pattern_matching.rs | 14 +- clippy_lints/src/redundant_pub_crate.rs | 6 +- clippy_lints/src/regex.rs | 16 +- clippy_lints/src/serde_api.rs | 4 +- clippy_lints/src/shadow.rs | 24 +-- .../src/slow_vector_initialization.rs | 14 +- clippy_lints/src/strings.rs | 12 +- clippy_lints/src/suspicious_trait_impl.rs | 6 +- clippy_lints/src/swap.rs | 10 +- clippy_lints/src/temporary_assignment.rs | 6 +- clippy_lints/src/to_digit_is_some.rs | 4 +- clippy_lints/src/trait_bounds.rs | 4 +- clippy_lints/src/transmute.rs | 8 +- clippy_lints/src/transmuting_null.rs | 4 +- .../src/trivially_copy_pass_by_ref.rs | 8 +- clippy_lints/src/try_err.rs | 8 +- clippy_lints/src/types.rs | 136 ++++++------ clippy_lints/src/unicode.rs | 6 +- clippy_lints/src/unnamed_address.rs | 8 +- clippy_lints/src/unnecessary_sort_by.rs | 8 +- clippy_lints/src/unused_io_amount.rs | 6 +- clippy_lints/src/unused_self.rs | 6 +- clippy_lints/src/unwrap.rs | 14 +- clippy_lints/src/use_self.rs | 14 +- clippy_lints/src/useless_conversion.rs | 6 +- clippy_lints/src/utils/author.rs | 20 +- clippy_lints/src/utils/diagnostics.rs | 4 +- clippy_lints/src/utils/higher.rs | 4 +- clippy_lints/src/utils/hir_utils.rs | 8 +- clippy_lints/src/utils/inspector.rs | 28 +-- clippy_lints/src/utils/internal_lints.rs | 35 ++-- clippy_lints/src/utils/mod.rs | 72 +++---- clippy_lints/src/utils/ptr.rs | 8 +- clippy_lints/src/utils/sugg.rs | 10 +- clippy_lints/src/utils/usage.rs | 8 +- clippy_lints/src/vec.rs | 6 +- clippy_lints/src/vec_resize_to_zero.rs | 4 +- clippy_lints/src/verbose_file_reads.rs | 8 +- clippy_lints/src/wildcard_dependencies.rs | 4 +- clippy_lints/src/wildcard_imports.rs | 6 +- clippy_lints/src/zero_div_zero.rs | 4 +- doc/common_tools_writing_lints.md | 16 +- tests/ui/outer_expn_data.fixed | 4 +- tests/ui/outer_expn_data.rs | 4 +- 156 files changed, 966 insertions(+), 1041 deletions(-) diff --git a/clippy_lints/src/approx_const.rs b/clippy_lints/src/approx_const.rs index 7e6e2c7eaebea..1d511a86c9099 100644 --- a/clippy_lints/src/approx_const.rs +++ b/clippy_lints/src/approx_const.rs @@ -60,15 +60,15 @@ const KNOWN_CONSTS: [(f64, &str, usize); 18] = [ declare_lint_pass!(ApproxConstant => [APPROX_CONSTANT]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ApproxConstant { - fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr<'_>) { +impl<'tcx> LateLintPass<'tcx> for ApproxConstant { + fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) { if let ExprKind::Lit(lit) = &e.kind { check_lit(cx, &lit.node, e); } } } -fn check_lit(cx: &LateContext<'_, '_>, lit: &LitKind, e: &Expr<'_>) { +fn check_lit(cx: &LateContext<'_>, lit: &LitKind, e: &Expr<'_>) { match *lit { LitKind::Float(s, LitFloatType::Suffixed(fty)) => match fty { FloatTy::F32 => check_known_consts(cx, e, s, "f32"), @@ -79,7 +79,7 @@ fn check_lit(cx: &LateContext<'_, '_>, lit: &LitKind, e: &Expr<'_>) { } } -fn check_known_consts(cx: &LateContext<'_, '_>, e: &Expr<'_>, s: symbol::Symbol, module: &str) { +fn check_known_consts(cx: &LateContext<'_>, e: &Expr<'_>, s: symbol::Symbol, module: &str) { let s = s.as_str(); if s.parse::().is_ok() { for &(constant, name, min_digits) in &KNOWN_CONSTS { diff --git a/clippy_lints/src/arithmetic.rs b/clippy_lints/src/arithmetic.rs index cc09b99cf1dd1..da60856fac932 100644 --- a/clippy_lints/src/arithmetic.rs +++ b/clippy_lints/src/arithmetic.rs @@ -58,8 +58,8 @@ pub struct Arithmetic { impl_lint_pass!(Arithmetic => [INTEGER_ARITHMETIC, FLOAT_ARITHMETIC]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Arithmetic { - fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx hir::Expr<'_>) { +impl<'tcx> LateLintPass<'tcx> for Arithmetic { + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>) { if self.expr_span.is_some() { return; } @@ -111,13 +111,13 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Arithmetic { } } - fn check_expr_post(&mut self, _: &LateContext<'a, 'tcx>, expr: &'tcx hir::Expr<'_>) { + fn check_expr_post(&mut self, _: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>) { if Some(expr.span) == self.expr_span { self.expr_span = None; } } - fn check_body(&mut self, cx: &LateContext<'_, '_>, body: &hir::Body<'_>) { + fn check_body(&mut self, cx: &LateContext<'_>, body: &hir::Body<'_>) { let body_owner = cx.tcx.hir().body_owner(body.id()); match cx.tcx.hir().body_owner_kind(body_owner) { @@ -135,7 +135,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Arithmetic { } } - fn check_body_post(&mut self, cx: &LateContext<'_, '_>, body: &hir::Body<'_>) { + fn check_body_post(&mut self, cx: &LateContext<'_>, body: &hir::Body<'_>) { let body_owner = cx.tcx.hir().body_owner(body.id()); let body_span = cx.tcx.hir().span(body_owner); diff --git a/clippy_lints/src/assertions_on_constants.rs b/clippy_lints/src/assertions_on_constants.rs index c4536b57f8a99..cffe8d94e2797 100644 --- a/clippy_lints/src/assertions_on_constants.rs +++ b/clippy_lints/src/assertions_on_constants.rs @@ -29,8 +29,8 @@ declare_clippy_lint! { declare_lint_pass!(AssertionsOnConstants => [ASSERTIONS_ON_CONSTANTS]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for AssertionsOnConstants { - fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr<'_>) { +impl<'tcx> LateLintPass<'tcx> for AssertionsOnConstants { + fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) { let lint_true = |is_debug: bool| { span_lint_and_help( cx, @@ -114,7 +114,7 @@ enum AssertKind { /// ``` /// /// where `message` is any expression and `c` is a constant bool. -fn match_assert_with_message<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) -> Option { +fn match_assert_with_message<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) -> Option { if_chain! { if let ExprKind::Match(ref expr, ref arms, _) = expr.kind; // matches { let _t = expr; _t } diff --git a/clippy_lints/src/assign_ops.rs b/clippy_lints/src/assign_ops.rs index 51a7647d3208f..bc6e868823f77 100644 --- a/clippy_lints/src/assign_ops.rs +++ b/clippy_lints/src/assign_ops.rs @@ -60,9 +60,9 @@ declare_clippy_lint! { declare_lint_pass!(AssignOps => [ASSIGN_OP_PATTERN, MISREFACTORED_ASSIGN_OP]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for AssignOps { +impl<'tcx> LateLintPass<'tcx> for AssignOps { #[allow(clippy::too_many_lines)] - fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx hir::Expr<'_>) { + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>) { match &expr.kind { hir::ExprKind::AssignOp(op, lhs, rhs) => { if let hir::ExprKind::Binary(binop, l, r) = &rhs.kind { @@ -191,7 +191,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for AssignOps { } fn lint_misrefactored_assign_op( - cx: &LateContext<'_, '_>, + cx: &LateContext<'_>, expr: &hir::Expr<'_>, op: hir::BinOp, rhs: &hir::Expr<'_>, @@ -246,7 +246,7 @@ fn is_commutative(op: hir::BinOpKind) -> bool { struct ExprVisitor<'a, 'tcx> { assignee: &'a hir::Expr<'a>, counter: u8, - cx: &'a LateContext<'a, 'tcx>, + cx: &'a LateContext<'tcx>, } impl<'a, 'tcx> Visitor<'tcx> for ExprVisitor<'a, 'tcx> { diff --git a/clippy_lints/src/atomic_ordering.rs b/clippy_lints/src/atomic_ordering.rs index 1115ba1bf922d..efd3f0f671cdd 100644 --- a/clippy_lints/src/atomic_ordering.rs +++ b/clippy_lints/src/atomic_ordering.rs @@ -52,7 +52,7 @@ const ATOMIC_TYPES: [&str; 12] = [ "AtomicUsize", ]; -fn type_is_atomic(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> bool { +fn type_is_atomic(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { if let ty::Adt(&ty::AdtDef { did, .. }, _) = cx.tables().expr_ty(expr).kind { ATOMIC_TYPES .iter() @@ -62,13 +62,13 @@ fn type_is_atomic(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> bool { } } -fn match_ordering_def_path(cx: &LateContext<'_, '_>, did: DefId, orderings: &[&str]) -> bool { +fn match_ordering_def_path(cx: &LateContext<'_>, did: DefId, orderings: &[&str]) -> bool { orderings .iter() .any(|ordering| match_def_path(cx, did, &["core", "sync", "atomic", "Ordering", ordering])) } -fn check_atomic_load_store(cx: &LateContext<'_, '_>, expr: &Expr<'_>) { +fn check_atomic_load_store(cx: &LateContext<'_>, expr: &Expr<'_>) { if_chain! { if let ExprKind::MethodCall(ref method_path, _, args, _) = &expr.kind; let method = method_path.ident.name.as_str(); @@ -103,7 +103,7 @@ fn check_atomic_load_store(cx: &LateContext<'_, '_>, expr: &Expr<'_>) { } } -fn check_memory_fence(cx: &LateContext<'_, '_>, expr: &Expr<'_>) { +fn check_memory_fence(cx: &LateContext<'_>, expr: &Expr<'_>) { if_chain! { if let ExprKind::Call(ref func, ref args) = expr.kind; if let ExprKind::Path(ref func_qpath) = func.kind; @@ -127,8 +127,8 @@ fn check_memory_fence(cx: &LateContext<'_, '_>, expr: &Expr<'_>) { } } -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for AtomicOrdering { - fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) { +impl<'tcx> LateLintPass<'tcx> for AtomicOrdering { + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { check_atomic_load_store(cx, expr); check_memory_fence(cx, expr); } diff --git a/clippy_lints/src/attrs.rs b/clippy_lints/src/attrs.rs index 41f125d48398f..2505ff32fe523 100644 --- a/clippy_lints/src/attrs.rs +++ b/clippy_lints/src/attrs.rs @@ -251,8 +251,8 @@ declare_lint_pass!(Attributes => [ UNKNOWN_CLIPPY_LINTS, ]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Attributes { - fn check_attribute(&mut self, cx: &LateContext<'a, 'tcx>, attr: &'tcx Attribute) { +impl<'tcx> LateLintPass<'tcx> for Attributes { + fn check_attribute(&mut self, cx: &LateContext<'tcx>, attr: &'tcx Attribute) { if let Some(items) = &attr.meta_item_list() { if let Some(ident) = attr.ident() { match &*ident.as_str() { @@ -278,7 +278,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Attributes { } } - fn check_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx Item<'_>) { + fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) { if is_relevant_item(cx, item) { check_attrs(cx, item.span, item.ident.name, &item.attrs) } @@ -350,13 +350,13 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Attributes { } } - fn check_impl_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx ImplItem<'_>) { + fn check_impl_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx ImplItem<'_>) { if is_relevant_impl(cx, item) { check_attrs(cx, item.span, item.ident.name, &item.attrs) } } - fn check_trait_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx TraitItem<'_>) { + fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx TraitItem<'_>) { if is_relevant_trait(cx, item) { check_attrs(cx, item.span, item.ident.name, &item.attrs) } @@ -364,7 +364,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Attributes { } #[allow(clippy::single_match_else)] -fn check_clippy_lint_names(cx: &LateContext<'_, '_>, items: &[NestedMetaItem]) { +fn check_clippy_lint_names(cx: &LateContext<'_>, items: &[NestedMetaItem]) { let lint_store = cx.lints(); for lint in items { if_chain! { @@ -416,7 +416,7 @@ fn check_clippy_lint_names(cx: &LateContext<'_, '_>, items: &[NestedMetaItem]) { } } -fn is_relevant_item(cx: &LateContext<'_, '_>, item: &Item<'_>) -> bool { +fn is_relevant_item(cx: &LateContext<'_>, item: &Item<'_>) -> bool { if let ItemKind::Fn(_, _, eid) = item.kind { is_relevant_expr(cx, cx.tcx.body_tables(eid), &cx.tcx.hir().body(eid).value) } else { @@ -424,14 +424,14 @@ fn is_relevant_item(cx: &LateContext<'_, '_>, item: &Item<'_>) -> bool { } } -fn is_relevant_impl(cx: &LateContext<'_, '_>, item: &ImplItem<'_>) -> bool { +fn is_relevant_impl(cx: &LateContext<'_>, item: &ImplItem<'_>) -> bool { match item.kind { ImplItemKind::Fn(_, eid) => is_relevant_expr(cx, cx.tcx.body_tables(eid), &cx.tcx.hir().body(eid).value), _ => false, } } -fn is_relevant_trait(cx: &LateContext<'_, '_>, item: &TraitItem<'_>) -> bool { +fn is_relevant_trait(cx: &LateContext<'_>, item: &TraitItem<'_>) -> bool { match item.kind { TraitItemKind::Fn(_, TraitFn::Required(_)) => true, TraitItemKind::Fn(_, TraitFn::Provided(eid)) => { @@ -441,7 +441,7 @@ fn is_relevant_trait(cx: &LateContext<'_, '_>, item: &TraitItem<'_>) -> bool { } } -fn is_relevant_block(cx: &LateContext<'_, '_>, tables: &ty::TypeckTables<'_>, block: &Block<'_>) -> bool { +fn is_relevant_block(cx: &LateContext<'_>, tables: &ty::TypeckTables<'_>, block: &Block<'_>) -> bool { if let Some(stmt) = block.stmts.first() { match &stmt.kind { StmtKind::Local(_) => true, @@ -453,7 +453,7 @@ fn is_relevant_block(cx: &LateContext<'_, '_>, tables: &ty::TypeckTables<'_>, bl } } -fn is_relevant_expr(cx: &LateContext<'_, '_>, tables: &ty::TypeckTables<'_>, expr: &Expr<'_>) -> bool { +fn is_relevant_expr(cx: &LateContext<'_>, tables: &ty::TypeckTables<'_>, expr: &Expr<'_>) -> bool { match &expr.kind { ExprKind::Block(block, _) => is_relevant_block(cx, tables, block), ExprKind::Ret(Some(e)) => is_relevant_expr(cx, tables, e), @@ -473,7 +473,7 @@ fn is_relevant_expr(cx: &LateContext<'_, '_>, tables: &ty::TypeckTables<'_>, exp } } -fn check_attrs(cx: &LateContext<'_, '_>, span: Span, name: Name, attrs: &[Attribute]) { +fn check_attrs(cx: &LateContext<'_>, span: Span, name: Name, attrs: &[Attribute]) { if span.from_expansion() { return; } @@ -498,7 +498,7 @@ fn check_attrs(cx: &LateContext<'_, '_>, span: Span, name: Name, attrs: &[Attrib } } -fn check_semver(cx: &LateContext<'_, '_>, span: Span, lit: &Lit) { +fn check_semver(cx: &LateContext<'_>, span: Span, lit: &Lit) { if let LitKind::Str(is, _) = lit.kind { if Version::parse(&is.as_str()).is_ok() { return; diff --git a/clippy_lints/src/await_holding_lock.rs b/clippy_lints/src/await_holding_lock.rs index a88f922d8e03d..20b91bc0f1baf 100644 --- a/clippy_lints/src/await_holding_lock.rs +++ b/clippy_lints/src/await_holding_lock.rs @@ -51,8 +51,8 @@ declare_clippy_lint! { declare_lint_pass!(AwaitHoldingLock => [AWAIT_HOLDING_LOCK]); -impl LateLintPass<'_, '_> for AwaitHoldingLock { - fn check_body(&mut self, cx: &LateContext<'_, '_>, body: &'_ Body<'_>) { +impl LateLintPass<'_> for AwaitHoldingLock { + fn check_body(&mut self, cx: &LateContext<'_>, body: &'_ Body<'_>) { use AsyncGeneratorKind::{Block, Closure, Fn}; if let Some(GeneratorKind::Async(Block | Closure | Fn)) = body.generator_kind { let body_id = BodyId { @@ -65,7 +65,7 @@ impl LateLintPass<'_, '_> for AwaitHoldingLock { } } -fn check_interior_types(cx: &LateContext<'_, '_>, ty_causes: &[GeneratorInteriorTypeCause<'_>], span: Span) { +fn check_interior_types(cx: &LateContext<'_>, ty_causes: &[GeneratorInteriorTypeCause<'_>], span: Span) { for ty_cause in ty_causes { if let rustc_middle::ty::Adt(adt, _) = ty_cause.ty.kind { if is_mutex_guard(cx, adt.did) { @@ -82,7 +82,7 @@ fn check_interior_types(cx: &LateContext<'_, '_>, ty_causes: &[GeneratorInterior } } -fn is_mutex_guard(cx: &LateContext<'_, '_>, def_id: DefId) -> bool { +fn is_mutex_guard(cx: &LateContext<'_>, def_id: DefId) -> bool { match_def_path(cx, def_id, &paths::MUTEX_GUARD) || match_def_path(cx, def_id, &paths::RWLOCK_READ_GUARD) || match_def_path(cx, def_id, &paths::RWLOCK_WRITE_GUARD) diff --git a/clippy_lints/src/bit_mask.rs b/clippy_lints/src/bit_mask.rs index a53f3249b85b6..d1d177e7a4abb 100644 --- a/clippy_lints/src/bit_mask.rs +++ b/clippy_lints/src/bit_mask.rs @@ -110,8 +110,8 @@ impl BitMask { impl_lint_pass!(BitMask => [BAD_BIT_MASK, INEFFECTIVE_BIT_MASK, VERBOSE_BIT_MASK]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for BitMask { - fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr<'_>) { +impl<'tcx> LateLintPass<'tcx> for BitMask { + fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) { if let ExprKind::Binary(cmp, left, right) = &e.kind { if cmp.node.is_comparison() { if let Some(cmp_opt) = fetch_int_literal(cx, right) { @@ -164,7 +164,7 @@ fn invert_cmp(cmp: BinOpKind) -> BinOpKind { } } -fn check_compare(cx: &LateContext<'_, '_>, bit_op: &Expr<'_>, cmp_op: BinOpKind, cmp_value: u128, span: Span) { +fn check_compare(cx: &LateContext<'_>, bit_op: &Expr<'_>, cmp_op: BinOpKind, cmp_value: u128, span: Span) { if let ExprKind::Binary(op, left, right) = &bit_op.kind { if op.node != BinOpKind::BitAnd && op.node != BinOpKind::BitOr { return; @@ -177,7 +177,7 @@ fn check_compare(cx: &LateContext<'_, '_>, bit_op: &Expr<'_>, cmp_op: BinOpKind, #[allow(clippy::too_many_lines)] fn check_bit_mask( - cx: &LateContext<'_, '_>, + cx: &LateContext<'_>, bit_op: BinOpKind, cmp_op: BinOpKind, mask_value: u128, @@ -290,7 +290,7 @@ fn check_bit_mask( } } -fn check_ineffective_lt(cx: &LateContext<'_, '_>, span: Span, m: u128, c: u128, op: &str) { +fn check_ineffective_lt(cx: &LateContext<'_>, span: Span, m: u128, c: u128, op: &str) { if c.is_power_of_two() && m < c { span_lint( cx, @@ -304,7 +304,7 @@ fn check_ineffective_lt(cx: &LateContext<'_, '_>, span: Span, m: u128, c: u128, } } -fn check_ineffective_gt(cx: &LateContext<'_, '_>, span: Span, m: u128, c: u128, op: &str) { +fn check_ineffective_gt(cx: &LateContext<'_>, span: Span, m: u128, c: u128, op: &str) { if (c + 1).is_power_of_two() && m <= c { span_lint( cx, @@ -318,7 +318,7 @@ fn check_ineffective_gt(cx: &LateContext<'_, '_>, span: Span, m: u128, c: u128, } } -fn fetch_int_literal(cx: &LateContext<'_, '_>, lit: &Expr<'_>) -> Option { +fn fetch_int_literal(cx: &LateContext<'_>, lit: &Expr<'_>) -> Option { match constant(cx, cx.tables(), lit)?.0 { Constant::Int(n) => Some(n), _ => None, diff --git a/clippy_lints/src/blacklisted_name.rs b/clippy_lints/src/blacklisted_name.rs index 6f26f031431db..153870fb41658 100644 --- a/clippy_lints/src/blacklisted_name.rs +++ b/clippy_lints/src/blacklisted_name.rs @@ -35,8 +35,8 @@ impl BlacklistedName { impl_lint_pass!(BlacklistedName => [BLACKLISTED_NAME]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for BlacklistedName { - fn check_pat(&mut self, cx: &LateContext<'a, 'tcx>, pat: &'tcx Pat<'_>) { +impl<'tcx> LateLintPass<'tcx> for BlacklistedName { + fn check_pat(&mut self, cx: &LateContext<'tcx>, pat: &'tcx Pat<'_>) { if let PatKind::Binding(.., ident, _) = pat.kind { if self.blacklist.contains(&ident.name.to_string()) { span_lint( diff --git a/clippy_lints/src/blocks_in_if_conditions.rs b/clippy_lints/src/blocks_in_if_conditions.rs index 8fa9b05ca3297..1b73ced89b32b 100644 --- a/clippy_lints/src/blocks_in_if_conditions.rs +++ b/clippy_lints/src/blocks_in_if_conditions.rs @@ -45,7 +45,7 @@ declare_lint_pass!(BlocksInIfConditions => [BLOCKS_IN_IF_CONDITIONS]); struct ExVisitor<'a, 'tcx> { found_block: Option<&'tcx Expr<'tcx>>, - cx: &'a LateContext<'a, 'tcx>, + cx: &'a LateContext<'tcx>, } impl<'a, 'tcx> Visitor<'tcx> for ExVisitor<'a, 'tcx> { @@ -71,8 +71,8 @@ const BRACED_EXPR_MESSAGE: &str = "omit braces around single expression conditio const COMPLEX_BLOCK_MESSAGE: &str = "in an `if` condition, avoid complex blocks or closures with blocks; \ instead, move the block or closure higher and bind it with a `let`"; -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for BlocksInIfConditions { - fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) { +impl<'tcx> LateLintPass<'tcx> for BlocksInIfConditions { + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { if in_external_macro(cx.sess(), expr.span) { return; } diff --git a/clippy_lints/src/booleans.rs b/clippy_lints/src/booleans.rs index cc399a1f8a009..32d0979e99b60 100644 --- a/clippy_lints/src/booleans.rs +++ b/clippy_lints/src/booleans.rs @@ -55,10 +55,10 @@ const METHODS_WITH_NEGATION: [(&str, &str); 2] = [("is_some", "is_none"), ("is_e declare_lint_pass!(NonminimalBool => [NONMINIMAL_BOOL, LOGIC_BUG]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NonminimalBool { +impl<'tcx> LateLintPass<'tcx> for NonminimalBool { fn check_fn( &mut self, - cx: &LateContext<'a, 'tcx>, + cx: &LateContext<'tcx>, _: FnKind<'tcx>, _: &'tcx FnDecl<'_>, body: &'tcx Body<'_>, @@ -70,13 +70,13 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NonminimalBool { } struct NonminimalBoolVisitor<'a, 'tcx> { - cx: &'a LateContext<'a, 'tcx>, + cx: &'a LateContext<'tcx>, } use quine_mc_cluskey::Bool; struct Hir2Qmm<'a, 'tcx, 'v> { terminals: Vec<&'v Expr<'v>>, - cx: &'a LateContext<'a, 'tcx>, + cx: &'a LateContext<'tcx>, } impl<'a, 'tcx, 'v> Hir2Qmm<'a, 'tcx, 'v> { @@ -155,7 +155,7 @@ impl<'a, 'tcx, 'v> Hir2Qmm<'a, 'tcx, 'v> { struct SuggestContext<'a, 'tcx, 'v> { terminals: &'v [&'v Expr<'v>], - cx: &'a LateContext<'a, 'tcx>, + cx: &'a LateContext<'tcx>, output: String, } @@ -222,7 +222,7 @@ impl<'a, 'tcx, 'v> SuggestContext<'a, 'tcx, 'v> { } } -fn simplify_not(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> Option { +fn simplify_not(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option { match &expr.kind { ExprKind::Binary(binop, lhs, rhs) => { if !implements_ord(cx, lhs) { @@ -268,7 +268,7 @@ fn simplify_not(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> Option { } } -fn suggest(cx: &LateContext<'_, '_>, suggestion: &Bool, terminals: &[&Expr<'_>]) -> String { +fn suggest(cx: &LateContext<'_>, suggestion: &Bool, terminals: &[&Expr<'_>]) -> String { let mut suggest_context = SuggestContext { terminals, cx, @@ -464,13 +464,13 @@ impl<'a, 'tcx> Visitor<'tcx> for NonminimalBoolVisitor<'a, 'tcx> { } } -fn implements_ord<'a, 'tcx>(cx: &'a LateContext<'a, 'tcx>, expr: &Expr<'_>) -> bool { +fn implements_ord<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>) -> bool { let ty = cx.tables().expr_ty(expr); get_trait_def_id(cx, &paths::ORD).map_or(false, |id| implements_trait(cx, ty, id, &[])) } struct NotSimplificationVisitor<'a, 'tcx> { - cx: &'a LateContext<'a, 'tcx>, + cx: &'a LateContext<'tcx>, } impl<'a, 'tcx> Visitor<'tcx> for NotSimplificationVisitor<'a, 'tcx> { diff --git a/clippy_lints/src/bytecount.rs b/clippy_lints/src/bytecount.rs index c00bb23069bf4..1cdfea1f52655 100644 --- a/clippy_lints/src/bytecount.rs +++ b/clippy_lints/src/bytecount.rs @@ -35,8 +35,8 @@ declare_clippy_lint! { declare_lint_pass!(ByteCount => [NAIVE_BYTECOUNT]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ByteCount { - fn check_expr(&mut self, cx: &LateContext<'_, '_>, expr: &Expr<'_>) { +impl<'tcx> LateLintPass<'tcx> for ByteCount { + fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) { if_chain! { if let ExprKind::MethodCall(ref count, _, ref count_args, _) = expr.kind; if count.ident.name == sym!(count); diff --git a/clippy_lints/src/cargo_common_metadata.rs b/clippy_lints/src/cargo_common_metadata.rs index c40a387d29797..76a000157df03 100644 --- a/clippy_lints/src/cargo_common_metadata.rs +++ b/clippy_lints/src/cargo_common_metadata.rs @@ -36,7 +36,7 @@ declare_clippy_lint! { "common metadata is defined in `Cargo.toml`" } -fn missing_warning(cx: &LateContext<'_, '_>, package: &cargo_metadata::Package, field: &str) { +fn missing_warning(cx: &LateContext<'_>, package: &cargo_metadata::Package, field: &str) { let message = format!("package `{}` is missing `{}` metadata", package.name, field); span_lint(cx, CARGO_COMMON_METADATA, DUMMY_SP, &message); } @@ -56,8 +56,8 @@ fn is_empty_vec(value: &[String]) -> bool { declare_lint_pass!(CargoCommonMetadata => [CARGO_COMMON_METADATA]); -impl LateLintPass<'_, '_> for CargoCommonMetadata { - fn check_crate(&mut self, cx: &LateContext<'_, '_>, _: &Crate<'_>) { +impl LateLintPass<'_> for CargoCommonMetadata { + fn check_crate(&mut self, cx: &LateContext<'_>, _: &Crate<'_>) { if !run_lints(cx, &[CARGO_COMMON_METADATA], CRATE_HIR_ID) { return; } diff --git a/clippy_lints/src/checked_conversions.rs b/clippy_lints/src/checked_conversions.rs index 88145015ba8bd..841902943f002 100644 --- a/clippy_lints/src/checked_conversions.rs +++ b/clippy_lints/src/checked_conversions.rs @@ -41,8 +41,8 @@ declare_clippy_lint! { declare_lint_pass!(CheckedConversions => [CHECKED_CONVERSIONS]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for CheckedConversions { - fn check_expr(&mut self, cx: &LateContext<'_, '_>, item: &Expr<'_>) { +impl<'tcx> LateLintPass<'tcx> for CheckedConversions { + fn check_expr(&mut self, cx: &LateContext<'_>, item: &Expr<'_>) { let result = if_chain! { if !in_external_macro(cx.sess(), item.span); if let ExprKind::Binary(op, ref left, ref right) = &item.kind; @@ -83,7 +83,7 @@ fn single_check<'tcx>(expr: &'tcx Expr<'tcx>) -> Option> { } /// Searches for a combination of upper & lower bound checks -fn double_check<'a>(cx: &LateContext<'_, '_>, left: &'a Expr<'_>, right: &'a Expr<'_>) -> Option> { +fn double_check<'a>(cx: &LateContext<'_>, left: &'a Expr<'_>, right: &'a Expr<'_>) -> Option> { let upper_lower = |l, r| { let upper = check_upper_bound(l); let lower = check_lower_bound(r); @@ -112,7 +112,7 @@ enum ConversionType { impl<'a> Conversion<'a> { /// Combine multiple conversions if the are compatible - pub fn combine(self, other: Self, cx: &LateContext<'_, '_>) -> Option> { + pub fn combine(self, other: Self, cx: &LateContext<'_>) -> Option> { if self.is_compatible(&other, cx) { // Prefer a Conversion that contains a type-constraint Some(if self.to_type.is_some() { self } else { other }) @@ -123,7 +123,7 @@ impl<'a> Conversion<'a> { /// Checks if two conversions are compatible /// same type of conversion, same 'castee' and same 'to type' - pub fn is_compatible(&self, other: &Self, cx: &LateContext<'_, '_>) -> bool { + pub fn is_compatible(&self, other: &Self, cx: &LateContext<'_>) -> bool { (self.cvt == other.cvt) && (SpanlessEq::new(cx).eq_expr(self.expr_to_cast, other.expr_to_cast)) && (self.has_compatible_to_type(other)) diff --git a/clippy_lints/src/cognitive_complexity.rs b/clippy_lints/src/cognitive_complexity.rs index 78e509d2ecd83..6bbdbe957cc83 100644 --- a/clippy_lints/src/cognitive_complexity.rs +++ b/clippy_lints/src/cognitive_complexity.rs @@ -43,9 +43,9 @@ impl_lint_pass!(CognitiveComplexity => [COGNITIVE_COMPLEXITY]); impl CognitiveComplexity { #[allow(clippy::cast_possible_truncation)] - fn check<'a, 'tcx>( + fn check<'tcx>( &mut self, - cx: &'a LateContext<'a, 'tcx>, + cx: &LateContext<'tcx>, kind: FnKind<'tcx>, decl: &'tcx FnDecl<'_>, body: &'tcx Body<'_>, @@ -112,10 +112,10 @@ impl CognitiveComplexity { } } -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for CognitiveComplexity { +impl<'tcx> LateLintPass<'tcx> for CognitiveComplexity { fn check_fn( &mut self, - cx: &LateContext<'a, 'tcx>, + cx: &LateContext<'tcx>, kind: FnKind<'tcx>, decl: &'tcx FnDecl<'_>, body: &'tcx Body<'_>, @@ -128,10 +128,10 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for CognitiveComplexity { } } - fn enter_lint_attrs(&mut self, cx: &LateContext<'a, 'tcx>, attrs: &'tcx [Attribute]) { + fn enter_lint_attrs(&mut self, cx: &LateContext<'tcx>, attrs: &'tcx [Attribute]) { self.limit.push_attrs(cx.sess(), attrs, "cognitive_complexity"); } - fn exit_lint_attrs(&mut self, cx: &LateContext<'a, 'tcx>, attrs: &'tcx [Attribute]) { + fn exit_lint_attrs(&mut self, cx: &LateContext<'tcx>, attrs: &'tcx [Attribute]) { self.limit.pop_attrs(cx.sess(), attrs, "cognitive_complexity"); } } diff --git a/clippy_lints/src/comparison_chain.rs b/clippy_lints/src/comparison_chain.rs index 9c0d33f928015..26476af4cb629 100644 --- a/clippy_lints/src/comparison_chain.rs +++ b/clippy_lints/src/comparison_chain.rs @@ -52,8 +52,8 @@ declare_clippy_lint! { declare_lint_pass!(ComparisonChain => [COMPARISON_CHAIN]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ComparisonChain { - fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) { +impl<'tcx> LateLintPass<'tcx> for ComparisonChain { + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { if expr.span.from_expansion() { return; } diff --git a/clippy_lints/src/consts.rs b/clippy_lints/src/consts.rs index 550752396c732..2f963dfcf8b18 100644 --- a/clippy_lints/src/consts.rs +++ b/clippy_lints/src/consts.rs @@ -172,9 +172,9 @@ pub fn lit_to_constant(lit: &LitKind, ty: Option>) -> Constant { } } -pub fn constant<'c, 'cc>( - lcx: &LateContext<'c, 'cc>, - tables: &'c ty::TypeckTables<'cc>, +pub fn constant<'tcx>( + lcx: &LateContext<'tcx>, + tables: &ty::TypeckTables<'tcx>, e: &Expr<'_>, ) -> Option<(Constant, bool)> { let mut cx = ConstEvalLateContext { @@ -187,19 +187,19 @@ pub fn constant<'c, 'cc>( cx.expr(e).map(|cst| (cst, cx.needed_resolution)) } -pub fn constant_simple<'c, 'cc>( - lcx: &LateContext<'c, 'cc>, - tables: &'c ty::TypeckTables<'cc>, +pub fn constant_simple<'tcx>( + lcx: &LateContext<'tcx>, + tables: &ty::TypeckTables<'tcx>, e: &Expr<'_>, ) -> Option { constant(lcx, tables, e).and_then(|(cst, res)| if res { None } else { Some(cst) }) } /// Creates a `ConstEvalLateContext` from the given `LateContext` and `TypeckTables`. -pub fn constant_context<'c, 'cc>( - lcx: &'c LateContext<'c, 'cc>, - tables: &'c ty::TypeckTables<'cc>, -) -> ConstEvalLateContext<'c, 'cc> { +pub fn constant_context<'a, 'tcx>( + lcx: &'a LateContext<'tcx>, + tables: &'a ty::TypeckTables<'tcx>, +) -> ConstEvalLateContext<'a, 'tcx> { ConstEvalLateContext { lcx, tables, @@ -210,14 +210,14 @@ pub fn constant_context<'c, 'cc>( } pub struct ConstEvalLateContext<'a, 'tcx> { - lcx: &'a LateContext<'a, 'tcx>, + lcx: &'a LateContext<'tcx>, tables: &'a ty::TypeckTables<'tcx>, param_env: ty::ParamEnv<'tcx>, needed_resolution: bool, substs: SubstsRef<'tcx>, } -impl<'c, 'cc> ConstEvalLateContext<'c, 'cc> { +impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> { /// Simple constant folding: Insert an expression, get a constant or none. pub fn expr(&mut self, e: &Expr<'_>) -> Option { if let Some((ref cond, ref then, otherwise)) = higher::if_block(&e) { @@ -318,7 +318,7 @@ impl<'c, 'cc> ConstEvalLateContext<'c, 'cc> { } /// Lookup a possibly constant expression from a `ExprKind::Path`. - fn fetch_path(&mut self, qpath: &QPath<'_>, id: HirId, ty: Ty<'cc>) -> Option { + fn fetch_path(&mut self, qpath: &QPath<'_>, id: HirId, ty: Ty<'tcx>) -> Option { let res = self.tables.qpath_res(qpath, id); match res { Res::Def(DefKind::Const | DefKind::AssocConst, def_id) => { diff --git a/clippy_lints/src/copies.rs b/clippy_lints/src/copies.rs index 8cc69c806aa99..1257032337acc 100644 --- a/clippy_lints/src/copies.rs +++ b/clippy_lints/src/copies.rs @@ -151,8 +151,8 @@ declare_clippy_lint! { declare_lint_pass!(CopyAndPaste => [IFS_SAME_COND, SAME_FUNCTIONS_IN_IF_CONDITION, IF_SAME_THEN_ELSE, MATCH_SAME_ARMS]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for CopyAndPaste { - fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) { +impl<'tcx> LateLintPass<'tcx> for CopyAndPaste { + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { 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) { @@ -173,7 +173,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for CopyAndPaste { } /// Implementation of `IF_SAME_THEN_ELSE`. -fn lint_same_then_else(cx: &LateContext<'_, '_>, blocks: &[&Block<'_>]) { +fn lint_same_then_else(cx: &LateContext<'_>, blocks: &[&Block<'_>]) { let eq: &dyn Fn(&&Block<'_>, &&Block<'_>) -> bool = &|&lhs, &rhs| -> bool { SpanlessEq::new(cx).eq_block(lhs, rhs) }; @@ -190,7 +190,7 @@ fn lint_same_then_else(cx: &LateContext<'_, '_>, blocks: &[&Block<'_>]) { } /// Implementation of `IFS_SAME_COND`. -fn lint_same_cond(cx: &LateContext<'_, '_>, conds: &[&Expr<'_>]) { +fn lint_same_cond(cx: &LateContext<'_>, conds: &[&Expr<'_>]) { let hash: &dyn Fn(&&Expr<'_>) -> u64 = &|expr| -> u64 { let mut h = SpanlessHash::new(cx); h.hash_expr(expr); @@ -213,7 +213,7 @@ fn lint_same_cond(cx: &LateContext<'_, '_>, conds: &[&Expr<'_>]) { } /// Implementation of `SAME_FUNCTIONS_IN_IF_CONDITION`. -fn lint_same_fns_in_if_cond(cx: &LateContext<'_, '_>, conds: &[&Expr<'_>]) { +fn lint_same_fns_in_if_cond(cx: &LateContext<'_>, conds: &[&Expr<'_>]) { let hash: &dyn Fn(&&Expr<'_>) -> u64 = &|expr| -> u64 { let mut h = SpanlessHash::new(cx); h.hash_expr(expr); @@ -241,7 +241,7 @@ fn lint_same_fns_in_if_cond(cx: &LateContext<'_, '_>, conds: &[&Expr<'_>]) { } /// Implementation of `MATCH_SAME_ARMS`. -fn lint_match_arms<'tcx>(cx: &LateContext<'_, 'tcx>, expr: &Expr<'_>) { +fn lint_match_arms<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>) { fn same_bindings<'tcx>(lhs: &FxHashMap>, rhs: &FxHashMap>) -> bool { lhs.len() == rhs.len() && lhs @@ -309,8 +309,8 @@ fn lint_match_arms<'tcx>(cx: &LateContext<'_, 'tcx>, expr: &Expr<'_>) { } /// Returns the list of bindings in a pattern. -fn bindings<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, pat: &Pat<'_>) -> FxHashMap> { - fn bindings_impl<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, pat: &Pat<'_>, map: &mut FxHashMap>) { +fn bindings<'tcx>(cx: &LateContext<'tcx>, pat: &Pat<'_>) -> FxHashMap> { + fn bindings_impl<'tcx>(cx: &LateContext<'tcx>, pat: &Pat<'_>, map: &mut FxHashMap>) { match pat.kind { PatKind::Box(ref pat) | PatKind::Ref(ref pat, _) => bindings_impl(cx, pat, map), PatKind::TupleStruct(_, pats, _) => { diff --git a/clippy_lints/src/copy_iterator.rs b/clippy_lints/src/copy_iterator.rs index d79aa2ef0209e..349402453226a 100644 --- a/clippy_lints/src/copy_iterator.rs +++ b/clippy_lints/src/copy_iterator.rs @@ -31,8 +31,8 @@ declare_clippy_lint! { declare_lint_pass!(CopyIterator => [COPY_ITERATOR]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for CopyIterator { - fn check_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx Item<'_>) { +impl<'tcx> LateLintPass<'tcx> for CopyIterator { + fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) { if let ItemKind::Impl { of_trait: Some(ref trait_ref), .. diff --git a/clippy_lints/src/default_trait_access.rs b/clippy_lints/src/default_trait_access.rs index a918c72fb275e..fab95db019604 100644 --- a/clippy_lints/src/default_trait_access.rs +++ b/clippy_lints/src/default_trait_access.rs @@ -30,8 +30,8 @@ declare_clippy_lint! { declare_lint_pass!(DefaultTraitAccess => [DEFAULT_TRAIT_ACCESS]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for DefaultTraitAccess { - fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) { +impl<'tcx> LateLintPass<'tcx> for DefaultTraitAccess { + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { if_chain! { if let ExprKind::Call(ref path, ..) = expr.kind; if !any_parent_is_automatically_derived(cx.tcx, expr.hir_id); diff --git a/clippy_lints/src/dereference.rs b/clippy_lints/src/dereference.rs index 1c6cc93690096..d740d88a77d6c 100644 --- a/clippy_lints/src/dereference.rs +++ b/clippy_lints/src/dereference.rs @@ -38,8 +38,8 @@ declare_lint_pass!(Dereferencing => [ EXPLICIT_DEREF_METHODS ]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Dereferencing { - fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) { +impl<'tcx> LateLintPass<'tcx> for Dereferencing { + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { if_chain! { if !expr.span.from_expansion(); if let ExprKind::MethodCall(ref method_name, _, ref args, _) = &expr.kind; @@ -70,7 +70,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Dereferencing { } } -fn lint_deref(cx: &LateContext<'_, '_>, method_name: &str, call_expr: &Expr<'_>, var_span: Span, expr_span: Span) { +fn lint_deref(cx: &LateContext<'_>, method_name: &str, call_expr: &Expr<'_>, var_span: Span, expr_span: Span) { match method_name { "deref" => { if cx.tcx.lang_items().deref_trait().map_or(false, |id| { diff --git a/clippy_lints/src/derive.rs b/clippy_lints/src/derive.rs index 3cbb8fa72f74f..59c62f1ae9440 100644 --- a/clippy_lints/src/derive.rs +++ b/clippy_lints/src/derive.rs @@ -105,8 +105,8 @@ declare_clippy_lint! { declare_lint_pass!(Derive => [EXPL_IMPL_CLONE_ON_COPY, DERIVE_HASH_XOR_EQ, UNSAFE_DERIVE_DESERIALIZE]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Derive { - fn check_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx Item<'_>) { +impl<'tcx> LateLintPass<'tcx> for Derive { + fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) { if let ItemKind::Impl { of_trait: Some(ref trait_ref), .. @@ -127,8 +127,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Derive { } /// Implementation of the `DERIVE_HASH_XOR_EQ` lint. -fn check_hash_peq<'a, 'tcx>( - cx: &LateContext<'a, 'tcx>, +fn check_hash_peq<'tcx>( + cx: &LateContext<'tcx>, span: Span, trait_ref: &TraitRef<'_>, ty: Ty<'tcx>, @@ -181,7 +181,7 @@ fn check_hash_peq<'a, 'tcx>( } /// Implementation of the `EXPL_IMPL_CLONE_ON_COPY` lint. -fn check_copy_clone<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, item: &Item<'_>, trait_ref: &TraitRef<'_>, ty: Ty<'tcx>) { +fn check_copy_clone<'tcx>(cx: &LateContext<'tcx>, item: &Item<'_>, trait_ref: &TraitRef<'_>, ty: Ty<'tcx>) { if match_path(&trait_ref.path, &paths::CLONE_TRAIT) { if !is_copy(cx, ty) { return; @@ -222,18 +222,18 @@ fn check_copy_clone<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, item: &Item<'_>, trait } /// Implementation of the `UNSAFE_DERIVE_DESERIALIZE` lint. -fn check_unsafe_derive_deserialize<'a, 'tcx>( - cx: &LateContext<'a, 'tcx>, +fn check_unsafe_derive_deserialize<'tcx>( + cx: &LateContext<'tcx>, item: &Item<'_>, trait_ref: &TraitRef<'_>, ty: Ty<'tcx>, ) { - fn item_from_def_id<'tcx>(cx: &LateContext<'_, 'tcx>, def_id: DefId) -> &'tcx Item<'tcx> { + fn item_from_def_id<'tcx>(cx: &LateContext<'tcx>, def_id: DefId) -> &'tcx Item<'tcx> { let hir_id = cx.tcx.hir().as_local_hir_id(def_id.expect_local()); cx.tcx.hir().expect_item(hir_id) } - fn has_unsafe<'tcx>(cx: &LateContext<'_, 'tcx>, item: &'tcx Item<'_>) -> bool { + fn has_unsafe<'tcx>(cx: &LateContext<'tcx>, item: &'tcx Item<'_>) -> bool { let mut visitor = UnsafeVisitor { cx, has_unsafe: false }; walk_item(&mut visitor, item); visitor.has_unsafe @@ -261,7 +261,7 @@ fn check_unsafe_derive_deserialize<'a, 'tcx>( } struct UnsafeVisitor<'a, 'tcx> { - cx: &'a LateContext<'a, 'tcx>, + cx: &'a LateContext<'tcx>, has_unsafe: bool, } diff --git a/clippy_lints/src/doc.rs b/clippy_lints/src/doc.rs index 8d1e91f9adbd6..d52bb8961fae7 100644 --- a/clippy_lints/src/doc.rs +++ b/clippy_lints/src/doc.rs @@ -146,12 +146,12 @@ impl DocMarkdown { impl_lint_pass!(DocMarkdown => [DOC_MARKDOWN, MISSING_SAFETY_DOC, MISSING_ERRORS_DOC, NEEDLESS_DOCTEST_MAIN]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for DocMarkdown { - fn check_crate(&mut self, cx: &LateContext<'a, 'tcx>, krate: &'tcx hir::Crate<'_>) { +impl<'tcx> LateLintPass<'tcx> for DocMarkdown { + fn check_crate(&mut self, cx: &LateContext<'tcx>, krate: &'tcx hir::Crate<'_>) { check_attrs(cx, &self.valid_idents, &krate.item.attrs); } - fn check_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx hir::Item<'_>) { + fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>) { let headers = check_attrs(cx, &self.valid_idents, &item.attrs); match item.kind { hir::ItemKind::Fn(ref sig, _, body_id) => { @@ -171,13 +171,13 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for DocMarkdown { } } - fn check_item_post(&mut self, _cx: &LateContext<'a, 'tcx>, item: &'tcx hir::Item<'_>) { + fn check_item_post(&mut self, _cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>) { if let hir::ItemKind::Impl { .. } = item.kind { self.in_trait_impl = false; } } - fn check_trait_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx hir::TraitItem<'_>) { + fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::TraitItem<'_>) { let headers = check_attrs(cx, &self.valid_idents, &item.attrs); if let hir::TraitItemKind::Fn(ref sig, ..) = item.kind { if !in_external_macro(cx.tcx.sess, item.span) { @@ -186,7 +186,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for DocMarkdown { } } - fn check_impl_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx hir::ImplItem<'_>) { + fn check_impl_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::ImplItem<'_>) { let headers = check_attrs(cx, &self.valid_idents, &item.attrs); if self.in_trait_impl || in_external_macro(cx.tcx.sess, item.span) { return; @@ -197,8 +197,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for DocMarkdown { } } -fn lint_for_missing_headers<'a, 'tcx>( - cx: &LateContext<'a, 'tcx>, +fn lint_for_missing_headers<'tcx>( + cx: &LateContext<'tcx>, hir_id: hir::HirId, span: impl Into + Copy, sig: &hir::FnSig<'_>, @@ -313,7 +313,7 @@ struct DocHeaders { errors: bool, } -fn check_attrs<'a>(cx: &LateContext<'_, '_>, valid_idents: &FxHashSet, attrs: &'a [Attribute]) -> DocHeaders { +fn check_attrs<'a>(cx: &LateContext<'_>, valid_idents: &FxHashSet, attrs: &'a [Attribute]) -> DocHeaders { let mut doc = String::new(); let mut spans = vec![]; @@ -370,7 +370,7 @@ fn check_attrs<'a>(cx: &LateContext<'_, '_>, valid_idents: &FxHashSet, a const RUST_CODE: &[&str] = &["rust", "no_run", "should_panic", "compile_fail", "edition2018"]; fn check_doc<'a, Events: Iterator, Range)>>( - cx: &LateContext<'_, '_>, + cx: &LateContext<'_>, valid_idents: &FxHashSet, events: Events, spans: &[(usize, Span)], @@ -442,13 +442,13 @@ fn check_doc<'a, Events: Iterator, Range, text: &str, span: Span) { +fn check_code(cx: &LateContext<'_>, text: &str, span: Span) { if text.contains("fn main() {") && !LEAVE_MAIN_PATTERNS.iter().any(|p| text.contains(p)) { span_lint(cx, NEEDLESS_DOCTEST_MAIN, span, "needless `fn main` in doctest"); } } -fn check_text(cx: &LateContext<'_, '_>, valid_idents: &FxHashSet, text: &str, span: Span) { +fn check_text(cx: &LateContext<'_>, valid_idents: &FxHashSet, text: &str, span: Span) { for word in text.split(|c: char| c.is_whitespace() || c == '\'') { // Trim punctuation as in `some comment (see foo::bar).` // ^^ @@ -471,7 +471,7 @@ fn check_text(cx: &LateContext<'_, '_>, valid_idents: &FxHashSet, text: } } -fn check_word(cx: &LateContext<'_, '_>, word: &str, span: Span) { +fn check_word(cx: &LateContext<'_>, word: &str, span: Span) { /// Checks if a string is camel-case, i.e., contains at least two uppercase /// letters (`Clippy` is ok) and one lower-case letter (`NASA` is ok). /// Plurals are also excluded (`IDs` is ok). diff --git a/clippy_lints/src/double_comparison.rs b/clippy_lints/src/double_comparison.rs index 44f85d1ea6e19..5d16192b7543b 100644 --- a/clippy_lints/src/double_comparison.rs +++ b/clippy_lints/src/double_comparison.rs @@ -37,9 +37,9 @@ declare_clippy_lint! { declare_lint_pass!(DoubleComparisons => [DOUBLE_COMPARISONS]); -impl<'a, 'tcx> DoubleComparisons { +impl<'tcx> DoubleComparisons { #[allow(clippy::similar_names)] - fn check_binop(cx: &LateContext<'a, 'tcx>, op: BinOpKind, lhs: &'tcx Expr<'_>, rhs: &'tcx Expr<'_>, span: Span) { + fn check_binop(cx: &LateContext<'tcx>, op: BinOpKind, lhs: &'tcx Expr<'_>, rhs: &'tcx Expr<'_>, span: Span) { let (lkind, llhs, lrhs, rkind, rlhs, rrhs) = match (&lhs.kind, &rhs.kind) { (ExprKind::Binary(lb, llhs, lrhs), ExprKind::Binary(rb, rlhs, rrhs)) => { (lb.node, llhs, lrhs, rb.node, rlhs, rrhs) @@ -86,8 +86,8 @@ impl<'a, 'tcx> DoubleComparisons { } } -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for DoubleComparisons { - fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) { +impl<'tcx> LateLintPass<'tcx> for DoubleComparisons { + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { if let ExprKind::Binary(ref kind, ref lhs, ref rhs) = expr.kind { Self::check_binop(cx, kind.node, lhs, rhs, expr.span); } diff --git a/clippy_lints/src/drop_bounds.rs b/clippy_lints/src/drop_bounds.rs index 5a7f759486edd..4afbd1ed0e59b 100644 --- a/clippy_lints/src/drop_bounds.rs +++ b/clippy_lints/src/drop_bounds.rs @@ -1,7 +1,7 @@ use crate::utils::{match_def_path, paths, span_lint}; use if_chain::if_chain; use rustc_hir::{GenericBound, GenericParam, WhereBoundPredicate, WherePredicate}; -use rustc_lint::LateLintPass; +use rustc_lint::{LateContext, LateLintPass}; use rustc_session::{declare_lint_pass, declare_tool_lint}; declare_clippy_lint! { @@ -41,13 +41,13 @@ const DROP_BOUNDS_SUMMARY: &str = "Bounds of the form `T: Drop` are useless. \ declare_lint_pass!(DropBounds => [DROP_BOUNDS]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for DropBounds { - fn check_generic_param(&mut self, cx: &rustc_lint::LateContext<'a, 'tcx>, p: &'tcx GenericParam<'_>) { +impl<'tcx> LateLintPass<'tcx> for DropBounds { + fn check_generic_param(&mut self, cx: &LateContext<'tcx>, p: &'tcx GenericParam<'_>) { for bound in p.bounds.iter() { lint_bound(cx, bound); } } - fn check_where_predicate(&mut self, cx: &rustc_lint::LateContext<'a, 'tcx>, p: &'tcx WherePredicate<'_>) { + fn check_where_predicate(&mut self, cx: &LateContext<'tcx>, p: &'tcx WherePredicate<'_>) { if let WherePredicate::BoundPredicate(WhereBoundPredicate { bounds, .. }) = p { for bound in *bounds { lint_bound(cx, bound); @@ -56,7 +56,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for DropBounds { } } -fn lint_bound<'a, 'tcx>(cx: &rustc_lint::LateContext<'a, 'tcx>, bound: &'tcx GenericBound<'_>) { +fn lint_bound<'tcx>(cx: &LateContext<'tcx>, bound: &'tcx GenericBound<'_>) { if_chain! { if let GenericBound::Trait(t, _) = bound; if let Some(def_id) = t.trait_ref.path.res.opt_def_id(); diff --git a/clippy_lints/src/drop_forget_ref.rs b/clippy_lints/src/drop_forget_ref.rs index 014873eb13255..dcf772572e8cb 100644 --- a/clippy_lints/src/drop_forget_ref.rs +++ b/clippy_lints/src/drop_forget_ref.rs @@ -108,8 +108,8 @@ const FORGET_COPY_SUMMARY: &str = "calls to `std::mem::forget` with a value that declare_lint_pass!(DropForgetRef => [DROP_REF, FORGET_REF, DROP_COPY, FORGET_COPY]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for DropForgetRef { - fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) { +impl<'tcx> LateLintPass<'tcx> for DropForgetRef { + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { if_chain! { if let ExprKind::Call(ref path, ref args) = expr.kind; if let ExprKind::Path(ref qpath) = path.kind; diff --git a/clippy_lints/src/duration_subsec.rs b/clippy_lints/src/duration_subsec.rs index 5eb320ceca247..2ded375091c60 100644 --- a/clippy_lints/src/duration_subsec.rs +++ b/clippy_lints/src/duration_subsec.rs @@ -38,8 +38,8 @@ declare_clippy_lint! { declare_lint_pass!(DurationSubsec => [DURATION_SUBSEC]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for DurationSubsec { - fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) { +impl<'tcx> LateLintPass<'tcx> for DurationSubsec { + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { if_chain! { if let ExprKind::Binary(Spanned { node: BinOpKind::Div, .. }, ref left, ref right) = expr.kind; if let ExprKind::MethodCall(ref method_path, _ , ref args, _) = left.kind; diff --git a/clippy_lints/src/empty_enum.rs b/clippy_lints/src/empty_enum.rs index 3bfef6f4bed12..a249117d182fa 100644 --- a/clippy_lints/src/empty_enum.rs +++ b/clippy_lints/src/empty_enum.rs @@ -38,8 +38,8 @@ declare_clippy_lint! { declare_lint_pass!(EmptyEnum => [EMPTY_ENUM]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for EmptyEnum { - fn check_item(&mut self, cx: &LateContext<'_, '_>, item: &Item<'_>) { +impl<'tcx> LateLintPass<'tcx> for EmptyEnum { + fn check_item(&mut self, cx: &LateContext<'_>, item: &Item<'_>) { let did = cx.tcx.hir().local_def_id(item.hir_id); if let ItemKind::Enum(..) = item.kind { let ty = cx.tcx.type_of(did); diff --git a/clippy_lints/src/entry.rs b/clippy_lints/src/entry.rs index e37e23b8944d7..4d2e17933ed6b 100644 --- a/clippy_lints/src/entry.rs +++ b/clippy_lints/src/entry.rs @@ -52,8 +52,8 @@ declare_clippy_lint! { declare_lint_pass!(HashMapPass => [MAP_ENTRY]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for HashMapPass { - fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) { +impl<'tcx> LateLintPass<'tcx> for HashMapPass { + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { if let Some((ref check, ref then_block, ref else_block)) = higher::if_block(&expr) { if let ExprKind::Unary(UnOp::UnNot, ref check) = check.kind { if let Some((ty, map, key)) = check_cond(cx, check) { @@ -98,10 +98,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for HashMapPass { } } -fn check_cond<'a, 'tcx, 'b>( - cx: &'a LateContext<'a, 'tcx>, - check: &'b Expr<'b>, -) -> Option<(&'static str, &'b Expr<'b>, &'b Expr<'b>)> { +fn check_cond<'a>(cx: &LateContext<'_>, check: &'a Expr<'a>) -> Option<(&'static str, &'a Expr<'a>, &'a Expr<'a>)> { if_chain! { if let ExprKind::MethodCall(ref path, _, ref params, _) = check.kind; if params.len() >= 2; @@ -127,7 +124,7 @@ fn check_cond<'a, 'tcx, 'b>( } struct InsertVisitor<'a, 'tcx, 'b> { - cx: &'a LateContext<'a, 'tcx>, + cx: &'a LateContext<'tcx>, span: Span, ty: &'static str, map: &'b Expr<'b>, diff --git a/clippy_lints/src/enum_clike.rs b/clippy_lints/src/enum_clike.rs index 12b62f5cf9789..91214f277be69 100644 --- a/clippy_lints/src/enum_clike.rs +++ b/clippy_lints/src/enum_clike.rs @@ -36,9 +36,9 @@ declare_clippy_lint! { declare_lint_pass!(UnportableVariant => [ENUM_CLIKE_UNPORTABLE_VARIANT]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnportableVariant { +impl<'tcx> LateLintPass<'tcx> for UnportableVariant { #[allow(clippy::cast_possible_truncation, clippy::cast_possible_wrap, clippy::cast_sign_loss)] - fn check_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx Item<'_>) { + fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) { if cx.tcx.data_layout.pointer_size.bits() != 64 { return; } diff --git a/clippy_lints/src/eq_op.rs b/clippy_lints/src/eq_op.rs index 98757624a13b5..ca921dcfdfe92 100644 --- a/clippy_lints/src/eq_op.rs +++ b/clippy_lints/src/eq_op.rs @@ -52,9 +52,9 @@ declare_clippy_lint! { declare_lint_pass!(EqOp => [EQ_OP, OP_REF]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for EqOp { +impl<'tcx> LateLintPass<'tcx> for EqOp { #[allow(clippy::similar_names, clippy::too_many_lines)] - fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr<'_>) { + fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) { if let ExprKind::Binary(op, ref left, ref right) = e.kind { if e.span.from_expansion() { return; diff --git a/clippy_lints/src/erasing_op.rs b/clippy_lints/src/erasing_op.rs index 804a9c1904b73..8a26838061826 100644 --- a/clippy_lints/src/erasing_op.rs +++ b/clippy_lints/src/erasing_op.rs @@ -29,8 +29,8 @@ declare_clippy_lint! { 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<'_>) { +impl<'tcx> LateLintPass<'tcx> for ErasingOp { + fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) { if e.span.from_expansion() { return; } @@ -47,7 +47,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ErasingOp { } } -fn check(cx: &LateContext<'_, '_>, e: &Expr<'_>, span: Span) { +fn check(cx: &LateContext<'_>, e: &Expr<'_>, span: Span) { if let Some(Constant::Int(0)) = constant_simple(cx, cx.tables(), e) { span_lint( cx, diff --git a/clippy_lints/src/escape.rs b/clippy_lints/src/escape.rs index bb74f193a48e7..d40cdfcca9f66 100644 --- a/clippy_lints/src/escape.rs +++ b/clippy_lints/src/escape.rs @@ -49,17 +49,17 @@ fn is_non_trait_box(ty: Ty<'_>) -> bool { } struct EscapeDelegate<'a, 'tcx> { - cx: &'a LateContext<'a, 'tcx>, + cx: &'a LateContext<'tcx>, set: HirIdSet, too_large_for_stack: u64, } impl_lint_pass!(BoxedLocal => [BOXED_LOCAL]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for BoxedLocal { +impl<'tcx> LateLintPass<'tcx> for BoxedLocal { fn check_fn( &mut self, - cx: &LateContext<'a, 'tcx>, + cx: &LateContext<'tcx>, _: intravisit::FnKind<'tcx>, _: &'tcx FnDecl<'_>, body: &'tcx Body<'_>, diff --git a/clippy_lints/src/eta_reduction.rs b/clippy_lints/src/eta_reduction.rs index 0ac8b95de8d61..ceed6a74c4fcc 100644 --- a/clippy_lints/src/eta_reduction.rs +++ b/clippy_lints/src/eta_reduction.rs @@ -64,8 +64,8 @@ declare_clippy_lint! { declare_lint_pass!(EtaReduction => [REDUNDANT_CLOSURE, REDUNDANT_CLOSURE_FOR_METHOD_CALLS]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for EtaReduction { - fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) { +impl<'tcx> LateLintPass<'tcx> for EtaReduction { + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { if in_external_macro(cx.sess(), expr.span) { return; } @@ -81,7 +81,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for EtaReduction { } } -fn check_closure(cx: &LateContext<'_, '_>, expr: &Expr<'_>) { +fn check_closure(cx: &LateContext<'_>, expr: &Expr<'_>) { if let ExprKind::Closure(_, ref decl, eid, _, _) = expr.kind { let body = cx.tcx.hir().body(eid); let ex = &body.value; @@ -151,7 +151,7 @@ fn check_closure(cx: &LateContext<'_, '_>, expr: &Expr<'_>) { } /// Tries to determine the type for universal function call to be used instead of the closure -fn get_ufcs_type_name(cx: &LateContext<'_, '_>, method_def_id: def_id::DefId, self_arg: &Expr<'_>) -> Option { +fn get_ufcs_type_name(cx: &LateContext<'_>, method_def_id: def_id::DefId, self_arg: &Expr<'_>) -> Option { let expected_type_of_self = &cx.tcx.fn_sig(method_def_id).inputs_and_output().skip_binder()[0]; let actual_type_of_self = &cx.tables().node_type(self_arg.hir_id); @@ -196,7 +196,7 @@ fn match_types(lhs: Ty<'_>, rhs: Ty<'_>) -> bool { } } -fn get_type_name(cx: &LateContext<'_, '_>, ty: Ty<'_>) -> String { +fn get_type_name(cx: &LateContext<'_>, ty: Ty<'_>) -> String { match ty.kind { ty::Adt(t, _) => cx.tcx.def_path_str(t.did), ty::Ref(_, r, _) => get_type_name(cx, &r), diff --git a/clippy_lints/src/eval_order_dependence.rs b/clippy_lints/src/eval_order_dependence.rs index 31fe7382e46de..01b0d3c5edec2 100644 --- a/clippy_lints/src/eval_order_dependence.rs +++ b/clippy_lints/src/eval_order_dependence.rs @@ -67,8 +67,8 @@ declare_clippy_lint! { declare_lint_pass!(EvalOrderDependence => [EVAL_ORDER_DEPENDENCE, DIVERGING_SUB_EXPRESSION]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for EvalOrderDependence { - fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) { +impl<'tcx> LateLintPass<'tcx> for EvalOrderDependence { + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { // Find a write to a local variable. match expr.kind { ExprKind::Assign(ref lhs, ..) | ExprKind::AssignOp(_, ref lhs, _) => { @@ -91,7 +91,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for EvalOrderDependence { _ => {}, } } - fn check_stmt(&mut self, cx: &LateContext<'a, 'tcx>, stmt: &'tcx Stmt<'_>) { + fn check_stmt(&mut self, cx: &LateContext<'tcx>, stmt: &'tcx Stmt<'_>) { match stmt.kind { StmtKind::Local(ref local) => { if let Local { init: Some(ref e), .. } = **local { @@ -105,7 +105,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for EvalOrderDependence { } struct DivergenceVisitor<'a, 'tcx> { - cx: &'a LateContext<'a, 'tcx>, + cx: &'a LateContext<'tcx>, } impl<'a, 'tcx> DivergenceVisitor<'a, 'tcx> { @@ -285,7 +285,7 @@ fn check_stmt<'a, 'tcx>(vis: &mut ReadVisitor<'a, 'tcx>, stmt: &'tcx Stmt<'_>) - /// A visitor that looks for reads from a variable. struct ReadVisitor<'a, 'tcx> { - cx: &'a LateContext<'a, 'tcx>, + cx: &'a LateContext<'tcx>, /// The ID of the variable we're looking for. var: HirId, /// The expressions where the write to the variable occurred (for reporting @@ -354,7 +354,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ReadVisitor<'a, 'tcx> { } /// Returns `true` if `expr` is the LHS of an assignment, like `expr = ...`. -fn is_in_assignment_position(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> bool { +fn is_in_assignment_position(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { if let Some(parent) = get_parent_expr(cx, expr) { if let ExprKind::Assign(ref lhs, ..) = parent.kind { return lhs.hir_id == expr.hir_id; diff --git a/clippy_lints/src/exit.rs b/clippy_lints/src/exit.rs index 621d56185a9dd..7337d98c8be37 100644 --- a/clippy_lints/src/exit.rs +++ b/clippy_lints/src/exit.rs @@ -24,8 +24,8 @@ declare_clippy_lint! { declare_lint_pass!(Exit => [EXIT]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Exit { - fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr<'_>) { +impl<'tcx> LateLintPass<'tcx> for Exit { + fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) { if_chain! { if let ExprKind::Call(ref path_expr, ref _args) = e.kind; if let ExprKind::Path(ref path) = path_expr.kind; diff --git a/clippy_lints/src/explicit_write.rs b/clippy_lints/src/explicit_write.rs index 7269e2b52c2ce..0240e80d81418 100644 --- a/clippy_lints/src/explicit_write.rs +++ b/clippy_lints/src/explicit_write.rs @@ -28,8 +28,8 @@ declare_clippy_lint! { declare_lint_pass!(ExplicitWrite => [EXPLICIT_WRITE]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ExplicitWrite { - fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) { +impl<'tcx> LateLintPass<'tcx> for ExplicitWrite { + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { if_chain! { // match call to unwrap if let ExprKind::MethodCall(ref unwrap_fun, _, ref unwrap_args, _) = expr.kind; diff --git a/clippy_lints/src/fallible_impl_from.rs b/clippy_lints/src/fallible_impl_from.rs index 92812816461c5..01ed0c426d436 100644 --- a/clippy_lints/src/fallible_impl_from.rs +++ b/clippy_lints/src/fallible_impl_from.rs @@ -52,8 +52,8 @@ declare_clippy_lint! { declare_lint_pass!(FallibleImplFrom => [FALLIBLE_IMPL_FROM]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for FallibleImplFrom { - fn check_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx hir::Item<'_>) { +impl<'tcx> LateLintPass<'tcx> for FallibleImplFrom { + fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>) { // check for `impl From for ..` let impl_def_id = cx.tcx.hir().local_def_id(item.hir_id); if_chain! { @@ -67,12 +67,12 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for FallibleImplFrom { } } -fn lint_impl_body<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, impl_span: Span, impl_items: &[hir::ImplItemRef<'_>]) { +fn lint_impl_body<'tcx>(cx: &LateContext<'tcx>, impl_span: Span, impl_items: &[hir::ImplItemRef<'_>]) { use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor}; use rustc_hir::{Expr, ExprKind, ImplItemKind, QPath}; struct FindPanicUnwrap<'a, 'tcx> { - lcx: &'a LateContext<'a, 'tcx>, + lcx: &'a LateContext<'tcx>, tables: &'tcx ty::TypeckTables<'tcx>, result: Vec, } diff --git a/clippy_lints/src/float_literal.rs b/clippy_lints/src/float_literal.rs index cd3d443ec58ef..a3d2a949535a4 100644 --- a/clippy_lints/src/float_literal.rs +++ b/clippy_lints/src/float_literal.rs @@ -58,8 +58,8 @@ declare_clippy_lint! { declare_lint_pass!(FloatLiteral => [EXCESSIVE_PRECISION, LOSSY_FLOAT_LITERAL]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for FloatLiteral { - fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx hir::Expr<'_>) { +impl<'tcx> LateLintPass<'tcx> for FloatLiteral { + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>) { if_chain! { let ty = cx.tables().expr_ty(expr); if let ty::Float(fty) = ty.kind; diff --git a/clippy_lints/src/floating_point_arithmetic.rs b/clippy_lints/src/floating_point_arithmetic.rs index 76713cb1afc41..4efd068926796 100644 --- a/clippy_lints/src/floating_point_arithmetic.rs +++ b/clippy_lints/src/floating_point_arithmetic.rs @@ -111,7 +111,7 @@ declare_lint_pass!(FloatingPointArithmetic => [ // Returns the specialized log method for a given base if base is constant // and is one of 2, 10 and e -fn get_specialized_log_method(cx: &LateContext<'_, '_>, base: &Expr<'_>) -> Option<&'static str> { +fn get_specialized_log_method(cx: &LateContext<'_>, base: &Expr<'_>) -> Option<&'static str> { if let Some((value, _)) = constant(cx, cx.tables(), base) { if F32(2.0) == value || F64(2.0) == value { return Some("log2"); @@ -126,7 +126,7 @@ fn get_specialized_log_method(cx: &LateContext<'_, '_>, base: &Expr<'_>) -> Opti } // Adds type suffixes and parenthesis to method receivers if necessary -fn prepare_receiver_sugg<'a>(cx: &LateContext<'_, '_>, mut expr: &'a Expr<'a>) -> Sugg<'a> { +fn prepare_receiver_sugg<'a>(cx: &LateContext<'_>, mut expr: &'a Expr<'a>) -> Sugg<'a> { let mut suggestion = Sugg::hir(cx, expr, ".."); if let ExprKind::Unary(UnOp::UnNeg, inner_expr) = &expr.kind { @@ -163,7 +163,7 @@ fn prepare_receiver_sugg<'a>(cx: &LateContext<'_, '_>, mut expr: &'a Expr<'a>) - suggestion.maybe_par() } -fn check_log_base(cx: &LateContext<'_, '_>, expr: &Expr<'_>, args: &[Expr<'_>]) { +fn check_log_base(cx: &LateContext<'_>, expr: &Expr<'_>, args: &[Expr<'_>]) { if let Some(method) = get_specialized_log_method(cx, &args[1]) { span_lint_and_sugg( cx, @@ -179,7 +179,7 @@ fn check_log_base(cx: &LateContext<'_, '_>, expr: &Expr<'_>, args: &[Expr<'_>]) // TODO: Lint expressions of the form `(x + y).ln()` where y > 1 and // suggest usage of `(x + (y - 1)).ln_1p()` instead -fn check_ln1p(cx: &LateContext<'_, '_>, expr: &Expr<'_>, args: &[Expr<'_>]) { +fn check_ln1p(cx: &LateContext<'_>, expr: &Expr<'_>, args: &[Expr<'_>]) { if let ExprKind::Binary( Spanned { node: BinOpKind::Add, .. @@ -231,7 +231,7 @@ fn get_integer_from_float_constant(value: &Constant) -> Option { } } -fn check_powf(cx: &LateContext<'_, '_>, expr: &Expr<'_>, args: &[Expr<'_>]) { +fn check_powf(cx: &LateContext<'_>, expr: &Expr<'_>, args: &[Expr<'_>]) { // Check receiver if let Some((value, _)) = constant(cx, cx.tables(), &args[0]) { let method = if F32(f32_consts::E) == value || F64(f64_consts::E) == value { @@ -295,7 +295,7 @@ fn check_powf(cx: &LateContext<'_, '_>, expr: &Expr<'_>, args: &[Expr<'_>]) { // TODO: Lint expressions of the form `x.exp() - y` where y > 1 // and suggest usage of `x.exp_m1() - (y - 1)` instead -fn check_expm1(cx: &LateContext<'_, '_>, expr: &Expr<'_>) { +fn check_expm1(cx: &LateContext<'_>, expr: &Expr<'_>) { if_chain! { if let ExprKind::Binary(Spanned { node: BinOpKind::Sub, .. }, ref lhs, ref rhs) = expr.kind; if cx.tables().expr_ty(lhs).is_floating_point(); @@ -321,7 +321,7 @@ fn check_expm1(cx: &LateContext<'_, '_>, expr: &Expr<'_>) { } } -fn is_float_mul_expr<'a>(cx: &LateContext<'_, '_>, expr: &'a Expr<'a>) -> Option<(&'a Expr<'a>, &'a Expr<'a>)> { +fn is_float_mul_expr<'a>(cx: &LateContext<'_>, expr: &'a Expr<'a>) -> Option<(&'a Expr<'a>, &'a Expr<'a>)> { if_chain! { if let ExprKind::Binary(Spanned { node: BinOpKind::Mul, .. }, ref lhs, ref rhs) = &expr.kind; if cx.tables().expr_ty(lhs).is_floating_point(); @@ -335,7 +335,7 @@ fn is_float_mul_expr<'a>(cx: &LateContext<'_, '_>, expr: &'a Expr<'a>) -> Option } // TODO: Fix rust-lang/rust-clippy#4735 -fn check_mul_add(cx: &LateContext<'_, '_>, expr: &Expr<'_>) { +fn check_mul_add(cx: &LateContext<'_>, expr: &Expr<'_>) { if let ExprKind::Binary( Spanned { node: BinOpKind::Add, .. @@ -373,7 +373,7 @@ fn check_mul_add(cx: &LateContext<'_, '_>, expr: &Expr<'_>) { /// test is positive or an expression which tests whether or not test /// is nonnegative. /// Used for check-custom-abs function below -fn is_testing_positive(cx: &LateContext<'_, '_>, expr: &Expr<'_>, test: &Expr<'_>) -> bool { +fn is_testing_positive(cx: &LateContext<'_>, expr: &Expr<'_>, test: &Expr<'_>) -> bool { if let ExprKind::Binary(Spanned { node: op, .. }, left, right) = expr.kind { match op { BinOpKind::Gt | BinOpKind::Ge => is_zero(cx, right) && are_exprs_equal(cx, left, test), @@ -386,7 +386,7 @@ fn is_testing_positive(cx: &LateContext<'_, '_>, expr: &Expr<'_>, test: &Expr<'_ } /// See [`is_testing_positive`] -fn is_testing_negative(cx: &LateContext<'_, '_>, expr: &Expr<'_>, test: &Expr<'_>) -> bool { +fn is_testing_negative(cx: &LateContext<'_>, expr: &Expr<'_>, test: &Expr<'_>) -> bool { if let ExprKind::Binary(Spanned { node: op, .. }, left, right) = expr.kind { match op { BinOpKind::Gt | BinOpKind::Ge => is_zero(cx, left) && are_exprs_equal(cx, right, test), @@ -398,12 +398,12 @@ fn is_testing_negative(cx: &LateContext<'_, '_>, expr: &Expr<'_>, test: &Expr<'_ } } -fn are_exprs_equal(cx: &LateContext<'_, '_>, expr1: &Expr<'_>, expr2: &Expr<'_>) -> bool { +fn are_exprs_equal(cx: &LateContext<'_>, expr1: &Expr<'_>, expr2: &Expr<'_>) -> bool { SpanlessEq::new(cx).ignore_fn().eq_expr(expr1, expr2) } /// Returns true iff expr is some zero literal -fn is_zero(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> bool { +fn is_zero(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { match constant_simple(cx, cx.tables(), expr) { Some(Constant::Int(i)) => i == 0, Some(Constant::F32(f)) => f == 0.0, @@ -418,7 +418,7 @@ fn is_zero(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> bool { /// one of the two expressions /// If the two expressions are not negations of each other, then it /// returns None. -fn are_negated<'a>(cx: &LateContext<'_, '_>, expr1: &'a Expr<'a>, expr2: &'a Expr<'a>) -> Option<(bool, &'a Expr<'a>)> { +fn are_negated<'a>(cx: &LateContext<'_>, expr1: &'a Expr<'a>, expr2: &'a Expr<'a>) -> Option<(bool, &'a Expr<'a>)> { if let ExprKind::Unary(UnOp::UnNeg, expr1_negated) = &expr1.kind { if are_exprs_equal(cx, expr1_negated, expr2) { return Some((false, expr2)); @@ -432,7 +432,7 @@ fn are_negated<'a>(cx: &LateContext<'_, '_>, expr1: &'a Expr<'a>, expr2: &'a Exp None } -fn check_custom_abs(cx: &LateContext<'_, '_>, expr: &Expr<'_>) { +fn check_custom_abs(cx: &LateContext<'_>, expr: &Expr<'_>) { if_chain! { if let Some((cond, body, Some(else_body))) = higher::if_block(&expr); if let ExprKind::Block(block, _) = body.kind; @@ -479,8 +479,8 @@ fn check_custom_abs(cx: &LateContext<'_, '_>, expr: &Expr<'_>) { } } -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for FloatingPointArithmetic { - fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) { +impl<'tcx> LateLintPass<'tcx> for FloatingPointArithmetic { + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { if let ExprKind::MethodCall(ref path, _, args, _) = &expr.kind { let recv_ty = cx.tables().expr_ty(&args[0]); diff --git a/clippy_lints/src/format.rs b/clippy_lints/src/format.rs index dc8795e3d11eb..33b6bfc459f91 100644 --- a/clippy_lints/src/format.rs +++ b/clippy_lints/src/format.rs @@ -40,8 +40,8 @@ declare_clippy_lint! { 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<'_>) { +impl<'tcx> LateLintPass<'tcx> for UselessFormat { + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { let span = match is_expn_of(expr.span, "format") { Some(s) if !s.from_expansion() => s, _ => return, @@ -75,11 +75,7 @@ fn span_useless_format(cx: &T, span: Span, help: &str, mut sugg: }); } -fn on_argumentv1_new<'a, 'tcx>( - cx: &LateContext<'a, 'tcx>, - expr: &'tcx Expr<'_>, - arms: &'tcx [Arm<'_>], -) -> Option { +fn on_argumentv1_new<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, arms: &'tcx [Arm<'_>]) -> Option { if_chain! { if let ExprKind::AddrOf(BorrowKind::Ref, _, ref format_args) = expr.kind; if let ExprKind::Array(ref elems) = arms[0].body.kind; @@ -118,7 +114,7 @@ fn on_argumentv1_new<'a, 'tcx>( None } -fn on_new_v1<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) -> Option { +fn on_new_v1<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) -> Option { if_chain! { if let Some(args) = match_function_call(cx, expr, &paths::FMT_ARGUMENTS_NEW_V1); if args.len() == 2; @@ -145,7 +141,7 @@ fn on_new_v1<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) -> Opti None } -fn on_new_v1_fmt<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) -> Option { +fn on_new_v1_fmt<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) -> Option { if_chain! { if let Some(args) = match_function_call(cx, expr, &paths::FMT_ARGUMENTS_NEW_V1_FORMATTED); if args.len() == 3; diff --git a/clippy_lints/src/functions.rs b/clippy_lints/src/functions.rs index 1f9bd7a691b52..3f030dd84225b 100644 --- a/clippy_lints/src/functions.rs +++ b/clippy_lints/src/functions.rs @@ -190,10 +190,10 @@ impl_lint_pass!(Functions => [ MUST_USE_CANDIDATE, ]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Functions { +impl<'tcx> LateLintPass<'tcx> for Functions { fn check_fn( &mut self, - cx: &LateContext<'a, 'tcx>, + cx: &LateContext<'tcx>, kind: intravisit::FnKind<'tcx>, decl: &'tcx hir::FnDecl<'_>, body: &'tcx hir::Body<'_>, @@ -230,7 +230,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Functions { self.check_line_number(cx, span, body); } - fn check_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx hir::Item<'_>) { + fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>) { let attr = must_use_attr(&item.attrs); if let hir::ItemKind::Fn(ref sig, ref _generics, ref body_id) = item.kind { if let Some(attr) = attr { @@ -255,7 +255,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Functions { } } - fn check_impl_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx hir::ImplItem<'_>) { + fn check_impl_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::ImplItem<'_>) { if let hir::ImplItemKind::Fn(ref sig, ref body_id) = item.kind { let attr = must_use_attr(&item.attrs); if let Some(attr) = attr { @@ -278,7 +278,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Functions { } } - fn check_trait_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx hir::TraitItem<'_>) { + fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::TraitItem<'_>) { if let hir::TraitItemKind::Fn(ref sig, ref eid) = item.kind { // don't lint extern functions decls, it's not their fault if sig.header.abi == Abi::Rust { @@ -310,8 +310,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Functions { } } -impl<'a, 'tcx> Functions { - fn check_arg_number(self, cx: &LateContext<'_, '_>, decl: &hir::FnDecl<'_>, fn_span: Span) { +impl<'tcx> Functions { + fn check_arg_number(self, cx: &LateContext<'_>, decl: &hir::FnDecl<'_>, fn_span: Span) { let args = decl.inputs.len() as u64; if args > self.threshold { span_lint( @@ -323,7 +323,7 @@ impl<'a, 'tcx> Functions { } } - fn check_line_number(self, cx: &LateContext<'_, '_>, span: Span, body: &'tcx hir::Body<'_>) { + fn check_line_number(self, cx: &LateContext<'_>, span: Span, body: &'tcx hir::Body<'_>) { if in_external_macro(cx.sess(), span) { return; } @@ -378,7 +378,7 @@ impl<'a, 'tcx> Functions { } fn check_raw_ptr( - cx: &LateContext<'a, 'tcx>, + cx: &LateContext<'tcx>, unsafety: hir::Unsafety, decl: &'tcx hir::FnDecl<'_>, body: &'tcx hir::Body<'_>, @@ -406,7 +406,7 @@ impl<'a, 'tcx> Functions { } fn check_needless_must_use( - cx: &LateContext<'_, '_>, + cx: &LateContext<'_>, decl: &hir::FnDecl<'_>, item_id: hir::HirId, item_span: Span, @@ -443,8 +443,8 @@ fn check_needless_must_use( } } -fn check_must_use_candidate<'a, 'tcx>( - cx: &LateContext<'a, 'tcx>, +fn check_must_use_candidate<'tcx>( + cx: &LateContext<'tcx>, decl: &'tcx hir::FnDecl<'_>, body: &'tcx hir::Body<'_>, item_span: Span, @@ -484,12 +484,12 @@ fn returns_unit(decl: &hir::FnDecl<'_>) -> bool { } } -fn has_mutable_arg(cx: &LateContext<'_, '_>, body: &hir::Body<'_>) -> bool { +fn has_mutable_arg(cx: &LateContext<'_>, body: &hir::Body<'_>) -> bool { let mut tys = FxHashSet::default(); body.params.iter().any(|param| is_mutable_pat(cx, ¶m.pat, &mut tys)) } -fn is_mutable_pat(cx: &LateContext<'_, '_>, pat: &hir::Pat<'_>, tys: &mut FxHashSet) -> bool { +fn is_mutable_pat(cx: &LateContext<'_>, pat: &hir::Pat<'_>, tys: &mut FxHashSet) -> bool { if let hir::PatKind::Wild = pat.kind { return false; // ignore `_` patterns } @@ -508,7 +508,7 @@ fn is_mutable_pat(cx: &LateContext<'_, '_>, pat: &hir::Pat<'_>, tys: &mut FxHash static KNOWN_WRAPPER_TYS: &[&[&str]] = &[&["alloc", "rc", "Rc"], &["std", "sync", "Arc"]]; -fn is_mutable_ty<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, ty: Ty<'tcx>, span: Span, tys: &mut FxHashSet) -> bool { +fn is_mutable_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>, span: Span, tys: &mut FxHashSet) -> bool { match ty.kind { // primitive types are never mutable ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::Str => false, @@ -537,7 +537,7 @@ fn raw_ptr_arg(arg: &hir::Param<'_>, ty: &hir::Ty<'_>) -> Option { } struct DerefVisitor<'a, 'tcx> { - cx: &'a LateContext<'a, 'tcx>, + cx: &'a LateContext<'tcx>, ptrs: FxHashSet, tables: &'a ty::TypeckTables<'tcx>, } @@ -596,7 +596,7 @@ impl<'a, 'tcx> DerefVisitor<'a, 'tcx> { } struct StaticMutVisitor<'a, 'tcx> { - cx: &'a LateContext<'a, 'tcx>, + cx: &'a LateContext<'tcx>, mutates_static: bool, } @@ -641,7 +641,7 @@ impl<'a, 'tcx> intravisit::Visitor<'tcx> for StaticMutVisitor<'a, 'tcx> { } } -fn is_mutated_static(cx: &LateContext<'_, '_>, e: &hir::Expr<'_>) -> bool { +fn is_mutated_static(cx: &LateContext<'_>, e: &hir::Expr<'_>) -> bool { use hir::ExprKind::{Field, Index, Path}; match e.kind { @@ -657,7 +657,7 @@ fn is_mutated_static(cx: &LateContext<'_, '_>, e: &hir::Expr<'_>) -> bool { } } -fn mutates_static<'a, 'tcx>(cx: &'a LateContext<'a, 'tcx>, body: &'tcx hir::Body<'_>) -> bool { +fn mutates_static<'tcx>(cx: &LateContext<'tcx>, body: &'tcx hir::Body<'_>) -> bool { let mut v = StaticMutVisitor { cx, mutates_static: false, diff --git a/clippy_lints/src/future_not_send.rs b/clippy_lints/src/future_not_send.rs index 17dd3cd5493e7..92c7e66a0eb85 100644 --- a/clippy_lints/src/future_not_send.rs +++ b/clippy_lints/src/future_not_send.rs @@ -47,10 +47,10 @@ declare_clippy_lint! { declare_lint_pass!(FutureNotSend => [FUTURE_NOT_SEND]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for FutureNotSend { +impl<'tcx> LateLintPass<'tcx> for FutureNotSend { fn check_fn( &mut self, - cx: &LateContext<'a, 'tcx>, + cx: &LateContext<'tcx>, kind: FnKind<'tcx>, decl: &'tcx FnDecl<'tcx>, _: &'tcx Body<'tcx>, diff --git a/clippy_lints/src/get_last_with_len.rs b/clippy_lints/src/get_last_with_len.rs index 57a7fbb565679..2d93ecc00a769 100644 --- a/clippy_lints/src/get_last_with_len.rs +++ b/clippy_lints/src/get_last_with_len.rs @@ -43,8 +43,8 @@ declare_clippy_lint! { declare_lint_pass!(GetLastWithLen => [GET_LAST_WITH_LEN]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for GetLastWithLen { - fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) { +impl<'tcx> LateLintPass<'tcx> for GetLastWithLen { + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { if_chain! { // Is a method call if let ExprKind::MethodCall(ref path, _, ref args, _) = expr.kind; diff --git a/clippy_lints/src/identity_op.rs b/clippy_lints/src/identity_op.rs index 1c25e050997ea..dc9d636bc6de1 100644 --- a/clippy_lints/src/identity_op.rs +++ b/clippy_lints/src/identity_op.rs @@ -28,8 +28,8 @@ declare_clippy_lint! { 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<'_>) { +impl<'tcx> LateLintPass<'tcx> for IdentityOp { + fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) { if e.span.from_expansion() { return; } @@ -58,7 +58,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for IdentityOp { } } -fn is_allowed(cx: &LateContext<'_, '_>, cmp: BinOp, left: &Expr<'_>, right: &Expr<'_>) -> bool { +fn is_allowed(cx: &LateContext<'_>, cmp: BinOp, left: &Expr<'_>, right: &Expr<'_>) -> bool { // `1 << 0` is a common pattern in bit manipulation code if_chain! { if let BinOpKind::Shl = cmp.node; @@ -73,7 +73,7 @@ fn is_allowed(cx: &LateContext<'_, '_>, cmp: BinOp, left: &Expr<'_>, right: &Exp } #[allow(clippy::cast_possible_wrap)] -fn check(cx: &LateContext<'_, '_>, e: &Expr<'_>, m: i8, span: Span, arg: Span) { +fn check(cx: &LateContext<'_>, e: &Expr<'_>, m: i8, span: Span, arg: Span) { if let Some(Constant::Int(v)) = constant_simple(cx, cx.tables(), e) { let check = match cx.tables().expr_ty(e).kind { ty::Int(ity) => unsext(cx.tcx, -1_i128, ity), diff --git a/clippy_lints/src/if_let_mutex.rs b/clippy_lints/src/if_let_mutex.rs index e357c7b3b2eb2..f911cb68ea579 100644 --- a/clippy_lints/src/if_let_mutex.rs +++ b/clippy_lints/src/if_let_mutex.rs @@ -40,8 +40,8 @@ declare_clippy_lint! { declare_lint_pass!(IfLetMutex => [IF_LET_MUTEX]); -impl LateLintPass<'_, '_> for IfLetMutex { - fn check_expr(&mut self, cx: &LateContext<'_, '_>, ex: &'_ Expr<'_>) { +impl<'tcx> LateLintPass<'tcx> for IfLetMutex { + fn check_expr(&mut self, cx: &LateContext<'tcx>, ex: &'tcx Expr<'tcx>) { let mut arm_visit = ArmVisitor { mutex_lock_called: false, found_mutex: None, @@ -82,13 +82,13 @@ impl LateLintPass<'_, '_> for IfLetMutex { } /// Checks if `Mutex::lock` is called in the `if let _ = expr. -pub struct OppVisitor<'tcx, 'l> { +pub struct OppVisitor<'a, 'tcx> { mutex_lock_called: bool, found_mutex: Option<&'tcx Expr<'tcx>>, - cx: &'tcx LateContext<'tcx, 'l>, + cx: &'a LateContext<'tcx>, } -impl<'tcx, 'l> Visitor<'tcx> for OppVisitor<'tcx, 'l> { +impl<'tcx> Visitor<'tcx> for OppVisitor<'_, 'tcx> { type Map = Map<'tcx>; fn visit_expr(&mut self, expr: &'tcx Expr<'_>) { @@ -109,13 +109,13 @@ impl<'tcx, 'l> Visitor<'tcx> for OppVisitor<'tcx, 'l> { } /// Checks if `Mutex::lock` is called in any of the branches. -pub struct ArmVisitor<'tcx, 'l> { +pub struct ArmVisitor<'a, 'tcx> { mutex_lock_called: bool, found_mutex: Option<&'tcx Expr<'tcx>>, - cx: &'tcx LateContext<'tcx, 'l>, + cx: &'a LateContext<'tcx>, } -impl<'tcx, 'l> Visitor<'tcx> for ArmVisitor<'tcx, 'l> { +impl<'tcx> Visitor<'tcx> for ArmVisitor<'_, 'tcx> { type Map = Map<'tcx>; fn visit_expr(&mut self, expr: &'tcx Expr<'tcx>) { @@ -135,8 +135,8 @@ impl<'tcx, 'l> Visitor<'tcx> for ArmVisitor<'tcx, 'l> { } } -impl<'tcx, 'l> ArmVisitor<'tcx, 'l> { - fn same_mutex(&self, cx: &LateContext<'_, '_>, op_mutex: &Expr<'_>) -> bool { +impl<'tcx> ArmVisitor<'_, 'tcx> { + fn same_mutex(&self, cx: &LateContext<'_>, op_mutex: &Expr<'_>) -> bool { if let Some(arm_mutex) = self.found_mutex { SpanlessEq::new(cx).eq_expr(op_mutex, arm_mutex) } else { @@ -145,7 +145,7 @@ impl<'tcx, 'l> ArmVisitor<'tcx, 'l> { } } -fn is_mutex_lock_call<'a>(cx: &LateContext<'a, '_>, expr: &'a Expr<'_>) -> Option<&'a Expr<'a>> { +fn is_mutex_lock_call<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) -> Option<&'tcx Expr<'tcx>> { if_chain! { if let ExprKind::MethodCall(path, _span, args, _) = &expr.kind; if path.ident.to_string() == "lock"; diff --git a/clippy_lints/src/if_let_some_result.rs b/clippy_lints/src/if_let_some_result.rs index 3f1ae9b86d387..9e2989dc01e52 100644 --- a/clippy_lints/src/if_let_some_result.rs +++ b/clippy_lints/src/if_let_some_result.rs @@ -37,8 +37,8 @@ declare_clippy_lint! { declare_lint_pass!(OkIfLet => [IF_LET_SOME_RESULT]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for OkIfLet { - fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) { +impl<'tcx> LateLintPass<'tcx> for OkIfLet { + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { if_chain! { //begin checking variables if let ExprKind::Match(ref op, ref body, source) = expr.kind; //test if expr is a match if let MatchSource::IfLetDesugar { .. } = source; //test if it is an If Let diff --git a/clippy_lints/src/implicit_return.rs b/clippy_lints/src/implicit_return.rs index b43babc1de879..22c4fef32a32b 100644 --- a/clippy_lints/src/implicit_return.rs +++ b/clippy_lints/src/implicit_return.rs @@ -44,7 +44,7 @@ declare_lint_pass!(ImplicitReturn => [IMPLICIT_RETURN]); static LINT_BREAK: &str = "change `break` to `return` as shown"; static LINT_RETURN: &str = "add `return` as shown"; -fn lint(cx: &LateContext<'_, '_>, outer_span: Span, inner_span: Span, msg: &str) { +fn lint(cx: &LateContext<'_>, outer_span: Span, inner_span: Span, msg: &str) { let outer_span = outer_span.source_callsite(); let inner_span = inner_span.source_callsite(); @@ -60,7 +60,7 @@ fn lint(cx: &LateContext<'_, '_>, outer_span: Span, inner_span: Span, msg: &str) }); } -fn expr_match(cx: &LateContext<'_, '_>, expr: &Expr<'_>) { +fn expr_match(cx: &LateContext<'_>, expr: &Expr<'_>) { match expr.kind { // loops could be using `break` instead of `return` ExprKind::Block(block, ..) | ExprKind::Loop(block, ..) => { @@ -122,10 +122,10 @@ fn expr_match(cx: &LateContext<'_, '_>, expr: &Expr<'_>) { } } -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ImplicitReturn { +impl<'tcx> LateLintPass<'tcx> for ImplicitReturn { fn check_fn( &mut self, - cx: &LateContext<'a, 'tcx>, + cx: &LateContext<'tcx>, _: FnKind<'tcx>, _: &'tcx FnDecl<'_>, body: &'tcx Body<'_>, diff --git a/clippy_lints/src/implicit_saturating_sub.rs b/clippy_lints/src/implicit_saturating_sub.rs index 1a6cb0b0c566e..f38530aca0cec 100644 --- a/clippy_lints/src/implicit_saturating_sub.rs +++ b/clippy_lints/src/implicit_saturating_sub.rs @@ -36,8 +36,8 @@ declare_clippy_lint! { declare_lint_pass!(ImplicitSaturatingSub => [IMPLICIT_SATURATING_SUB]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ImplicitSaturatingSub { - fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'tcx>) { +impl<'tcx> LateLintPass<'tcx> for ImplicitSaturatingSub { + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) { if in_macro(expr.span) { return; } @@ -118,7 +118,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ImplicitSaturatingSub { } } -fn subtracts_one<'a>(cx: &LateContext<'_, '_>, expr: &Expr<'a>) -> Option<&'a Expr<'a>> { +fn subtracts_one<'a>(cx: &LateContext<'_>, expr: &Expr<'a>) -> Option<&'a Expr<'a>> { match expr.kind { ExprKind::AssignOp(ref op1, ref target, ref value) => { if_chain! { @@ -153,7 +153,7 @@ fn subtracts_one<'a>(cx: &LateContext<'_, '_>, expr: &Expr<'a>) -> Option<&'a Ex } } -fn print_lint_and_sugg(cx: &LateContext<'_, '_>, var_name: &str, expr: &Expr<'_>) { +fn print_lint_and_sugg(cx: &LateContext<'_>, var_name: &str, expr: &Expr<'_>) { span_lint_and_sugg( cx, IMPLICIT_SATURATING_SUB, diff --git a/clippy_lints/src/indexing_slicing.rs b/clippy_lints/src/indexing_slicing.rs index c5e4abc94a8a6..5857a405b0cf3 100644 --- a/clippy_lints/src/indexing_slicing.rs +++ b/clippy_lints/src/indexing_slicing.rs @@ -85,8 +85,8 @@ declare_clippy_lint! { declare_lint_pass!(IndexingSlicing => [INDEXING_SLICING, OUT_OF_BOUNDS_INDEXING]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for IndexingSlicing { - fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) { +impl<'tcx> LateLintPass<'tcx> for IndexingSlicing { + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { if let ExprKind::Index(ref array, ref index) = &expr.kind { let ty = cx.tables().expr_ty(array); if let Some(range) = higher::range(cx, index) { @@ -164,8 +164,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for IndexingSlicing { /// Returns a tuple of options with the start and end (exclusive) values of /// the range. If the start or end is not constant, None is returned. -fn to_const_range<'a, 'tcx>( - cx: &LateContext<'a, 'tcx>, +fn to_const_range<'tcx>( + cx: &LateContext<'tcx>, range: higher::Range<'_>, array_size: u128, ) -> (Option, Option) { diff --git a/clippy_lints/src/infinite_iter.rs b/clippy_lints/src/infinite_iter.rs index 38f086c9221fe..3ffc2dd60d9c0 100644 --- a/clippy_lints/src/infinite_iter.rs +++ b/clippy_lints/src/infinite_iter.rs @@ -44,8 +44,8 @@ declare_clippy_lint! { declare_lint_pass!(InfiniteIter => [INFINITE_ITER, MAYBE_INFINITE_ITER]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for InfiniteIter { - fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) { +impl<'tcx> LateLintPass<'tcx> for InfiniteIter { + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { let (lint, msg) = match complete_infinite_iter(cx, expr) { Infinite => (INFINITE_ITER, "infinite iteration detected"), MaybeInfinite => (MAYBE_INFINITE_ITER, "possible infinite iteration detected"), @@ -140,7 +140,7 @@ const HEURISTICS: [(&str, usize, Heuristic, Finiteness); 19] = [ ("scan", 3, First, MaybeInfinite), ]; -fn is_infinite(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> Finiteness { +fn is_infinite(cx: &LateContext<'_>, expr: &Expr<'_>) -> Finiteness { match expr.kind { ExprKind::MethodCall(ref method, _, ref args, _) => { for &(name, len, heuristic, cap) in &HEURISTICS { @@ -216,7 +216,7 @@ const INFINITE_COLLECTORS: [&[&str]; 8] = [ &paths::VEC_DEQUE, ]; -fn complete_infinite_iter(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> Finiteness { +fn complete_infinite_iter(cx: &LateContext<'_>, expr: &Expr<'_>) -> Finiteness { match expr.kind { ExprKind::MethodCall(ref method, _, ref args, _) => { for &(name, len) in &COMPLETING_METHODS { diff --git a/clippy_lints/src/inherent_impl.rs b/clippy_lints/src/inherent_impl.rs index 7e2975ac2ae90..bd7ca03883945 100644 --- a/clippy_lints/src/inherent_impl.rs +++ b/clippy_lints/src/inherent_impl.rs @@ -47,8 +47,8 @@ pub struct MultipleInherentImpl { impl_lint_pass!(MultipleInherentImpl => [MULTIPLE_INHERENT_IMPL]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MultipleInherentImpl { - fn check_item(&mut self, _: &LateContext<'a, 'tcx>, item: &'tcx Item<'_>) { +impl<'tcx> LateLintPass<'tcx> for MultipleInherentImpl { + fn check_item(&mut self, _: &LateContext<'tcx>, item: &'tcx Item<'_>) { if let ItemKind::Impl { ref generics, of_trait: None, @@ -64,7 +64,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MultipleInherentImpl { } } - fn check_crate_post(&mut self, cx: &LateContext<'a, 'tcx>, krate: &'tcx Crate<'_>) { + fn check_crate_post(&mut self, cx: &LateContext<'tcx>, krate: &'tcx Crate<'_>) { if let Some(item) = krate.items.values().next() { // Retrieve all inherent implementations from the crate, grouped by type for impls in cx diff --git a/clippy_lints/src/inherent_to_string.rs b/clippy_lints/src/inherent_to_string.rs index 289628a2752af..f330fa8fab8f4 100644 --- a/clippy_lints/src/inherent_to_string.rs +++ b/clippy_lints/src/inherent_to_string.rs @@ -92,8 +92,8 @@ declare_clippy_lint! { declare_lint_pass!(InherentToString => [INHERENT_TO_STRING, INHERENT_TO_STRING_SHADOW_DISPLAY]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for InherentToString { - fn check_impl_item(&mut self, cx: &LateContext<'a, 'tcx>, impl_item: &'tcx ImplItem<'_>) { +impl<'tcx> LateLintPass<'tcx> for InherentToString { + fn check_impl_item(&mut self, cx: &LateContext<'tcx>, impl_item: &'tcx ImplItem<'_>) { if impl_item.span.from_expansion() { return; } @@ -119,7 +119,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for InherentToString { } } -fn show_lint(cx: &LateContext<'_, '_>, item: &ImplItem<'_>) { +fn show_lint(cx: &LateContext<'_>, item: &ImplItem<'_>) { let display_trait_id = get_trait_def_id(cx, &paths::DISPLAY_TRAIT).expect("Failed to get trait ID of `Display`!"); // Get the real type of 'self' diff --git a/clippy_lints/src/inline_fn_without_body.rs b/clippy_lints/src/inline_fn_without_body.rs index 475610dda4753..decbee278154a 100644 --- a/clippy_lints/src/inline_fn_without_body.rs +++ b/clippy_lints/src/inline_fn_without_body.rs @@ -31,15 +31,15 @@ declare_clippy_lint! { declare_lint_pass!(InlineFnWithoutBody => [INLINE_FN_WITHOUT_BODY]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for InlineFnWithoutBody { - fn check_trait_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx TraitItem<'_>) { +impl<'tcx> LateLintPass<'tcx> for InlineFnWithoutBody { + fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx TraitItem<'_>) { if let TraitItemKind::Fn(_, TraitFn::Required(_)) = item.kind { check_attrs(cx, item.ident.name, &item.attrs); } } } -fn check_attrs(cx: &LateContext<'_, '_>, name: Symbol, attrs: &[Attribute]) { +fn check_attrs(cx: &LateContext<'_>, name: Symbol, attrs: &[Attribute]) { for attr in attrs { if !attr.check_name(sym!(inline)) { continue; diff --git a/clippy_lints/src/integer_division.rs b/clippy_lints/src/integer_division.rs index 83ae1c1a971e1..e754c7b482a68 100644 --- a/clippy_lints/src/integer_division.rs +++ b/clippy_lints/src/integer_division.rs @@ -30,8 +30,8 @@ declare_clippy_lint! { declare_lint_pass!(IntegerDivision => [INTEGER_DIVISION]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for IntegerDivision { - fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx hir::Expr<'_>) { +impl<'tcx> LateLintPass<'tcx> for IntegerDivision { + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>) { if is_integer_division(cx, expr) { span_lint_and_help( cx, @@ -45,7 +45,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for IntegerDivision { } } -fn is_integer_division<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx hir::Expr<'_>) -> bool { +fn is_integer_division<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>) -> bool { if_chain! { if let hir::ExprKind::Binary(binop, left, right) = &expr.kind; if let hir::BinOpKind::Div = &binop.node; diff --git a/clippy_lints/src/large_const_arrays.rs b/clippy_lints/src/large_const_arrays.rs index c9e12fc535ec0..c6cc174a8c97b 100644 --- a/clippy_lints/src/large_const_arrays.rs +++ b/clippy_lints/src/large_const_arrays.rs @@ -45,8 +45,8 @@ impl LargeConstArrays { impl_lint_pass!(LargeConstArrays => [LARGE_CONST_ARRAYS]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for LargeConstArrays { - fn check_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx Item<'_>) { +impl<'tcx> LateLintPass<'tcx> for LargeConstArrays { + fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) { if_chain! { if !item.span.from_expansion(); if let ItemKind::Const(hir_ty, _) = &item.kind; diff --git a/clippy_lints/src/large_enum_variant.rs b/clippy_lints/src/large_enum_variant.rs index 5bc3234e3252f..3c7880d74ee64 100644 --- a/clippy_lints/src/large_enum_variant.rs +++ b/clippy_lints/src/large_enum_variant.rs @@ -56,8 +56,8 @@ impl LargeEnumVariant { impl_lint_pass!(LargeEnumVariant => [LARGE_ENUM_VARIANT]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for LargeEnumVariant { - fn check_item(&mut self, cx: &LateContext<'_, '_>, item: &Item<'_>) { +impl<'tcx> LateLintPass<'tcx> for LargeEnumVariant { + fn check_item(&mut self, cx: &LateContext<'_>, item: &Item<'_>) { let did = cx.tcx.hir().local_def_id(item.hir_id); if let ItemKind::Enum(ref def, _) = item.kind { let ty = cx.tcx.type_of(did); diff --git a/clippy_lints/src/large_stack_arrays.rs b/clippy_lints/src/large_stack_arrays.rs index 0301f263489f4..8eb986c25ff79 100644 --- a/clippy_lints/src/large_stack_arrays.rs +++ b/clippy_lints/src/large_stack_arrays.rs @@ -38,8 +38,8 @@ impl LargeStackArrays { impl_lint_pass!(LargeStackArrays => [LARGE_STACK_ARRAYS]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for LargeStackArrays { - fn check_expr(&mut self, cx: &LateContext<'_, '_>, expr: &Expr<'_>) { +impl<'tcx> LateLintPass<'tcx> for LargeStackArrays { + fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) { if_chain! { if let ExprKind::Repeat(_, _) = expr.kind; if let ty::Array(element_type, cst) = cx.tables().expr_ty(expr).kind; diff --git a/clippy_lints/src/len_zero.rs b/clippy_lints/src/len_zero.rs index e17297e969516..26d96428771d6 100644 --- a/clippy_lints/src/len_zero.rs +++ b/clippy_lints/src/len_zero.rs @@ -70,8 +70,8 @@ declare_clippy_lint! { 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<'_>) { +impl<'tcx> LateLintPass<'tcx> for LenZero { + fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) { if item.span.from_expansion() { return; } @@ -87,7 +87,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for LenZero { } } - fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) { + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { if expr.span.from_expansion() { return; } @@ -118,8 +118,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for LenZero { } } -fn check_trait_items(cx: &LateContext<'_, '_>, visited_trait: &Item<'_>, trait_items: &[TraitItemRef]) { - fn is_named_self(cx: &LateContext<'_, '_>, item: &TraitItemRef, name: &str) -> bool { +fn check_trait_items(cx: &LateContext<'_>, visited_trait: &Item<'_>, trait_items: &[TraitItemRef]) { + fn is_named_self(cx: &LateContext<'_>, item: &TraitItemRef, name: &str) -> bool { item.ident.name.as_str() == name && if let AssocItemKind::Fn { has_self } = item.kind { has_self && { @@ -132,7 +132,7 @@ fn check_trait_items(cx: &LateContext<'_, '_>, visited_trait: &Item<'_>, trait_i } // fill the set with current and super traits - fn fill_trait_set(traitt: DefId, set: &mut FxHashSet, cx: &LateContext<'_, '_>) { + fn fill_trait_set(traitt: DefId, set: &mut FxHashSet, cx: &LateContext<'_>) { if set.insert(traitt) { for supertrait in rustc_trait_selection::traits::supertrait_def_ids(cx.tcx, traitt) { fill_trait_set(supertrait, set, cx); @@ -169,8 +169,8 @@ fn check_trait_items(cx: &LateContext<'_, '_>, visited_trait: &Item<'_>, trait_i } } -fn check_impl_items(cx: &LateContext<'_, '_>, item: &Item<'_>, impl_items: &[ImplItemRef<'_>]) { - fn is_named_self(cx: &LateContext<'_, '_>, item: &ImplItemRef<'_>, name: &str) -> bool { +fn check_impl_items(cx: &LateContext<'_>, item: &Item<'_>, impl_items: &[ImplItemRef<'_>]) { + fn is_named_self(cx: &LateContext<'_>, item: &ImplItemRef<'_>, name: &str) -> bool { item.ident.name.as_str() == name && if let AssocItemKind::Fn { has_self } = item.kind { has_self && { @@ -210,7 +210,7 @@ fn check_impl_items(cx: &LateContext<'_, '_>, item: &Item<'_>, impl_items: &[Imp } } -fn check_cmp(cx: &LateContext<'_, '_>, span: Span, method: &Expr<'_>, lit: &Expr<'_>, op: &str, compare_to: u32) { +fn check_cmp(cx: &LateContext<'_>, span: Span, method: &Expr<'_>, lit: &Expr<'_>, op: &str, compare_to: u32) { if let (&ExprKind::MethodCall(ref method_path, _, ref args, _), &ExprKind::Lit(ref lit)) = (&method.kind, &lit.kind) { // check if we are in an is_empty() method @@ -225,7 +225,7 @@ fn check_cmp(cx: &LateContext<'_, '_>, span: Span, method: &Expr<'_>, lit: &Expr } fn check_len( - cx: &LateContext<'_, '_>, + cx: &LateContext<'_>, span: Span, method_name: Symbol, args: &[Expr<'_>], @@ -259,9 +259,9 @@ fn check_len( } /// Checks if this type has an `is_empty` method. -fn has_is_empty(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> bool { +fn has_is_empty(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { /// Special case ranges until `range_is_empty` is stabilized. See issue 3807. - fn should_skip_range(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> bool { + fn should_skip_range(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { higher::range(cx, expr).map_or(false, |_| { !cx.tcx .features() @@ -272,7 +272,7 @@ fn has_is_empty(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> bool { } /// Gets an `AssocItem` and return true if it matches `is_empty(self)`. - fn is_is_empty(cx: &LateContext<'_, '_>, item: &ty::AssocItem) -> bool { + fn is_is_empty(cx: &LateContext<'_>, item: &ty::AssocItem) -> bool { if let ty::AssocKind::Fn = item.kind { if item.ident.name.as_str() == "is_empty" { let sig = cx.tcx.fn_sig(item.def_id); @@ -287,7 +287,7 @@ fn has_is_empty(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> bool { } /// Checks the inherent impl's items for an `is_empty(self)` method. - fn has_is_empty_impl(cx: &LateContext<'_, '_>, id: DefId) -> bool { + fn has_is_empty_impl(cx: &LateContext<'_>, id: DefId) -> bool { cx.tcx.inherent_impls(id).iter().any(|imp| { cx.tcx .associated_items(*imp) diff --git a/clippy_lints/src/let_and_return.rs b/clippy_lints/src/let_and_return.rs index 7d338cfa86f9f..ddc41f89f8dec 100644 --- a/clippy_lints/src/let_and_return.rs +++ b/clippy_lints/src/let_and_return.rs @@ -40,8 +40,8 @@ declare_clippy_lint! { declare_lint_pass!(LetReturn => [LET_AND_RETURN]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for LetReturn { - fn check_block(&mut self, cx: &LateContext<'a, 'tcx>, block: &'tcx Block<'_>) { +impl<'tcx> LateLintPass<'tcx> for LetReturn { + fn check_block(&mut self, cx: &LateContext<'tcx>, block: &'tcx Block<'_>) { // we need both a let-binding stmt and an expr if_chain! { if let Some(retexpr) = block.expr; @@ -86,14 +86,14 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for LetReturn { } } -fn last_statement_borrows<'tcx>(cx: &LateContext<'_, 'tcx>, expr: &'tcx Expr<'tcx>) -> bool { +fn last_statement_borrows<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) -> bool { let mut visitor = BorrowVisitor { cx, borrows: false }; walk_expr(&mut visitor, expr); visitor.borrows } struct BorrowVisitor<'a, 'tcx> { - cx: &'a LateContext<'a, 'tcx>, + cx: &'a LateContext<'tcx>, borrows: bool, } diff --git a/clippy_lints/src/let_if_seq.rs b/clippy_lints/src/let_if_seq.rs index 7b03812b82260..706c73ce66c61 100644 --- a/clippy_lints/src/let_if_seq.rs +++ b/clippy_lints/src/let_if_seq.rs @@ -56,8 +56,8 @@ declare_clippy_lint! { declare_lint_pass!(LetIfSeq => [USELESS_LET_IF_SEQ]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for LetIfSeq { - fn check_block(&mut self, cx: &LateContext<'a, 'tcx>, block: &'tcx hir::Block<'_>) { +impl<'tcx> LateLintPass<'tcx> for LetIfSeq { + fn check_block(&mut self, cx: &LateContext<'tcx>, block: &'tcx hir::Block<'_>) { let mut it = block.stmts.iter().peekable(); while let Some(stmt) = it.next() { if_chain! { @@ -137,7 +137,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for LetIfSeq { } struct UsedVisitor<'a, 'tcx> { - cx: &'a LateContext<'a, 'tcx>, + cx: &'a LateContext<'tcx>, id: hir::HirId, used: bool, } @@ -162,8 +162,8 @@ impl<'a, 'tcx> intravisit::Visitor<'tcx> for UsedVisitor<'a, 'tcx> { } } -fn check_assign<'a, 'tcx>( - cx: &LateContext<'a, 'tcx>, +fn check_assign<'tcx>( + cx: &LateContext<'tcx>, decl: hir::HirId, block: &'tcx hir::Block<'_>, ) -> Option<&'tcx hir::Expr<'tcx>> { @@ -197,7 +197,7 @@ fn check_assign<'a, 'tcx>( None } -fn used_in_expr<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, id: hir::HirId, expr: &'tcx hir::Expr<'_>) -> bool { +fn used_in_expr<'tcx>(cx: &LateContext<'tcx>, id: hir::HirId, expr: &'tcx hir::Expr<'_>) -> bool { let mut v = UsedVisitor { cx, id, used: false }; intravisit::walk_expr(&mut v, expr); v.used diff --git a/clippy_lints/src/let_underscore.rs b/clippy_lints/src/let_underscore.rs index 0864bbe0f9127..c7dda3c992826 100644 --- a/clippy_lints/src/let_underscore.rs +++ b/clippy_lints/src/let_underscore.rs @@ -66,8 +66,8 @@ const SYNC_GUARD_PATHS: [&[&str]; 3] = [ &paths::RWLOCK_WRITE_GUARD, ]; -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for LetUnderscore { - fn check_local(&mut self, cx: &LateContext<'_, '_>, local: &Local<'_>) { +impl<'tcx> LateLintPass<'tcx> for LetUnderscore { + fn check_local(&mut self, cx: &LateContext<'_>, local: &Local<'_>) { if in_external_macro(cx.tcx.sess, local.span) { return; } diff --git a/clippy_lints/src/lifetimes.rs b/clippy_lints/src/lifetimes.rs index c0d8c1127b9d3..a79f94855bdab 100644 --- a/clippy_lints/src/lifetimes.rs +++ b/clippy_lints/src/lifetimes.rs @@ -76,14 +76,14 @@ declare_clippy_lint! { declare_lint_pass!(Lifetimes => [NEEDLESS_LIFETIMES, EXTRA_UNUSED_LIFETIMES]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Lifetimes { - fn check_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx Item<'_>) { +impl<'tcx> LateLintPass<'tcx> for Lifetimes { + fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) { if let ItemKind::Fn(ref sig, ref generics, id) = item.kind { check_fn_inner(cx, &sig.decl, Some(id), generics, item.span, true); } } - fn check_impl_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx ImplItem<'_>) { + fn check_impl_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx ImplItem<'_>) { if let ImplItemKind::Fn(ref sig, id) = item.kind { let report_extra_lifetimes = trait_ref_of_method(cx, item.hir_id).is_none(); check_fn_inner( @@ -97,7 +97,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Lifetimes { } } - fn check_trait_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx TraitItem<'_>) { + fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx TraitItem<'_>) { if let TraitItemKind::Fn(ref sig, ref body) = item.kind { let body = match *body { TraitFn::Required(_) => None, @@ -116,8 +116,8 @@ enum RefLt { Named(Name), } -fn check_fn_inner<'a, 'tcx>( - cx: &LateContext<'a, 'tcx>, +fn check_fn_inner<'tcx>( + cx: &LateContext<'tcx>, decl: &'tcx FnDecl<'_>, body: Option, generics: &'tcx Generics<'_>, @@ -177,8 +177,8 @@ fn check_fn_inner<'a, 'tcx>( } } -fn could_use_elision<'a, 'tcx>( - cx: &LateContext<'a, 'tcx>, +fn could_use_elision<'tcx>( + cx: &LateContext<'tcx>, func: &'tcx FnDecl<'_>, body: Option, named_generics: &'tcx [GenericParam<'_>], @@ -296,13 +296,13 @@ fn unique_lifetimes(lts: &[RefLt]) -> usize { /// A visitor usable for `rustc_front::visit::walk_ty()`. struct RefVisitor<'a, 'tcx> { - cx: &'a LateContext<'a, 'tcx>, + cx: &'a LateContext<'tcx>, lts: Vec, abort: bool, } -impl<'v, 't> RefVisitor<'v, 't> { - fn new(cx: &'v LateContext<'v, 't>) -> Self { +impl<'a, 'tcx> RefVisitor<'a, 'tcx> { + fn new(cx: &'a LateContext<'tcx>) -> Self { Self { cx, lts: Vec::new(), @@ -412,7 +412,7 @@ impl<'a, 'tcx> Visitor<'tcx> for RefVisitor<'a, 'tcx> { /// Are any lifetimes mentioned in the `where` clause? If so, we don't try to /// reason about elision. -fn has_where_lifetimes<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, where_clause: &'tcx WhereClause<'_>) -> bool { +fn has_where_lifetimes<'tcx>(cx: &LateContext<'tcx>, where_clause: &'tcx WhereClause<'_>) -> bool { for predicate in where_clause.predicates { match *predicate { WherePredicate::RegionPredicate(..) => return true, @@ -482,7 +482,7 @@ impl<'tcx> Visitor<'tcx> for LifetimeChecker { } } -fn report_extra_lifetimes<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, func: &'tcx FnDecl<'_>, generics: &'tcx Generics<'_>) { +fn report_extra_lifetimes<'tcx>(cx: &LateContext<'tcx>, func: &'tcx FnDecl<'_>, generics: &'tcx Generics<'_>) { let hs = generics .params .iter() diff --git a/clippy_lints/src/loops.rs b/clippy_lints/src/loops.rs index 18b979176a0a0..d821b5134841e 100644 --- a/clippy_lints/src/loops.rs +++ b/clippy_lints/src/loops.rs @@ -438,9 +438,9 @@ declare_lint_pass!(Loops => [ WHILE_IMMUTABLE_CONDITION, ]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Loops { +impl<'tcx> LateLintPass<'tcx> for Loops { #[allow(clippy::too_many_lines)] - fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) { + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { if let Some((pat, arg, body)) = higher::for_loop(expr) { // we don't want to check expanded macros // this check is not at the top of the function @@ -732,8 +732,8 @@ fn never_loop_expr_branch<'a, T: Iterator>>(e: &mut T, main_ .fold(NeverLoopResult::AlwaysBreak, combine_branches) } -fn check_for_loop<'a, 'tcx>( - cx: &LateContext<'a, 'tcx>, +fn check_for_loop<'tcx>( + cx: &LateContext<'tcx>, pat: &'tcx Pat<'_>, arg: &'tcx Expr<'_>, body: &'tcx Expr<'_>, @@ -747,7 +747,7 @@ fn check_for_loop<'a, 'tcx>( detect_manual_memcpy(cx, pat, arg, body, expr); } -fn same_var<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &Expr<'_>, var: HirId) -> bool { +fn same_var<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>, var: HirId) -> bool { if_chain! { if let ExprKind::Path(qpath) = &expr.kind; if let QPath::Resolved(None, path) = qpath; @@ -794,7 +794,7 @@ struct FixedOffsetVar<'hir> { offset: Offset, } -fn is_slice_like<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, ty: Ty<'_>) -> bool { +fn is_slice_like<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'_>) -> bool { let is_slice = match ty.kind { ty::Ref(_, subty, _) => is_slice_like(cx, subty), ty::Slice(..) | ty::Array(..) => true, @@ -814,8 +814,8 @@ fn fetch_cloned_expr<'tcx>(expr: &'tcx Expr<'tcx>) -> &'tcx Expr<'tcx> { } } -fn get_offset<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, idx: &Expr<'_>, var: HirId) -> Option { - fn extract_offset<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, e: &Expr<'_>, var: HirId) -> Option { +fn get_offset<'tcx>(cx: &LateContext<'tcx>, idx: &Expr<'_>, var: HirId) -> Option { + fn extract_offset<'tcx>(cx: &LateContext<'tcx>, e: &Expr<'_>, var: HirId) -> Option { match &e.kind { ExprKind::Lit(l) => match l.node { ast::LitKind::Int(x, _ty) => Some(x.to_string()), @@ -880,8 +880,8 @@ fn get_assignments<'tcx>(body: &'tcx Expr<'tcx>) -> impl Iterator( - cx: &LateContext<'a, 'tcx>, +fn build_manual_memcpy_suggestion<'tcx>( + cx: &LateContext<'tcx>, start: &Expr<'_>, end: &Expr<'_>, limits: ast::RangeLimits, @@ -961,8 +961,8 @@ fn build_manual_memcpy_suggestion<'a, 'tcx>( } /// Checks for for loops that sequentially copy items from one slice-like /// object to another. -fn detect_manual_memcpy<'a, 'tcx>( - cx: &LateContext<'a, 'tcx>, +fn detect_manual_memcpy<'tcx>( + cx: &LateContext<'tcx>, pat: &'tcx Pat<'_>, arg: &'tcx Expr<'_>, body: &'tcx Expr<'_>, @@ -1024,8 +1024,8 @@ fn detect_manual_memcpy<'a, 'tcx>( /// Checks for looping over a range and then indexing a sequence with it. /// The iteratee must be a range literal. #[allow(clippy::too_many_lines)] -fn check_for_loop_range<'a, 'tcx>( - cx: &LateContext<'a, 'tcx>, +fn check_for_loop_range<'tcx>( + cx: &LateContext<'tcx>, pat: &'tcx Pat<'_>, arg: &'tcx Expr<'_>, body: &'tcx Expr<'_>, @@ -1205,7 +1205,7 @@ fn is_len_call(expr: &Expr<'_>, var: Name) -> bool { } fn is_end_eq_array_len<'tcx>( - cx: &LateContext<'_, 'tcx>, + cx: &LateContext<'tcx>, end: &Expr<'_>, limits: ast::RangeLimits, indexed_ty: Ty<'tcx>, @@ -1226,7 +1226,7 @@ fn is_end_eq_array_len<'tcx>( false } -fn lint_iter_method(cx: &LateContext<'_, '_>, args: &[Expr<'_>], arg: &Expr<'_>, method_name: &str) { +fn lint_iter_method(cx: &LateContext<'_>, args: &[Expr<'_>], arg: &Expr<'_>, method_name: &str) { let mut applicability = Applicability::MachineApplicable; let object = snippet_with_applicability(cx, args[0].span, "_", &mut applicability); let muta = if method_name == "iter_mut" { "mut " } else { "" }; @@ -1242,7 +1242,7 @@ fn lint_iter_method(cx: &LateContext<'_, '_>, args: &[Expr<'_>], arg: &Expr<'_>, ) } -fn check_for_loop_arg(cx: &LateContext<'_, '_>, pat: &Pat<'_>, arg: &Expr<'_>, expr: &Expr<'_>) { +fn check_for_loop_arg(cx: &LateContext<'_>, pat: &Pat<'_>, arg: &Expr<'_>, expr: &Expr<'_>) { let mut next_loop_linted = false; // whether or not ITER_NEXT_LOOP lint was used if let ExprKind::MethodCall(ref method, _, ref args, _) = arg.kind { // just the receiver, no arguments @@ -1299,7 +1299,7 @@ fn check_for_loop_arg(cx: &LateContext<'_, '_>, pat: &Pat<'_>, arg: &Expr<'_>, e } /// Checks for `for` loops over `Option`s and `Result`s. -fn check_arg_type(cx: &LateContext<'_, '_>, pat: &Pat<'_>, arg: &Expr<'_>) { +fn check_arg_type(cx: &LateContext<'_>, pat: &Pat<'_>, arg: &Expr<'_>) { let ty = cx.tables().expr_ty(arg); if is_type_diagnostic_item(cx, ty, sym!(option_type)) { span_lint_and_help( @@ -1338,8 +1338,8 @@ fn check_arg_type(cx: &LateContext<'_, '_>, pat: &Pat<'_>, arg: &Expr<'_>) { } } -fn check_for_loop_explicit_counter<'a, 'tcx>( - cx: &LateContext<'a, 'tcx>, +fn check_for_loop_explicit_counter<'tcx>( + cx: &LateContext<'tcx>, pat: &'tcx Pat<'_>, arg: &'tcx Expr<'_>, body: &'tcx Expr<'_>, @@ -1403,7 +1403,7 @@ fn check_for_loop_explicit_counter<'a, 'tcx>( /// If `arg` was the argument to a `for` loop, return the "cleanest" way of writing the /// actual `Iterator` that the loop uses. -fn make_iterator_snippet(cx: &LateContext<'_, '_>, arg: &Expr<'_>, applic_ref: &mut Applicability) -> String { +fn make_iterator_snippet(cx: &LateContext<'_>, arg: &Expr<'_>, applic_ref: &mut Applicability) -> String { let impls_iterator = get_trait_def_id(cx, &paths::ITERATOR) .map_or(false, |id| implements_trait(cx, cx.tables().expr_ty(arg), id, &[])); if impls_iterator { @@ -1437,8 +1437,8 @@ fn make_iterator_snippet(cx: &LateContext<'_, '_>, arg: &Expr<'_>, applic_ref: & } /// Checks for the `FOR_KV_MAP` lint. -fn check_for_loop_over_map_kv<'a, 'tcx>( - cx: &LateContext<'a, 'tcx>, +fn check_for_loop_over_map_kv<'tcx>( + cx: &LateContext<'tcx>, pat: &'tcx Pat<'_>, arg: &'tcx Expr<'_>, body: &'tcx Expr<'_>, @@ -1490,7 +1490,7 @@ fn check_for_loop_over_map_kv<'a, 'tcx>( } struct MutatePairDelegate<'a, 'tcx> { - cx: &'a LateContext<'a, 'tcx>, + cx: &'a LateContext<'tcx>, hir_id_low: Option, hir_id_high: Option, span_low: Option, @@ -1531,7 +1531,7 @@ impl MutatePairDelegate<'_, '_> { } } -fn check_for_mut_range_bound(cx: &LateContext<'_, '_>, arg: &Expr<'_>, body: &Expr<'_>) { +fn check_for_mut_range_bound(cx: &LateContext<'_>, arg: &Expr<'_>, body: &Expr<'_>) { if let Some(higher::Range { start: Some(start), end: Some(end), @@ -1547,7 +1547,7 @@ fn check_for_mut_range_bound(cx: &LateContext<'_, '_>, arg: &Expr<'_>, body: &Ex } } -fn mut_warn_with_span(cx: &LateContext<'_, '_>, span: Option) { +fn mut_warn_with_span(cx: &LateContext<'_>, span: Option) { if let Some(sp) = span { span_lint( cx, @@ -1558,7 +1558,7 @@ fn mut_warn_with_span(cx: &LateContext<'_, '_>, span: Option) { } } -fn check_for_mutability(cx: &LateContext<'_, '_>, bound: &Expr<'_>) -> Option { +fn check_for_mutability(cx: &LateContext<'_>, bound: &Expr<'_>) -> Option { if_chain! { if let ExprKind::Path(ref qpath) = bound.kind; if let QPath::Resolved(None, _) = *qpath; @@ -1580,8 +1580,8 @@ fn check_for_mutability(cx: &LateContext<'_, '_>, bound: &Expr<'_>) -> Option( - cx: &LateContext<'a, 'tcx>, +fn check_for_mutation<'tcx>( + cx: &LateContext<'tcx>, body: &Expr<'_>, bound_ids: &[Option], ) -> (Option, Option) { @@ -1609,7 +1609,7 @@ fn pat_is_wild<'tcx>(pat: &'tcx PatKind<'_>, body: &'tcx Expr<'_>) -> bool { } struct LocalUsedVisitor<'a, 'tcx> { - cx: &'a LateContext<'a, 'tcx>, + cx: &'a LateContext<'tcx>, local: HirId, used: bool, } @@ -1632,7 +1632,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LocalUsedVisitor<'a, 'tcx> { struct VarVisitor<'a, 'tcx> { /// context reference - cx: &'a LateContext<'a, 'tcx>, + cx: &'a LateContext<'tcx>, /// var name to look for as index var: HirId, /// indexed variables that are used mutably @@ -1803,7 +1803,7 @@ impl<'a, 'tcx> Visitor<'tcx> for VarVisitor<'a, 'tcx> { } } -fn is_used_inside<'a, 'tcx>(cx: &'a LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>, container: &'tcx Expr<'_>) -> bool { +fn is_used_inside<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, container: &'tcx Expr<'_>) -> bool { let def_id = match var_def_id(cx, expr) { Some(id) => id, None => return false, @@ -1816,7 +1816,7 @@ fn is_used_inside<'a, 'tcx>(cx: &'a LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>, false } -fn is_iterator_used_after_while_let<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, iter_expr: &'tcx Expr<'_>) -> bool { +fn is_iterator_used_after_while_let<'tcx>(cx: &LateContext<'tcx>, iter_expr: &'tcx Expr<'_>) -> bool { let def_id = match var_def_id(cx, iter_expr) { Some(id) => id, None => return false, @@ -1835,7 +1835,7 @@ fn is_iterator_used_after_while_let<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, iter_e } struct VarUsedAfterLoopVisitor<'a, 'tcx> { - cx: &'a LateContext<'a, 'tcx>, + cx: &'a LateContext<'tcx>, def_id: HirId, iter_expr_id: HirId, past_while_let: bool, @@ -1863,7 +1863,7 @@ impl<'a, 'tcx> Visitor<'tcx> for VarUsedAfterLoopVisitor<'a, 'tcx> { /// Returns `true` if the type of expr is one that provides `IntoIterator` impls /// for `&T` and `&mut T`, such as `Vec`. #[rustfmt::skip] -fn is_ref_iterable_type(cx: &LateContext<'_, '_>, e: &Expr<'_>) -> bool { +fn is_ref_iterable_type(cx: &LateContext<'_>, e: &Expr<'_>) -> bool { // no walk_ptrs_ty: calling iter() on a reference can make sense because it // will allow further borrows afterwards let ty = cx.tables().expr_ty(e); @@ -1878,7 +1878,7 @@ fn is_ref_iterable_type(cx: &LateContext<'_, '_>, e: &Expr<'_>) -> bool { match_type(cx, ty, &paths::BTREESET) } -fn is_iterable_array<'tcx>(ty: Ty<'tcx>, cx: &LateContext<'_, 'tcx>) -> bool { +fn is_iterable_array<'tcx>(ty: Ty<'tcx>, cx: &LateContext<'tcx>) -> bool { // IntoIterator is currently only implemented for array sizes <= 32 in rustc match ty.kind { ty::Array(_, n) => { @@ -1946,7 +1946,7 @@ enum VarState { /// Scan a for loop for variables that are incremented exactly once. struct IncrementVisitor<'a, 'tcx> { - cx: &'a LateContext<'a, 'tcx>, // context reference + cx: &'a LateContext<'tcx>, // context reference states: FxHashMap, // incremented variables depth: u32, // depth of conditional expressions done: bool, @@ -2004,8 +2004,8 @@ impl<'a, 'tcx> Visitor<'tcx> for IncrementVisitor<'a, 'tcx> { /// Checks whether a variable is initialized to zero at the start of a loop. struct InitializeVisitor<'a, 'tcx> { - cx: &'a LateContext<'a, 'tcx>, // context reference - end_expr: &'tcx Expr<'tcx>, // the for loop. Stop scanning here. + cx: &'a LateContext<'tcx>, // context reference + end_expr: &'tcx Expr<'tcx>, // the for loop. Stop scanning here. var_id: HirId, state: VarState, name: Option, @@ -2094,7 +2094,7 @@ impl<'a, 'tcx> Visitor<'tcx> for InitializeVisitor<'a, 'tcx> { } } -fn var_def_id(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> Option { +fn var_def_id(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option { if let ExprKind::Path(ref qpath) = expr.kind { let path_res = qpath_res(cx, qpath, expr.hir_id); if let Res::Local(hir_id) = path_res { @@ -2118,7 +2118,7 @@ fn is_conditional(expr: &Expr<'_>) -> bool { } } -fn is_nested(cx: &LateContext<'_, '_>, match_expr: &Expr<'_>, iter_expr: &Expr<'_>) -> bool { +fn is_nested(cx: &LateContext<'_>, match_expr: &Expr<'_>, iter_expr: &Expr<'_>) -> bool { if_chain! { if let Some(loop_block) = get_enclosing_block(cx, match_expr.hir_id); let parent_node = cx.tcx.hir().get_parent_node(loop_block.hir_id); @@ -2130,7 +2130,7 @@ fn is_nested(cx: &LateContext<'_, '_>, match_expr: &Expr<'_>, iter_expr: &Expr<' false } -fn is_loop_nested(cx: &LateContext<'_, '_>, loop_expr: &Expr<'_>, iter_expr: &Expr<'_>) -> bool { +fn is_loop_nested(cx: &LateContext<'_>, loop_expr: &Expr<'_>, iter_expr: &Expr<'_>) -> bool { let mut id = loop_expr.hir_id; let iter_name = if let Some(name) = path_name(iter_expr) { name @@ -2240,7 +2240,7 @@ fn path_name(e: &Expr<'_>) -> Option { None } -fn check_infinite_loop<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, cond: &'tcx Expr<'_>, expr: &'tcx Expr<'_>) { +fn check_infinite_loop<'tcx>(cx: &LateContext<'tcx>, cond: &'tcx Expr<'_>, expr: &'tcx Expr<'_>) { if constant(cx, cx.tables(), cond).is_some() { // A pure constant condition (e.g., `while false`) is not linted. return; @@ -2321,7 +2321,7 @@ impl<'tcx> Visitor<'tcx> for HasBreakOrReturnVisitor { /// Note: In some cases such as `self`, there are no mutable annotation, /// All variables definition IDs are collected struct VarCollectorVisitor<'a, 'tcx> { - cx: &'a LateContext<'a, 'tcx>, + cx: &'a LateContext<'tcx>, ids: FxHashSet, def_ids: FxHashMap, skip: bool, @@ -2369,7 +2369,7 @@ impl<'a, 'tcx> Visitor<'tcx> for VarCollectorVisitor<'a, 'tcx> { const NEEDLESS_COLLECT_MSG: &str = "avoid using `collect()` when not needed"; -fn check_needless_collect<'a, 'tcx>(expr: &'tcx Expr<'_>, cx: &LateContext<'a, 'tcx>) { +fn check_needless_collect<'tcx>(expr: &'tcx Expr<'_>, cx: &LateContext<'tcx>) { if_chain! { if let ExprKind::MethodCall(ref method, _, ref args, _) = expr.kind; if let ExprKind::MethodCall(ref chain_method, _, _, _) = args[0].kind; diff --git a/clippy_lints/src/macro_use.rs b/clippy_lints/src/macro_use.rs index b845b20d2c012..065c7c042d367 100644 --- a/clippy_lints/src/macro_use.rs +++ b/clippy_lints/src/macro_use.rs @@ -44,7 +44,7 @@ pub struct MacroRefData { } impl MacroRefData { - pub fn new(name: String, callee: Span, cx: &LateContext<'_, '_>) -> Self { + pub fn new(name: String, callee: Span, cx: &LateContext<'_>) -> Self { let mut path = cx.sess().source_map().span_to_filename(callee).to_string(); // std lib paths are <::std::module::file type> @@ -72,7 +72,7 @@ pub struct MacroUseImports { impl_lint_pass!(MacroUseImports => [MACRO_USE_IMPORTS]); impl MacroUseImports { - fn push_unique_macro(&mut self, cx: &LateContext<'_, '_>, span: Span) { + fn push_unique_macro(&mut self, cx: &LateContext<'_>, span: Span) { let call_site = span.source_callsite(); let name = snippet(cx, cx.sess().source_map().span_until_char(call_site, '!'), "_"); if let Some(callee) = span.source_callee() { @@ -89,7 +89,7 @@ impl MacroUseImports { } } - fn push_unique_macro_pat_ty(&mut self, cx: &LateContext<'_, '_>, span: Span) { + fn push_unique_macro_pat_ty(&mut self, cx: &LateContext<'_>, span: Span) { let call_site = span.source_callsite(); let name = snippet(cx, cx.sess().source_map().span_until_char(call_site, '!'), "_"); if let Some(callee) = span.source_callee() { @@ -102,8 +102,8 @@ impl MacroUseImports { } } -impl<'l, 'txc> LateLintPass<'l, 'txc> for MacroUseImports { - fn check_item(&mut self, cx: &LateContext<'_, '_>, item: &hir::Item<'_>) { +impl<'tcx> LateLintPass<'tcx> for MacroUseImports { + fn check_item(&mut self, cx: &LateContext<'_>, item: &hir::Item<'_>) { if_chain! { if cx.sess().opts.edition == Edition::Edition2018; if let hir::ItemKind::Use(path, _kind) = &item.kind; @@ -127,33 +127,33 @@ impl<'l, 'txc> LateLintPass<'l, 'txc> for MacroUseImports { } } } - fn check_attribute(&mut self, cx: &LateContext<'_, '_>, attr: &ast::Attribute) { + fn check_attribute(&mut self, cx: &LateContext<'_>, attr: &ast::Attribute) { if in_macro(attr.span) { self.push_unique_macro(cx, attr.span); } } - fn check_expr(&mut self, cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>) { + fn check_expr(&mut self, cx: &LateContext<'_>, expr: &hir::Expr<'_>) { if in_macro(expr.span) { self.push_unique_macro(cx, expr.span); } } - fn check_stmt(&mut self, cx: &LateContext<'_, '_>, stmt: &hir::Stmt<'_>) { + fn check_stmt(&mut self, cx: &LateContext<'_>, stmt: &hir::Stmt<'_>) { if in_macro(stmt.span) { self.push_unique_macro(cx, stmt.span); } } - fn check_pat(&mut self, cx: &LateContext<'_, '_>, pat: &hir::Pat<'_>) { + fn check_pat(&mut self, cx: &LateContext<'_>, pat: &hir::Pat<'_>) { if in_macro(pat.span) { self.push_unique_macro_pat_ty(cx, pat.span); } } - fn check_ty(&mut self, cx: &LateContext<'_, '_>, ty: &hir::Ty<'_>) { + fn check_ty(&mut self, cx: &LateContext<'_>, ty: &hir::Ty<'_>) { if in_macro(ty.span) { self.push_unique_macro_pat_ty(cx, ty.span); } } #[allow(clippy::too_many_lines)] - fn check_crate_post(&mut self, cx: &LateContext<'_, '_>, _krate: &hir::Crate<'_>) { + fn check_crate_post(&mut self, cx: &LateContext<'_>, _krate: &hir::Crate<'_>) { let mut used = FxHashMap::default(); let mut check_dup = vec![]; for (import, span) in &self.imports { diff --git a/clippy_lints/src/main_recursion.rs b/clippy_lints/src/main_recursion.rs index 8a0e47a3d31c5..eceae706e4fc7 100644 --- a/clippy_lints/src/main_recursion.rs +++ b/clippy_lints/src/main_recursion.rs @@ -31,12 +31,12 @@ pub struct MainRecursion { impl_lint_pass!(MainRecursion => [MAIN_RECURSION]); -impl LateLintPass<'_, '_> for MainRecursion { - fn check_crate(&mut self, _: &LateContext<'_, '_>, krate: &Crate<'_>) { +impl LateLintPass<'_> for MainRecursion { + fn check_crate(&mut self, _: &LateContext<'_>, krate: &Crate<'_>) { self.has_no_std_attr = is_no_std_crate(krate); } - fn check_expr_post(&mut self, cx: &LateContext<'_, '_>, expr: &Expr<'_>) { + fn check_expr_post(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) { if self.has_no_std_attr { return; } diff --git a/clippy_lints/src/manual_async_fn.rs b/clippy_lints/src/manual_async_fn.rs index 03ab274d9ca9c..c19fb148cda59 100644 --- a/clippy_lints/src/manual_async_fn.rs +++ b/clippy_lints/src/manual_async_fn.rs @@ -38,10 +38,10 @@ declare_clippy_lint! { declare_lint_pass!(ManualAsyncFn => [MANUAL_ASYNC_FN]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ManualAsyncFn { +impl<'tcx> LateLintPass<'tcx> for ManualAsyncFn { fn check_fn( &mut self, - cx: &LateContext<'a, 'tcx>, + cx: &LateContext<'tcx>, kind: FnKind<'tcx>, decl: &'tcx FnDecl<'_>, body: &'tcx Body<'_>, @@ -97,7 +97,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ManualAsyncFn { } } -fn future_trait_ref<'tcx>(cx: &LateContext<'_, 'tcx>, ty: &'tcx Ty<'tcx>) -> Option<&'tcx TraitRef<'tcx>> { +fn future_trait_ref<'tcx>(cx: &LateContext<'tcx>, ty: &'tcx Ty<'tcx>) -> Option<&'tcx TraitRef<'tcx>> { if_chain! { if let TyKind::OpaqueDef(item_id, _) = ty.kind; let item = cx.tcx.hir().item(item_id.id); @@ -129,7 +129,7 @@ fn future_output_ty<'tcx>(trait_ref: &'tcx TraitRef<'tcx>) -> Option<&'tcx Ty<'t None } -fn desugared_async_block<'tcx>(cx: &LateContext<'_, 'tcx>, block: &'tcx Block<'tcx>) -> Option<&'tcx Body<'tcx>> { +fn desugared_async_block<'tcx>(cx: &LateContext<'tcx>, block: &'tcx Block<'tcx>) -> Option<&'tcx Body<'tcx>> { if_chain! { if let Some(block_expr) = block.expr; if let Some(args) = match_function_call(cx, block_expr, &FUTURE_FROM_GENERATOR); @@ -145,7 +145,7 @@ fn desugared_async_block<'tcx>(cx: &LateContext<'_, 'tcx>, block: &'tcx Block<'t None } -fn suggested_ret(cx: &LateContext<'_, '_>, output: &Ty<'_>) -> Option<(&'static str, String)> { +fn suggested_ret(cx: &LateContext<'_>, output: &Ty<'_>) -> Option<(&'static str, String)> { match output.kind { TyKind::Tup(tys) if tys.is_empty() => { let sugg = "remove the return type"; diff --git a/clippy_lints/src/map_clone.rs b/clippy_lints/src/map_clone.rs index 9109de9458f1c..905a3f3ca71c7 100644 --- a/clippy_lints/src/map_clone.rs +++ b/clippy_lints/src/map_clone.rs @@ -42,8 +42,8 @@ declare_clippy_lint! { declare_lint_pass!(MapClone => [MAP_CLONE]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MapClone { - fn check_expr(&mut self, cx: &LateContext<'_, '_>, e: &hir::Expr<'_>) { +impl<'tcx> LateLintPass<'tcx> for MapClone { + fn check_expr(&mut self, cx: &LateContext<'_>, e: &hir::Expr<'_>) { if e.span.from_expansion() { return; } @@ -106,7 +106,7 @@ fn ident_eq(name: Ident, path: &hir::Expr<'_>) -> bool { } } -fn lint_needless_cloning(cx: &LateContext<'_, '_>, root: Span, receiver: Span) { +fn lint_needless_cloning(cx: &LateContext<'_>, root: Span, receiver: Span) { span_lint_and_sugg( cx, MAP_CLONE, @@ -118,7 +118,7 @@ fn lint_needless_cloning(cx: &LateContext<'_, '_>, root: Span, receiver: Span) { ) } -fn lint(cx: &LateContext<'_, '_>, replace: Span, root: Span, copied: bool) { +fn lint(cx: &LateContext<'_>, replace: Span, root: Span, copied: bool) { let mut applicability = Applicability::MachineApplicable; if copied { span_lint_and_sugg( diff --git a/clippy_lints/src/map_unit_fn.rs b/clippy_lints/src/map_unit_fn.rs index 90d4a34a19a29..316a71c500512 100644 --- a/clippy_lints/src/map_unit_fn.rs +++ b/clippy_lints/src/map_unit_fn.rs @@ -100,7 +100,7 @@ fn is_unit_type(ty: Ty<'_>) -> bool { } } -fn is_unit_function(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>) -> bool { +fn is_unit_function(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> bool { let ty = cx.tables().expr_ty(expr); if let ty::FnDef(id, _) = ty.kind { @@ -111,7 +111,7 @@ fn is_unit_function(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>) -> bool { false } -fn is_unit_expression(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>) -> bool { +fn is_unit_expression(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> bool { is_unit_type(cx.tables().expr_ty(expr)) } @@ -119,7 +119,7 @@ fn is_unit_expression(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>) -> bool { /// semicolons, which causes problems when generating a suggestion. Given an /// expression that evaluates to '()' or '!', recursively remove useless braces /// and semi-colons until is suitable for including in the suggestion template -fn reduce_unit_expression<'a>(cx: &LateContext<'_, '_>, expr: &'a hir::Expr<'_>) -> Option { +fn reduce_unit_expression<'a>(cx: &LateContext<'_>, expr: &'a hir::Expr<'_>) -> Option { if !is_unit_expression(cx, expr) { return None; } @@ -161,7 +161,7 @@ fn reduce_unit_expression<'a>(cx: &LateContext<'_, '_>, expr: &'a hir::Expr<'_>) } fn unit_closure<'tcx>( - cx: &LateContext<'_, 'tcx>, + cx: &LateContext<'tcx>, expr: &hir::Expr<'_>, ) -> Option<(&'tcx hir::Param<'tcx>, &'tcx hir::Expr<'tcx>)> { if let hir::ExprKind::Closure(_, ref decl, inner_expr_id, _, _) = expr.kind { @@ -186,7 +186,7 @@ fn unit_closure<'tcx>( /// `y` => `_y` /// /// Anything else will return `a`. -fn let_binding_name(cx: &LateContext<'_, '_>, var_arg: &hir::Expr<'_>) -> String { +fn let_binding_name(cx: &LateContext<'_>, var_arg: &hir::Expr<'_>) -> String { match &var_arg.kind { hir::ExprKind::Field(_, _) => snippet(cx, var_arg.span, "_").replace(".", "_"), hir::ExprKind::Path(_) => format!("_{}", snippet(cx, var_arg.span, "")), @@ -202,7 +202,7 @@ fn suggestion_msg(function_type: &str, map_type: &str) -> String { ) } -fn lint_map_unit_fn(cx: &LateContext<'_, '_>, stmt: &hir::Stmt<'_>, expr: &hir::Expr<'_>, map_args: &[hir::Expr<'_>]) { +fn lint_map_unit_fn(cx: &LateContext<'_>, stmt: &hir::Stmt<'_>, expr: &hir::Expr<'_>, map_args: &[hir::Expr<'_>]) { let var_arg = &map_args[0]; let (map_type, variant, lint) = if is_type_diagnostic_item(cx, cx.tables().expr_ty(var_arg), sym!(option_type)) { @@ -258,8 +258,8 @@ fn lint_map_unit_fn(cx: &LateContext<'_, '_>, stmt: &hir::Stmt<'_>, expr: &hir:: } } -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MapUnit { - fn check_stmt(&mut self, cx: &LateContext<'_, '_>, stmt: &hir::Stmt<'_>) { +impl<'tcx> LateLintPass<'tcx> for MapUnit { + fn check_stmt(&mut self, cx: &LateContext<'_>, stmt: &hir::Stmt<'_>) { if stmt.span.from_expansion() { return; } diff --git a/clippy_lints/src/match_on_vec_items.rs b/clippy_lints/src/match_on_vec_items.rs index 4a025e0621f96..0003aa94a031e 100644 --- a/clippy_lints/src/match_on_vec_items.rs +++ b/clippy_lints/src/match_on_vec_items.rs @@ -44,8 +44,8 @@ declare_clippy_lint! { declare_lint_pass!(MatchOnVecItems => [MATCH_ON_VEC_ITEMS]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MatchOnVecItems { - fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'tcx>) { +impl<'tcx> LateLintPass<'tcx> for MatchOnVecItems { + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) { if_chain! { if !in_external_macro(cx.sess(), expr.span); if let ExprKind::Match(ref match_expr, _, MatchSource::Normal) = expr.kind; @@ -73,7 +73,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MatchOnVecItems { } } -fn is_vec_indexing<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'tcx>) -> Option<&'tcx Expr<'tcx>> { +fn is_vec_indexing<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) -> Option<&'tcx Expr<'tcx>> { if_chain! { if let ExprKind::Index(ref array, ref index) = expr.kind; if is_vector(cx, array); @@ -87,13 +87,13 @@ fn is_vec_indexing<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'tcx>) None } -fn is_vector(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> bool { +fn is_vector(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { let ty = cx.tables().expr_ty(expr); let ty = walk_ptrs_ty(ty); is_type_diagnostic_item(cx, ty, sym!(vec_type)) } -fn is_full_range(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> bool { +fn is_full_range(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { let ty = cx.tables().expr_ty(expr); let ty = walk_ptrs_ty(ty); match_type(cx, ty, &utils::paths::RANGE_FULL) diff --git a/clippy_lints/src/matches.rs b/clippy_lints/src/matches.rs index 0c91d8885d924..b754a45aa404f 100644 --- a/clippy_lints/src/matches.rs +++ b/clippy_lints/src/matches.rs @@ -430,8 +430,8 @@ impl_lint_pass!(Matches => [ REST_PAT_IN_FULLY_BOUND_STRUCTS ]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Matches { - fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) { +impl<'tcx> LateLintPass<'tcx> for Matches { + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { if in_external_macro(cx.sess(), expr.span) { return; } @@ -455,7 +455,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Matches { } } - fn check_local(&mut self, cx: &LateContext<'a, 'tcx>, local: &'tcx Local<'_>) { + fn check_local(&mut self, cx: &LateContext<'tcx>, local: &'tcx Local<'_>) { if_chain! { if !in_external_macro(cx.sess(), local.span); if !in_macro(local.span); @@ -491,7 +491,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Matches { } } - fn check_pat(&mut self, cx: &LateContext<'a, 'tcx>, pat: &'tcx Pat<'_>) { + fn check_pat(&mut self, cx: &LateContext<'tcx>, pat: &'tcx Pat<'_>) { if_chain! { if !in_external_macro(cx.sess(), pat.span); if !in_macro(pat.span); @@ -518,7 +518,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Matches { } #[rustfmt::skip] -fn check_single_match(cx: &LateContext<'_, '_>, ex: &Expr<'_>, arms: &[Arm<'_>], expr: &Expr<'_>) { +fn check_single_match(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>], expr: &Expr<'_>) { if arms.len() == 2 && arms[0].guard.is_none() && arms[1].guard.is_none() { if in_macro(expr.span) { // Don't lint match expressions present in @@ -549,7 +549,7 @@ fn check_single_match(cx: &LateContext<'_, '_>, ex: &Expr<'_>, arms: &[Arm<'_>], } fn check_single_match_single_pattern( - cx: &LateContext<'_, '_>, + cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>], expr: &Expr<'_>, @@ -561,7 +561,7 @@ fn check_single_match_single_pattern( } fn report_single_match_single_pattern( - cx: &LateContext<'_, '_>, + cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>], expr: &Expr<'_>, @@ -590,7 +590,7 @@ fn report_single_match_single_pattern( } fn check_single_match_opt_like( - cx: &LateContext<'_, '_>, + cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>], expr: &Expr<'_>, @@ -630,7 +630,7 @@ fn check_single_match_opt_like( } } -fn check_match_bool(cx: &LateContext<'_, '_>, ex: &Expr<'_>, arms: &[Arm<'_>], expr: &Expr<'_>) { +fn check_match_bool(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>], expr: &Expr<'_>) { // Type of expression is `bool`. if cx.tables().expr_ty(ex).kind == ty::Bool { span_lint_and_then( @@ -694,7 +694,7 @@ fn check_match_bool(cx: &LateContext<'_, '_>, ex: &Expr<'_>, arms: &[Arm<'_>], e } } -fn check_overlapping_arms<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, ex: &'tcx Expr<'_>, arms: &'tcx [Arm<'_>]) { +fn check_overlapping_arms<'tcx>(cx: &LateContext<'tcx>, ex: &'tcx Expr<'_>, arms: &'tcx [Arm<'_>]) { if arms.len() >= 2 && cx.tables().expr_ty(ex).is_integral() { let ranges = all_ranges(cx, arms, cx.tables().expr_ty(ex)); let type_ranges = type_ranges(&ranges); @@ -713,7 +713,7 @@ fn check_overlapping_arms<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, ex: &'tcx Expr<' } } -fn check_wild_err_arm(cx: &LateContext<'_, '_>, ex: &Expr<'_>, arms: &[Arm<'_>]) { +fn check_wild_err_arm(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>]) { let ex_ty = walk_ptrs_ty(cx.tables().expr_ty(ex)); if is_type_diagnostic_item(cx, ex_ty, sym!(result_type)) { for arm in arms { @@ -754,7 +754,7 @@ fn check_wild_err_arm(cx: &LateContext<'_, '_>, ex: &Expr<'_>, arms: &[Arm<'_>]) } } -fn check_wild_enum_match(cx: &LateContext<'_, '_>, ex: &Expr<'_>, arms: &[Arm<'_>]) { +fn check_wild_enum_match(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>]) { let ty = cx.tables().expr_ty(ex); if !ty.is_enum() { // If there isn't a nice closed set of possible values that can be conveniently enumerated, @@ -884,7 +884,7 @@ fn is_panic_block(block: &Block<'_>) -> bool { } } -fn check_match_ref_pats(cx: &LateContext<'_, '_>, ex: &Expr<'_>, arms: &[Arm<'_>], expr: &Expr<'_>) { +fn check_match_ref_pats(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>], expr: &Expr<'_>) { if has_only_ref_pats(arms) { let mut suggs = Vec::with_capacity(arms.len() + 1); let (title, msg) = if let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Not, ref inner) = ex.kind { @@ -919,7 +919,7 @@ fn check_match_ref_pats(cx: &LateContext<'_, '_>, ex: &Expr<'_>, arms: &[Arm<'_> } } -fn check_match_as_ref(cx: &LateContext<'_, '_>, ex: &Expr<'_>, arms: &[Arm<'_>], expr: &Expr<'_>) { +fn check_match_as_ref(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>], expr: &Expr<'_>) { if arms.len() == 2 && arms[0].guard.is_none() && arms[1].guard.is_none() { let arm_ref: Option = if is_none_arm(&arms[0]) { is_ref_some_arm(&arms[1]) @@ -971,7 +971,7 @@ fn check_match_as_ref(cx: &LateContext<'_, '_>, ex: &Expr<'_>, arms: &[Arm<'_>], } } -fn check_wild_in_or_pats(cx: &LateContext<'_, '_>, arms: &[Arm<'_>]) { +fn check_wild_in_or_pats(cx: &LateContext<'_>, arms: &[Arm<'_>]) { for arm in arms { if let PatKind::Or(ref fields) = arm.pat.kind { // look for multiple fields in this arm that contains at least one Wild pattern @@ -989,7 +989,7 @@ fn check_wild_in_or_pats(cx: &LateContext<'_, '_>, arms: &[Arm<'_>]) { } } -fn check_match_single_binding<'a>(cx: &LateContext<'_, 'a>, ex: &Expr<'a>, arms: &[Arm<'_>], expr: &Expr<'_>) { +fn check_match_single_binding<'a>(cx: &LateContext<'a>, ex: &Expr<'a>, arms: &[Arm<'_>], expr: &Expr<'_>) { if in_macro(expr.span) || arms.len() != 1 || is_refutable(cx, arms[0].pat) { return; } @@ -1085,7 +1085,7 @@ fn check_match_single_binding<'a>(cx: &LateContext<'_, 'a>, ex: &Expr<'a>, arms: } /// Returns true if the `ex` match expression is in a local (`let`) statement -fn opt_parent_let<'a>(cx: &LateContext<'_, 'a>, ex: &Expr<'a>) -> Option<&'a Local<'a>> { +fn opt_parent_let<'a>(cx: &LateContext<'a>, ex: &Expr<'a>) -> Option<&'a Local<'a>> { if_chain! { let map = &cx.tcx.hir(); if let Some(Node::Expr(parent_arm_expr)) = map.find(map.get_parent_node(ex.hir_id)); @@ -1098,11 +1098,7 @@ fn opt_parent_let<'a>(cx: &LateContext<'_, 'a>, ex: &Expr<'a>) -> Option<&'a Loc } /// Gets all arms that are unbounded `PatRange`s. -fn all_ranges<'a, 'tcx>( - cx: &LateContext<'a, 'tcx>, - arms: &'tcx [Arm<'_>], - ty: Ty<'tcx>, -) -> Vec> { +fn all_ranges<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'_>], ty: Ty<'tcx>) -> Vec> { arms.iter() .flat_map(|arm| { if let Arm { diff --git a/clippy_lints/src/mem_discriminant.rs b/clippy_lints/src/mem_discriminant.rs index 8a665a6e1fad3..06c568513035f 100644 --- a/clippy_lints/src/mem_discriminant.rs +++ b/clippy_lints/src/mem_discriminant.rs @@ -29,8 +29,8 @@ declare_clippy_lint! { declare_lint_pass!(MemDiscriminant => [MEM_DISCRIMINANT_NON_ENUM]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MemDiscriminant { - fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) { +impl<'tcx> LateLintPass<'tcx> for MemDiscriminant { + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { if_chain! { if let ExprKind::Call(ref func, ref func_args) = expr.kind; // is `mem::discriminant` diff --git a/clippy_lints/src/mem_forget.rs b/clippy_lints/src/mem_forget.rs index 1821bd9135f98..b895ba324c78a 100644 --- a/clippy_lints/src/mem_forget.rs +++ b/clippy_lints/src/mem_forget.rs @@ -25,8 +25,8 @@ declare_clippy_lint! { declare_lint_pass!(MemForget => [MEM_FORGET]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MemForget { - fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr<'_>) { +impl<'tcx> LateLintPass<'tcx> for MemForget { + fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) { if let ExprKind::Call(ref path_expr, ref args) = e.kind { if let ExprKind::Path(ref qpath) = path_expr.kind { if let Some(def_id) = qpath_res(cx, qpath, path_expr.hir_id).opt_def_id() { diff --git a/clippy_lints/src/mem_replace.rs b/clippy_lints/src/mem_replace.rs index 703f91f8ac028..25f332cdcc286 100644 --- a/clippy_lints/src/mem_replace.rs +++ b/clippy_lints/src/mem_replace.rs @@ -97,7 +97,7 @@ declare_clippy_lint! { declare_lint_pass!(MemReplace => [MEM_REPLACE_OPTION_WITH_NONE, MEM_REPLACE_WITH_UNINIT, MEM_REPLACE_WITH_DEFAULT]); -fn check_replace_option_with_none(cx: &LateContext<'_, '_>, src: &Expr<'_>, dest: &Expr<'_>, expr_span: Span) { +fn check_replace_option_with_none(cx: &LateContext<'_>, src: &Expr<'_>, dest: &Expr<'_>, expr_span: Span) { if let ExprKind::Path(ref replacement_qpath) = src.kind { // Check that second argument is `Option::None` if match_qpath(replacement_qpath, &paths::OPTION_NONE) { @@ -135,7 +135,7 @@ fn check_replace_option_with_none(cx: &LateContext<'_, '_>, src: &Expr<'_>, dest } } -fn check_replace_with_uninit(cx: &LateContext<'_, '_>, src: &Expr<'_>, dest: &Expr<'_>, expr_span: Span) { +fn check_replace_with_uninit(cx: &LateContext<'_>, src: &Expr<'_>, dest: &Expr<'_>, expr_span: Span) { if_chain! { // check if replacement is mem::MaybeUninit::uninit().assume_init() if let Some(method_def_id) = cx.tables().type_dependent_def_id(src.hir_id); @@ -193,7 +193,7 @@ fn check_replace_with_uninit(cx: &LateContext<'_, '_>, src: &Expr<'_>, dest: &Ex } } -fn check_replace_with_default(cx: &LateContext<'_, '_>, src: &Expr<'_>, dest: &Expr<'_>, expr_span: Span) { +fn check_replace_with_default(cx: &LateContext<'_>, src: &Expr<'_>, dest: &Expr<'_>, expr_span: Span) { if let ExprKind::Call(ref repl_func, _) = src.kind { if_chain! { if !in_external_macro(cx.tcx.sess, expr_span); @@ -224,8 +224,8 @@ fn check_replace_with_default(cx: &LateContext<'_, '_>, src: &Expr<'_>, dest: &E } } -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MemReplace { - fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) { +impl<'tcx> LateLintPass<'tcx> for MemReplace { + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { if_chain! { // Check that `expr` is a call to `mem::replace()` if let ExprKind::Call(ref func, ref func_args) = expr.kind; diff --git a/clippy_lints/src/methods/bind_instead_of_map.rs b/clippy_lints/src/methods/bind_instead_of_map.rs index 092702c8b8c7b..fcf7b509eadbf 100644 --- a/clippy_lints/src/methods/bind_instead_of_map.rs +++ b/clippy_lints/src/methods/bind_instead_of_map.rs @@ -77,7 +77,7 @@ pub(crate) trait BindInsteadOfMap { } fn lint_closure_autofixable( - cx: &LateContext<'_, '_>, + cx: &LateContext<'_>, expr: &hir::Expr<'_>, args: &[hir::Expr<'_>], closure_expr: &hir::Expr<'_>, @@ -120,7 +120,7 @@ pub(crate) trait BindInsteadOfMap { } } - fn lint_closure(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, closure_expr: &hir::Expr<'_>) { + fn lint_closure(cx: &LateContext<'_>, expr: &hir::Expr<'_>, closure_expr: &hir::Expr<'_>) { let mut suggs = Vec::new(); let can_sugg = find_all_ret_expressions(cx, closure_expr, |ret_expr| { if_chain! { @@ -156,7 +156,7 @@ pub(crate) trait BindInsteadOfMap { } /// Lint use of `_.and_then(|x| Some(y))` for `Option`s - fn lint(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, args: &[hir::Expr<'_>]) { + fn lint(cx: &LateContext<'_>, expr: &hir::Expr<'_>, args: &[hir::Expr<'_>]) { if !match_type(cx, cx.tables().expr_ty(&args[0]), Self::TYPE_QPATH) { return; } @@ -216,7 +216,7 @@ fn contains_try(expr: &hir::Expr<'_>) -> bool { visitor.found } -fn find_all_ret_expressions<'hir, F>(_cx: &LateContext<'_, '_>, expr: &'hir hir::Expr<'hir>, callback: F) -> bool +fn find_all_ret_expressions<'hir, F>(_cx: &LateContext<'_>, expr: &'hir hir::Expr<'hir>, callback: F) -> bool where F: FnMut(&'hir hir::Expr<'hir>) -> bool, { diff --git a/clippy_lints/src/methods/inefficient_to_string.rs b/clippy_lints/src/methods/inefficient_to_string.rs index d29b9adcb7d43..1c0018a5b95e2 100644 --- a/clippy_lints/src/methods/inefficient_to_string.rs +++ b/clippy_lints/src/methods/inefficient_to_string.rs @@ -9,7 +9,7 @@ use rustc_lint::LateContext; use rustc_middle::ty::{self, Ty}; /// Checks for the `INEFFICIENT_TO_STRING` lint -pub fn lint<'tcx>(cx: &LateContext<'_, 'tcx>, expr: &hir::Expr<'_>, arg: &hir::Expr<'_>, arg_ty: Ty<'tcx>) { +pub fn lint<'tcx>(cx: &LateContext<'tcx>, expr: &hir::Expr<'_>, arg: &hir::Expr<'_>, arg_ty: Ty<'tcx>) { if_chain! { if let Some(to_string_meth_did) = cx.tables().type_dependent_def_id(expr.hir_id); if match_def_path(cx, to_string_meth_did, &paths::TO_STRING_METHOD); @@ -45,7 +45,7 @@ pub fn lint<'tcx>(cx: &LateContext<'_, 'tcx>, expr: &hir::Expr<'_>, arg: &hir::E /// Returns whether `ty` specializes `ToString`. /// Currently, these are `str`, `String`, and `Cow<'_, str>`. -fn specializes_tostring(cx: &LateContext<'_, '_>, ty: Ty<'_>) -> bool { +fn specializes_tostring(cx: &LateContext<'_>, ty: Ty<'_>) -> bool { if let ty::Str = ty.kind { return true; } diff --git a/clippy_lints/src/methods/manual_saturating_arithmetic.rs b/clippy_lints/src/methods/manual_saturating_arithmetic.rs index eb02314f4680a..9c04b6d57b90f 100644 --- a/clippy_lints/src/methods/manual_saturating_arithmetic.rs +++ b/clippy_lints/src/methods/manual_saturating_arithmetic.rs @@ -6,7 +6,7 @@ use rustc_hir as hir; use rustc_lint::LateContext; use rustc_target::abi::LayoutOf; -pub fn lint(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, args: &[&[hir::Expr<'_>]], arith: &str) { +pub fn lint(cx: &LateContext<'_>, expr: &hir::Expr<'_>, args: &[&[hir::Expr<'_>]], arith: &str) { let unwrap_arg = &args[0][1]; let arith_lhs = &args[1][0]; let arith_rhs = &args[1][1]; @@ -85,7 +85,7 @@ enum MinMax { Max, } -fn is_min_or_max<'tcx>(cx: &LateContext<'_, 'tcx>, expr: &hir::Expr<'_>) -> Option { +fn is_min_or_max<'tcx>(cx: &LateContext<'tcx>, expr: &hir::Expr<'_>) -> Option { // `T::max_value()` `T::min_value()` inherent methods if_chain! { if let hir::ExprKind::Call(func, args) = &expr.kind; diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index 7018a2f403976..216db12f0115f 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -1357,9 +1357,9 @@ declare_lint_pass!(Methods => [ OPTION_AS_REF_DEREF, ]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Methods { +impl<'tcx> LateLintPass<'tcx> for Methods { #[allow(clippy::too_many_lines)] - fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx hir::Expr<'_>) { + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>) { if in_macro(expr.span) { return; } @@ -1471,7 +1471,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Methods { } } - fn check_impl_item(&mut self, cx: &LateContext<'a, 'tcx>, impl_item: &'tcx hir::ImplItem<'_>) { + fn check_impl_item(&mut self, cx: &LateContext<'tcx>, impl_item: &'tcx hir::ImplItem<'_>) { if in_external_macro(cx.sess(), impl_item.span) { return; } @@ -1585,8 +1585,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Methods { /// Checks for the `OR_FUN_CALL` lint. #[allow(clippy::too_many_lines)] -fn lint_or_fun_call<'a, 'tcx>( - cx: &LateContext<'a, 'tcx>, +fn lint_or_fun_call<'tcx>( + cx: &LateContext<'tcx>, expr: &hir::Expr<'_>, method_span: Span, name: &str, @@ -1594,7 +1594,7 @@ fn lint_or_fun_call<'a, 'tcx>( ) { // Searches an expression for method calls or function calls that aren't ctors struct FunCallFinder<'a, 'tcx> { - cx: &'a LateContext<'a, 'tcx>, + cx: &'a LateContext<'tcx>, found: bool, } @@ -1625,7 +1625,7 @@ fn lint_or_fun_call<'a, 'tcx>( /// Checks for `unwrap_or(T::new())` or `unwrap_or(T::default())`. fn check_unwrap_or_default( - cx: &LateContext<'_, '_>, + cx: &LateContext<'_>, name: &str, fun: &hir::Expr<'_>, self_expr: &hir::Expr<'_>, @@ -1667,8 +1667,8 @@ fn lint_or_fun_call<'a, 'tcx>( /// Checks for `*or(foo())`. #[allow(clippy::too_many_arguments)] - fn check_general_case<'a, 'tcx>( - cx: &LateContext<'a, 'tcx>, + fn check_general_case<'tcx>( + cx: &LateContext<'tcx>, name: &str, method_span: Span, fun_span: Span, @@ -1769,7 +1769,7 @@ fn lint_or_fun_call<'a, 'tcx>( /// Checks for the `EXPECT_FUN_CALL` lint. #[allow(clippy::too_many_lines)] fn lint_expect_fun_call( - cx: &LateContext<'_, '_>, + cx: &LateContext<'_>, expr: &hir::Expr<'_>, method_span: Span, name: &str, @@ -1777,7 +1777,7 @@ fn lint_expect_fun_call( ) { // Strip `&`, `as_ref()` and `as_str()` off `arg` until we're left with either a `String` or // `&str` - fn get_arg_root<'a>(cx: &LateContext<'_, '_>, arg: &'a hir::Expr<'a>) -> &'a hir::Expr<'a> { + fn get_arg_root<'a>(cx: &LateContext<'_>, arg: &'a hir::Expr<'a>) -> &'a hir::Expr<'a> { let mut arg_root = arg; loop { arg_root = match &arg_root.kind { @@ -1804,7 +1804,7 @@ fn lint_expect_fun_call( // Only `&'static str` or `String` can be used directly in the `panic!`. Other types should be // converted to string. - fn requires_to_string(cx: &LateContext<'_, '_>, arg: &hir::Expr<'_>) -> bool { + fn requires_to_string(cx: &LateContext<'_>, arg: &hir::Expr<'_>) -> bool { let arg_ty = cx.tables().expr_ty(arg); if is_type_diagnostic_item(cx, arg_ty, sym!(string_type)) { return false; @@ -1819,7 +1819,7 @@ fn lint_expect_fun_call( // Check if an expression could have type `&'static str`, knowing that it // has type `&str` for some lifetime. - fn can_be_static_str(cx: &LateContext<'_, '_>, arg: &hir::Expr<'_>) -> bool { + fn can_be_static_str(cx: &LateContext<'_>, arg: &hir::Expr<'_>) -> bool { match arg.kind { hir::ExprKind::Lit(_) => true, hir::ExprKind::Call(fun, _) => { @@ -1853,7 +1853,7 @@ fn lint_expect_fun_call( } fn generate_format_arg_snippet( - cx: &LateContext<'_, '_>, + cx: &LateContext<'_>, a: &hir::Expr<'_>, applicability: &mut Applicability, ) -> Vec { @@ -1956,7 +1956,7 @@ fn lint_expect_fun_call( } /// Checks for the `CLONE_ON_COPY` lint. -fn lint_clone_on_copy(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, arg: &hir::Expr<'_>, arg_ty: Ty<'_>) { +fn lint_clone_on_copy(cx: &LateContext<'_>, expr: &hir::Expr<'_>, arg: &hir::Expr<'_>, arg_ty: Ty<'_>) { let ty = cx.tables().expr_ty(expr); if let ty::Ref(_, inner, _) = arg_ty.kind { if let ty::Ref(_, innermost, _) = inner.kind { @@ -2050,7 +2050,7 @@ fn lint_clone_on_copy(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, arg: &hir: } } -fn lint_clone_on_ref_ptr(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, arg: &hir::Expr<'_>) { +fn lint_clone_on_ref_ptr(cx: &LateContext<'_>, expr: &hir::Expr<'_>, arg: &hir::Expr<'_>) { let obj_ty = walk_ptrs_ty(cx.tables().expr_ty(arg)); if let ty::Adt(_, subst) = obj_ty.kind { @@ -2081,7 +2081,7 @@ fn lint_clone_on_ref_ptr(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, arg: &h } } -fn lint_string_extend(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, args: &[hir::Expr<'_>]) { +fn lint_string_extend(cx: &LateContext<'_>, expr: &hir::Expr<'_>, args: &[hir::Expr<'_>]) { let arg = &args[1]; if let Some(arglists) = method_chain_args(arg, &["chars"]) { let target = &arglists[0][0]; @@ -2112,14 +2112,14 @@ fn lint_string_extend(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, args: &[hi } } -fn lint_extend(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, args: &[hir::Expr<'_>]) { +fn lint_extend(cx: &LateContext<'_>, expr: &hir::Expr<'_>, args: &[hir::Expr<'_>]) { let obj_ty = walk_ptrs_ty(cx.tables().expr_ty(&args[0])); if is_type_diagnostic_item(cx, obj_ty, sym!(string_type)) { lint_string_extend(cx, expr, args); } } -fn lint_cstring_as_ptr(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, source: &hir::Expr<'_>, unwrap: &hir::Expr<'_>) { +fn lint_cstring_as_ptr(cx: &LateContext<'_>, expr: &hir::Expr<'_>, source: &hir::Expr<'_>, unwrap: &hir::Expr<'_>) { if_chain! { let source_type = cx.tables().expr_ty(source); if let ty::Adt(def, substs) = source_type.kind; @@ -2139,11 +2139,7 @@ fn lint_cstring_as_ptr(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, source: & } } -fn lint_iter_cloned_collect<'a, 'tcx>( - cx: &LateContext<'a, 'tcx>, - expr: &hir::Expr<'_>, - iter_args: &'tcx [hir::Expr<'_>], -) { +fn lint_iter_cloned_collect<'tcx>(cx: &LateContext<'tcx>, expr: &hir::Expr<'_>, iter_args: &'tcx [hir::Expr<'_>]) { if_chain! { if is_type_diagnostic_item(cx, cx.tables().expr_ty(expr), sym!(vec_type)); if let Some(slice) = derefs_to_slice(cx, &iter_args[0], cx.tables().expr_ty(&iter_args[0])); @@ -2164,9 +2160,9 @@ fn lint_iter_cloned_collect<'a, 'tcx>( } } -fn lint_unnecessary_fold(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, fold_args: &[hir::Expr<'_>], fold_span: Span) { +fn lint_unnecessary_fold(cx: &LateContext<'_>, expr: &hir::Expr<'_>, fold_args: &[hir::Expr<'_>], fold_span: Span) { fn check_fold_with_op( - cx: &LateContext<'_, '_>, + cx: &LateContext<'_>, expr: &hir::Expr<'_>, fold_args: &[hir::Expr<'_>], fold_span: Span, @@ -2251,7 +2247,7 @@ fn lint_unnecessary_fold(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, fold_ar } } -fn lint_step_by<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &hir::Expr<'_>, args: &'tcx [hir::Expr<'_>]) { +fn lint_step_by<'tcx>(cx: &LateContext<'tcx>, expr: &hir::Expr<'_>, args: &'tcx [hir::Expr<'_>]) { if match_trait_method(cx, expr, &paths::ITERATOR) { if let Some((Constant::Int(0), _)) = constant(cx, cx.tables(), &args[1]) { span_lint( @@ -2264,7 +2260,7 @@ fn lint_step_by<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &hir::Expr<'_>, args } } -fn lint_iter_next<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx hir::Expr<'_>, iter_args: &'tcx [hir::Expr<'_>]) { +fn lint_iter_next<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>, iter_args: &'tcx [hir::Expr<'_>]) { let caller_expr = &iter_args[0]; // Skip lint if the `iter().next()` expression is a for loop argument, @@ -2318,8 +2314,8 @@ fn lint_iter_next<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx hir::Expr<'_ } } -fn lint_iter_nth<'a, 'tcx>( - cx: &LateContext<'a, 'tcx>, +fn lint_iter_nth<'tcx>( + cx: &LateContext<'tcx>, expr: &hir::Expr<'_>, nth_and_iter_args: &[&'tcx [hir::Expr<'tcx>]], is_mut: bool, @@ -2348,7 +2344,7 @@ fn lint_iter_nth<'a, 'tcx>( ); } -fn lint_iter_nth_zero<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &hir::Expr<'_>, nth_args: &'tcx [hir::Expr<'_>]) { +fn lint_iter_nth_zero<'tcx>(cx: &LateContext<'tcx>, expr: &hir::Expr<'_>, nth_args: &'tcx [hir::Expr<'_>]) { if_chain! { if match_trait_method(cx, expr, &paths::ITERATOR); if let Some((Constant::Int(0), _)) = constant(cx, cx.tables(), &nth_args[1]); @@ -2367,12 +2363,7 @@ fn lint_iter_nth_zero<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &hir::Expr<'_> } } -fn lint_get_unwrap<'a, 'tcx>( - cx: &LateContext<'a, 'tcx>, - expr: &hir::Expr<'_>, - get_args: &'tcx [hir::Expr<'_>], - is_mut: bool, -) { +fn lint_get_unwrap<'tcx>(cx: &LateContext<'tcx>, expr: &hir::Expr<'_>, get_args: &'tcx [hir::Expr<'_>], is_mut: bool) { // Note: we don't want to lint `get_mut().unwrap` for `HashMap` or `BTreeMap`, // because they do not implement `IndexMut` let mut applicability = Applicability::MachineApplicable; @@ -2445,7 +2436,7 @@ fn lint_get_unwrap<'a, 'tcx>( ); } -fn lint_iter_skip_next(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>) { +fn lint_iter_skip_next(cx: &LateContext<'_>, expr: &hir::Expr<'_>) { // lint if caller of skip is an Iterator if match_trait_method(cx, expr, &paths::ITERATOR) { span_lint_and_help( @@ -2459,12 +2450,12 @@ fn lint_iter_skip_next(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>) { } } -fn derefs_to_slice<'a, 'tcx>( - cx: &LateContext<'a, 'tcx>, +fn derefs_to_slice<'tcx>( + cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'tcx>, ty: Ty<'tcx>, ) -> Option<&'tcx hir::Expr<'tcx>> { - fn may_slice<'a>(cx: &LateContext<'_, 'a>, ty: Ty<'a>) -> bool { + fn may_slice<'a>(cx: &LateContext<'a>, ty: Ty<'a>) -> bool { match ty.kind { ty::Slice(_) => true, ty::Adt(def, _) if def.is_box() => may_slice(cx, ty.boxed_ty()), @@ -2504,7 +2495,7 @@ fn derefs_to_slice<'a, 'tcx>( } /// lint use of `unwrap()` for `Option`s and `Result`s -fn lint_unwrap(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, unwrap_args: &[hir::Expr<'_>]) { +fn lint_unwrap(cx: &LateContext<'_>, expr: &hir::Expr<'_>, unwrap_args: &[hir::Expr<'_>]) { let obj_ty = walk_ptrs_ty(cx.tables().expr_ty(&unwrap_args[0])); let mess = if is_type_diagnostic_item(cx, obj_ty, sym!(option_type)) { @@ -2532,7 +2523,7 @@ fn lint_unwrap(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, unwrap_args: &[hi } /// lint use of `expect()` for `Option`s and `Result`s -fn lint_expect(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, expect_args: &[hir::Expr<'_>]) { +fn lint_expect(cx: &LateContext<'_>, expr: &hir::Expr<'_>, expect_args: &[hir::Expr<'_>]) { let obj_ty = walk_ptrs_ty(cx.tables().expr_ty(&expect_args[0])); let mess = if is_type_diagnostic_item(cx, obj_ty, sym!(option_type)) { @@ -2556,7 +2547,7 @@ fn lint_expect(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, expect_args: &[hi } /// lint use of `ok().expect()` for `Result`s -fn lint_ok_expect(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, ok_args: &[hir::Expr<'_>]) { +fn lint_ok_expect(cx: &LateContext<'_>, expr: &hir::Expr<'_>, ok_args: &[hir::Expr<'_>]) { if_chain! { // lint if the caller of `ok()` is a `Result` if is_type_diagnostic_item(cx, cx.tables().expr_ty(&ok_args[0]), sym!(result_type)); @@ -2578,7 +2569,7 @@ fn lint_ok_expect(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, ok_args: &[hir } /// lint use of `map().flatten()` for `Iterators` and 'Options' -fn lint_map_flatten<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx hir::Expr<'_>, map_args: &'tcx [hir::Expr<'_>]) { +fn lint_map_flatten<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>, map_args: &'tcx [hir::Expr<'_>]) { // lint if caller of `.map().flatten()` is an Iterator if match_trait_method(cx, expr, &paths::ITERATOR) { let msg = "called `map(..).flatten()` on an `Iterator`. \ @@ -2617,8 +2608,8 @@ fn lint_map_flatten<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx hir::Expr< } /// lint use of `map().unwrap_or_else()` for `Option`s and `Result`s -fn lint_map_unwrap_or_else<'a, 'tcx>( - cx: &LateContext<'a, 'tcx>, +fn lint_map_unwrap_or_else<'tcx>( + cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>, map_args: &'tcx [hir::Expr<'_>], unwrap_args: &'tcx [hir::Expr<'_>], @@ -2674,11 +2665,7 @@ fn lint_map_unwrap_or_else<'a, 'tcx>( } /// lint use of `_.map_or(None, _)` for `Option`s and `Result`s -fn lint_map_or_none<'a, 'tcx>( - cx: &LateContext<'a, 'tcx>, - expr: &'tcx hir::Expr<'_>, - map_or_args: &'tcx [hir::Expr<'_>], -) { +fn lint_map_or_none<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>, map_or_args: &'tcx [hir::Expr<'_>]) { let is_option = is_type_diagnostic_item(cx, cx.tables().expr_ty(&map_or_args[0]), sym!(option_type)); let is_result = is_type_diagnostic_item(cx, cx.tables().expr_ty(&map_or_args[0]), sym!(result_type)); @@ -2748,11 +2735,7 @@ fn lint_map_or_none<'a, 'tcx>( } /// 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<'_>], -) { +fn lint_filter_next<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>, filter_args: &'tcx [hir::Expr<'_>]) { // lint if caller of `.filter().next()` is an Iterator if match_trait_method(cx, expr, &paths::ITERATOR) { let msg = "called `filter(p).next()` on an `Iterator`. This is more succinctly expressed by calling \ @@ -2775,8 +2758,8 @@ fn lint_filter_next<'a, 'tcx>( } /// lint use of `skip_while().next()` for `Iterators` -fn lint_skip_while_next<'a, 'tcx>( - cx: &LateContext<'a, 'tcx>, +fn lint_skip_while_next<'tcx>( + cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>, _skip_while_args: &'tcx [hir::Expr<'_>], ) { @@ -2794,8 +2777,8 @@ fn lint_skip_while_next<'a, 'tcx>( } /// lint use of `filter().map()` for `Iterators` -fn lint_filter_map<'a, 'tcx>( - cx: &LateContext<'a, 'tcx>, +fn lint_filter_map<'tcx>( + cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>, _filter_args: &'tcx [hir::Expr<'_>], _map_args: &'tcx [hir::Expr<'_>], @@ -2809,11 +2792,7 @@ fn lint_filter_map<'a, 'tcx>( } /// lint use of `filter_map().next()` for `Iterators` -fn lint_filter_map_next<'a, 'tcx>( - cx: &LateContext<'a, 'tcx>, - expr: &'tcx hir::Expr<'_>, - filter_args: &'tcx [hir::Expr<'_>], -) { +fn lint_filter_map_next<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>, filter_args: &'tcx [hir::Expr<'_>]) { if match_trait_method(cx, expr, &paths::ITERATOR) { let msg = "called `filter_map(p).next()` on an `Iterator`. This is more succinctly expressed by calling \ `.find_map(p)` instead."; @@ -2834,8 +2813,8 @@ fn lint_filter_map_next<'a, 'tcx>( } /// lint use of `find().map()` for `Iterators` -fn lint_find_map<'a, 'tcx>( - cx: &LateContext<'a, 'tcx>, +fn lint_find_map<'tcx>( + cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>, _find_args: &'tcx [hir::Expr<'_>], map_args: &'tcx [hir::Expr<'_>], @@ -2849,8 +2828,8 @@ fn lint_find_map<'a, 'tcx>( } /// lint use of `filter_map().map()` for `Iterators` -fn lint_filter_map_map<'a, 'tcx>( - cx: &LateContext<'a, 'tcx>, +fn lint_filter_map_map<'tcx>( + cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>, _filter_args: &'tcx [hir::Expr<'_>], _map_args: &'tcx [hir::Expr<'_>], @@ -2864,8 +2843,8 @@ fn lint_filter_map_map<'a, 'tcx>( } /// lint use of `filter().flat_map()` for `Iterators` -fn lint_filter_flat_map<'a, 'tcx>( - cx: &LateContext<'a, 'tcx>, +fn lint_filter_flat_map<'tcx>( + cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>, _filter_args: &'tcx [hir::Expr<'_>], _map_args: &'tcx [hir::Expr<'_>], @@ -2880,8 +2859,8 @@ fn lint_filter_flat_map<'a, 'tcx>( } /// lint use of `filter_map().flat_map()` for `Iterators` -fn lint_filter_map_flat_map<'a, 'tcx>( - cx: &LateContext<'a, 'tcx>, +fn lint_filter_map_flat_map<'tcx>( + cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>, _filter_args: &'tcx [hir::Expr<'_>], _map_args: &'tcx [hir::Expr<'_>], @@ -2896,8 +2875,8 @@ fn lint_filter_map_flat_map<'a, 'tcx>( } /// lint use of `flat_map` for `Iterators` where `flatten` would be sufficient -fn lint_flat_map_identity<'a, 'tcx>( - cx: &LateContext<'a, 'tcx>, +fn lint_flat_map_identity<'tcx>( + cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>, flat_map_args: &'tcx [hir::Expr<'_>], flat_map_span: Span, @@ -2945,8 +2924,8 @@ fn lint_flat_map_identity<'a, 'tcx>( } /// lint searching an Iterator followed by `is_some()` -fn lint_search_is_some<'a, 'tcx>( - cx: &LateContext<'a, 'tcx>, +fn lint_search_is_some<'tcx>( + cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>, search_method: &str, search_args: &'tcx [hir::Expr<'_>], @@ -3010,7 +2989,7 @@ struct BinaryExprInfo<'a> { } /// Checks for the `CHARS_NEXT_CMP` and `CHARS_LAST_CMP` lints. -fn lint_binary_expr_with_method_call(cx: &LateContext<'_, '_>, info: &mut BinaryExprInfo<'_>) { +fn lint_binary_expr_with_method_call(cx: &LateContext<'_>, info: &mut BinaryExprInfo<'_>) { macro_rules! lint_with_both_lhs_and_rhs { ($func:ident, $cx:expr, $info:ident) => { if !$func($cx, $info) { @@ -3030,7 +3009,7 @@ fn lint_binary_expr_with_method_call(cx: &LateContext<'_, '_>, info: &mut Binary /// Wrapper fn for `CHARS_NEXT_CMP` and `CHARS_LAST_CMP` lints. fn lint_chars_cmp( - cx: &LateContext<'_, '_>, + cx: &LateContext<'_>, info: &BinaryExprInfo<'_>, chain_methods: &[&str], lint: &'static Lint, @@ -3073,12 +3052,12 @@ fn lint_chars_cmp( } /// Checks for the `CHARS_NEXT_CMP` lint. -fn lint_chars_next_cmp<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, info: &BinaryExprInfo<'_>) -> bool { +fn lint_chars_next_cmp<'tcx>(cx: &LateContext<'tcx>, info: &BinaryExprInfo<'_>) -> bool { lint_chars_cmp(cx, info, &["chars", "next"], CHARS_NEXT_CMP, "starts_with") } /// Checks for the `CHARS_LAST_CMP` lint. -fn lint_chars_last_cmp<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, info: &BinaryExprInfo<'_>) -> bool { +fn lint_chars_last_cmp<'tcx>(cx: &LateContext<'tcx>, info: &BinaryExprInfo<'_>) -> bool { if lint_chars_cmp(cx, info, &["chars", "last"], CHARS_LAST_CMP, "ends_with") { true } else { @@ -3087,8 +3066,8 @@ fn lint_chars_last_cmp<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, info: &BinaryExprIn } /// Wrapper fn for `CHARS_NEXT_CMP` and `CHARS_LAST_CMP` lints with `unwrap()`. -fn lint_chars_cmp_with_unwrap<'a, 'tcx>( - cx: &LateContext<'a, 'tcx>, +fn lint_chars_cmp_with_unwrap<'tcx>( + cx: &LateContext<'tcx>, info: &BinaryExprInfo<'_>, chain_methods: &[&str], lint: &'static Lint, @@ -3122,12 +3101,12 @@ fn lint_chars_cmp_with_unwrap<'a, 'tcx>( } /// Checks for the `CHARS_NEXT_CMP` lint with `unwrap()`. -fn lint_chars_next_cmp_with_unwrap<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, info: &BinaryExprInfo<'_>) -> bool { +fn lint_chars_next_cmp_with_unwrap<'tcx>(cx: &LateContext<'tcx>, info: &BinaryExprInfo<'_>) -> bool { lint_chars_cmp_with_unwrap(cx, info, &["chars", "next", "unwrap"], CHARS_NEXT_CMP, "starts_with") } /// Checks for the `CHARS_LAST_CMP` lint with `unwrap()`. -fn lint_chars_last_cmp_with_unwrap<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, info: &BinaryExprInfo<'_>) -> bool { +fn lint_chars_last_cmp_with_unwrap<'tcx>(cx: &LateContext<'tcx>, info: &BinaryExprInfo<'_>) -> bool { if lint_chars_cmp_with_unwrap(cx, info, &["chars", "last", "unwrap"], CHARS_LAST_CMP, "ends_with") { true } else { @@ -3136,11 +3115,7 @@ fn lint_chars_last_cmp_with_unwrap<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, info: & } /// lint for length-1 `str`s for methods in `PATTERN_METHODS` -fn lint_single_char_pattern<'a, 'tcx>( - cx: &LateContext<'a, 'tcx>, - _expr: &'tcx hir::Expr<'_>, - arg: &'tcx hir::Expr<'_>, -) { +fn lint_single_char_pattern<'tcx>(cx: &LateContext<'tcx>, _expr: &'tcx hir::Expr<'_>, arg: &'tcx hir::Expr<'_>) { if_chain! { if let hir::ExprKind::Lit(lit) = &arg.kind; if let ast::LitKind::Str(r, style) = lit.node; @@ -3171,7 +3146,7 @@ fn lint_single_char_pattern<'a, 'tcx>( } /// Checks for the `USELESS_ASREF` lint. -fn lint_asref(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, call_name: &str, as_ref_args: &[hir::Expr<'_>]) { +fn lint_asref(cx: &LateContext<'_>, expr: &hir::Expr<'_>, call_name: &str, as_ref_args: &[hir::Expr<'_>]) { // when we get here, we've already checked that the call name is "as_ref" or "as_mut" // check if the call is to the actual `AsRef` or `AsMut` trait if match_trait_method(cx, expr, &paths::ASREF_TRAIT) || match_trait_method(cx, expr, &paths::ASMUT_TRAIT) { @@ -3206,7 +3181,7 @@ fn lint_asref(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, call_name: &str, a } } -fn ty_has_iter_method(cx: &LateContext<'_, '_>, self_ref_ty: Ty<'_>) -> Option<(&'static str, &'static str)> { +fn ty_has_iter_method(cx: &LateContext<'_>, self_ref_ty: Ty<'_>) -> Option<(&'static str, &'static str)> { has_iter_method(cx, self_ref_ty).map(|ty_name| { let mutbl = match self_ref_ty.kind { ty::Ref(_, _, mutbl) => mutbl, @@ -3220,7 +3195,7 @@ fn ty_has_iter_method(cx: &LateContext<'_, '_>, self_ref_ty: Ty<'_>) -> Option<( }) } -fn lint_into_iter(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, self_ref_ty: Ty<'_>, method_span: Span) { +fn lint_into_iter(cx: &LateContext<'_>, expr: &hir::Expr<'_>, self_ref_ty: Ty<'_>, method_span: Span) { if !match_trait_method(cx, expr, &paths::INTO_ITERATOR) { return; } @@ -3241,7 +3216,7 @@ fn lint_into_iter(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, self_ref_ty: T } /// lint for `MaybeUninit::uninit().assume_init()` (we already have the latter) -fn lint_maybe_uninit(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, outer: &hir::Expr<'_>) { +fn lint_maybe_uninit(cx: &LateContext<'_>, expr: &hir::Expr<'_>, outer: &hir::Expr<'_>) { if_chain! { if let hir::ExprKind::Call(ref callee, ref args) = expr.kind; if args.is_empty(); @@ -3259,7 +3234,7 @@ fn lint_maybe_uninit(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, outer: &hir } } -fn is_maybe_uninit_ty_valid(cx: &LateContext<'_, '_>, ty: Ty<'_>) -> bool { +fn is_maybe_uninit_ty_valid(cx: &LateContext<'_>, ty: Ty<'_>) -> bool { match ty.kind { ty::Array(ref component, _) => is_maybe_uninit_ty_valid(cx, component), ty::Tuple(ref types) => types.types().all(|ty| is_maybe_uninit_ty_valid(cx, ty)), @@ -3268,7 +3243,7 @@ fn is_maybe_uninit_ty_valid(cx: &LateContext<'_, '_>, ty: Ty<'_>) -> bool { } } -fn lint_suspicious_map(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>) { +fn lint_suspicious_map(cx: &LateContext<'_>, expr: &hir::Expr<'_>) { span_lint_and_help( cx, SUSPICIOUS_MAP, @@ -3280,8 +3255,8 @@ fn lint_suspicious_map(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>) { } /// lint use of `_.as_ref().map(Deref::deref)` for `Option`s -fn lint_option_as_ref_deref<'a, 'tcx>( - cx: &LateContext<'a, 'tcx>, +fn lint_option_as_ref_deref<'tcx>( + cx: &LateContext<'tcx>, expr: &hir::Expr<'_>, as_ref_args: &[hir::Expr<'_>], map_args: &[hir::Expr<'_>], @@ -3376,7 +3351,7 @@ fn lint_option_as_ref_deref<'a, 'tcx>( } /// Given a `Result` type, return its error type (`E`). -fn get_error_type<'a>(cx: &LateContext<'_, '_>, ty: Ty<'a>) -> Option> { +fn get_error_type<'a>(cx: &LateContext<'_>, ty: Ty<'a>) -> Option> { match ty.kind { ty::Adt(_, substs) if is_type_diagnostic_item(cx, ty, sym!(result_type)) => substs.types().nth(1), _ => None, @@ -3384,7 +3359,7 @@ fn get_error_type<'a>(cx: &LateContext<'_, '_>, ty: Ty<'a>) -> Option> { } /// This checks whether a given type is known to implement Debug. -fn has_debug_impl<'a, 'b>(ty: Ty<'a>, cx: &LateContext<'b, 'a>) -> bool { +fn has_debug_impl<'tcx>(ty: Ty<'tcx>, cx: &LateContext<'tcx>) -> bool { cx.tcx .get_diagnostic_item(sym::debug_trait) .map_or(false, |debug| implements_trait(cx, ty, debug, &[])) @@ -3477,8 +3452,8 @@ enum SelfKind { } impl SelfKind { - fn matches<'a>(self, cx: &LateContext<'_, 'a>, parent_ty: Ty<'a>, ty: Ty<'a>) -> bool { - fn matches_value<'a>(cx: &LateContext<'_, 'a>, parent_ty: Ty<'_>, ty: Ty<'_>) -> bool { + fn matches<'a>(self, cx: &LateContext<'a>, parent_ty: Ty<'a>, ty: Ty<'a>) -> bool { + fn matches_value<'a>(cx: &LateContext<'a>, parent_ty: Ty<'_>, ty: Ty<'_>) -> bool { if ty == parent_ty { true } else if ty.is_box() { @@ -3494,12 +3469,7 @@ impl SelfKind { } } - fn matches_ref<'a>( - cx: &LateContext<'_, 'a>, - mutability: hir::Mutability, - parent_ty: Ty<'a>, - ty: Ty<'a>, - ) -> bool { + fn matches_ref<'a>(cx: &LateContext<'a>, mutability: hir::Mutability, parent_ty: Ty<'a>, ty: Ty<'a>) -> bool { if let ty::Ref(_, t, m) = ty.kind { return m == mutability && t == parent_ty; } @@ -3563,7 +3533,7 @@ enum OutType { } impl OutType { - fn matches(self, cx: &LateContext<'_, '_>, ty: &hir::FnRetTy<'_>) -> bool { + fn matches(self, cx: &LateContext<'_>, ty: &hir::FnRetTy<'_>) -> bool { let is_unit = |ty: &hir::Ty<'_>| SpanlessEq::new(cx).eq_ty_kind(&ty.kind, &hir::TyKind::Tup(&[])); match (self, ty) { (Self::Unit, &hir::FnRetTy::DefaultReturn(_)) => true, @@ -3614,7 +3584,7 @@ fn contains_return(expr: &hir::Expr<'_>) -> bool { visitor.found } -fn check_pointer_offset(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, args: &[hir::Expr<'_>]) { +fn check_pointer_offset(cx: &LateContext<'_>, expr: &hir::Expr<'_>, args: &[hir::Expr<'_>]) { if_chain! { if args.len() == 2; if let ty::RawPtr(ty::TypeAndMut { ref ty, .. }) = cx.tables().expr_ty(&args[0]).kind; @@ -3626,7 +3596,7 @@ fn check_pointer_offset(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, args: &[ } } -fn lint_filetype_is_file(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, args: &[hir::Expr<'_>]) { +fn lint_filetype_is_file(cx: &LateContext<'_>, expr: &hir::Expr<'_>, args: &[hir::Expr<'_>]) { let ty = cx.tables().expr_ty(&args[0]); if !match_type(cx, ty, &paths::FILE_TYPE) { diff --git a/clippy_lints/src/methods/option_map_unwrap_or.rs b/clippy_lints/src/methods/option_map_unwrap_or.rs index 7f4529a5870ac..672eb75c57fc6 100644 --- a/clippy_lints/src/methods/option_map_unwrap_or.rs +++ b/clippy_lints/src/methods/option_map_unwrap_or.rs @@ -12,8 +12,8 @@ use rustc_span::symbol::Symbol; use super::MAP_UNWRAP_OR; /// lint use of `map().unwrap_or()` for `Option`s -pub(super) fn lint<'a, 'tcx>( - cx: &LateContext<'a, 'tcx>, +pub(super) fn lint<'tcx>( + cx: &LateContext<'tcx>, expr: &rustc_hir::Expr<'_>, map_args: &'tcx [rustc_hir::Expr<'_>], unwrap_args: &'tcx [rustc_hir::Expr<'_>], @@ -87,7 +87,7 @@ pub(super) fn lint<'a, 'tcx>( } struct UnwrapVisitor<'a, 'tcx> { - cx: &'a LateContext<'a, 'tcx>, + cx: &'a LateContext<'tcx>, identifiers: FxHashSet, } @@ -105,7 +105,7 @@ impl<'a, 'tcx> Visitor<'tcx> for UnwrapVisitor<'a, 'tcx> { } struct MapExprVisitor<'a, 'tcx> { - cx: &'a LateContext<'a, 'tcx>, + cx: &'a LateContext<'tcx>, identifiers: FxHashSet, found_identifier: bool, } diff --git a/clippy_lints/src/methods/unnecessary_filter_map.rs b/clippy_lints/src/methods/unnecessary_filter_map.rs index 8a3df85c91bff..fdcba11054288 100644 --- a/clippy_lints/src/methods/unnecessary_filter_map.rs +++ b/clippy_lints/src/methods/unnecessary_filter_map.rs @@ -11,7 +11,7 @@ use if_chain::if_chain; use super::UNNECESSARY_FILTER_MAP; -pub(super) fn lint(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, args: &[hir::Expr<'_>]) { +pub(super) fn lint(cx: &LateContext<'_>, expr: &hir::Expr<'_>, args: &[hir::Expr<'_>]) { if !match_trait_method(cx, expr, &paths::ITERATOR) { return; } @@ -52,11 +52,7 @@ pub(super) fn lint(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, args: &[hir:: } // returns (found_mapping, found_filtering) -fn check_expression<'a, 'tcx>( - cx: &'a LateContext<'a, 'tcx>, - arg_id: hir::HirId, - expr: &'tcx hir::Expr<'_>, -) -> (bool, bool) { +fn check_expression<'tcx>(cx: &LateContext<'tcx>, arg_id: hir::HirId, expr: &'tcx hir::Expr<'_>) -> (bool, bool) { match &expr.kind { hir::ExprKind::Call(ref func, ref args) => { if_chain! { @@ -104,7 +100,7 @@ fn check_expression<'a, 'tcx>( } struct ReturnVisitor<'a, 'tcx> { - cx: &'a LateContext<'a, 'tcx>, + cx: &'a LateContext<'tcx>, arg_id: hir::HirId, // Found a non-None return that isn't Some(input) found_mapping: bool, @@ -113,7 +109,7 @@ struct ReturnVisitor<'a, 'tcx> { } impl<'a, 'tcx> ReturnVisitor<'a, 'tcx> { - fn new(cx: &'a LateContext<'a, 'tcx>, arg_id: hir::HirId) -> ReturnVisitor<'a, 'tcx> { + fn new(cx: &'a LateContext<'tcx>, arg_id: hir::HirId) -> ReturnVisitor<'a, 'tcx> { ReturnVisitor { cx, arg_id, diff --git a/clippy_lints/src/minmax.rs b/clippy_lints/src/minmax.rs index 8e6f3925d6605..0a2d577396a5f 100644 --- a/clippy_lints/src/minmax.rs +++ b/clippy_lints/src/minmax.rs @@ -27,8 +27,8 @@ declare_clippy_lint! { declare_lint_pass!(MinMaxPass => [MIN_MAX]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MinMaxPass { - fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) { +impl<'tcx> LateLintPass<'tcx> for MinMaxPass { + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { if let Some((outer_max, outer_c, oe)) = min_max(cx, expr) { if let Some((inner_max, inner_c, ie)) = min_max(cx, oe) { if outer_max == inner_max { @@ -59,7 +59,7 @@ enum MinMax { Max, } -fn min_max<'a>(cx: &LateContext<'_, '_>, expr: &'a Expr<'a>) -> Option<(MinMax, Constant, &'a Expr<'a>)> { +fn min_max<'a>(cx: &LateContext<'_>, expr: &'a Expr<'a>) -> Option<(MinMax, Constant, &'a Expr<'a>)> { if let ExprKind::Call(ref path, ref args) = expr.kind { if let ExprKind::Path(ref qpath) = path.kind { cx.tables() @@ -82,11 +82,7 @@ fn min_max<'a>(cx: &LateContext<'_, '_>, expr: &'a Expr<'a>) -> Option<(MinMax, } } -fn fetch_const<'a>( - cx: &LateContext<'_, '_>, - args: &'a [Expr<'a>], - m: MinMax, -) -> Option<(MinMax, Constant, &'a Expr<'a>)> { +fn fetch_const<'a>(cx: &LateContext<'_>, args: &'a [Expr<'a>], m: MinMax) -> Option<(MinMax, Constant, &'a Expr<'a>)> { if args.len() != 2 { return None; } diff --git a/clippy_lints/src/misc.rs b/clippy_lints/src/misc.rs index fcd77088b88eb..d7e1a62a19d52 100644 --- a/clippy_lints/src/misc.rs +++ b/clippy_lints/src/misc.rs @@ -260,10 +260,10 @@ declare_lint_pass!(MiscLints => [ FLOAT_CMP_CONST ]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MiscLints { +impl<'tcx> LateLintPass<'tcx> for MiscLints { fn check_fn( &mut self, - cx: &LateContext<'a, 'tcx>, + cx: &LateContext<'tcx>, k: FnKind<'tcx>, decl: &'tcx FnDecl<'_>, body: &'tcx Body<'_>, @@ -287,7 +287,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MiscLints { } } - fn check_stmt(&mut self, cx: &LateContext<'a, 'tcx>, stmt: &'tcx Stmt<'_>) { + fn check_stmt(&mut self, cx: &LateContext<'tcx>, stmt: &'tcx Stmt<'_>) { if_chain! { if let StmtKind::Local(ref local) = stmt.kind; if let PatKind::Binding(an, .., name, None) = local.pat.kind; @@ -360,7 +360,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MiscLints { }; } - fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) { + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { match expr.kind { ExprKind::Cast(ref e, ref ty) => { check_cast(cx, expr.span, e, ty); @@ -493,7 +493,7 @@ fn get_lint_and_message( } } -fn check_nan(cx: &LateContext<'_, '_>, expr: &Expr<'_>, cmp_expr: &Expr<'_>) { +fn check_nan(cx: &LateContext<'_>, expr: &Expr<'_>, cmp_expr: &Expr<'_>) { if_chain! { if !in_constant(cx, cmp_expr.hir_id); if let Some((value, _)) = constant(cx, cx.tables(), expr); @@ -516,7 +516,7 @@ fn check_nan(cx: &LateContext<'_, '_>, expr: &Expr<'_>, cmp_expr: &Expr<'_>) { } } -fn is_named_constant<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) -> bool { +fn is_named_constant<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) -> bool { if let Some((_, res)) = constant(cx, cx.tables(), expr) { res } else { @@ -524,7 +524,7 @@ fn is_named_constant<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) } } -fn is_allowed<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) -> bool { +fn is_allowed<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) -> bool { match constant(cx, cx.tables(), expr) { Some((Constant::F32(f), _)) => f == 0.0 || f.is_infinite(), Some((Constant::F64(f), _)) => f == 0.0 || f.is_infinite(), @@ -538,7 +538,7 @@ fn is_allowed<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) -> boo } // Return true if `expr` is the result of `signum()` invoked on a float value. -fn is_signum(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> bool { +fn is_signum(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { // The negation of a signum is still a signum if let ExprKind::Unary(UnOp::UnNeg, ref child_expr) = expr.kind { return is_signum(cx, &child_expr); @@ -556,7 +556,7 @@ fn is_signum(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> bool { false } -fn is_float(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> bool { +fn is_float(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { let value = &walk_ptrs_ty(cx.tables().expr_ty(expr)).kind; if let ty::Array(arr_ty, _) = value { @@ -566,11 +566,11 @@ fn is_float(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> bool { matches!(value, ty::Float(_)) } -fn is_array(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> bool { +fn is_array(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { matches!(&walk_ptrs_ty(cx.tables().expr_ty(expr)).kind, ty::Array(_, _)) } -fn check_to_owned(cx: &LateContext<'_, '_>, expr: &Expr<'_>, other: &Expr<'_>) { +fn check_to_owned(cx: &LateContext<'_>, expr: &Expr<'_>, other: &Expr<'_>) { let (arg_ty, snip) = match expr.kind { ExprKind::MethodCall(.., ref args, _) if args.len() == 1 => { if match_trait_method(cx, expr, &paths::TO_STRING) || match_trait_method(cx, expr, &paths::TO_OWNED) { @@ -655,7 +655,7 @@ fn check_to_owned(cx: &LateContext<'_, '_>, expr: &Expr<'_>, other: &Expr<'_>) { /// Heuristic to see if an expression is used. Should be compatible with /// `unused_variables`'s idea /// of what it means for an expression to be "used". -fn is_used(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> bool { +fn is_used(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { if let Some(parent) = get_parent_expr(cx, expr) { match parent.kind { ExprKind::Assign(_, ref rhs, _) | ExprKind::AssignOp(_, _, ref rhs) => { @@ -686,7 +686,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 { +fn non_macro_local(cx: &LateContext<'_>, res: def::Res) -> bool { if let def::Res::Local(id) = res { !cx.tcx.hir().span(id).from_expansion() } else { @@ -694,7 +694,7 @@ fn non_macro_local(cx: &LateContext<'_, '_>, res: def::Res) -> bool { } } -fn check_cast(cx: &LateContext<'_, '_>, span: Span, e: &Expr<'_>, ty: &Ty<'_>) { +fn check_cast(cx: &LateContext<'_>, span: Span, e: &Expr<'_>, ty: &Ty<'_>) { if_chain! { if let TyKind::Ptr(ref mut_ty) = ty.kind; if let ExprKind::Lit(ref lit) = e.kind; diff --git a/clippy_lints/src/missing_const_for_fn.rs b/clippy_lints/src/missing_const_for_fn.rs index 9cfc8d1913497..bdce1bf152180 100644 --- a/clippy_lints/src/missing_const_for_fn.rs +++ b/clippy_lints/src/missing_const_for_fn.rs @@ -71,10 +71,10 @@ declare_clippy_lint! { declare_lint_pass!(MissingConstForFn => [MISSING_CONST_FOR_FN]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingConstForFn { +impl<'tcx> LateLintPass<'tcx> for MissingConstForFn { fn check_fn( &mut self, - cx: &LateContext<'_, '_>, + cx: &LateContext<'_>, kind: FnKind<'_>, _: &FnDecl<'_>, _: &Body<'_>, @@ -130,7 +130,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingConstForFn { /// Returns true if any of the method parameters is a type that implements `Drop`. The method /// can't be made const then, because `drop` can't be const-evaluated. -fn method_accepts_dropable(cx: &LateContext<'_, '_>, param_tys: &[hir::Ty<'_>]) -> bool { +fn method_accepts_dropable(cx: &LateContext<'_>, param_tys: &[hir::Ty<'_>]) -> bool { // If any of the params are dropable, return true param_tys.iter().any(|hir_ty| { let ty_ty = hir_ty_to_ty(cx.tcx, hir_ty); diff --git a/clippy_lints/src/missing_doc.rs b/clippy_lints/src/missing_doc.rs index 0fd1e87f9e415..06e0f43c10bb8 100644 --- a/clippy_lints/src/missing_doc.rs +++ b/clippy_lints/src/missing_doc.rs @@ -69,13 +69,7 @@ impl MissingDoc { } } - fn check_missing_docs_attrs( - &self, - cx: &LateContext<'_, '_>, - attrs: &[ast::Attribute], - sp: Span, - desc: &'static str, - ) { + fn check_missing_docs_attrs(&self, cx: &LateContext<'_>, attrs: &[ast::Attribute], sp: Span, desc: &'static str) { // If we're building a test harness, then warning about // documentation is probably not really relevant right now. if cx.sess().opts.test { @@ -107,8 +101,8 @@ impl MissingDoc { impl_lint_pass!(MissingDoc => [MISSING_DOCS_IN_PRIVATE_ITEMS]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingDoc { - fn enter_lint_attrs(&mut self, _: &LateContext<'a, 'tcx>, attrs: &'tcx [ast::Attribute]) { +impl<'tcx> LateLintPass<'tcx> for MissingDoc { + fn enter_lint_attrs(&mut self, _: &LateContext<'tcx>, attrs: &'tcx [ast::Attribute]) { let doc_hidden = self.doc_hidden() || attrs.iter().any(|attr| { attr.check_name(sym!(doc)) @@ -120,15 +114,15 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingDoc { self.doc_hidden_stack.push(doc_hidden); } - fn exit_lint_attrs(&mut self, _: &LateContext<'a, 'tcx>, _: &'tcx [ast::Attribute]) { + fn exit_lint_attrs(&mut self, _: &LateContext<'tcx>, _: &'tcx [ast::Attribute]) { self.doc_hidden_stack.pop().expect("empty doc_hidden_stack"); } - fn check_crate(&mut self, cx: &LateContext<'a, 'tcx>, krate: &'tcx hir::Crate<'_>) { + fn check_crate(&mut self, cx: &LateContext<'tcx>, krate: &'tcx hir::Crate<'_>) { self.check_missing_docs_attrs(cx, &krate.item.attrs, krate.item.span, "crate"); } - fn check_item(&mut self, cx: &LateContext<'a, 'tcx>, it: &'tcx hir::Item<'_>) { + fn check_item(&mut self, cx: &LateContext<'tcx>, it: &'tcx hir::Item<'_>) { let desc = match it.kind { hir::ItemKind::Const(..) => "a constant", hir::ItemKind::Enum(..) => "an enum", @@ -161,7 +155,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingDoc { self.check_missing_docs_attrs(cx, &it.attrs, it.span, desc); } - fn check_trait_item(&mut self, cx: &LateContext<'a, 'tcx>, trait_item: &'tcx hir::TraitItem<'_>) { + fn check_trait_item(&mut self, cx: &LateContext<'tcx>, trait_item: &'tcx hir::TraitItem<'_>) { let desc = match trait_item.kind { hir::TraitItemKind::Const(..) => "an associated constant", hir::TraitItemKind::Fn(..) => "a trait method", @@ -171,7 +165,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingDoc { self.check_missing_docs_attrs(cx, &trait_item.attrs, trait_item.span, desc); } - fn check_impl_item(&mut self, cx: &LateContext<'a, 'tcx>, impl_item: &'tcx hir::ImplItem<'_>) { + fn check_impl_item(&mut self, cx: &LateContext<'tcx>, impl_item: &'tcx hir::ImplItem<'_>) { // If the method is an impl for a trait, don't doc. let def_id = cx.tcx.hir().local_def_id(impl_item.hir_id); match cx.tcx.associated_item(def_id).container { @@ -191,13 +185,13 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingDoc { self.check_missing_docs_attrs(cx, &impl_item.attrs, impl_item.span, desc); } - fn check_struct_field(&mut self, cx: &LateContext<'a, 'tcx>, sf: &'tcx hir::StructField<'_>) { + fn check_struct_field(&mut self, cx: &LateContext<'tcx>, sf: &'tcx hir::StructField<'_>) { if !sf.is_positional() { self.check_missing_docs_attrs(cx, &sf.attrs, sf.span, "a struct field"); } } - fn check_variant(&mut self, cx: &LateContext<'a, 'tcx>, v: &'tcx hir::Variant<'_>) { + fn check_variant(&mut self, cx: &LateContext<'tcx>, v: &'tcx hir::Variant<'_>) { self.check_missing_docs_attrs(cx, &v.attrs, v.span, "a variant"); } } diff --git a/clippy_lints/src/missing_inline.rs b/clippy_lints/src/missing_inline.rs index 1802470b1841e..bf80b62afe6e0 100644 --- a/clippy_lints/src/missing_inline.rs +++ b/clippy_lints/src/missing_inline.rs @@ -56,7 +56,7 @@ declare_clippy_lint! { "detects missing `#[inline]` attribute for public callables (functions, trait methods, methods...)" } -fn check_missing_inline_attrs(cx: &LateContext<'_, '_>, attrs: &[ast::Attribute], sp: Span, desc: &'static str) { +fn check_missing_inline_attrs(cx: &LateContext<'_>, attrs: &[ast::Attribute], sp: Span, desc: &'static str) { let has_inline = attrs.iter().any(|a| a.check_name(sym!(inline))); if !has_inline { span_lint( @@ -68,7 +68,7 @@ fn check_missing_inline_attrs(cx: &LateContext<'_, '_>, attrs: &[ast::Attribute] } } -fn is_executable(cx: &LateContext<'_, '_>) -> bool { +fn is_executable(cx: &LateContext<'_>) -> bool { use rustc_session::config::CrateType; cx.tcx.sess.crate_types().iter().any(|t: &CrateType| match t { @@ -79,8 +79,8 @@ fn is_executable(cx: &LateContext<'_, '_>) -> bool { declare_lint_pass!(MissingInline => [MISSING_INLINE_IN_PUBLIC_ITEMS]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingInline { - fn check_item(&mut self, cx: &LateContext<'a, 'tcx>, it: &'tcx hir::Item<'_>) { +impl<'tcx> LateLintPass<'tcx> for MissingInline { + fn check_item(&mut self, cx: &LateContext<'tcx>, it: &'tcx hir::Item<'_>) { if rustc_middle::lint::in_external_macro(cx.sess(), it.span) || is_executable(cx) { return; } @@ -129,7 +129,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingInline { }; } - fn check_impl_item(&mut self, cx: &LateContext<'a, 'tcx>, impl_item: &'tcx hir::ImplItem<'_>) { + fn check_impl_item(&mut self, cx: &LateContext<'tcx>, impl_item: &'tcx hir::ImplItem<'_>) { use rustc_middle::ty::{ImplContainer, TraitContainer}; if rustc_middle::lint::in_external_macro(cx.sess(), impl_item.span) || is_executable(cx) { return; diff --git a/clippy_lints/src/modulo_arithmetic.rs b/clippy_lints/src/modulo_arithmetic.rs index f76e4721e1f63..59ccc6333fdcd 100644 --- a/clippy_lints/src/modulo_arithmetic.rs +++ b/clippy_lints/src/modulo_arithmetic.rs @@ -36,7 +36,7 @@ struct OperandInfo { is_integral: bool, } -fn analyze_operand(operand: &Expr<'_>, cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> Option { +fn analyze_operand(operand: &Expr<'_>, cx: &LateContext<'_>, expr: &Expr<'_>) -> Option { match constant(cx, cx.tables(), operand) { Some((Constant::Int(v), _)) => match cx.tables().expr_ty(expr).kind { ty::Int(ity) => { @@ -79,8 +79,8 @@ fn might_have_negative_value(t: &ty::TyS<'_>) -> bool { t.is_signed() || t.is_floating_point() } -fn check_const_operands<'a, 'tcx>( - cx: &LateContext<'a, 'tcx>, +fn check_const_operands<'tcx>( + cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, lhs_operand: &OperandInfo, rhs_operand: &OperandInfo, @@ -105,7 +105,7 @@ fn check_const_operands<'a, 'tcx>( } } -fn check_non_const_operands<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>, operand: &Expr<'_>) { +fn check_non_const_operands<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, operand: &Expr<'_>) { let operand_type = cx.tables().expr_ty(operand); if might_have_negative_value(operand_type) { span_lint_and_then( @@ -123,8 +123,8 @@ fn check_non_const_operands<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Ex } } -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ModuloArithmetic { - fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) { +impl<'tcx> LateLintPass<'tcx> for ModuloArithmetic { + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { match &expr.kind { ExprKind::Binary(op, lhs, rhs) | ExprKind::AssignOp(op, lhs, rhs) => { if let BinOpKind::Rem = op.node { diff --git a/clippy_lints/src/multiple_crate_versions.rs b/clippy_lints/src/multiple_crate_versions.rs index 6c42014b4c8a1..c1773cef7a8b7 100644 --- a/clippy_lints/src/multiple_crate_versions.rs +++ b/clippy_lints/src/multiple_crate_versions.rs @@ -36,8 +36,8 @@ declare_clippy_lint! { declare_lint_pass!(MultipleCrateVersions => [MULTIPLE_CRATE_VERSIONS]); -impl LateLintPass<'_, '_> for MultipleCrateVersions { - fn check_crate(&mut self, cx: &LateContext<'_, '_>, _: &Crate<'_>) { +impl LateLintPass<'_> for MultipleCrateVersions { + fn check_crate(&mut self, cx: &LateContext<'_>, _: &Crate<'_>) { if !run_lints(cx, &[MULTIPLE_CRATE_VERSIONS], CRATE_HIR_ID) { return; } diff --git a/clippy_lints/src/mut_key.rs b/clippy_lints/src/mut_key.rs index 755b196c698c2..d8fb8a4bb776b 100644 --- a/clippy_lints/src/mut_key.rs +++ b/clippy_lints/src/mut_key.rs @@ -51,14 +51,14 @@ declare_clippy_lint! { declare_lint_pass!(MutableKeyType => [ MUTABLE_KEY_TYPE ]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MutableKeyType { - fn check_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx hir::Item<'tcx>) { +impl<'tcx> LateLintPass<'tcx> for MutableKeyType { + fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'tcx>) { if let hir::ItemKind::Fn(ref sig, ..) = item.kind { check_sig(cx, item.hir_id, &sig.decl); } } - fn check_impl_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx hir::ImplItem<'tcx>) { + fn check_impl_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::ImplItem<'tcx>) { if let hir::ImplItemKind::Fn(ref sig, ..) = item.kind { if trait_ref_of_method(cx, item.hir_id).is_none() { check_sig(cx, item.hir_id, &sig.decl); @@ -66,13 +66,13 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MutableKeyType { } } - fn check_trait_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx hir::TraitItem<'tcx>) { + fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::TraitItem<'tcx>) { if let hir::TraitItemKind::Fn(ref sig, ..) = item.kind { check_sig(cx, item.hir_id, &sig.decl); } } - fn check_local(&mut self, cx: &LateContext<'_, '_>, local: &hir::Local<'_>) { + fn check_local(&mut self, cx: &LateContext<'_>, local: &hir::Local<'_>) { if let hir::PatKind::Wild = local.pat.kind { return; } @@ -80,7 +80,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MutableKeyType { } } -fn check_sig<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, item_hir_id: hir::HirId, decl: &hir::FnDecl<'_>) { +fn check_sig<'tcx>(cx: &LateContext<'tcx>, item_hir_id: hir::HirId, decl: &hir::FnDecl<'_>) { let fn_def_id = cx.tcx.hir().local_def_id(item_hir_id); let fn_sig = cx.tcx.fn_sig(fn_def_id); for (hir_ty, ty) in decl.inputs.iter().zip(fn_sig.inputs().skip_binder().iter()) { @@ -95,7 +95,7 @@ fn check_sig<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, item_hir_id: hir::HirId, decl // We want to lint 1. sets or maps with 2. not immutable key types and 3. no unerased // generics (because the compiler cannot ensure immutability for unknown types). -fn check_ty<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, span: Span, ty: Ty<'tcx>) { +fn check_ty<'tcx>(cx: &LateContext<'tcx>, span: Span, ty: Ty<'tcx>) { let ty = walk_ptrs_ty(ty); if let Adt(def, substs) = ty.kind { if [&paths::HASHMAP, &paths::BTREEMAP, &paths::HASHSET, &paths::BTREESET] @@ -108,7 +108,7 @@ fn check_ty<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, span: Span, ty: Ty<'tcx>) { } } -fn is_mutable_type<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, ty: Ty<'tcx>, span: Span) -> bool { +fn is_mutable_type<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>, span: Span) -> bool { match ty.kind { RawPtr(TypeAndMut { ty: inner_ty, mutbl }) | Ref(_, inner_ty, mutbl) => { mutbl == hir::Mutability::Mut || is_mutable_type(cx, inner_ty, span) diff --git a/clippy_lints/src/mut_mut.rs b/clippy_lints/src/mut_mut.rs index 6aa77b4df83aa..259b4c73d7609 100644 --- a/clippy_lints/src/mut_mut.rs +++ b/clippy_lints/src/mut_mut.rs @@ -28,12 +28,12 @@ declare_clippy_lint! { declare_lint_pass!(MutMut => [MUT_MUT]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MutMut { - fn check_block(&mut self, cx: &LateContext<'a, 'tcx>, block: &'tcx hir::Block<'_>) { +impl<'tcx> LateLintPass<'tcx> for MutMut { + fn check_block(&mut self, cx: &LateContext<'tcx>, block: &'tcx hir::Block<'_>) { intravisit::walk_block(&mut MutVisitor { cx }, block); } - fn check_ty(&mut self, cx: &LateContext<'a, 'tcx>, ty: &'tcx hir::Ty<'_>) { + fn check_ty(&mut self, cx: &LateContext<'tcx>, ty: &'tcx hir::Ty<'_>) { use rustc_hir::intravisit::Visitor; MutVisitor { cx }.visit_ty(ty); @@ -41,7 +41,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MutMut { } pub struct MutVisitor<'a, 'tcx> { - cx: &'a LateContext<'a, 'tcx>, + cx: &'a LateContext<'tcx>, } impl<'a, 'tcx> intravisit::Visitor<'tcx> for MutVisitor<'a, 'tcx> { diff --git a/clippy_lints/src/mut_reference.rs b/clippy_lints/src/mut_reference.rs index dbe257069c3e2..53341b6eba752 100644 --- a/clippy_lints/src/mut_reference.rs +++ b/clippy_lints/src/mut_reference.rs @@ -29,8 +29,8 @@ declare_clippy_lint! { declare_lint_pass!(UnnecessaryMutPassed => [UNNECESSARY_MUT_PASSED]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnnecessaryMutPassed { - fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr<'_>) { +impl<'tcx> LateLintPass<'tcx> for UnnecessaryMutPassed { + fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) { match e.kind { ExprKind::Call(ref fn_expr, ref arguments) => { if let ExprKind::Path(ref path) = fn_expr.kind { @@ -53,12 +53,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnnecessaryMutPassed { } } -fn check_arguments<'a, 'tcx>( - cx: &LateContext<'a, 'tcx>, - arguments: &[Expr<'_>], - type_definition: Ty<'tcx>, - name: &str, -) { +fn check_arguments<'tcx>(cx: &LateContext<'tcx>, arguments: &[Expr<'_>], type_definition: Ty<'tcx>, name: &str) { match type_definition.kind { ty::FnDef(..) | ty::FnPtr(_) => { let parameters = type_definition.fn_sig(cx.tcx).skip_binder().inputs(); diff --git a/clippy_lints/src/mutable_debug_assertion.rs b/clippy_lints/src/mutable_debug_assertion.rs index 45db5140711ad..78d2356748f1e 100644 --- a/clippy_lints/src/mutable_debug_assertion.rs +++ b/clippy_lints/src/mutable_debug_assertion.rs @@ -35,8 +35,8 @@ declare_lint_pass!(DebugAssertWithMutCall => [DEBUG_ASSERT_WITH_MUT_CALL]); const DEBUG_MACRO_NAMES: [&str; 3] = ["debug_assert", "debug_assert_eq", "debug_assert_ne"]; -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for DebugAssertWithMutCall { - fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr<'_>) { +impl<'tcx> LateLintPass<'tcx> for DebugAssertWithMutCall { + fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) { for dmn in &DEBUG_MACRO_NAMES { if is_direct_expn_of(e.span, dmn).is_some() { if let Some(span) = extract_call(cx, e) { @@ -53,7 +53,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for DebugAssertWithMutCall { } //HACK(hellow554): remove this when #4694 is implemented -fn extract_call<'a, 'tcx>(cx: &'a LateContext<'a, 'tcx>, e: &'tcx Expr<'_>) -> Option { +fn extract_call<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> Option { if_chain! { if let ExprKind::Block(ref block, _) = e.kind; if block.stmts.len() == 1; @@ -102,13 +102,13 @@ fn extract_call<'a, 'tcx>(cx: &'a LateContext<'a, 'tcx>, e: &'tcx Expr<'_>) -> O } struct MutArgVisitor<'a, 'tcx> { - cx: &'a LateContext<'a, 'tcx>, + cx: &'a LateContext<'tcx>, expr_span: Option, found: bool, } impl<'a, 'tcx> MutArgVisitor<'a, 'tcx> { - fn new(cx: &'a LateContext<'a, 'tcx>) -> Self { + fn new(cx: &'a LateContext<'tcx>) -> Self { Self { cx, expr_span: None, diff --git a/clippy_lints/src/mutex_atomic.rs b/clippy_lints/src/mutex_atomic.rs index c227dc54f2939..1a821491fcaf2 100644 --- a/clippy_lints/src/mutex_atomic.rs +++ b/clippy_lints/src/mutex_atomic.rs @@ -64,8 +64,8 @@ declare_clippy_lint! { declare_lint_pass!(Mutex => [MUTEX_ATOMIC, MUTEX_INTEGER]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Mutex { - fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) { +impl<'tcx> LateLintPass<'tcx> for Mutex { + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { let ty = cx.tables().expr_ty(expr); if let ty::Adt(_, subst) = ty.kind { if is_type_diagnostic_item(cx, ty, sym!(mutex_type)) { diff --git a/clippy_lints/src/needless_bool.rs b/clippy_lints/src/needless_bool.rs index 653f9e2ae8625..e15376b932628 100644 --- a/clippy_lints/src/needless_bool.rs +++ b/clippy_lints/src/needless_bool.rs @@ -67,8 +67,8 @@ declare_clippy_lint! { declare_lint_pass!(NeedlessBool => [NEEDLESS_BOOL]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessBool { - fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr<'_>) { +impl<'tcx> LateLintPass<'tcx> for NeedlessBool { + fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) { use self::Expression::{Bool, RetBool}; if let Some((ref pred, ref then_block, Some(ref else_expr))) = higher::if_block(&e) { let reduce = |ret, not| { @@ -127,8 +127,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessBool { 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<'_>) { +impl<'tcx> LateLintPass<'tcx> for BoolComparison { + fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) { if e.span.from_expansion() { return; } @@ -218,7 +218,7 @@ fn one_side_is_unary_not<'tcx>(left_side: &'tcx Expr<'_>, right_side: &'tcx Expr } fn check_comparison<'a, 'tcx>( - cx: &LateContext<'a, 'tcx>, + cx: &LateContext<'tcx>, e: &'tcx Expr<'_>, left_true: Option<(impl FnOnce(Sugg<'a>) -> Sugg<'a>, &str)>, left_false: Option<(impl FnOnce(Sugg<'a>) -> Sugg<'a>, &str)>, @@ -285,7 +285,7 @@ fn check_comparison<'a, 'tcx>( } fn suggest_bool_comparison<'a, 'tcx>( - cx: &LateContext<'a, 'tcx>, + cx: &LateContext<'tcx>, e: &'tcx Expr<'_>, expr: &Expr<'_>, mut applicability: Applicability, diff --git a/clippy_lints/src/needless_borrow.rs b/clippy_lints/src/needless_borrow.rs index 6bb06defb7034..1bea93fcb7522 100644 --- a/clippy_lints/src/needless_borrow.rs +++ b/clippy_lints/src/needless_borrow.rs @@ -40,8 +40,8 @@ pub struct NeedlessBorrow { 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<'_>) { +impl<'tcx> LateLintPass<'tcx> for NeedlessBorrow { + fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) { if e.span.from_expansion() || self.derived_item.is_some() { return; } @@ -79,7 +79,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessBorrow { } } } - fn check_pat(&mut self, cx: &LateContext<'a, 'tcx>, pat: &'tcx Pat<'_>) { + fn check_pat(&mut self, cx: &LateContext<'tcx>, pat: &'tcx Pat<'_>) { if pat.span.from_expansion() || self.derived_item.is_some() { return; } @@ -111,14 +111,14 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessBorrow { } } - fn check_item(&mut self, _: &LateContext<'a, 'tcx>, item: &'tcx Item<'_>) { + fn check_item(&mut self, _: &LateContext<'tcx>, item: &'tcx Item<'_>) { if item.attrs.iter().any(|a| a.check_name(sym!(automatically_derived))) { debug_assert!(self.derived_item.is_none()); self.derived_item = Some(item.hir_id); } } - fn check_item_post(&mut self, _: &LateContext<'a, 'tcx>, item: &'tcx Item<'_>) { + fn check_item_post(&mut self, _: &LateContext<'tcx>, item: &'tcx Item<'_>) { if let Some(id) = self.derived_item { if item.hir_id == id { self.derived_item = None; diff --git a/clippy_lints/src/needless_borrowed_ref.rs b/clippy_lints/src/needless_borrowed_ref.rs index e56489c6d434d..85184fdea4779 100644 --- a/clippy_lints/src/needless_borrowed_ref.rs +++ b/clippy_lints/src/needless_borrowed_ref.rs @@ -52,8 +52,8 @@ declare_clippy_lint! { 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<'_>) { +impl<'tcx> LateLintPass<'tcx> for NeedlessBorrowedRef { + fn check_pat(&mut self, cx: &LateContext<'tcx>, pat: &'tcx Pat<'_>) { if pat.span.from_expansion() { // OK, simple enough, lints doesn't check in macro. return; diff --git a/clippy_lints/src/needless_pass_by_value.rs b/clippy_lints/src/needless_pass_by_value.rs index 6954f0cc683f1..bc70c675ad691 100644 --- a/clippy_lints/src/needless_pass_by_value.rs +++ b/clippy_lints/src/needless_pass_by_value.rs @@ -64,11 +64,11 @@ macro_rules! need { }; } -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessPassByValue { +impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue { #[allow(clippy::too_many_lines)] fn check_fn( &mut self, - cx: &LateContext<'a, 'tcx>, + cx: &LateContext<'tcx>, kind: FnKind<'tcx>, decl: &'tcx FnDecl<'_>, body: &'tcx Body<'_>, diff --git a/clippy_lints/src/needless_update.rs b/clippy_lints/src/needless_update.rs index 9b556dbb8540e..6ec73041604e6 100644 --- a/clippy_lints/src/needless_update.rs +++ b/clippy_lints/src/needless_update.rs @@ -44,8 +44,8 @@ declare_clippy_lint! { declare_lint_pass!(NeedlessUpdate => [NEEDLESS_UPDATE]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessUpdate { - fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) { +impl<'tcx> LateLintPass<'tcx> for NeedlessUpdate { + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { if let ExprKind::Struct(_, ref fields, Some(ref base)) = expr.kind { let ty = cx.tables().expr_ty(expr); if let ty::Adt(def, _) = ty.kind { diff --git a/clippy_lints/src/neg_cmp_op_on_partial_ord.rs b/clippy_lints/src/neg_cmp_op_on_partial_ord.rs index 0f56daa3659e8..1be766d8e8dc5 100644 --- a/clippy_lints/src/neg_cmp_op_on_partial_ord.rs +++ b/clippy_lints/src/neg_cmp_op_on_partial_ord.rs @@ -45,8 +45,8 @@ declare_clippy_lint! { declare_lint_pass!(NoNegCompOpForPartialOrd => [NEG_CMP_OP_ON_PARTIAL_ORD]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NoNegCompOpForPartialOrd { - fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) { +impl<'tcx> LateLintPass<'tcx> for NoNegCompOpForPartialOrd { + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { if_chain! { if !in_external_macro(cx.sess(), expr.span); diff --git a/clippy_lints/src/neg_multiply.rs b/clippy_lints/src/neg_multiply.rs index a9ce01b67b097..1346145da327e 100644 --- a/clippy_lints/src/neg_multiply.rs +++ b/clippy_lints/src/neg_multiply.rs @@ -26,8 +26,8 @@ declare_clippy_lint! { declare_lint_pass!(NegMultiply => [NEG_MULTIPLY]); #[allow(clippy::match_same_arms)] -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NegMultiply { - fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr<'_>) { +impl<'tcx> LateLintPass<'tcx> for NegMultiply { + fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) { if let ExprKind::Binary(ref op, ref left, ref right) = e.kind { if BinOpKind::Mul == op.node { match (&left.kind, &right.kind) { @@ -41,7 +41,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NegMultiply { } } -fn check_mul(cx: &LateContext<'_, '_>, span: Span, lit: &Expr<'_>, exp: &Expr<'_>) { +fn check_mul(cx: &LateContext<'_>, span: Span, lit: &Expr<'_>, exp: &Expr<'_>) { if_chain! { if let ExprKind::Lit(ref l) = lit.kind; if let Constant::Int(1) = consts::lit_to_constant(&l.node, cx.tables().expr_ty_opt(lit)); diff --git a/clippy_lints/src/new_without_default.rs b/clippy_lints/src/new_without_default.rs index 42200385932b0..2597f5f6f17e2 100644 --- a/clippy_lints/src/new_without_default.rs +++ b/clippy_lints/src/new_without_default.rs @@ -56,9 +56,9 @@ pub struct NewWithoutDefault { impl_lint_pass!(NewWithoutDefault => [NEW_WITHOUT_DEFAULT]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NewWithoutDefault { +impl<'tcx> LateLintPass<'tcx> for NewWithoutDefault { #[allow(clippy::too_many_lines)] - fn check_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx hir::Item<'_>) { + fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>) { if let hir::ItemKind::Impl { of_trait: None, items, .. } = item.kind diff --git a/clippy_lints/src/no_effect.rs b/clippy_lints/src/no_effect.rs index 5fdc656580f29..95283dae71470 100644 --- a/clippy_lints/src/no_effect.rs +++ b/clippy_lints/src/no_effect.rs @@ -42,7 +42,7 @@ declare_clippy_lint! { "outer expressions with no effect" } -fn has_no_effect(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> bool { +fn has_no_effect(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { if expr.span.from_expansion() { return false; } @@ -87,8 +87,8 @@ fn has_no_effect(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> bool { declare_lint_pass!(NoEffect => [NO_EFFECT, UNNECESSARY_OPERATION]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NoEffect { - fn check_stmt(&mut self, cx: &LateContext<'a, 'tcx>, stmt: &'tcx Stmt<'_>) { +impl<'tcx> LateLintPass<'tcx> for NoEffect { + fn check_stmt(&mut self, cx: &LateContext<'tcx>, stmt: &'tcx Stmt<'_>) { if let StmtKind::Semi(ref expr) = stmt.kind { if has_no_effect(cx, expr) { span_lint(cx, NO_EFFECT, stmt.span, "statement with no effect"); @@ -119,7 +119,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NoEffect { } } -fn reduce_expression<'a>(cx: &LateContext<'_, '_>, expr: &'a Expr<'a>) -> Option>> { +fn reduce_expression<'a>(cx: &LateContext<'_>, expr: &'a Expr<'a>) -> Option>> { if expr.span.from_expansion() { return None; } diff --git a/clippy_lints/src/non_copy_const.rs b/clippy_lints/src/non_copy_const.rs index 21d7a7439f25c..c11a2ff9ee07e 100644 --- a/clippy_lints/src/non_copy_const.rs +++ b/clippy_lints/src/non_copy_const.rs @@ -109,7 +109,7 @@ impl Source { } } -fn verify_ty_bound<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, ty: Ty<'tcx>, source: Source) { +fn verify_ty_bound<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>, source: Source) { if ty.is_freeze(cx.tcx.at(DUMMY_SP), cx.param_env) || is_copy(cx, ty) { // An `UnsafeCell` is `!Copy`, and an `UnsafeCell` is also the only type which // is `!Freeze`, thus if our type is `Copy` we can be sure it must be `Freeze` @@ -141,15 +141,15 @@ fn verify_ty_bound<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, ty: Ty<'tcx>, source: S declare_lint_pass!(NonCopyConst => [DECLARE_INTERIOR_MUTABLE_CONST, BORROW_INTERIOR_MUTABLE_CONST]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NonCopyConst { - fn check_item(&mut self, cx: &LateContext<'a, 'tcx>, it: &'tcx Item<'_>) { +impl<'tcx> LateLintPass<'tcx> for NonCopyConst { + fn check_item(&mut self, cx: &LateContext<'tcx>, it: &'tcx Item<'_>) { if let ItemKind::Const(hir_ty, ..) = &it.kind { let ty = hir_ty_to_ty(cx.tcx, hir_ty); verify_ty_bound(cx, ty, Source::Item { item: it.span }); } } - fn check_trait_item(&mut self, cx: &LateContext<'a, 'tcx>, trait_item: &'tcx TraitItem<'_>) { + fn check_trait_item(&mut self, cx: &LateContext<'tcx>, trait_item: &'tcx TraitItem<'_>) { if let TraitItemKind::Const(hir_ty, ..) = &trait_item.kind { let ty = hir_ty_to_ty(cx.tcx, hir_ty); verify_ty_bound( @@ -163,7 +163,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NonCopyConst { } } - fn check_impl_item(&mut self, cx: &LateContext<'a, 'tcx>, impl_item: &'tcx ImplItem<'_>) { + fn check_impl_item(&mut self, cx: &LateContext<'tcx>, impl_item: &'tcx ImplItem<'_>) { if let ImplItemKind::Const(hir_ty, ..) = &impl_item.kind { let item_hir_id = cx.tcx.hir().get_parent_node(impl_item.hir_id); let item = cx.tcx.hir().expect_item(item_hir_id); @@ -182,7 +182,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NonCopyConst { } } - fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) { + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { if let ExprKind::Path(qpath) = &expr.kind { // Only lint if we use the const item inside a function. if in_constant(cx, expr.hir_id) { diff --git a/clippy_lints/src/open_options.rs b/clippy_lints/src/open_options.rs index 2467a14cea12f..2b83efa84f64d 100644 --- a/clippy_lints/src/open_options.rs +++ b/clippy_lints/src/open_options.rs @@ -27,8 +27,8 @@ declare_clippy_lint! { declare_lint_pass!(OpenOptions => [NONSENSICAL_OPEN_OPTIONS]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for OpenOptions { - fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr<'_>) { +impl<'tcx> LateLintPass<'tcx> for OpenOptions { + fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) { if let ExprKind::MethodCall(ref path, _, ref arguments, _) = e.kind { let obj_ty = walk_ptrs_ty(cx.tables().expr_ty(&arguments[0])); if path.ident.name == sym!(open) && match_type(cx, obj_ty, &paths::OPEN_OPTIONS) { @@ -56,7 +56,7 @@ enum OpenOption { Append, } -fn get_open_options(cx: &LateContext<'_, '_>, argument: &Expr<'_>, options: &mut Vec<(OpenOption, Argument)>) { +fn get_open_options(cx: &LateContext<'_>, argument: &Expr<'_>, options: &mut Vec<(OpenOption, Argument)>) { if let ExprKind::MethodCall(ref path, _, ref arguments, _) = argument.kind { let obj_ty = walk_ptrs_ty(cx.tables().expr_ty(&arguments[0])); @@ -107,7 +107,7 @@ fn get_open_options(cx: &LateContext<'_, '_>, argument: &Expr<'_>, options: &mut } } -fn check_open_options(cx: &LateContext<'_, '_>, options: &[(OpenOption, Argument)], span: Span) { +fn check_open_options(cx: &LateContext<'_>, options: &[(OpenOption, Argument)], span: Span) { let (mut create, mut append, mut truncate, mut read, mut write) = (false, false, false, false, false); let (mut create_arg, mut append_arg, mut truncate_arg, mut read_arg, mut write_arg) = (false, false, false, false, false); diff --git a/clippy_lints/src/overflow_check_conditional.rs b/clippy_lints/src/overflow_check_conditional.rs index 5984b09120d0e..0850f88df44fe 100644 --- a/clippy_lints/src/overflow_check_conditional.rs +++ b/clippy_lints/src/overflow_check_conditional.rs @@ -25,9 +25,9 @@ declare_clippy_lint! { declare_lint_pass!(OverflowCheckConditional => [OVERFLOW_CHECK_CONDITIONAL]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for OverflowCheckConditional { +impl<'tcx> LateLintPass<'tcx> for OverflowCheckConditional { // a + b < a, a > a + b, a < a - b, a - b > a - fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) { + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { let eq = |l, r| SpanlessEq::new(cx).eq_path_segment(l, r); if_chain! { if let ExprKind::Binary(ref op, ref first, ref second) = expr.kind; diff --git a/clippy_lints/src/panic_unimplemented.rs b/clippy_lints/src/panic_unimplemented.rs index 2cd9200ddb252..10f4694640eed 100644 --- a/clippy_lints/src/panic_unimplemented.rs +++ b/clippy_lints/src/panic_unimplemented.rs @@ -91,8 +91,8 @@ declare_clippy_lint! { declare_lint_pass!(PanicUnimplemented => [PANIC_PARAMS, UNIMPLEMENTED, UNREACHABLE, TODO, PANIC]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for PanicUnimplemented { - fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) { +impl<'tcx> LateLintPass<'tcx> for PanicUnimplemented { + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { if_chain! { if let ExprKind::Block(ref block, _) = expr.kind; if let Some(ref ex) = block.expr; @@ -136,7 +136,7 @@ fn get_outer_span(expr: &Expr<'_>) -> Span { } } -fn match_panic(params: &[Expr<'_>], expr: &Expr<'_>, cx: &LateContext<'_, '_>) { +fn match_panic(params: &[Expr<'_>], expr: &Expr<'_>, cx: &LateContext<'_>) { if_chain! { if let ExprKind::Lit(ref lit) = params[0].kind; if is_direct_expn_of(expr.span, "panic").is_some(); diff --git a/clippy_lints/src/partialeq_ne_impl.rs b/clippy_lints/src/partialeq_ne_impl.rs index 1445df41c452f..19d355e64ca86 100644 --- a/clippy_lints/src/partialeq_ne_impl.rs +++ b/clippy_lints/src/partialeq_ne_impl.rs @@ -30,8 +30,8 @@ declare_clippy_lint! { declare_lint_pass!(PartialEqNeImpl => [PARTIALEQ_NE_IMPL]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for PartialEqNeImpl { - fn check_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx Item<'_>) { +impl<'tcx> LateLintPass<'tcx> for PartialEqNeImpl { + fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) { if_chain! { if let ItemKind::Impl{ of_trait: Some(ref trait_ref), items: impl_items, .. } = item.kind; if !is_automatically_derived(&*item.attrs); diff --git a/clippy_lints/src/path_buf_push_overwrite.rs b/clippy_lints/src/path_buf_push_overwrite.rs index f26a5258782a7..48e609542793b 100644 --- a/clippy_lints/src/path_buf_push_overwrite.rs +++ b/clippy_lints/src/path_buf_push_overwrite.rs @@ -40,8 +40,8 @@ declare_clippy_lint! { declare_lint_pass!(PathBufPushOverwrite => [PATH_BUF_PUSH_OVERWRITE]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for PathBufPushOverwrite { - fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) { +impl<'tcx> LateLintPass<'tcx> for PathBufPushOverwrite { + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { if_chain! { if let ExprKind::MethodCall(ref path, _, ref args, _) = expr.kind; if path.ident.name == sym!(push); diff --git a/clippy_lints/src/ptr.rs b/clippy_lints/src/ptr.rs index c77b44e0c99c7..7b6bd69ffca5c 100644 --- a/clippy_lints/src/ptr.rs +++ b/clippy_lints/src/ptr.rs @@ -108,14 +108,14 @@ declare_clippy_lint! { declare_lint_pass!(Ptr => [PTR_ARG, CMP_NULL, MUT_FROM_REF]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Ptr { - fn check_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx Item<'_>) { +impl<'tcx> LateLintPass<'tcx> for Ptr { + fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) { if let ItemKind::Fn(ref sig, _, body_id) = item.kind { check_fn(cx, &sig.decl, item.hir_id, Some(body_id)); } } - fn check_impl_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx ImplItem<'_>) { + fn check_impl_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx ImplItem<'_>) { if let ImplItemKind::Fn(ref sig, body_id) = item.kind { let parent_item = cx.tcx.hir().get_parent_item(item.hir_id); if let Some(Node::Item(it)) = cx.tcx.hir().find(parent_item) { @@ -127,7 +127,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Ptr { } } - fn check_trait_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx TraitItem<'_>) { + fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx TraitItem<'_>) { if let TraitItemKind::Fn(ref sig, ref trait_method) = item.kind { let body_id = if let TraitFn::Provided(b) = *trait_method { Some(b) @@ -138,7 +138,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Ptr { } } - fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) { + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { if let ExprKind::Binary(ref op, ref l, ref r) = expr.kind { if (op.node == BinOpKind::Eq || op.node == BinOpKind::Ne) && (is_null_path(l) || is_null_path(r)) { span_lint( @@ -153,7 +153,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Ptr { } #[allow(clippy::too_many_lines)] -fn check_fn(cx: &LateContext<'_, '_>, decl: &FnDecl<'_>, fn_id: HirId, opt_body_id: Option) { +fn check_fn(cx: &LateContext<'_>, decl: &FnDecl<'_>, fn_id: HirId, opt_body_id: Option) { let fn_def_id = cx.tcx.hir().local_def_id(fn_id); let sig = cx.tcx.fn_sig(fn_def_id); let fn_ty = sig.skip_binder(); diff --git a/clippy_lints/src/ptr_offset_with_cast.rs b/clippy_lints/src/ptr_offset_with_cast.rs index b35a7e64bff27..61e186a4b4653 100644 --- a/clippy_lints/src/ptr_offset_with_cast.rs +++ b/clippy_lints/src/ptr_offset_with_cast.rs @@ -43,8 +43,8 @@ declare_clippy_lint! { declare_lint_pass!(PtrOffsetWithCast => [PTR_OFFSET_WITH_CAST]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for PtrOffsetWithCast { - fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) { +impl<'tcx> LateLintPass<'tcx> for PtrOffsetWithCast { + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { // Check if the expressions is a ptr.offset or ptr.wrapping_offset method call let (receiver_expr, arg_expr, method) = match expr_as_ptr_offset_call(cx, expr) { Some(call_arg) => call_arg, @@ -75,7 +75,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for PtrOffsetWithCast { } // If the given expression is a cast from a usize, return the lhs of the cast -fn expr_as_cast_from_usize<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'tcx>) -> Option<&'tcx Expr<'tcx>> { +fn expr_as_cast_from_usize<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) -> Option<&'tcx Expr<'tcx>> { if let ExprKind::Cast(ref cast_lhs_expr, _) = expr.kind { if is_expr_ty_usize(cx, &cast_lhs_expr) { return Some(cast_lhs_expr); @@ -86,8 +86,8 @@ fn expr_as_cast_from_usize<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Exp // If the given expression is a ptr::offset or ptr::wrapping_offset method call, return the // receiver, the arg of the method call, and the method. -fn expr_as_ptr_offset_call<'a, 'tcx>( - cx: &LateContext<'a, 'tcx>, +fn expr_as_ptr_offset_call<'tcx>( + cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, ) -> Option<(&'tcx Expr<'tcx>, &'tcx Expr<'tcx>, Method)> { if let ExprKind::MethodCall(ref path_segment, _, ref args, _) = expr.kind { @@ -104,17 +104,17 @@ fn expr_as_ptr_offset_call<'a, 'tcx>( } // Is the type of the expression a usize? -fn is_expr_ty_usize<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &Expr<'_>) -> bool { +fn is_expr_ty_usize<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>) -> bool { cx.tables().expr_ty(expr) == cx.tcx.types.usize } // Is the type of the expression a raw pointer? -fn is_expr_ty_raw_ptr<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &Expr<'_>) -> bool { +fn is_expr_ty_raw_ptr<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>) -> bool { cx.tables().expr_ty(expr).is_unsafe_ptr() } -fn build_suggestion<'a, 'tcx>( - cx: &LateContext<'a, 'tcx>, +fn build_suggestion<'tcx>( + cx: &LateContext<'tcx>, method: Method, receiver_expr: &Expr<'_>, cast_lhs_expr: &Expr<'_>, diff --git a/clippy_lints/src/question_mark.rs b/clippy_lints/src/question_mark.rs index a77e104bb8f0f..cc9c2f196079f 100644 --- a/clippy_lints/src/question_mark.rs +++ b/clippy_lints/src/question_mark.rs @@ -47,7 +47,7 @@ impl QuestionMark { /// ``` /// /// If it matches, it will suggest to use the question mark operator instead - fn check_is_none_and_early_return_none(cx: &LateContext<'_, '_>, expr: &Expr<'_>) { + fn check_is_none_and_early_return_none(cx: &LateContext<'_>, expr: &Expr<'_>) { if_chain! { if let Some((if_expr, body, else_)) = higher::if_block(&expr); if let ExprKind::MethodCall(segment, _, args, _) = &if_expr.kind; @@ -93,7 +93,7 @@ impl QuestionMark { } } - fn check_if_let_some_and_early_return_none(cx: &LateContext<'_, '_>, expr: &Expr<'_>) { + fn check_if_let_some_and_early_return_none(cx: &LateContext<'_>, expr: &Expr<'_>) { if_chain! { if let ExprKind::Match(subject, arms, source) = &expr.kind; if *source == MatchSource::IfLetDesugar { contains_else_clause: true }; @@ -134,19 +134,19 @@ impl QuestionMark { } } - fn moves_by_default(cx: &LateContext<'_, '_>, expression: &Expr<'_>) -> bool { + fn moves_by_default(cx: &LateContext<'_>, expression: &Expr<'_>) -> bool { let expr_ty = cx.tables().expr_ty(expression); !expr_ty.is_copy_modulo_regions(cx.tcx.at(expression.span), cx.param_env) } - fn is_option(cx: &LateContext<'_, '_>, expression: &Expr<'_>) -> bool { + fn is_option(cx: &LateContext<'_>, expression: &Expr<'_>) -> bool { let expr_ty = cx.tables().expr_ty(expression); is_type_diagnostic_item(cx, expr_ty, sym!(option_type)) } - fn expression_returns_none(cx: &LateContext<'_, '_>, expression: &Expr<'_>) -> bool { + fn expression_returns_none(cx: &LateContext<'_>, expression: &Expr<'_>) -> bool { match expression.kind { ExprKind::Block(ref block, _) => { if let Some(return_expression) = Self::return_expression(block) { @@ -196,8 +196,8 @@ impl QuestionMark { } } -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for QuestionMark { - fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) { +impl<'tcx> LateLintPass<'tcx> for QuestionMark { + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { Self::check_is_none_and_early_return_none(cx, expr); Self::check_if_let_some_and_early_return_none(cx, expr); } diff --git a/clippy_lints/src/ranges.rs b/clippy_lints/src/ranges.rs index 43ef236a92420..c164ec9aaf173 100644 --- a/clippy_lints/src/ranges.rs +++ b/clippy_lints/src/ranges.rs @@ -127,8 +127,8 @@ declare_lint_pass!(Ranges => [ REVERSED_EMPTY_RANGES, ]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Ranges { - fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) { +impl<'tcx> LateLintPass<'tcx> for Ranges { + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { if let ExprKind::MethodCall(ref path, _, ref args, _) = expr.kind { let name = path.ident.as_str(); if name == "zip" && args.len() == 2 { @@ -166,7 +166,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Ranges { } // exclusive range plus one: `x..(y+1)` -fn check_exclusive_range_plus_one(cx: &LateContext<'_, '_>, expr: &Expr<'_>) { +fn check_exclusive_range_plus_one(cx: &LateContext<'_>, expr: &Expr<'_>) { if_chain! { if let Some(higher::Range { start, @@ -215,7 +215,7 @@ fn check_exclusive_range_plus_one(cx: &LateContext<'_, '_>, expr: &Expr<'_>) { } // inclusive range minus one: `x..=(y-1)` -fn check_inclusive_range_minus_one(cx: &LateContext<'_, '_>, expr: &Expr<'_>) { +fn check_inclusive_range_minus_one(cx: &LateContext<'_>, expr: &Expr<'_>) { if_chain! { if let Some(higher::Range { start, end: Some(end), limits: RangeLimits::Closed }) = higher::range(cx, expr); if let Some(y) = y_minus_one(cx, end); @@ -240,8 +240,8 @@ fn check_inclusive_range_minus_one(cx: &LateContext<'_, '_>, expr: &Expr<'_>) { } } -fn check_reversed_empty_range(cx: &LateContext<'_, '_>, expr: &Expr<'_>) { - fn inside_indexing_expr(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> bool { +fn check_reversed_empty_range(cx: &LateContext<'_>, expr: &Expr<'_>) { + fn inside_indexing_expr(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { matches!( get_parent_expr(cx, expr), Some(Expr { @@ -251,7 +251,7 @@ fn check_reversed_empty_range(cx: &LateContext<'_, '_>, expr: &Expr<'_>) { ) } - fn is_for_loop_arg(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> bool { + fn is_for_loop_arg(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { let mut cur_expr = expr; while let Some(parent_expr) = get_parent_expr(cx, cur_expr) { match higher::for_loop(parent_expr) { @@ -320,7 +320,7 @@ fn check_reversed_empty_range(cx: &LateContext<'_, '_>, expr: &Expr<'_>) { } } -fn y_plus_one<'t>(cx: &LateContext<'_, '_>, expr: &'t Expr<'_>) -> Option<&'t Expr<'t>> { +fn y_plus_one<'t>(cx: &LateContext<'_>, expr: &'t Expr<'_>) -> Option<&'t Expr<'t>> { match expr.kind { ExprKind::Binary( Spanned { @@ -341,7 +341,7 @@ fn y_plus_one<'t>(cx: &LateContext<'_, '_>, expr: &'t Expr<'_>) -> Option<&'t Ex } } -fn y_minus_one<'t>(cx: &LateContext<'_, '_>, expr: &'t Expr<'_>) -> Option<&'t Expr<'t>> { +fn y_minus_one<'t>(cx: &LateContext<'_>, expr: &'t Expr<'_>) -> Option<&'t Expr<'t>> { match expr.kind { ExprKind::Binary( Spanned { diff --git a/clippy_lints/src/redundant_clone.rs b/clippy_lints/src/redundant_clone.rs index d563eb886ae7e..fda7480194dce 100644 --- a/clippy_lints/src/redundant_clone.rs +++ b/clippy_lints/src/redundant_clone.rs @@ -66,11 +66,11 @@ declare_clippy_lint! { declare_lint_pass!(RedundantClone => [REDUNDANT_CLONE]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for RedundantClone { +impl<'tcx> LateLintPass<'tcx> for RedundantClone { #[allow(clippy::too_many_lines)] fn check_fn( &mut self, - cx: &LateContext<'a, 'tcx>, + cx: &LateContext<'tcx>, _: FnKind<'tcx>, _: &'tcx FnDecl<'_>, body: &'tcx Body<'_>, @@ -273,7 +273,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for RedundantClone { /// If `kind` is `y = func(x: &T)` where `T: !Copy`, returns `(DefId of func, x, T, y)`. fn is_call_with_ref_arg<'tcx>( - cx: &LateContext<'_, 'tcx>, + cx: &LateContext<'tcx>, mir: &'tcx mir::Body<'tcx>, kind: &'tcx mir::TerminatorKind<'tcx>, ) -> Option<(def_id::DefId, mir::Local, Ty<'tcx>, mir::Local)> { @@ -297,7 +297,7 @@ type CannotMoveOut = bool; /// Finds the first `to = (&)from`, and returns /// ``Some((from, whether `from` cannot be moved out))``. fn find_stmt_assigns_to<'tcx>( - cx: &LateContext<'_, 'tcx>, + cx: &LateContext<'tcx>, mir: &mir::Body<'tcx>, to_local: mir::Local, by_ref: bool, @@ -331,7 +331,7 @@ fn find_stmt_assigns_to<'tcx>( /// /// Also reports whether given `place` cannot be moved out. fn base_local_and_movability<'tcx>( - cx: &LateContext<'_, 'tcx>, + cx: &LateContext<'tcx>, mir: &mir::Body<'tcx>, place: mir::Place<'tcx>, ) -> Option<(mir::Local, CannotMoveOut)> { @@ -459,11 +459,11 @@ impl BottomValue for MaybeStorageLive { struct PossibleBorrowerVisitor<'a, 'tcx> { possible_borrower: TransitiveRelation, body: &'a mir::Body<'tcx>, - cx: &'a LateContext<'a, 'tcx>, + cx: &'a LateContext<'tcx>, } impl<'a, 'tcx> PossibleBorrowerVisitor<'a, 'tcx> { - fn new(cx: &'a LateContext<'a, 'tcx>, body: &'a mir::Body<'tcx>) -> Self { + fn new(cx: &'a LateContext<'tcx>, body: &'a mir::Body<'tcx>) -> Self { Self { possible_borrower: TransitiveRelation::default(), cx, @@ -473,7 +473,7 @@ impl<'a, 'tcx> PossibleBorrowerVisitor<'a, 'tcx> { fn into_map( self, - cx: &LateContext<'a, 'tcx>, + cx: &LateContext<'tcx>, maybe_live: ResultsCursor<'tcx, 'tcx, MaybeStorageLive>, ) -> PossibleBorrowerMap<'a, 'tcx> { let mut map = FxHashMap::default(); diff --git a/clippy_lints/src/redundant_pattern_matching.rs b/clippy_lints/src/redundant_pattern_matching.rs index 3c528a295b044..d8d16efb978a5 100644 --- a/clippy_lints/src/redundant_pattern_matching.rs +++ b/clippy_lints/src/redundant_pattern_matching.rs @@ -47,8 +47,8 @@ declare_clippy_lint! { declare_lint_pass!(RedundantPatternMatching => [REDUNDANT_PATTERN_MATCHING]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for RedundantPatternMatching { - fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) { +impl<'tcx> LateLintPass<'tcx> for RedundantPatternMatching { + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { if let ExprKind::Match(op, arms, ref match_source) = &expr.kind { match match_source { MatchSource::Normal => find_sugg_for_match(cx, expr, op, arms), @@ -60,14 +60,14 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for RedundantPatternMatching { } } -fn find_sugg_for_if_let<'a, 'tcx>( - cx: &LateContext<'a, 'tcx>, +fn find_sugg_for_if_let<'tcx>( + cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, op: &Expr<'_>, arms: &[Arm<'_>], keyword: &'static str, ) { - fn find_suggestion(cx: &LateContext<'_, '_>, hir_id: HirId, path: &QPath<'_>) -> Option<&'static str> { + fn find_suggestion(cx: &LateContext<'_>, hir_id: HirId, path: &QPath<'_>) -> Option<&'static str> { if match_qpath(path, &paths::RESULT_OK) && can_suggest(cx, hir_id, sym!(result_type), "is_ok") { return Some("is_ok()"); } @@ -138,7 +138,7 @@ fn find_sugg_for_if_let<'a, 'tcx>( ); } -fn find_sugg_for_match<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>, op: &Expr<'_>, arms: &[Arm<'_>]) { +fn find_sugg_for_match<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, op: &Expr<'_>, arms: &[Arm<'_>]) { if arms.len() == 2 { let node_pair = (&arms[0].pat.kind, &arms[1].pat.kind); @@ -237,7 +237,7 @@ fn find_good_method_for_match<'a>( } } -fn can_suggest(cx: &LateContext<'_, '_>, hir_id: HirId, diag_item: Symbol, name: &str) -> bool { +fn can_suggest(cx: &LateContext<'_>, hir_id: HirId, diag_item: Symbol, name: &str) -> bool { if !in_constant(cx, hir_id) { return true; } diff --git a/clippy_lints/src/redundant_pub_crate.rs b/clippy_lints/src/redundant_pub_crate.rs index 6fc07f91660ee..acd9047ace617 100644 --- a/clippy_lints/src/redundant_pub_crate.rs +++ b/clippy_lints/src/redundant_pub_crate.rs @@ -39,8 +39,8 @@ pub struct RedundantPubCrate { impl_lint_pass!(RedundantPubCrate => [REDUNDANT_PUB_CRATE]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for RedundantPubCrate { - fn check_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx Item<'tcx>) { +impl<'tcx> LateLintPass<'tcx> for RedundantPubCrate { + fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) { if let VisibilityKind::Crate { .. } = item.vis.node { if !cx.access_levels.is_exported(item.hir_id) { if let Some(false) = self.is_exported.last() { @@ -70,7 +70,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for RedundantPubCrate { } } - fn check_item_post(&mut self, _cx: &LateContext<'a, 'tcx>, item: &'tcx Item<'tcx>) { + fn check_item_post(&mut self, _cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) { if let ItemKind::Mod { .. } = item.kind { self.is_exported.pop().expect("unbalanced check_item/check_item_post"); } diff --git a/clippy_lints/src/regex.rs b/clippy_lints/src/regex.rs index 0b56ef02a844b..b67abad6ccb8f 100644 --- a/clippy_lints/src/regex.rs +++ b/clippy_lints/src/regex.rs @@ -73,12 +73,12 @@ pub struct Regex { impl_lint_pass!(Regex => [INVALID_REGEX, REGEX_MACRO, TRIVIAL_REGEX]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Regex { - fn check_crate(&mut self, _: &LateContext<'a, 'tcx>, _: &'tcx Crate<'_>) { +impl<'tcx> LateLintPass<'tcx> for Regex { + fn check_crate(&mut self, _: &LateContext<'tcx>, _: &'tcx Crate<'_>) { self.spans.clear(); } - fn check_block(&mut self, cx: &LateContext<'a, 'tcx>, block: &'tcx Block<'_>) { + fn check_block(&mut self, cx: &LateContext<'tcx>, block: &'tcx Block<'_>) { if_chain! { if self.last.is_none(); if let Some(ref expr) = block.expr; @@ -100,13 +100,13 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Regex { } } - fn check_block_post(&mut self, _: &LateContext<'a, 'tcx>, block: &'tcx Block<'_>) { + fn check_block_post(&mut self, _: &LateContext<'tcx>, block: &'tcx Block<'_>) { if self.last.map_or(false, |id| block.hir_id == id) { self.last = None; } } - fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) { + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { if_chain! { if let ExprKind::Call(ref fun, ref args) = expr.kind; if let ExprKind::Path(ref qpath) = fun.kind; @@ -139,7 +139,7 @@ fn str_span(base: Span, c: regex_syntax::ast::Span, offset: u16) -> Span { Span::new(start, end, base.ctxt()) } -fn const_str<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, e: &'tcx Expr<'_>) -> Option { +fn const_str<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> Option { constant(cx, cx.tables(), e).and_then(|(c, _)| match c { Constant::Str(s) => Some(s), _ => None, @@ -185,7 +185,7 @@ fn is_trivial_regex(s: ®ex_syntax::hir::Hir) -> Option<&'static str> { } } -fn check_set<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>, utf8: bool) { +fn check_set<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, utf8: bool) { if_chain! { if let ExprKind::AddrOf(BorrowKind::Ref, _, ref expr) = expr.kind; if let ExprKind::Array(exprs) = expr.kind; @@ -197,7 +197,7 @@ fn check_set<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>, utf8: b } } -fn check_regex<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>, utf8: bool) { +fn check_regex<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, utf8: bool) { let mut parser = regex_syntax::ParserBuilder::new() .unicode(utf8) .allow_invalid_utf8(!utf8) diff --git a/clippy_lints/src/serde_api.rs b/clippy_lints/src/serde_api.rs index 6820d1620bd18..339a7cf3bf5d2 100644 --- a/clippy_lints/src/serde_api.rs +++ b/clippy_lints/src/serde_api.rs @@ -20,8 +20,8 @@ declare_clippy_lint! { declare_lint_pass!(SerdeAPI => [SERDE_API_MISUSE]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for SerdeAPI { - fn check_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx Item<'_>) { +impl<'tcx> LateLintPass<'tcx> for SerdeAPI { + fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) { if let ItemKind::Impl { of_trait: Some(ref trait_ref), items, diff --git a/clippy_lints/src/shadow.rs b/clippy_lints/src/shadow.rs index 4780249bcb8e3..7da47ee4ff94b 100644 --- a/clippy_lints/src/shadow.rs +++ b/clippy_lints/src/shadow.rs @@ -96,10 +96,10 @@ declare_clippy_lint! { declare_lint_pass!(Shadow => [SHADOW_SAME, SHADOW_REUSE, SHADOW_UNRELATED]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Shadow { +impl<'tcx> LateLintPass<'tcx> for Shadow { fn check_fn( &mut self, - cx: &LateContext<'a, 'tcx>, + cx: &LateContext<'tcx>, _: FnKind<'tcx>, decl: &'tcx FnDecl<'_>, body: &'tcx Body<'_>, @@ -113,7 +113,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Shadow { } } -fn check_fn<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, decl: &'tcx FnDecl<'_>, body: &'tcx Body<'_>) { +fn check_fn<'tcx>(cx: &LateContext<'tcx>, decl: &'tcx FnDecl<'_>, body: &'tcx Body<'_>) { let mut bindings = Vec::with_capacity(decl.inputs.len()); for arg in iter_input_pats(decl, body) { if let PatKind::Binding(.., ident, _) = arg.pat.kind { @@ -123,7 +123,7 @@ fn check_fn<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, decl: &'tcx FnDecl<'_>, body: check_expr(cx, &body.value, &mut bindings); } -fn check_block<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, block: &'tcx Block<'_>, bindings: &mut Vec<(Name, Span)>) { +fn check_block<'tcx>(cx: &LateContext<'tcx>, block: &'tcx Block<'_>, bindings: &mut Vec<(Name, Span)>) { let len = bindings.len(); for stmt in block.stmts { match stmt.kind { @@ -138,7 +138,7 @@ fn check_block<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, block: &'tcx Block<'_>, bin bindings.truncate(len); } -fn check_local<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, local: &'tcx Local<'_>, bindings: &mut Vec<(Name, Span)>) { +fn check_local<'tcx>(cx: &LateContext<'tcx>, local: &'tcx Local<'_>, bindings: &mut Vec<(Name, Span)>) { if in_external_macro(cx.sess(), local.span) { return; } @@ -163,7 +163,7 @@ fn check_local<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, local: &'tcx Local<'_>, bin } } -fn is_binding(cx: &LateContext<'_, '_>, pat_id: HirId) -> bool { +fn is_binding(cx: &LateContext<'_>, pat_id: HirId) -> bool { let var_ty = cx.tables().node_type_opt(pat_id); if let Some(var_ty) = var_ty { match var_ty.kind { @@ -175,8 +175,8 @@ fn is_binding(cx: &LateContext<'_, '_>, pat_id: HirId) -> bool { } } -fn check_pat<'a, 'tcx>( - cx: &LateContext<'a, 'tcx>, +fn check_pat<'tcx>( + cx: &LateContext<'tcx>, pat: &'tcx Pat<'_>, init: Option<&'tcx Expr<'_>>, span: Span, @@ -259,8 +259,8 @@ fn check_pat<'a, 'tcx>( } } -fn lint_shadow<'a, 'tcx>( - cx: &LateContext<'a, 'tcx>, +fn lint_shadow<'tcx>( + cx: &LateContext<'tcx>, name: Name, span: Span, pattern_span: Span, @@ -326,7 +326,7 @@ fn lint_shadow<'a, 'tcx>( } } -fn check_expr<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>, bindings: &mut Vec<(Name, Span)>) { +fn check_expr<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, bindings: &mut Vec<(Name, Span)>) { if in_external_macro(cx.sess(), expr.span) { return; } @@ -362,7 +362,7 @@ fn check_expr<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>, bindin } } -fn check_ty<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, ty: &'tcx Ty<'_>, bindings: &mut Vec<(Name, Span)>) { +fn check_ty<'tcx>(cx: &LateContext<'tcx>, ty: &'tcx Ty<'_>, bindings: &mut Vec<(Name, Span)>) { match ty.kind { TyKind::Slice(ref sty) => check_ty(cx, sty, bindings), TyKind::Array(ref fty, ref anon_const) => { diff --git a/clippy_lints/src/slow_vector_initialization.rs b/clippy_lints/src/slow_vector_initialization.rs index 44c9cc19cfb4e..96f6881556cf3 100644 --- a/clippy_lints/src/slow_vector_initialization.rs +++ b/clippy_lints/src/slow_vector_initialization.rs @@ -65,8 +65,8 @@ enum InitializationType<'tcx> { Resize(&'tcx Expr<'tcx>), } -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for SlowVectorInit { - fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) { +impl<'tcx> LateLintPass<'tcx> for SlowVectorInit { + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { // Matches initialization on reassignements. For example: `vec = Vec::with_capacity(100)` if_chain! { if let ExprKind::Assign(ref left, ref right, _) = expr.kind; @@ -90,7 +90,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for SlowVectorInit { } } - fn check_stmt(&mut self, cx: &LateContext<'a, 'tcx>, stmt: &'tcx Stmt<'_>) { + fn check_stmt(&mut self, cx: &LateContext<'tcx>, stmt: &'tcx Stmt<'_>) { // Matches statements which initializes vectors. For example: `let mut vec = Vec::with_capacity(10)` if_chain! { if let StmtKind::Local(ref local) = stmt.kind; @@ -130,7 +130,7 @@ impl SlowVectorInit { } /// Search initialization for the given vector - fn search_initialization<'tcx>(cx: &LateContext<'_, 'tcx>, vec_alloc: VecAllocation<'tcx>, parent_node: HirId) { + fn search_initialization<'tcx>(cx: &LateContext<'tcx>, vec_alloc: VecAllocation<'tcx>, parent_node: HirId) { let enclosing_body = get_enclosing_block(cx, parent_node); if enclosing_body.is_none() { @@ -152,7 +152,7 @@ impl SlowVectorInit { } fn lint_initialization<'tcx>( - cx: &LateContext<'_, 'tcx>, + cx: &LateContext<'tcx>, initialization: &InitializationType<'tcx>, vec_alloc: &VecAllocation<'_>, ) { @@ -168,7 +168,7 @@ impl SlowVectorInit { } fn emit_lint<'tcx>( - cx: &LateContext<'_, 'tcx>, + cx: &LateContext<'tcx>, slow_fill: &Expr<'_>, vec_alloc: &VecAllocation<'_>, msg: &str, @@ -190,7 +190,7 @@ impl SlowVectorInit { /// `VectorInitializationVisitor` searches for unsafe or slow vector initializations for the given /// vector. struct VectorInitializationVisitor<'a, 'tcx> { - cx: &'a LateContext<'a, 'tcx>, + cx: &'a LateContext<'tcx>, /// Contains the information. vec_alloc: VecAllocation<'tcx>, diff --git a/clippy_lints/src/strings.rs b/clippy_lints/src/strings.rs index ef66850358e57..89aa6a4edd62d 100644 --- a/clippy_lints/src/strings.rs +++ b/clippy_lints/src/strings.rs @@ -86,8 +86,8 @@ declare_clippy_lint! { declare_lint_pass!(StringAdd => [STRING_ADD, STRING_ADD_ASSIGN]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for StringAdd { - fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr<'_>) { +impl<'tcx> LateLintPass<'tcx> for StringAdd { + fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) { if in_external_macro(cx.sess(), e.span) { return; } @@ -133,11 +133,11 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for StringAdd { } } -fn is_string(cx: &LateContext<'_, '_>, e: &Expr<'_>) -> bool { +fn is_string(cx: &LateContext<'_>, e: &Expr<'_>) -> bool { is_type_diagnostic_item(cx, walk_ptrs_ty(cx.tables().expr_ty(e)), sym!(string_type)) } -fn is_add(cx: &LateContext<'_, '_>, src: &Expr<'_>, target: &Expr<'_>) -> bool { +fn is_add(cx: &LateContext<'_>, src: &Expr<'_>, target: &Expr<'_>) -> bool { match src.kind { ExprKind::Binary( Spanned { @@ -158,8 +158,8 @@ const MAX_LENGTH_BYTE_STRING_LIT: usize = 32; 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<'_>) { +impl<'tcx> LateLintPass<'tcx> for StringLitAsBytes { + fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) { use crate::utils::{snippet, snippet_with_applicability}; use rustc_ast::ast::LitKind; diff --git a/clippy_lints/src/suspicious_trait_impl.rs b/clippy_lints/src/suspicious_trait_impl.rs index cf71c3144a2eb..6d1d083fa8d40 100644 --- a/clippy_lints/src/suspicious_trait_impl.rs +++ b/clippy_lints/src/suspicious_trait_impl.rs @@ -52,8 +52,8 @@ declare_clippy_lint! { declare_lint_pass!(SuspiciousImpl => [SUSPICIOUS_ARITHMETIC_IMPL, SUSPICIOUS_OP_ASSIGN_IMPL]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for SuspiciousImpl { - fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx hir::Expr<'_>) { +impl<'tcx> LateLintPass<'tcx> for SuspiciousImpl { + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>) { if let hir::ExprKind::Binary(binop, _, _) | hir::ExprKind::AssignOp(binop, ..) = expr.kind { match binop.node { hir::BinOpKind::Eq @@ -147,7 +147,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for SuspiciousImpl { } fn check_binop( - cx: &LateContext<'_, '_>, + cx: &LateContext<'_>, expr: &hir::Expr<'_>, binop: hir::BinOpKind, traits: &[&'static str], diff --git a/clippy_lints/src/swap.rs b/clippy_lints/src/swap.rs index 7fdc872c01f54..eb7d35839206b 100644 --- a/clippy_lints/src/swap.rs +++ b/clippy_lints/src/swap.rs @@ -65,15 +65,15 @@ declare_clippy_lint! { declare_lint_pass!(Swap => [MANUAL_SWAP, ALMOST_SWAPPED]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Swap { - fn check_block(&mut self, cx: &LateContext<'a, 'tcx>, block: &'tcx Block<'_>) { +impl<'tcx> LateLintPass<'tcx> for Swap { + fn check_block(&mut self, cx: &LateContext<'tcx>, block: &'tcx Block<'_>) { check_manual_swap(cx, block); check_suspicious_swap(cx, block); } } /// Implementation of the `MANUAL_SWAP` lint. -fn check_manual_swap(cx: &LateContext<'_, '_>, block: &Block<'_>) { +fn check_manual_swap(cx: &LateContext<'_>, block: &Block<'_>) { for w in block.stmts.windows(3) { if_chain! { // let t = foo(); @@ -190,7 +190,7 @@ enum Slice<'a> { } /// Checks if both expressions are index operations into "slice-like" types. -fn check_for_slice<'a>(cx: &LateContext<'_, '_>, lhs1: &'a Expr<'_>, lhs2: &'a Expr<'_>) -> Slice<'a> { +fn check_for_slice<'a>(cx: &LateContext<'_>, lhs1: &'a Expr<'_>, lhs2: &'a Expr<'_>) -> Slice<'a> { if let ExprKind::Index(ref lhs1, ref idx1) = lhs1.kind { if let ExprKind::Index(ref lhs2, ref idx2) = lhs2.kind { if SpanlessEq::new(cx).ignore_fn().eq_expr(lhs1, lhs2) { @@ -213,7 +213,7 @@ fn check_for_slice<'a>(cx: &LateContext<'_, '_>, lhs1: &'a Expr<'_>, lhs2: &'a E } /// Implementation of the `ALMOST_SWAPPED` lint. -fn check_suspicious_swap(cx: &LateContext<'_, '_>, block: &Block<'_>) { +fn check_suspicious_swap(cx: &LateContext<'_>, block: &Block<'_>) { for w in block.stmts.windows(2) { if_chain! { if let StmtKind::Semi(ref first) = w[0].kind; diff --git a/clippy_lints/src/temporary_assignment.rs b/clippy_lints/src/temporary_assignment.rs index bc282e4bd987c..509bbfd27c1a5 100644 --- a/clippy_lints/src/temporary_assignment.rs +++ b/clippy_lints/src/temporary_assignment.rs @@ -22,7 +22,7 @@ declare_clippy_lint! { "assignments to temporaries" } -fn is_temporary(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> bool { +fn is_temporary(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { match &expr.kind { ExprKind::Struct(..) | ExprKind::Tup(..) => true, ExprKind::Path(qpath) => { @@ -38,8 +38,8 @@ fn is_temporary(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> bool { declare_lint_pass!(TemporaryAssignment => [TEMPORARY_ASSIGNMENT]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TemporaryAssignment { - fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) { +impl<'tcx> LateLintPass<'tcx> for TemporaryAssignment { + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { if let ExprKind::Assign(target, ..) = &expr.kind { let mut base = target; while let ExprKind::Field(f, _) | ExprKind::Index(f, _) = &base.kind { diff --git a/clippy_lints/src/to_digit_is_some.rs b/clippy_lints/src/to_digit_is_some.rs index 4f943eeaeebc7..4157103a574e1 100644 --- a/clippy_lints/src/to_digit_is_some.rs +++ b/clippy_lints/src/to_digit_is_some.rs @@ -31,8 +31,8 @@ declare_clippy_lint! { declare_lint_pass!(ToDigitIsSome => [TO_DIGIT_IS_SOME]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ToDigitIsSome { - fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx hir::Expr<'_>) { +impl<'tcx> LateLintPass<'tcx> for ToDigitIsSome { + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>) { if_chain! { if let hir::ExprKind::MethodCall(is_some_path, _, is_some_args, _) = &expr.kind; if is_some_path.ident.name.as_str() == "is_some"; diff --git a/clippy_lints/src/trait_bounds.rs b/clippy_lints/src/trait_bounds.rs index c3e4eb05eb4ed..9eb2079c3ca2d 100644 --- a/clippy_lints/src/trait_bounds.rs +++ b/clippy_lints/src/trait_bounds.rs @@ -31,8 +31,8 @@ declare_clippy_lint! { impl_lint_pass!(TraitBounds => [TYPE_REPETITION_IN_BOUNDS]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TraitBounds { - fn check_generics(&mut self, cx: &LateContext<'a, 'tcx>, gen: &'tcx Generics<'_>) { +impl<'tcx> LateLintPass<'tcx> for TraitBounds { + fn check_generics(&mut self, cx: &LateContext<'tcx>, gen: &'tcx Generics<'_>) { if in_macro(gen.span) { return; } diff --git a/clippy_lints/src/transmute.rs b/clippy_lints/src/transmute.rs index 6ef4b8dcfc194..5f76d5c46efba 100644 --- a/clippy_lints/src/transmute.rs +++ b/clippy_lints/src/transmute.rs @@ -293,9 +293,9 @@ static COLLECTIONS: &[&[&str]] = &[ &paths::HASHSET, &paths::HASHMAP, ]; -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Transmute { +impl<'tcx> LateLintPass<'tcx> for Transmute { #[allow(clippy::similar_names, clippy::too_many_lines)] - fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr<'_>) { + fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) { if_chain! { if let ExprKind::Call(ref path_expr, ref args) = e.kind; if let ExprKind::Path(ref qpath) = path_expr.kind; @@ -613,7 +613,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Transmute { /// the type's `ToString` implementation. In weird cases it could lead to types /// with invalid `'_` /// lifetime, but it should be rare. -fn get_type_snippet(cx: &LateContext<'_, '_>, path: &QPath<'_>, to_ref_ty: Ty<'_>) -> String { +fn get_type_snippet(cx: &LateContext<'_>, path: &QPath<'_>, to_ref_ty: Ty<'_>) -> String { let seg = last_path_segment(path); if_chain! { if let Some(ref params) = seg.args; @@ -633,7 +633,7 @@ fn get_type_snippet(cx: &LateContext<'_, '_>, path: &QPath<'_>, to_ref_ty: Ty<'_ // check if the component types of the transmuted collection and the result have different ABI, // size or alignment -fn is_layout_incompatible<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, from: Ty<'tcx>, to: Ty<'tcx>) -> bool { +fn is_layout_incompatible<'tcx>(cx: &LateContext<'tcx>, from: Ty<'tcx>, to: Ty<'tcx>) -> bool { let empty_param_env = ty::ParamEnv::empty(); // check if `from` and `to` are normalizable to avoid ICE (#4968) if !(is_normalizable(cx, empty_param_env, from) && is_normalizable(cx, empty_param_env, to)) { diff --git a/clippy_lints/src/transmuting_null.rs b/clippy_lints/src/transmuting_null.rs index 3351488a45c4d..2f03c6db42d99 100644 --- a/clippy_lints/src/transmuting_null.rs +++ b/clippy_lints/src/transmuting_null.rs @@ -29,8 +29,8 @@ declare_lint_pass!(TransmutingNull => [TRANSMUTING_NULL]); const LINT_MSG: &str = "transmuting a known null pointer into a reference."; -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TransmutingNull { - fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) { +impl<'tcx> LateLintPass<'tcx> for TransmutingNull { + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { if in_external_macro(cx.sess(), expr.span) { return; } diff --git a/clippy_lints/src/trivially_copy_pass_by_ref.rs b/clippy_lints/src/trivially_copy_pass_by_ref.rs index 146ac4b09d5a4..6a2b05e3e6df7 100644 --- a/clippy_lints/src/trivially_copy_pass_by_ref.rs +++ b/clippy_lints/src/trivially_copy_pass_by_ref.rs @@ -73,7 +73,7 @@ impl<'tcx> TriviallyCopyPassByRef { Self { limit } } - fn check_poly_fn(&mut self, cx: &LateContext<'_, 'tcx>, hir_id: HirId, decl: &FnDecl<'_>, span: Option) { + fn check_poly_fn(&mut self, cx: &LateContext<'tcx>, hir_id: HirId, decl: &FnDecl<'_>, span: Option) { let fn_def_id = cx.tcx.hir().local_def_id(hir_id); let fn_sig = cx.tcx.fn_sig(fn_def_id); @@ -125,8 +125,8 @@ impl<'tcx> TriviallyCopyPassByRef { 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<'_>) { +impl<'tcx> LateLintPass<'tcx> for TriviallyCopyPassByRef { + fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::TraitItem<'_>) { if item.span.from_expansion() { return; } @@ -138,7 +138,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TriviallyCopyPassByRef { fn check_fn( &mut self, - cx: &LateContext<'a, 'tcx>, + cx: &LateContext<'tcx>, kind: FnKind<'tcx>, decl: &'tcx FnDecl<'_>, _body: &'tcx Body<'_>, diff --git a/clippy_lints/src/try_err.rs b/clippy_lints/src/try_err.rs index e129dd84d15a6..208d248faa57d 100644 --- a/clippy_lints/src/try_err.rs +++ b/clippy_lints/src/try_err.rs @@ -43,8 +43,8 @@ declare_clippy_lint! { declare_lint_pass!(TryErr => [TRY_ERR]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TryErr { - fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) { +impl<'tcx> LateLintPass<'tcx> for TryErr { + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { // Looks for a structure like this: // match ::std::ops::Try::into_result(Err(5)) { // ::std::result::Result::Err(err) => @@ -97,7 +97,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TryErr { // In order to determine whether to suggest `.into()` or not, we need to find the error type the // function returns. To do that, we look for the From::from call (see tree above), and capture // its output type. -fn find_err_return_type<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx ExprKind<'_>) -> Option> { +fn find_err_return_type<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx ExprKind<'_>) -> Option> { if let ExprKind::Match(_, ref arms, MatchSource::TryDesugar) = expr { arms.iter().find_map(|ty| find_err_return_type_arm(cx, ty)) } else { @@ -106,7 +106,7 @@ fn find_err_return_type<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx ExprKi } // Check for From::from in one of the match arms. -fn find_err_return_type_arm<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, arm: &'tcx Arm<'_>) -> Option> { +fn find_err_return_type_arm<'tcx>(cx: &LateContext<'tcx>, arm: &'tcx Arm<'_>) -> Option> { if_chain! { if let ExprKind::Ret(Some(ref err_ret)) = arm.body.kind; if let ExprKind::Call(ref from_error_path, ref from_error_args) = err_ret.kind; diff --git a/clippy_lints/src/types.rs b/clippy_lints/src/types.rs index 74db29e4f1d50..b1345f0de5e4b 100644 --- a/clippy_lints/src/types.rs +++ b/clippy_lints/src/types.rs @@ -218,16 +218,8 @@ pub struct Types { impl_lint_pass!(Types => [BOX_VEC, VEC_BOX, OPTION_OPTION, LINKEDLIST, BORROWED_BOX, REDUNDANT_ALLOCATION]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Types { - fn check_fn( - &mut self, - cx: &LateContext<'_, '_>, - _: FnKind<'_>, - decl: &FnDecl<'_>, - _: &Body<'_>, - _: Span, - id: HirId, - ) { +impl<'tcx> LateLintPass<'tcx> for Types { + fn check_fn(&mut self, cx: &LateContext<'_>, _: FnKind<'_>, decl: &FnDecl<'_>, _: &Body<'_>, _: Span, id: HirId) { // Skip trait implementations; see issue #605. if let Some(hir::Node::Item(item)) = cx.tcx.hir().find(cx.tcx.hir().get_parent_item(id)) { if let ItemKind::Impl { of_trait: Some(_), .. } = item.kind { @@ -238,11 +230,11 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Types { self.check_fn_decl(cx, decl); } - fn check_struct_field(&mut self, cx: &LateContext<'_, '_>, field: &hir::StructField<'_>) { + fn check_struct_field(&mut self, cx: &LateContext<'_>, field: &hir::StructField<'_>) { self.check_ty(cx, &field.ty, false); } - fn check_trait_item(&mut self, cx: &LateContext<'_, '_>, item: &TraitItem<'_>) { + fn check_trait_item(&mut self, cx: &LateContext<'_>, item: &TraitItem<'_>) { match item.kind { TraitItemKind::Const(ref ty, _) | TraitItemKind::Type(_, Some(ref ty)) => self.check_ty(cx, ty, false), TraitItemKind::Fn(ref sig, _) => self.check_fn_decl(cx, &sig.decl), @@ -250,7 +242,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Types { } } - fn check_local(&mut self, cx: &LateContext<'_, '_>, local: &Local<'_>) { + fn check_local(&mut self, cx: &LateContext<'_>, local: &Local<'_>) { if let Some(ref ty) = local.ty { self.check_ty(cx, ty, true); } @@ -258,7 +250,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Types { } /// Checks if `qpath` has last segment with type parameter matching `path` -fn match_type_parameter(cx: &LateContext<'_, '_>, qpath: &QPath<'_>, path: &[&str]) -> Option { +fn match_type_parameter(cx: &LateContext<'_>, qpath: &QPath<'_>, path: &[&str]) -> Option { let last = last_path_segment(qpath); if_chain! { if let Some(ref params) = last.args; @@ -277,7 +269,7 @@ fn match_type_parameter(cx: &LateContext<'_, '_>, qpath: &QPath<'_>, path: &[&st None } -fn match_borrows_parameter(_cx: &LateContext<'_, '_>, qpath: &QPath<'_>) -> Option { +fn match_borrows_parameter(_cx: &LateContext<'_>, qpath: &QPath<'_>) -> Option { let last = last_path_segment(qpath); if_chain! { if let Some(ref params) = last.args; @@ -299,7 +291,7 @@ impl Types { Self { vec_box_size_threshold } } - fn check_fn_decl(&mut self, cx: &LateContext<'_, '_>, decl: &FnDecl<'_>) { + fn check_fn_decl(&mut self, cx: &LateContext<'_>, decl: &FnDecl<'_>) { for input in decl.inputs { self.check_ty(cx, input, false); } @@ -315,7 +307,7 @@ impl Types { /// The parameter `is_local` distinguishes the context of the type; types from /// local bindings should only be checked for the `BORROWED_BOX` lint. #[allow(clippy::too_many_lines)] - fn check_ty(&mut self, cx: &LateContext<'_, '_>, hir_ty: &hir::Ty<'_>, is_local: bool) { + fn check_ty(&mut self, cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, is_local: bool) { if hir_ty.span.from_expansion() { return; } @@ -501,7 +493,7 @@ impl Types { fn check_ty_rptr( &mut self, - cx: &LateContext<'_, '_>, + cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, is_local: bool, lt: &Lifetime, @@ -600,8 +592,8 @@ declare_clippy_lint! { declare_lint_pass!(LetUnitValue => [LET_UNIT_VALUE]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for LetUnitValue { - fn check_stmt(&mut self, cx: &LateContext<'a, 'tcx>, stmt: &'tcx Stmt<'_>) { +impl<'tcx> LateLintPass<'tcx> for LetUnitValue { + fn check_stmt(&mut self, cx: &LateContext<'tcx>, stmt: &'tcx Stmt<'_>) { if let StmtKind::Local(ref local) = stmt.kind { if is_unit(cx.tables().pat_ty(&local.pat)) { if in_external_macro(cx.sess(), stmt.span) || local.pat.span.from_expansion() { @@ -681,8 +673,8 @@ declare_clippy_lint! { 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<'tcx>) { +impl<'tcx> LateLintPass<'tcx> for UnitCmp { + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) { if expr.span.from_expansion() { if let Some(callee) = expr.span.source_callee() { if let ExpnKind::Macro(MacroKind::Bang, symbol) = callee.kind { @@ -754,8 +746,8 @@ declare_clippy_lint! { 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<'_>) { +impl<'tcx> LateLintPass<'tcx> for UnitArg { + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { if expr.span.from_expansion() { return; } @@ -802,7 +794,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnitArg { } } -fn lint_unit_args(cx: &LateContext<'_, '_>, expr: &Expr<'_>, args_to_recover: &[&Expr<'_>]) { +fn lint_unit_args(cx: &LateContext<'_>, expr: &Expr<'_>, args_to_recover: &[&Expr<'_>]) { let mut applicability = Applicability::MachineApplicable; let (singular, plural) = if args_to_recover.len() > 1 { ("", "s") @@ -1168,7 +1160,7 @@ fn is_isize_or_usize(typ: Ty<'_>) -> bool { } } -fn span_precision_loss_lint(cx: &LateContext<'_, '_>, expr: &Expr<'_>, cast_from: Ty<'_>, cast_to_f64: bool) { +fn span_precision_loss_lint(cx: &LateContext<'_>, expr: &Expr<'_>, cast_from: Ty<'_>, cast_to_f64: bool) { let mantissa_nbits = if cast_to_f64 { 52 } else { 23 }; let arch_dependent = is_isize_or_usize(cast_from) && cast_to_f64; let arch_dependent_str = "on targets with 64-bit wide pointers "; @@ -1204,7 +1196,7 @@ fn should_strip_parens(op: &Expr<'_>, snip: &str) -> bool { false } -fn span_lossless_lint(cx: &LateContext<'_, '_>, expr: &Expr<'_>, op: &Expr<'_>, cast_from: Ty<'_>, cast_to: Ty<'_>) { +fn span_lossless_lint(cx: &LateContext<'_>, expr: &Expr<'_>, op: &Expr<'_>, cast_from: Ty<'_>, cast_to: Ty<'_>) { // Do not suggest using From in consts/statics until it is valid to do so (see #2267). if in_constant(cx, expr.hir_id) { return; @@ -1244,7 +1236,7 @@ enum ArchSuffix { None, } -fn check_loss_of_sign(cx: &LateContext<'_, '_>, expr: &Expr<'_>, op: &Expr<'_>, cast_from: Ty<'_>, cast_to: Ty<'_>) { +fn check_loss_of_sign(cx: &LateContext<'_>, expr: &Expr<'_>, op: &Expr<'_>, cast_from: Ty<'_>, cast_to: Ty<'_>) { if !cast_from.is_signed() || cast_to.is_signed() { return; } @@ -1291,7 +1283,7 @@ fn check_loss_of_sign(cx: &LateContext<'_, '_>, expr: &Expr<'_>, op: &Expr<'_>, ); } -fn check_truncation_and_wrapping(cx: &LateContext<'_, '_>, expr: &Expr<'_>, cast_from: Ty<'_>, cast_to: Ty<'_>) { +fn check_truncation_and_wrapping(cx: &LateContext<'_>, expr: &Expr<'_>, cast_from: Ty<'_>, cast_to: Ty<'_>) { let arch_64_suffix = " on targets with 64-bit wide pointers"; let arch_32_suffix = " on targets with 32-bit wide pointers"; let cast_unsigned_to_signed = !cast_from.is_signed() && cast_to.is_signed(); @@ -1362,7 +1354,7 @@ fn check_truncation_and_wrapping(cx: &LateContext<'_, '_>, expr: &Expr<'_>, cast } } -fn check_lossless(cx: &LateContext<'_, '_>, expr: &Expr<'_>, op: &Expr<'_>, cast_from: Ty<'_>, cast_to: Ty<'_>) { +fn check_lossless(cx: &LateContext<'_>, expr: &Expr<'_>, op: &Expr<'_>, cast_from: Ty<'_>, cast_to: Ty<'_>) { let cast_signed_to_unsigned = cast_from.is_signed() && !cast_to.is_signed(); let from_nbits = int_ty_to_nbits(cast_from, cx.tcx); let to_nbits = int_ty_to_nbits(cast_to, cx.tcx); @@ -1386,7 +1378,7 @@ declare_lint_pass!(Casts => [ // Check if the given type is either `core::ffi::c_void` or // one of the platform specific `libc::::c_void` of libc. -fn is_c_void(cx: &LateContext<'_, '_>, ty: Ty<'_>) -> bool { +fn is_c_void(cx: &LateContext<'_>, ty: Ty<'_>) -> bool { if let ty::Adt(adt, _) = ty.kind { let names = cx.get_def_path(adt.did); @@ -1410,8 +1402,8 @@ 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<'_>) { +impl<'tcx> LateLintPass<'tcx> for Casts { + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { if expr.span.from_expansion() { return; } @@ -1467,7 +1459,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Casts { } fn lint_numeric_casts<'tcx>( - cx: &LateContext<'_, 'tcx>, + cx: &LateContext<'tcx>, expr: &Expr<'tcx>, cast_expr: &Expr<'_>, cast_from: Ty<'tcx>, @@ -1528,7 +1520,7 @@ fn lint_numeric_casts<'tcx>( } } -fn lint_cast_ptr_alignment<'tcx>(cx: &LateContext<'_, 'tcx>, expr: &Expr<'_>, cast_from: Ty<'tcx>, cast_to: Ty<'tcx>) { +fn lint_cast_ptr_alignment<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>, cast_from: Ty<'tcx>, cast_to: Ty<'tcx>) { if_chain! { if let ty::RawPtr(from_ptr_ty) = &cast_from.kind; if let ty::RawPtr(to_ptr_ty) = &cast_to.kind; @@ -1557,7 +1549,7 @@ fn lint_cast_ptr_alignment<'tcx>(cx: &LateContext<'_, 'tcx>, expr: &Expr<'_>, ca } fn lint_fn_to_numeric_cast( - cx: &LateContext<'_, '_>, + cx: &LateContext<'_>, expr: &Expr<'_>, cast_expr: &Expr<'_>, cast_from: Ty<'_>, @@ -1637,10 +1629,10 @@ impl TypeComplexity { impl_lint_pass!(TypeComplexity => [TYPE_COMPLEXITY]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeComplexity { +impl<'tcx> LateLintPass<'tcx> for TypeComplexity { fn check_fn( &mut self, - cx: &LateContext<'a, 'tcx>, + cx: &LateContext<'tcx>, _: FnKind<'tcx>, decl: &'tcx FnDecl<'_>, _: &'tcx Body<'_>, @@ -1650,12 +1642,12 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeComplexity { self.check_fndecl(cx, decl); } - fn check_struct_field(&mut self, cx: &LateContext<'a, 'tcx>, field: &'tcx hir::StructField<'_>) { + fn check_struct_field(&mut self, cx: &LateContext<'tcx>, field: &'tcx hir::StructField<'_>) { // enum variants are also struct fields now self.check_type(cx, &field.ty); } - fn check_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx Item<'_>) { + fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) { match item.kind { ItemKind::Static(ref ty, _, _) | ItemKind::Const(ref ty, _) => self.check_type(cx, ty), // functions, enums, structs, impls and traits are covered @@ -1663,7 +1655,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeComplexity { } } - fn check_trait_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx TraitItem<'_>) { + fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx TraitItem<'_>) { match item.kind { TraitItemKind::Const(ref ty, _) | TraitItemKind::Type(_, Some(ref ty)) => self.check_type(cx, ty), TraitItemKind::Fn(FnSig { ref decl, .. }, TraitFn::Required(_)) => self.check_fndecl(cx, decl), @@ -1672,7 +1664,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeComplexity { } } - fn check_impl_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx ImplItem<'_>) { + fn check_impl_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx ImplItem<'_>) { match item.kind { ImplItemKind::Const(ref ty, _) | ImplItemKind::TyAlias(ref ty) => self.check_type(cx, ty), // methods are covered by check_fn @@ -1680,15 +1672,15 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeComplexity { } } - fn check_local(&mut self, cx: &LateContext<'a, 'tcx>, local: &'tcx Local<'_>) { + fn check_local(&mut self, cx: &LateContext<'tcx>, local: &'tcx Local<'_>) { if let Some(ref ty) = local.ty { self.check_type(cx, ty); } } } -impl<'a, 'tcx> TypeComplexity { - fn check_fndecl(&self, cx: &LateContext<'a, 'tcx>, decl: &'tcx FnDecl<'_>) { +impl<'tcx> TypeComplexity { + fn check_fndecl(&self, cx: &LateContext<'tcx>, decl: &'tcx FnDecl<'_>) { for arg in decl.inputs { self.check_type(cx, arg); } @@ -1697,7 +1689,7 @@ impl<'a, 'tcx> TypeComplexity { } } - fn check_type(&self, cx: &LateContext<'_, '_>, ty: &hir::Ty<'_>) { + fn check_type(&self, cx: &LateContext<'_>, ty: &hir::Ty<'_>) { if ty.span.from_expansion() { return; } @@ -1797,8 +1789,8 @@ declare_clippy_lint! { declare_lint_pass!(CharLitAsU8 => [CHAR_LIT_AS_U8]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for CharLitAsU8 { - fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) { +impl<'tcx> LateLintPass<'tcx> for CharLitAsU8 { + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { if_chain! { if !expr.span.from_expansion(); if let ExprKind::Cast(e, _) = &expr.kind; @@ -1878,7 +1870,7 @@ enum AbsurdComparisonResult { InequalityImpossible, } -fn is_cast_between_fixed_and_target<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'tcx>) -> bool { +fn is_cast_between_fixed_and_target<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) -> bool { if let ExprKind::Cast(ref cast_exp, _) = expr.kind { let precast_ty = cx.tables().expr_ty(cast_exp); let cast_ty = cx.tables().expr_ty(expr); @@ -1889,8 +1881,8 @@ fn is_cast_between_fixed_and_target<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: false } -fn detect_absurd_comparison<'a, 'tcx>( - cx: &LateContext<'a, 'tcx>, +fn detect_absurd_comparison<'tcx>( + cx: &LateContext<'tcx>, op: BinOpKind, lhs: &'tcx Expr<'_>, rhs: &'tcx Expr<'_>, @@ -1936,7 +1928,7 @@ fn detect_absurd_comparison<'a, 'tcx>( }) } -fn detect_extreme_expr<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) -> Option> { +fn detect_extreme_expr<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) -> Option> { use crate::types::ExtremeType::{Maximum, Minimum}; let ty = cx.tables().expr_ty(expr); @@ -1960,8 +1952,8 @@ fn detect_extreme_expr<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_ Some(ExtremeExpr { which, expr }) } -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for AbsurdExtremeComparisons { - fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) { +impl<'tcx> LateLintPass<'tcx> for AbsurdExtremeComparisons { + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { use crate::types::AbsurdComparisonResult::{AlwaysFalse, AlwaysTrue, InequalityImpossible}; use crate::types::ExtremeType::{Maximum, Minimum}; @@ -2069,7 +2061,7 @@ impl Ord for FullInt { } } -fn numeric_cast_precast_bounds<'a>(cx: &LateContext<'_, '_>, expr: &'a Expr<'_>) -> Option<(FullInt, FullInt)> { +fn numeric_cast_precast_bounds<'a>(cx: &LateContext<'_>, expr: &'a Expr<'_>) -> Option<(FullInt, FullInt)> { if let ExprKind::Cast(ref cast_exp, _) = expr.kind { let pre_cast_ty = cx.tables().expr_ty(cast_exp); let cast_ty = cx.tables().expr_ty(expr); @@ -2101,7 +2093,7 @@ fn numeric_cast_precast_bounds<'a>(cx: &LateContext<'_, '_>, expr: &'a Expr<'_>) } } -fn node_as_const_fullint<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) -> Option { +fn node_as_const_fullint<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) -> Option { let val = constant(cx, cx.tables(), expr)?.0; if let Constant::Int(const_int) = val { match cx.tables().expr_ty(expr).kind { @@ -2114,7 +2106,7 @@ fn node_as_const_fullint<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr< } } -fn err_upcast_comparison(cx: &LateContext<'_, '_>, span: Span, expr: &Expr<'_>, always: bool) { +fn err_upcast_comparison(cx: &LateContext<'_>, span: Span, expr: &Expr<'_>, always: bool) { if let ExprKind::Cast(ref cast_val, _) = expr.kind { span_lint( cx, @@ -2129,8 +2121,8 @@ fn err_upcast_comparison(cx: &LateContext<'_, '_>, span: Span, expr: &Expr<'_>, } } -fn upcast_comparison_bounds_err<'a, 'tcx>( - cx: &LateContext<'a, 'tcx>, +fn upcast_comparison_bounds_err<'tcx>( + cx: &LateContext<'tcx>, span: Span, rel: comparisons::Rel, lhs_bounds: Option<(FullInt, FullInt)>, @@ -2187,8 +2179,8 @@ fn upcast_comparison_bounds_err<'a, 'tcx>( } } -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for InvalidUpcastComparisons { - fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) { +impl<'tcx> LateLintPass<'tcx> for InvalidUpcastComparisons { + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { if let ExprKind::Binary(ref cmp, ref lhs, ref rhs) = expr.kind { let normalized = comparisons::normalize_comparison(cmp.node, lhs, rhs); let (rel, normalized_lhs, normalized_rhs) = if let Some(val) = normalized { @@ -2243,13 +2235,13 @@ declare_clippy_lint! { declare_lint_pass!(ImplicitHasher => [IMPLICIT_HASHER]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ImplicitHasher { +impl<'tcx> LateLintPass<'tcx> for ImplicitHasher { #[allow(clippy::cast_possible_truncation, clippy::too_many_lines)] - fn check_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx Item<'_>) { + fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) { use rustc_span::BytePos; - fn suggestion<'a, 'tcx>( - cx: &LateContext<'a, 'tcx>, + fn suggestion<'tcx>( + cx: &LateContext<'tcx>, diag: &mut DiagnosticBuilder<'_>, generics_span: Span, generics_suggestion_span: Span, @@ -2393,7 +2385,7 @@ enum ImplicitHasherType<'tcx> { impl<'tcx> ImplicitHasherType<'tcx> { /// Checks that `ty` is a target type without a `BuildHasher`. - fn new<'a>(cx: &LateContext<'a, 'tcx>, hir_ty: &hir::Ty<'_>) -> Option { + fn new(cx: &LateContext<'tcx>, hir_ty: &hir::Ty<'_>) -> Option { if let TyKind::Path(QPath::Resolved(None, ref path)) = hir_ty.kind { let params: Vec<_> = path .segments @@ -2461,12 +2453,12 @@ impl<'tcx> ImplicitHasherType<'tcx> { } struct ImplicitHasherTypeVisitor<'a, 'tcx> { - cx: &'a LateContext<'a, 'tcx>, + cx: &'a LateContext<'tcx>, found: Vec>, } impl<'a, 'tcx> ImplicitHasherTypeVisitor<'a, 'tcx> { - fn new(cx: &'a LateContext<'a, 'tcx>) -> Self { + fn new(cx: &'a LateContext<'tcx>) -> Self { Self { cx, found: vec![] } } } @@ -2489,14 +2481,14 @@ impl<'a, 'tcx> Visitor<'tcx> for ImplicitHasherTypeVisitor<'a, 'tcx> { /// Looks for default-hasher-dependent constructors like `HashMap::new`. struct ImplicitHasherConstructorVisitor<'a, 'b, 'tcx> { - cx: &'a LateContext<'a, 'tcx>, + cx: &'a LateContext<'tcx>, maybe_typeck_tables: Option<&'tcx TypeckTables<'tcx>>, target: &'b ImplicitHasherType<'tcx>, suggestions: BTreeMap, } impl<'a, 'b, 'tcx> ImplicitHasherConstructorVisitor<'a, 'b, 'tcx> { - fn new(cx: &'a LateContext<'a, 'tcx>, target: &'b ImplicitHasherType<'tcx>) -> Self { + fn new(cx: &'a LateContext<'tcx>, target: &'b ImplicitHasherType<'tcx>) -> Self { Self { cx, maybe_typeck_tables: cx.maybe_typeck_tables(), @@ -2599,8 +2591,8 @@ declare_clippy_lint! { declare_lint_pass!(RefToMut => [CAST_REF_TO_MUT]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for RefToMut { - fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) { +impl<'tcx> LateLintPass<'tcx> for RefToMut { + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { if_chain! { if let ExprKind::Unary(UnOp::UnDeref, e) = &expr.kind; if let ExprKind::Cast(e, t) = &e.kind; diff --git a/clippy_lints/src/unicode.rs b/clippy_lints/src/unicode.rs index d073c197656c6..d8c57f0e7ae7f 100644 --- a/clippy_lints/src/unicode.rs +++ b/clippy_lints/src/unicode.rs @@ -65,8 +65,8 @@ declare_clippy_lint! { declare_lint_pass!(Unicode => [ZERO_WIDTH_SPACE, NON_ASCII_LITERAL, UNICODE_NOT_NFC]); -impl LateLintPass<'_, '_> for Unicode { - fn check_expr(&mut self, cx: &LateContext<'_, '_>, expr: &'_ Expr<'_>) { +impl LateLintPass<'_> for Unicode { + fn check_expr(&mut self, cx: &LateContext<'_>, expr: &'_ Expr<'_>) { if let ExprKind::Lit(ref lit) = expr.kind { if let LitKind::Str(_, _) = lit.node { check_str(cx, lit.span, expr.hir_id) @@ -89,7 +89,7 @@ fn escape>(s: T) -> String { result } -fn check_str(cx: &LateContext<'_, '_>, span: Span, id: HirId) { +fn check_str(cx: &LateContext<'_>, span: Span, id: HirId) { let string = snippet(cx, span, ""); if string.contains('\u{200B}') { span_lint_and_sugg( diff --git a/clippy_lints/src/unnamed_address.rs b/clippy_lints/src/unnamed_address.rs index 0efbf68dcd842..b9aa202b328f6 100644 --- a/clippy_lints/src/unnamed_address.rs +++ b/clippy_lints/src/unnamed_address.rs @@ -55,8 +55,8 @@ declare_clippy_lint! { declare_lint_pass!(UnnamedAddress => [FN_ADDRESS_COMPARISONS, VTABLE_ADDRESS_COMPARISONS]); -impl LateLintPass<'_, '_> for UnnamedAddress { - fn check_expr(&mut self, cx: &LateContext<'_, '_>, expr: &Expr<'_>) { +impl LateLintPass<'_> for UnnamedAddress { + fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) { fn is_comparison(binop: BinOpKind) -> bool { match binop { BinOpKind::Eq | BinOpKind::Lt | BinOpKind::Le | BinOpKind::Ne | BinOpKind::Ge | BinOpKind::Gt => true, @@ -64,14 +64,14 @@ impl LateLintPass<'_, '_> for UnnamedAddress { } } - fn is_trait_ptr(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> bool { + fn is_trait_ptr(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { match cx.tables().expr_ty_adjusted(expr).kind { ty::RawPtr(ty::TypeAndMut { ty, .. }) => ty.is_trait(), _ => false, } } - fn is_fn_def(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> bool { + fn is_fn_def(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { if let ty::FnDef(..) = cx.tables().expr_ty(expr).kind { true } else { diff --git a/clippy_lints/src/unnecessary_sort_by.rs b/clippy_lints/src/unnecessary_sort_by.rs index bb68e50b33195..d940776817ca0 100644 --- a/clippy_lints/src/unnecessary_sort_by.rs +++ b/clippy_lints/src/unnecessary_sort_by.rs @@ -67,7 +67,7 @@ struct SortByKeyDetection { /// Detect if the two expressions are mirrored (identical, except one /// contains a and the other replaces it with b) fn mirrored_exprs( - cx: &LateContext<'_, '_>, + cx: &LateContext<'_>, a_expr: &Expr<'_>, a_ident: &Ident, b_expr: &Expr<'_>, @@ -171,7 +171,7 @@ fn mirrored_exprs( } } -fn detect_lint(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> Option { +fn detect_lint(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option { if_chain! { if let ExprKind::MethodCall(name_ident, _, args, _) = &expr.kind; if let name = name_ident.ident.name.to_ident_string(); @@ -225,8 +225,8 @@ fn detect_lint(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> Option } } -impl LateLintPass<'_, '_> for UnnecessarySortBy { - fn check_expr(&mut self, cx: &LateContext<'_, '_>, expr: &Expr<'_>) { +impl LateLintPass<'_> for UnnecessarySortBy { + fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) { match detect_lint(cx, expr) { Some(LintTrigger::SortByKey(trigger)) => utils::span_lint_and_sugg( cx, diff --git a/clippy_lints/src/unused_io_amount.rs b/clippy_lints/src/unused_io_amount.rs index 5f4b5fd9dd91c..1580f657d7711 100644 --- a/clippy_lints/src/unused_io_amount.rs +++ b/clippy_lints/src/unused_io_amount.rs @@ -32,8 +32,8 @@ declare_clippy_lint! { declare_lint_pass!(UnusedIoAmount => [UNUSED_IO_AMOUNT]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedIoAmount { - fn check_stmt(&mut self, cx: &LateContext<'_, '_>, s: &hir::Stmt<'_>) { +impl<'tcx> LateLintPass<'tcx> for UnusedIoAmount { + fn check_stmt(&mut self, cx: &LateContext<'_>, s: &hir::Stmt<'_>) { let expr = match s.kind { hir::StmtKind::Semi(ref expr) | hir::StmtKind::Expr(ref expr) => &**expr, _ => return, @@ -64,7 +64,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedIoAmount { } } -fn check_method_call(cx: &LateContext<'_, '_>, call: &hir::Expr<'_>, expr: &hir::Expr<'_>) { +fn check_method_call(cx: &LateContext<'_>, call: &hir::Expr<'_>, expr: &hir::Expr<'_>) { if let hir::ExprKind::MethodCall(ref path, _, _, _) = call.kind { let symbol = &*path.ident.as_str(); let read_trait = match_trait_method(cx, call, &paths::IO_READ); diff --git a/clippy_lints/src/unused_self.rs b/clippy_lints/src/unused_self.rs index 3d5e2f9fd2155..da7517125c13b 100644 --- a/clippy_lints/src/unused_self.rs +++ b/clippy_lints/src/unused_self.rs @@ -39,8 +39,8 @@ declare_clippy_lint! { declare_lint_pass!(UnusedSelf => [UNUSED_SELF]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedSelf { - fn check_impl_item(&mut self, cx: &LateContext<'a, 'tcx>, impl_item: &ImplItem<'_>) { +impl<'tcx> LateLintPass<'tcx> for UnusedSelf { + fn check_impl_item(&mut self, cx: &LateContext<'tcx>, impl_item: &ImplItem<'_>) { if impl_item.span.from_expansion() { return; } @@ -80,7 +80,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedSelf { } struct UnusedSelfVisitor<'a, 'tcx> { - cx: &'a LateContext<'a, 'tcx>, + cx: &'a LateContext<'tcx>, uses_self: bool, self_hir_id: &'a HirId, } diff --git a/clippy_lints/src/unwrap.rs b/clippy_lints/src/unwrap.rs index be55982f90556..56ff62eca033a 100644 --- a/clippy_lints/src/unwrap.rs +++ b/clippy_lints/src/unwrap.rs @@ -68,7 +68,7 @@ declare_clippy_lint! { /// Visitor that keeps track of which variables are unwrappable. struct UnwrappableVariablesVisitor<'a, 'tcx> { unwrappables: Vec>, - cx: &'a LateContext<'a, 'tcx>, + cx: &'a LateContext<'tcx>, } /// Contains information about whether a variable can be unwrapped. #[derive(Copy, Clone, Debug)] @@ -85,17 +85,17 @@ struct UnwrapInfo<'tcx> { /// Collects the information about unwrappable variables from an if condition /// The `invert` argument tells us whether the condition is negated. -fn collect_unwrap_info<'a, 'tcx>( - cx: &'a LateContext<'a, 'tcx>, +fn collect_unwrap_info<'tcx>( + cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, branch: &'tcx Expr<'_>, invert: bool, ) -> Vec> { - fn is_relevant_option_call(cx: &LateContext<'_, '_>, ty: Ty<'_>, method_name: &str) -> bool { + fn is_relevant_option_call(cx: &LateContext<'_>, ty: Ty<'_>, method_name: &str) -> bool { is_type_diagnostic_item(cx, ty, sym!(option_type)) && ["is_some", "is_none"].contains(&method_name) } - fn is_relevant_result_call(cx: &LateContext<'_, '_>, ty: Ty<'_>, method_name: &str) -> bool { + fn is_relevant_result_call(cx: &LateContext<'_>, ty: Ty<'_>, method_name: &str) -> bool { is_type_diagnostic_item(cx, ty, sym!(result_type)) && ["is_ok", "is_err"].contains(&method_name) } @@ -209,10 +209,10 @@ impl<'a, 'tcx> Visitor<'tcx> for UnwrappableVariablesVisitor<'a, 'tcx> { declare_lint_pass!(Unwrap => [PANICKING_UNWRAP, UNNECESSARY_UNWRAP]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Unwrap { +impl<'tcx> LateLintPass<'tcx> for Unwrap { fn check_fn( &mut self, - cx: &LateContext<'a, 'tcx>, + cx: &LateContext<'tcx>, kind: FnKind<'tcx>, decl: &'tcx FnDecl<'_>, body: &'tcx Body<'_>, diff --git a/clippy_lints/src/use_self.rs b/clippy_lints/src/use_self.rs index f8e1aff33e773..f85db1e2006e8 100644 --- a/clippy_lints/src/use_self.rs +++ b/clippy_lints/src/use_self.rs @@ -57,7 +57,7 @@ declare_lint_pass!(UseSelf => [USE_SELF]); const SEGMENTS_MSG: &str = "segments should be composed of at least 1 element"; -fn span_use_self_lint(cx: &LateContext<'_, '_>, path: &Path<'_>, last_segment: Option<&PathSegment<'_>>) { +fn span_use_self_lint(cx: &LateContext<'_>, path: &Path<'_>, last_segment: Option<&PathSegment<'_>>) { let last_segment = last_segment.unwrap_or_else(|| path.segments.last().expect(SEGMENTS_MSG)); // Path segments only include actual path, no methods or fields. @@ -83,7 +83,7 @@ fn span_use_self_lint(cx: &LateContext<'_, '_>, path: &Path<'_>, last_segment: O // FIXME: always use this (more correct) visitor, not just in method signatures. struct SemanticUseSelfVisitor<'a, 'tcx> { - cx: &'a LateContext<'a, 'tcx>, + cx: &'a LateContext<'tcx>, self_ty: Ty<'tcx>, } @@ -110,8 +110,8 @@ impl<'a, 'tcx> Visitor<'tcx> for SemanticUseSelfVisitor<'a, 'tcx> { } } -fn check_trait_method_impl_decl<'a, 'tcx>( - cx: &'a LateContext<'a, 'tcx>, +fn check_trait_method_impl_decl<'tcx>( + cx: &LateContext<'tcx>, impl_item: &ImplItem<'_>, impl_decl: &'tcx FnDecl<'_>, impl_trait_ref: ty::TraitRef<'tcx>, @@ -157,8 +157,8 @@ fn check_trait_method_impl_decl<'a, 'tcx>( } } -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UseSelf { - fn check_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx Item<'_>) { +impl<'tcx> LateLintPass<'tcx> for UseSelf { + fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) { if in_external_macro(cx.sess(), item.span) { return; } @@ -211,7 +211,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UseSelf { struct UseSelfVisitor<'a, 'tcx> { item_path: &'a Path<'a>, - cx: &'a LateContext<'a, 'tcx>, + cx: &'a LateContext<'tcx>, } impl<'a, 'tcx> Visitor<'tcx> for UseSelfVisitor<'a, 'tcx> { diff --git a/clippy_lints/src/useless_conversion.rs b/clippy_lints/src/useless_conversion.rs index ad5ecc0c02679..69c0b092520d8 100644 --- a/clippy_lints/src/useless_conversion.rs +++ b/clippy_lints/src/useless_conversion.rs @@ -40,8 +40,8 @@ pub struct UselessConversion { impl_lint_pass!(UselessConversion => [USELESS_CONVERSION]); #[allow(clippy::too_many_lines)] -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UselessConversion { - fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr<'_>) { +impl<'tcx> LateLintPass<'tcx> for UselessConversion { + fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) { if e.span.from_expansion() { return; } @@ -173,7 +173,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UselessConversion { } } - fn check_expr_post(&mut self, _: &LateContext<'a, 'tcx>, e: &'tcx Expr<'_>) { + fn check_expr_post(&mut self, _: &LateContext<'tcx>, e: &'tcx Expr<'_>) { if Some(&e.hir_id) == self.try_desugar_arm.last() { self.try_desugar_arm.pop(); } diff --git a/clippy_lints/src/utils/author.rs b/clippy_lints/src/utils/author.rs index 910b665ccb75e..128fa87a16212 100644 --- a/clippy_lints/src/utils/author.rs +++ b/clippy_lints/src/utils/author.rs @@ -64,8 +64,8 @@ fn done() { println!("}}"); } -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Author { - fn check_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx hir::Item<'_>) { +impl<'tcx> LateLintPass<'tcx> for Author { + fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>) { if !has_attr(cx.sess(), &item.attrs) { return; } @@ -74,7 +74,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Author { done(); } - fn check_impl_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx hir::ImplItem<'_>) { + fn check_impl_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::ImplItem<'_>) { if !has_attr(cx.sess(), &item.attrs) { return; } @@ -83,7 +83,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Author { done(); } - fn check_trait_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx hir::TraitItem<'_>) { + fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::TraitItem<'_>) { if !has_attr(cx.sess(), &item.attrs) { return; } @@ -92,7 +92,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Author { done(); } - fn check_variant(&mut self, cx: &LateContext<'a, 'tcx>, var: &'tcx hir::Variant<'_>) { + fn check_variant(&mut self, cx: &LateContext<'tcx>, var: &'tcx hir::Variant<'_>) { if !has_attr(cx.sess(), &var.attrs) { return; } @@ -102,7 +102,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Author { done(); } - fn check_struct_field(&mut self, cx: &LateContext<'a, 'tcx>, field: &'tcx hir::StructField<'_>) { + fn check_struct_field(&mut self, cx: &LateContext<'tcx>, field: &'tcx hir::StructField<'_>) { if !has_attr(cx.sess(), &field.attrs) { return; } @@ -111,7 +111,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Author { done(); } - fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx hir::Expr<'_>) { + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>) { if !has_attr(cx.sess(), &expr.attrs) { return; } @@ -120,7 +120,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Author { done(); } - fn check_arm(&mut self, cx: &LateContext<'a, 'tcx>, arm: &'tcx hir::Arm<'_>) { + fn check_arm(&mut self, cx: &LateContext<'tcx>, arm: &'tcx hir::Arm<'_>) { if !has_attr(cx.sess(), &arm.attrs) { return; } @@ -129,7 +129,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Author { done(); } - fn check_stmt(&mut self, cx: &LateContext<'a, 'tcx>, stmt: &'tcx hir::Stmt<'_>) { + fn check_stmt(&mut self, cx: &LateContext<'tcx>, stmt: &'tcx hir::Stmt<'_>) { if !has_attr(cx.sess(), stmt.kind.attrs()) { return; } @@ -138,7 +138,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Author { done(); } - fn check_foreign_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx hir::ForeignItem<'_>) { + fn check_foreign_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::ForeignItem<'_>) { if !has_attr(cx.sess(), &item.attrs) { return; } diff --git a/clippy_lints/src/utils/diagnostics.rs b/clippy_lints/src/utils/diagnostics.rs index f6d87c8532e43..e4e65b5f4d420 100644 --- a/clippy_lints/src/utils/diagnostics.rs +++ b/clippy_lints/src/utils/diagnostics.rs @@ -138,7 +138,7 @@ where }); } -pub fn span_lint_hir(cx: &LateContext<'_, '_>, lint: &'static Lint, hir_id: HirId, sp: Span, msg: &str) { +pub fn span_lint_hir(cx: &LateContext<'_>, lint: &'static Lint, hir_id: HirId, sp: Span, msg: &str) { cx.tcx.struct_span_lint_hir(lint, hir_id, sp, |diag| { let mut diag = diag.build(msg); docs_link(&mut diag, lint); @@ -147,7 +147,7 @@ pub fn span_lint_hir(cx: &LateContext<'_, '_>, lint: &'static Lint, hir_id: HirI } pub fn span_lint_hir_and_then( - cx: &LateContext<'_, '_>, + cx: &LateContext<'_>, lint: &'static Lint, hir_id: HirId, sp: Span, diff --git a/clippy_lints/src/utils/higher.rs b/clippy_lints/src/utils/higher.rs index 9502d85e6ee98..eb7ac2447e493 100644 --- a/clippy_lints/src/utils/higher.rs +++ b/clippy_lints/src/utils/higher.rs @@ -47,7 +47,7 @@ pub struct Range<'a> { } /// Higher a `hir` range to something similar to `ast::ExprKind::Range`. -pub fn range<'a, 'b, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'b hir::Expr<'_>) -> Option> { +pub fn range<'a, 'tcx>(cx: &LateContext<'tcx>, expr: &'a hir::Expr<'_>) -> Option> { /// Finds the field named `name` in the field. Always return `Some` for /// convenience. fn get_field<'c>(name: &str, fields: &'c [hir::Field<'_>]) -> Option<&'c hir::Expr<'c>> { @@ -257,7 +257,7 @@ pub enum VecArgs<'a> { /// Returns the arguments of the `vec!` macro if this expression was expanded /// from `vec!`. -pub fn vec_macro<'e>(cx: &LateContext<'_, '_>, expr: &'e hir::Expr<'_>) -> Option> { +pub fn vec_macro<'e>(cx: &LateContext<'_>, expr: &'e hir::Expr<'_>) -> Option> { if_chain! { if let hir::ExprKind::Call(ref fun, ref args) = expr.kind; if let hir::ExprKind::Path(ref qpath) = fun.kind; diff --git a/clippy_lints/src/utils/hir_utils.rs b/clippy_lints/src/utils/hir_utils.rs index bf1017d76ec63..ae58f0a1521e6 100644 --- a/clippy_lints/src/utils/hir_utils.rs +++ b/clippy_lints/src/utils/hir_utils.rs @@ -21,7 +21,7 @@ use std::hash::Hash; /// Note that some expressions kinds are not considered but could be added. pub struct SpanlessEq<'a, 'tcx> { /// Context used to evaluate constant expressions. - cx: &'a LateContext<'a, 'tcx>, + cx: &'a LateContext<'tcx>, maybe_typeck_tables: Option<&'tcx TypeckTables<'tcx>>, /// If is true, never consider as equal expressions containing function /// calls. @@ -29,7 +29,7 @@ pub struct SpanlessEq<'a, 'tcx> { } impl<'a, 'tcx> SpanlessEq<'a, 'tcx> { - pub fn new(cx: &'a LateContext<'a, 'tcx>) -> Self { + pub fn new(cx: &'a LateContext<'tcx>) -> Self { Self { cx, maybe_typeck_tables: cx.maybe_typeck_tables(), @@ -347,13 +347,13 @@ pub fn over(left: &[X], right: &[X], mut eq_fn: impl FnMut(&X, &X) -> bool) - /// All expressions kind are hashed, but some might have a weaker hash. pub struct SpanlessHash<'a, 'tcx> { /// Context used to evaluate constant expressions. - cx: &'a LateContext<'a, 'tcx>, + cx: &'a LateContext<'tcx>, maybe_typeck_tables: Option<&'tcx TypeckTables<'tcx>>, s: StableHasher, } impl<'a, 'tcx> SpanlessHash<'a, 'tcx> { - pub fn new(cx: &'a LateContext<'a, 'tcx>) -> Self { + pub fn new(cx: &'a LateContext<'tcx>) -> Self { Self { cx, maybe_typeck_tables: cx.maybe_typeck_tables(), diff --git a/clippy_lints/src/utils/inspector.rs b/clippy_lints/src/utils/inspector.rs index 3f5659c3d8c0f..fbd103323e313 100644 --- a/clippy_lints/src/utils/inspector.rs +++ b/clippy_lints/src/utils/inspector.rs @@ -31,15 +31,15 @@ declare_clippy_lint! { declare_lint_pass!(DeepCodeInspector => [DEEP_CODE_INSPECTION]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for DeepCodeInspector { - fn check_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx hir::Item<'_>) { +impl<'tcx> LateLintPass<'tcx> for DeepCodeInspector { + fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>) { if !has_attr(cx.sess(), &item.attrs) { return; } print_item(cx, item); } - fn check_impl_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx hir::ImplItem<'_>) { + fn check_impl_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::ImplItem<'_>) { if !has_attr(cx.sess(), &item.attrs) { return; } @@ -65,14 +65,14 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for DeepCodeInspector { hir::ImplItemKind::TyAlias(_) => println!("associated type"), } } - // fn check_trait_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx + // fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx // hir::TraitItem) { // if !has_attr(&item.attrs) { // return; // } // } // - // fn check_variant(&mut self, cx: &LateContext<'a, 'tcx>, var: &'tcx + // fn check_variant(&mut self, cx: &LateContext<'tcx>, var: &'tcx // hir::Variant, _: // &hir::Generics) { // if !has_attr(&var.node.attrs) { @@ -80,7 +80,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for DeepCodeInspector { // } // } // - // fn check_struct_field(&mut self, cx: &LateContext<'a, 'tcx>, field: &'tcx + // fn check_struct_field(&mut self, cx: &LateContext<'tcx>, field: &'tcx // hir::StructField) { // if !has_attr(&field.attrs) { // return; @@ -88,14 +88,14 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for DeepCodeInspector { // } // - fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx hir::Expr<'_>) { + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>) { if !has_attr(cx.sess(), &expr.attrs) { return; } print_expr(cx, expr, 0); } - fn check_arm(&mut self, cx: &LateContext<'a, 'tcx>, arm: &'tcx hir::Arm<'_>) { + fn check_arm(&mut self, cx: &LateContext<'tcx>, arm: &'tcx hir::Arm<'_>) { if !has_attr(cx.sess(), &arm.attrs) { return; } @@ -108,7 +108,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for DeepCodeInspector { print_expr(cx, &arm.body, 1); } - fn check_stmt(&mut self, cx: &LateContext<'a, 'tcx>, stmt: &'tcx hir::Stmt<'_>) { + fn check_stmt(&mut self, cx: &LateContext<'tcx>, stmt: &'tcx hir::Stmt<'_>) { if !has_attr(cx.sess(), stmt.kind.attrs()) { return; } @@ -126,7 +126,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for DeepCodeInspector { hir::StmtKind::Expr(ref e) | hir::StmtKind::Semi(ref e) => print_expr(cx, e, 0), } } - // fn check_foreign_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx + // fn check_foreign_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx // hir::ForeignItem) { // if !has_attr(&item.attrs) { // return; @@ -141,7 +141,7 @@ fn has_attr(sess: &Session, attrs: &[Attribute]) -> bool { #[allow(clippy::similar_names)] #[allow(clippy::too_many_lines)] -fn print_expr(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, indent: usize) { +fn print_expr(cx: &LateContext<'_>, expr: &hir::Expr<'_>, indent: usize) { let ind = " ".repeat(indent); println!("{}+", ind); println!("{}ty: {}", ind, cx.tables().expr_ty(expr)); @@ -348,7 +348,7 @@ fn print_expr(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, indent: usize) { } } -fn print_item(cx: &LateContext<'_, '_>, item: &hir::Item<'_>) { +fn print_item(cx: &LateContext<'_>, item: &hir::Item<'_>) { let did = cx.tcx.hir().local_def_id(item.hir_id); println!("item `{}`", item.ident.name); match item.vis.node { @@ -425,7 +425,7 @@ fn print_item(cx: &LateContext<'_, '_>, item: &hir::Item<'_>) { #[allow(clippy::similar_names)] #[allow(clippy::too_many_lines)] -fn print_pat(cx: &LateContext<'_, '_>, pat: &hir::Pat<'_>, indent: usize) { +fn print_pat(cx: &LateContext<'_>, pat: &hir::Pat<'_>, indent: usize) { let ind = " ".repeat(indent); println!("{}+", ind); match pat.kind { @@ -537,7 +537,7 @@ fn print_pat(cx: &LateContext<'_, '_>, pat: &hir::Pat<'_>, indent: usize) { } } -fn print_guard(cx: &LateContext<'_, '_>, guard: &hir::Guard<'_>, indent: usize) { +fn print_guard(cx: &LateContext<'_>, guard: &hir::Guard<'_>, indent: usize) { let ind = " ".repeat(indent); println!("{}+", ind); match guard { diff --git a/clippy_lints/src/utils/internal_lints.rs b/clippy_lints/src/utils/internal_lints.rs index ca947e9241f0f..38cb764adde7b 100644 --- a/clippy_lints/src/utils/internal_lints.rs +++ b/clippy_lints/src/utils/internal_lints.rs @@ -251,8 +251,8 @@ pub struct LintWithoutLintPass { impl_lint_pass!(LintWithoutLintPass => [DEFAULT_LINT, LINT_WITHOUT_LINT_PASS]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for LintWithoutLintPass { - fn check_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx Item<'_>) { +impl<'tcx> LateLintPass<'tcx> for LintWithoutLintPass { + fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) { if !run_lints(cx, &[DEFAULT_LINT], item.hir_id) { return; } @@ -310,7 +310,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for LintWithoutLintPass { } } - fn check_crate_post(&mut self, cx: &LateContext<'a, 'tcx>, _: &'tcx Crate<'_>) { + fn check_crate_post(&mut self, cx: &LateContext<'tcx>, _: &'tcx Crate<'_>) { if !run_lints(cx, &[LINT_WITHOUT_LINT_PASS], CRATE_HIR_ID) { return; } @@ -337,7 +337,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for LintWithoutLintPass { } } -fn is_lint_ref_type<'tcx>(cx: &LateContext<'_, 'tcx>, ty: &Ty<'_>) -> bool { +fn is_lint_ref_type<'tcx>(cx: &LateContext<'tcx>, ty: &Ty<'_>) -> bool { if let TyKind::Rptr( _, MutTy { @@ -358,7 +358,7 @@ fn is_lint_ref_type<'tcx>(cx: &LateContext<'_, 'tcx>, ty: &Ty<'_>) -> bool { struct LintCollector<'a, 'tcx> { output: &'a mut FxHashSet, - cx: &'a LateContext<'a, 'tcx>, + cx: &'a LateContext<'tcx>, } impl<'a, 'tcx> Visitor<'tcx> for LintCollector<'a, 'tcx> { @@ -395,8 +395,8 @@ impl CompilerLintFunctions { impl_lint_pass!(CompilerLintFunctions => [COMPILER_LINT_FUNCTIONS]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for CompilerLintFunctions { - fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) { +impl<'tcx> LateLintPass<'tcx> for CompilerLintFunctions { + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { if !run_lints(cx, &[COMPILER_LINT_FUNCTIONS], expr.hir_id) { return; } @@ -424,8 +424,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for CompilerLintFunctions { declare_lint_pass!(OuterExpnDataPass => [OUTER_EXPN_EXPN_DATA]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for OuterExpnDataPass { - fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx hir::Expr<'_>) { +impl<'tcx> LateLintPass<'tcx> for OuterExpnDataPass { + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>) { if !run_lints(cx, &[OUTER_EXPN_EXPN_DATA], expr.hir_id) { return; } @@ -474,8 +474,8 @@ fn is_trigger_fn(fn_kind: FnKind<'_>) -> bool { declare_lint_pass!(CollapsibleCalls => [COLLAPSIBLE_SPAN_LINT_CALLS]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for CollapsibleCalls { - fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx hir::Expr<'_>) { +impl<'tcx> LateLintPass<'tcx> for CollapsibleCalls { + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>) { if !run_lints(cx, &[COLLAPSIBLE_SPAN_LINT_CALLS], expr.hir_id) { return; } @@ -529,10 +529,7 @@ struct AndThenSnippets<'a> { msg: Cow<'a, str>, } -fn get_and_then_snippets<'a, 'hir>( - cx: &LateContext<'_, '_>, - and_then_snippets: &'hir [Expr<'hir>], -) -> AndThenSnippets<'a> { +fn get_and_then_snippets<'a, 'hir>(cx: &LateContext<'_>, and_then_snippets: &'hir [Expr<'hir>]) -> AndThenSnippets<'a> { let cx_snippet = snippet(cx, and_then_snippets[0].span, "cx"); let lint_snippet = snippet(cx, and_then_snippets[1].span, ".."); let span_snippet = snippet(cx, and_then_snippets[2].span, "span"); @@ -553,7 +550,7 @@ struct SpanSuggestionSnippets<'a> { } fn span_suggestion_snippets<'a, 'hir>( - cx: &LateContext<'_, '_>, + cx: &LateContext<'_>, span_call_args: &'hir [Expr<'hir>], ) -> SpanSuggestionSnippets<'a> { let help_snippet = snippet(cx, span_call_args[2].span, r#""...""#); @@ -568,7 +565,7 @@ fn span_suggestion_snippets<'a, 'hir>( } fn suggest_suggestion( - cx: &LateContext<'_, '_>, + cx: &LateContext<'_>, expr: &Expr<'_>, and_then_snippets: &AndThenSnippets<'_>, span_suggestion_snippets: &SpanSuggestionSnippets<'_>, @@ -594,7 +591,7 @@ fn suggest_suggestion( } fn suggest_help( - cx: &LateContext<'_, '_>, + cx: &LateContext<'_>, expr: &Expr<'_>, and_then_snippets: &AndThenSnippets<'_>, help: &str, @@ -626,7 +623,7 @@ fn suggest_help( } fn suggest_note( - cx: &LateContext<'_, '_>, + cx: &LateContext<'_>, expr: &Expr<'_>, and_then_snippets: &AndThenSnippets<'_>, note: &str, diff --git a/clippy_lints/src/utils/mod.rs b/clippy_lints/src/utils/mod.rs index 8be9ba2c3c244..99ba7d64331cd 100644 --- a/clippy_lints/src/utils/mod.rs +++ b/clippy_lints/src/utils/mod.rs @@ -70,7 +70,7 @@ pub fn differing_macro_contexts(lhs: Span, rhs: Span) -> bool { /// // Do something /// } /// ``` -pub fn in_constant(cx: &LateContext<'_, '_>, id: HirId) -> bool { +pub fn in_constant(cx: &LateContext<'_>, id: HirId) -> bool { let parent_id = cx.tcx.hir().get_parent_item(id); match cx.tcx.hir().get(parent_id) { Node::Item(&Item { @@ -134,7 +134,7 @@ pub fn is_wild<'tcx>(pat: &impl std::ops::Deref>) -> bool { } /// Checks if type is struct, enum or union type with the given def path. -pub fn match_type(cx: &LateContext<'_, '_>, ty: Ty<'_>, path: &[&str]) -> bool { +pub fn match_type(cx: &LateContext<'_>, ty: Ty<'_>, path: &[&str]) -> bool { match ty.kind { ty::Adt(adt, _) => match_def_path(cx, adt.did, path), _ => false, @@ -142,7 +142,7 @@ pub fn match_type(cx: &LateContext<'_, '_>, ty: Ty<'_>, path: &[&str]) -> bool { } /// Checks if the type is equal to a diagnostic item -pub fn is_type_diagnostic_item(cx: &LateContext<'_, '_>, ty: Ty<'_>, diag_item: Symbol) -> bool { +pub fn is_type_diagnostic_item(cx: &LateContext<'_>, ty: Ty<'_>, diag_item: Symbol) -> bool { match ty.kind { ty::Adt(adt, _) => cx.tcx.is_diagnostic_item(diag_item, adt.did), _ => false, @@ -150,7 +150,7 @@ pub fn is_type_diagnostic_item(cx: &LateContext<'_, '_>, ty: Ty<'_>, diag_item: } /// Checks if the method call given in `expr` belongs to the given trait. -pub fn match_trait_method(cx: &LateContext<'_, '_>, expr: &Expr<'_>, path: &[&str]) -> bool { +pub fn match_trait_method(cx: &LateContext<'_>, expr: &Expr<'_>, path: &[&str]) -> bool { let def_id = cx.tables().type_dependent_def_id(expr.hir_id).unwrap(); let trt_id = cx.tcx.trait_of_item(def_id); if let Some(trt_id) = trt_id { @@ -249,7 +249,7 @@ pub fn match_path_ast(path: &ast::Path, segments: &[&str]) -> bool { } /// Gets the definition associated to a path. -pub fn path_to_res(cx: &LateContext<'_, '_>, path: &[&str]) -> Option { +pub fn path_to_res(cx: &LateContext<'_>, path: &[&str]) -> Option { let crates = cx.tcx.crates(); let krate = crates .iter() @@ -285,7 +285,7 @@ pub fn path_to_res(cx: &LateContext<'_, '_>, path: &[&str]) -> Option } } -pub fn qpath_res(cx: &LateContext<'_, '_>, qpath: &hir::QPath<'_>, id: hir::HirId) -> Res { +pub fn qpath_res(cx: &LateContext<'_>, qpath: &hir::QPath<'_>, id: hir::HirId) -> Res { match qpath { hir::QPath::Resolved(_, path) => path.res, hir::QPath::TypeRelative(..) => { @@ -302,7 +302,7 @@ pub fn qpath_res(cx: &LateContext<'_, '_>, qpath: &hir::QPath<'_>, id: hir::HirI /// Convenience function to get the `DefId` of a trait by path. /// It could be a trait or trait alias. -pub fn get_trait_def_id(cx: &LateContext<'_, '_>, path: &[&str]) -> Option { +pub fn get_trait_def_id(cx: &LateContext<'_>, path: &[&str]) -> Option { let res = match path_to_res(cx, path) { Some(res) => res, None => return None, @@ -317,8 +317,8 @@ pub fn get_trait_def_id(cx: &LateContext<'_, '_>, path: &[&str]) -> Option( - cx: &LateContext<'a, 'tcx>, +pub fn implements_trait<'tcx>( + cx: &LateContext<'tcx>, ty: Ty<'tcx>, trait_id: DefId, ty_params: &[GenericArg<'tcx>], @@ -347,7 +347,7 @@ pub fn implements_trait<'a, 'tcx>( /// } /// } /// ``` -pub fn trait_ref_of_method<'tcx>(cx: &LateContext<'_, 'tcx>, hir_id: HirId) -> Option<&'tcx TraitRef<'tcx>> { +pub fn trait_ref_of_method<'tcx>(cx: &LateContext<'tcx>, hir_id: HirId) -> Option<&'tcx TraitRef<'tcx>> { // Get the implemented trait for the current function let parent_impl = cx.tcx.hir().get_parent_item(hir_id); if_chain! { @@ -360,7 +360,7 @@ pub fn trait_ref_of_method<'tcx>(cx: &LateContext<'_, 'tcx>, hir_id: HirId) -> O } /// Checks whether this type implements `Drop`. -pub fn has_drop<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, ty: Ty<'tcx>) -> bool { +pub fn has_drop<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool { match ty.ty_adt_def() { Some(def) => def.has_dtor(cx.tcx), None => false, @@ -426,14 +426,14 @@ pub fn method_chain_args<'a>(expr: &'a Expr<'_>, methods: &[&str]) -> Option, def_id: DefId) -> bool { +pub fn is_entrypoint_fn(cx: &LateContext<'_>, def_id: DefId) -> bool { cx.tcx .entry_fn(LOCAL_CRATE) .map_or(false, |(entry_fn_def_id, _)| def_id == entry_fn_def_id.to_def_id()) } /// Gets the name of the item the expression is in, if available. -pub fn get_item_name(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> Option { +pub fn get_item_name(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option { let parent_id = cx.tcx.hir().get_parent_item(expr.hir_id); match cx.tcx.hir().find(parent_id) { Some( @@ -717,7 +717,7 @@ fn trim_multiline_inner(s: Cow<'_, str>, ignore_first: bool, indent: Option(cx: &'c LateContext<'_, '_>, e: &Expr<'_>) -> Option<&'c Expr<'c>> { +pub fn get_parent_expr<'c>(cx: &'c LateContext<'_>, e: &Expr<'_>) -> Option<&'c Expr<'c>> { let map = &cx.tcx.hir(); let hir_id = e.hir_id; let parent_id = map.get_parent_node(hir_id); @@ -733,7 +733,7 @@ pub fn get_parent_expr<'c>(cx: &'c LateContext<'_, '_>, e: &Expr<'_>) -> Option< }) } -pub fn get_enclosing_block<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, hir_id: HirId) -> Option<&'tcx Block<'tcx>> { +pub fn get_enclosing_block<'tcx>(cx: &LateContext<'tcx>, hir_id: HirId) -> Option<&'tcx Block<'tcx>> { let map = &cx.tcx.hir(); let enclosing_node = map .get_enclosing_scope(hir_id) @@ -789,7 +789,7 @@ pub fn walk_ptrs_ty_depth(ty: Ty<'_>) -> (Ty<'_>, usize) { /// Checks whether the given expression is a constant integer of the given value. /// unlike `is_integer_literal`, this version does const folding -pub fn is_integer_const(cx: &LateContext<'_, '_>, e: &Expr<'_>, value: u128) -> bool { +pub fn is_integer_const(cx: &LateContext<'_>, e: &Expr<'_>, value: u128) -> bool { if is_integer_literal(e, value) { return true; } @@ -823,7 +823,7 @@ pub fn is_integer_literal(expr: &Expr<'_>, value: u128) -> bool { /// /// See `rustc_middle::ty::adjustment::Adjustment` and `rustc_typeck::check::coercion` for more /// information on adjustments and coercions. -pub fn is_adjusted(cx: &LateContext<'_, '_>, e: &Expr<'_>) -> bool { +pub fn is_adjusted(cx: &LateContext<'_>, e: &Expr<'_>) -> bool { cx.tables().adjustments().get(e.hir_id).is_some() } @@ -876,26 +876,26 @@ pub fn is_direct_expn_of(span: Span, name: &str) -> Option { } /// Convenience function to get the return type of a function. -pub fn return_ty<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, fn_item: hir::HirId) -> Ty<'tcx> { +pub fn return_ty<'tcx>(cx: &LateContext<'tcx>, fn_item: hir::HirId) -> Ty<'tcx> { let fn_def_id = cx.tcx.hir().local_def_id(fn_item); let ret_ty = cx.tcx.fn_sig(fn_def_id).output(); cx.tcx.erase_late_bound_regions(&ret_ty) } /// Returns `true` if the given type is an `unsafe` function. -pub fn type_is_unsafe_function<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, ty: Ty<'tcx>) -> bool { +pub fn type_is_unsafe_function<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool { match ty.kind { ty::FnDef(..) | ty::FnPtr(_) => ty.fn_sig(cx.tcx).unsafety() == Unsafety::Unsafe, _ => false, } } -pub fn is_copy<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, ty: Ty<'tcx>) -> bool { +pub fn is_copy<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool { ty.is_copy_modulo_regions(cx.tcx.at(DUMMY_SP), cx.param_env) } /// Checks if an expression is constructing a tuple-like enum variant or struct -pub fn is_ctor_or_promotable_const_function(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> bool { +pub fn is_ctor_or_promotable_const_function(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { if let ExprKind::Call(ref fun, _) = expr.kind { if let ExprKind::Path(ref qp) = fun.kind { let res = cx.qpath_res(qp, fun.hir_id); @@ -911,15 +911,15 @@ pub fn is_ctor_or_promotable_const_function(cx: &LateContext<'_, '_>, expr: &Exp /// Returns `true` if a pattern is refutable. // TODO: should be implemented using rustc/mir_build/hair machinery -pub fn is_refutable(cx: &LateContext<'_, '_>, pat: &Pat<'_>) -> bool { - fn is_enum_variant(cx: &LateContext<'_, '_>, qpath: &QPath<'_>, id: HirId) -> bool { +pub fn is_refutable(cx: &LateContext<'_>, pat: &Pat<'_>) -> bool { + fn is_enum_variant(cx: &LateContext<'_>, qpath: &QPath<'_>, id: HirId) -> bool { matches!( cx.qpath_res(qpath, id), def::Res::Def(DefKind::Variant, ..) | Res::Def(DefKind::Ctor(def::CtorOf::Variant, _), _) ) } - fn are_refutable<'a, I: Iterator>>(cx: &LateContext<'_, '_>, mut i: I) -> bool { + fn are_refutable<'a, I: Iterator>>(cx: &LateContext<'_>, mut i: I) -> bool { i.any(|pat| is_refutable(cx, pat)) } @@ -1050,7 +1050,7 @@ pub fn is_try<'tcx>(expr: &'tcx Expr<'tcx>) -> Option<&'tcx Expr<'tcx>> { /// Returns `true` if the lint is allowed in the current context /// /// Useful for skipping long running code when it's unnecessary -pub fn is_allowed(cx: &LateContext<'_, '_>, lint: &'static Lint, id: HirId) -> bool { +pub fn is_allowed(cx: &LateContext<'_>, lint: &'static Lint, id: HirId) -> bool { cx.tcx.lint_level_at_node(lint, id).0 == Level::Allow } @@ -1135,7 +1135,7 @@ pub fn any_parent_is_automatically_derived(tcx: TyCtxt<'_>, node: HirId) -> bool } /// Returns true if ty has `iter` or `iter_mut` methods -pub fn has_iter_method(cx: &LateContext<'_, '_>, probably_ref_ty: Ty<'_>) -> Option<&'static str> { +pub fn has_iter_method(cx: &LateContext<'_>, probably_ref_ty: Ty<'_>) -> Option<&'static str> { // FIXME: instead of this hard-coded list, we should check if `::iter` // exists and has the desired signature. Unfortunately FnCtxt is not exported // so we can't use its `lookup_method` method. @@ -1182,8 +1182,8 @@ pub fn has_iter_method(cx: &LateContext<'_, '_>, probably_ref_ty: Ty<'_>) -> Opt /// ```rust,ignore /// if let Some(args) = match_function_call(cx, begin_panic_call, &paths::BEGIN_PANIC); /// ``` -pub fn match_function_call<'a, 'tcx>( - cx: &LateContext<'a, 'tcx>, +pub fn match_function_call<'tcx>( + cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, path: &[&str], ) -> Option<&'tcx [Expr<'tcx>]> { @@ -1201,14 +1201,14 @@ pub fn match_function_call<'a, 'tcx>( /// Checks if `Ty` is normalizable. This function is useful /// to avoid crashes on `layout_of`. -pub fn is_normalizable<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, param_env: ty::ParamEnv<'tcx>, ty: Ty<'tcx>) -> bool { +pub fn is_normalizable<'tcx>(cx: &LateContext<'tcx>, param_env: ty::ParamEnv<'tcx>, ty: Ty<'tcx>) -> bool { cx.tcx.infer_ctxt().enter(|infcx| { let cause = rustc_middle::traits::ObligationCause::dummy(); infcx.at(&cause, param_env).normalize(&ty).is_ok() }) } -pub fn match_def_path<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, did: DefId, syms: &[&str]) -> bool { +pub fn match_def_path<'tcx>(cx: &LateContext<'tcx>, did: DefId, syms: &[&str]) -> bool { // We have to convert `syms` to `&[Symbol]` here because rustc's `match_def_path` // accepts only that. We should probably move to Symbols in Clippy as well. let syms = syms.iter().map(|p| Symbol::intern(p)).collect::>(); @@ -1250,7 +1250,7 @@ pub fn if_sequence<'tcx>( (conds, blocks) } -pub fn parent_node_is_if_expr<'a, 'b>(expr: &Expr<'_>, cx: &LateContext<'a, 'b>) -> bool { +pub fn parent_node_is_if_expr(expr: &Expr<'_>, cx: &LateContext<'_>) -> bool { let map = cx.tcx.hir(); let parent_id = map.get_parent_node(expr.hir_id); let parent_node = map.get(parent_id); @@ -1275,7 +1275,7 @@ pub fn must_use_attr(attrs: &[Attribute]) -> Option<&Attribute> { } // Returns whether the type has #[must_use] attribute -pub fn is_must_use_ty<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, ty: Ty<'tcx>) -> bool { +pub fn is_must_use_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool { match ty.kind { ty::Adt(ref adt, _) => must_use_attr(&cx.tcx.get_attrs(adt.did)).is_some(), ty::Foreign(ref did) => must_use_attr(&cx.tcx.get_attrs(*did)).is_some(), @@ -1313,7 +1313,7 @@ pub fn is_must_use_ty<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, ty: Ty<'tcx>) -> boo } // check if expr is calling method or function with #[must_use] attribyte -pub fn is_must_use_func_call(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> bool { +pub fn is_must_use_func_call(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { let did = match expr.kind { ExprKind::Call(ref path, _) => if_chain! { if let ExprKind::Path(ref qpath) = path.kind; @@ -1352,7 +1352,7 @@ pub fn is_no_std_crate(krate: &Crate<'_>) -> bool { /// fn f() {} /// } /// ``` -pub fn is_trait_impl_item(cx: &LateContext<'_, '_>, hir_id: HirId) -> bool { +pub fn is_trait_impl_item(cx: &LateContext<'_>, hir_id: HirId) -> bool { if let Some(Node::Item(item)) = cx.tcx.hir().find(cx.tcx.hir().get_parent_node(hir_id)) { matches!(item.kind, ItemKind::Impl{ of_trait: Some(_), .. }) } else { @@ -1369,7 +1369,7 @@ pub fn is_trait_impl_item(cx: &LateContext<'_, '_>, hir_id: HirId) -> bool { /// for _ in 2i32 {} /// } /// ``` -pub fn fn_has_unsatisfiable_preds(cx: &LateContext<'_, '_>, did: DefId) -> bool { +pub fn fn_has_unsatisfiable_preds(cx: &LateContext<'_>, did: DefId) -> bool { use rustc_trait_selection::traits; let predicates = cx.tcx @@ -1385,7 +1385,7 @@ pub fn fn_has_unsatisfiable_preds(cx: &LateContext<'_, '_>, did: DefId) -> bool ) } -pub fn run_lints(cx: &LateContext<'_, '_>, lints: &[&'static Lint], id: HirId) -> bool { +pub fn run_lints(cx: &LateContext<'_>, lints: &[&'static Lint], id: HirId) -> bool { lints.iter().any(|lint| { matches!( cx.tcx.lint_level_at_node(lint, id), diff --git a/clippy_lints/src/utils/ptr.rs b/clippy_lints/src/utils/ptr.rs index ee336ecc58d95..bd2c619f00028 100644 --- a/clippy_lints/src/utils/ptr.rs +++ b/clippy_lints/src/utils/ptr.rs @@ -7,7 +7,7 @@ use rustc_span::{Span, Symbol}; use std::borrow::Cow; pub fn get_spans( - cx: &LateContext<'_, '_>, + cx: &LateContext<'_>, opt_body_id: Option, idx: usize, replacements: &[(&'static str, &'static str)], @@ -22,8 +22,8 @@ pub fn get_spans( } } -fn extract_clone_suggestions<'a, 'tcx>( - cx: &LateContext<'a, 'tcx>, +fn extract_clone_suggestions<'tcx>( + cx: &LateContext<'tcx>, name: Symbol, replace: &[(&'static str, &'static str)], body: &'tcx Body<'_>, @@ -44,7 +44,7 @@ fn extract_clone_suggestions<'a, 'tcx>( } struct PtrCloneVisitor<'a, 'tcx> { - cx: &'a LateContext<'a, 'tcx>, + cx: &'a LateContext<'tcx>, name: Symbol, replace: &'a [(&'static str, &'static str)], spans: Vec<(Span, Cow<'static, str>)>, diff --git a/clippy_lints/src/utils/sugg.rs b/clippy_lints/src/utils/sugg.rs index e919b1522d89a..d05e81b950579 100644 --- a/clippy_lints/src/utils/sugg.rs +++ b/clippy_lints/src/utils/sugg.rs @@ -39,7 +39,7 @@ impl Display for Sugg<'_> { #[allow(clippy::wrong_self_convention)] // ok, because of the function `as_ty` method impl<'a> Sugg<'a> { /// Prepare a suggestion from an expression. - pub fn hir_opt(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>) -> Option { + pub fn hir_opt(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> Option { snippet_opt(cx, expr.span).map(|snippet| { let snippet = Cow::Owned(snippet); Self::hir_from_snippet(cx, expr, snippet) @@ -48,7 +48,7 @@ impl<'a> Sugg<'a> { /// Convenience function around `hir_opt` for suggestions with a default /// text. - pub fn hir(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, default: &'a str) -> Self { + pub fn hir(cx: &LateContext<'_>, expr: &hir::Expr<'_>, default: &'a str) -> Self { Self::hir_opt(cx, expr).unwrap_or_else(|| Sugg::NonParen(Cow::Borrowed(default))) } @@ -60,7 +60,7 @@ impl<'a> Sugg<'a> { /// to /// `HasPlaceholders` pub fn hir_with_applicability( - cx: &LateContext<'_, '_>, + cx: &LateContext<'_>, expr: &hir::Expr<'_>, default: &'a str, applicability: &mut Applicability, @@ -77,7 +77,7 @@ impl<'a> Sugg<'a> { } /// Same as `hir`, but will use the pre expansion span if the `expr` was in a macro. - pub fn hir_with_macro_callsite(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, default: &'a str) -> Self { + pub fn hir_with_macro_callsite(cx: &LateContext<'_>, expr: &hir::Expr<'_>, default: &'a str) -> Self { let snippet = snippet_with_macro_callsite(cx, expr.span, default); Self::hir_from_snippet(cx, expr, snippet) @@ -85,7 +85,7 @@ impl<'a> Sugg<'a> { /// Generate a suggestion for an expression with the given snippet. This is used by the `hir_*` /// function variants of `Sugg`, since these use different snippet functions. - fn hir_from_snippet(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, snippet: Cow<'a, str>) -> Self { + fn hir_from_snippet(cx: &LateContext<'_>, expr: &hir::Expr<'_>, snippet: Cow<'a, str>) -> Self { if let Some(range) = higher::range(cx, expr) { let op = match range.limits { ast::RangeLimits::HalfOpen => AssocOp::DotDot, diff --git a/clippy_lints/src/utils/usage.rs b/clippy_lints/src/utils/usage.rs index d280fe4ab4e02..53d3a241f58af 100644 --- a/clippy_lints/src/utils/usage.rs +++ b/clippy_lints/src/utils/usage.rs @@ -11,7 +11,7 @@ use rustc_span::symbol::{Ident, Symbol}; use rustc_typeck::expr_use_visitor::{ConsumeMode, Delegate, ExprUseVisitor, PlaceBase, PlaceWithHirId}; /// Returns a set of mutated local variable IDs, or `None` if mutations could not be determined. -pub fn mutated_variables<'a, 'tcx>(expr: &'tcx Expr<'_>, cx: &'a LateContext<'a, 'tcx>) -> Option> { +pub fn mutated_variables<'tcx>(expr: &'tcx Expr<'_>, cx: &LateContext<'tcx>) -> Option> { let mut delegate = MutVarsDelegate { used_mutably: FxHashSet::default(), skip: false, @@ -27,11 +27,7 @@ pub fn mutated_variables<'a, 'tcx>(expr: &'tcx Expr<'_>, cx: &'a LateContext<'a, Some(delegate.used_mutably) } -pub fn is_potentially_mutated<'a, 'tcx>( - variable: &'tcx Path<'_>, - expr: &'tcx Expr<'_>, - cx: &'a LateContext<'a, 'tcx>, -) -> bool { +pub fn is_potentially_mutated<'tcx>(variable: &'tcx Path<'_>, expr: &'tcx Expr<'_>, cx: &LateContext<'tcx>) -> bool { if let Res::Local(id) = variable.res { mutated_variables(expr, cx).map_or(true, |mutated| mutated.contains(&id)) } else { diff --git a/clippy_lints/src/vec.rs b/clippy_lints/src/vec.rs index 080785b177d65..e1043c36e0a54 100644 --- a/clippy_lints/src/vec.rs +++ b/clippy_lints/src/vec.rs @@ -33,8 +33,8 @@ declare_clippy_lint! { declare_lint_pass!(UselessVec => [USELESS_VEC]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UselessVec { - fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) { +impl<'tcx> LateLintPass<'tcx> for UselessVec { + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { // search for `&vec![_]` expressions where the adjusted type is `&[_]` if_chain! { if let ty::Ref(_, ty, _) = cx.tables().expr_ty_adjusted(expr).kind; @@ -66,7 +66,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UselessVec { } } -fn check_vec_macro<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, vec_args: &higher::VecArgs<'tcx>, span: Span) { +fn check_vec_macro<'tcx>(cx: &LateContext<'tcx>, vec_args: &higher::VecArgs<'tcx>, span: Span) { let mut applicability = Applicability::MachineApplicable; let snippet = match *vec_args { higher::VecArgs::Repeat(elem, len) => { diff --git a/clippy_lints/src/vec_resize_to_zero.rs b/clippy_lints/src/vec_resize_to_zero.rs index bb315e64e5de1..cc5e21a7ca6fc 100644 --- a/clippy_lints/src/vec_resize_to_zero.rs +++ b/clippy_lints/src/vec_resize_to_zero.rs @@ -28,8 +28,8 @@ declare_clippy_lint! { declare_lint_pass!(VecResizeToZero => [VEC_RESIZE_TO_ZERO]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for VecResizeToZero { - fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) { +impl<'tcx> LateLintPass<'tcx> for VecResizeToZero { + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { if_chain! { if let hir::ExprKind::MethodCall(path_segment, _, ref args, _) = expr.kind; if let Some(method_def_id) = cx.tables().type_dependent_def_id(expr.hir_id); diff --git a/clippy_lints/src/verbose_file_reads.rs b/clippy_lints/src/verbose_file_reads.rs index 85f9208457448..b06fe36da631b 100644 --- a/clippy_lints/src/verbose_file_reads.rs +++ b/clippy_lints/src/verbose_file_reads.rs @@ -33,8 +33,8 @@ declare_clippy_lint! { declare_lint_pass!(VerboseFileReads => [VERBOSE_FILE_READS]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for VerboseFileReads { - fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'tcx>) { +impl<'tcx> LateLintPass<'tcx> for VerboseFileReads { + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) { if is_file_read_to_end(cx, expr) { span_lint_and_help( cx, @@ -57,7 +57,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for VerboseFileReads { } } -fn is_file_read_to_end<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'tcx>) -> bool { +fn is_file_read_to_end<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) -> bool { if_chain! { if let ExprKind::MethodCall(method_name, _, exprs, _) = expr.kind; if method_name.ident.as_str() == "read_to_end"; @@ -71,7 +71,7 @@ fn is_file_read_to_end<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'t false } -fn is_file_read_to_string<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'tcx>) -> bool { +fn is_file_read_to_string<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) -> bool { if_chain! { if let ExprKind::MethodCall(method_name, _, exprs, _) = expr.kind; if method_name.ident.as_str() == "read_to_string"; diff --git a/clippy_lints/src/wildcard_dependencies.rs b/clippy_lints/src/wildcard_dependencies.rs index 511518082bec1..cd1864f461d3b 100644 --- a/clippy_lints/src/wildcard_dependencies.rs +++ b/clippy_lints/src/wildcard_dependencies.rs @@ -28,8 +28,8 @@ declare_clippy_lint! { declare_lint_pass!(WildcardDependencies => [WILDCARD_DEPENDENCIES]); -impl LateLintPass<'_, '_> for WildcardDependencies { - fn check_crate(&mut self, cx: &LateContext<'_, '_>, _: &Crate<'_>) { +impl LateLintPass<'_> for WildcardDependencies { + fn check_crate(&mut self, cx: &LateContext<'_>, _: &Crate<'_>) { if !run_lints(cx, &[WILDCARD_DEPENDENCIES], CRATE_HIR_ID) { return; } diff --git a/clippy_lints/src/wildcard_imports.rs b/clippy_lints/src/wildcard_imports.rs index 79f7705e281e5..e7eb7c2e9802d 100644 --- a/clippy_lints/src/wildcard_imports.rs +++ b/clippy_lints/src/wildcard_imports.rs @@ -101,8 +101,8 @@ impl WildcardImports { impl_lint_pass!(WildcardImports => [ENUM_GLOB_USE, WILDCARD_IMPORTS]); -impl LateLintPass<'_, '_> for WildcardImports { - fn check_item(&mut self, cx: &LateContext<'_, '_>, item: &Item<'_>) { +impl LateLintPass<'_> for WildcardImports { + fn check_item(&mut self, cx: &LateContext<'_>, item: &Item<'_>) { if is_test_module_or_function(item) { self.test_modules_deep = self.test_modules_deep.saturating_add(1); } @@ -180,7 +180,7 @@ impl LateLintPass<'_, '_> for WildcardImports { } } - fn check_item_post(&mut self, _: &LateContext<'_, '_>, item: &Item<'_>) { + fn check_item_post(&mut self, _: &LateContext<'_>, item: &Item<'_>) { if is_test_module_or_function(item) { self.test_modules_deep = self.test_modules_deep.saturating_sub(1); } diff --git a/clippy_lints/src/zero_div_zero.rs b/clippy_lints/src/zero_div_zero.rs index f0cf17c3b9549..1e011ea9cba5e 100644 --- a/clippy_lints/src/zero_div_zero.rs +++ b/clippy_lints/src/zero_div_zero.rs @@ -27,8 +27,8 @@ declare_clippy_lint! { declare_lint_pass!(ZeroDiv => [ZERO_DIVIDED_BY_ZERO]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ZeroDiv { - fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) { +impl<'tcx> LateLintPass<'tcx> for ZeroDiv { + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { // check for instances of 0.0/0.0 if_chain! { if let ExprKind::Binary(ref op, ref left, ref right) = expr.kind; diff --git a/doc/common_tools_writing_lints.md b/doc/common_tools_writing_lints.md index d06e359bc7aa5..412ff99314d99 100644 --- a/doc/common_tools_writing_lints.md +++ b/doc/common_tools_writing_lints.md @@ -28,8 +28,8 @@ that gives you access to the underlying structure [`TyS`][TyS]. Example of use: ```rust -impl LateLintPass<'_, '_> for MyStructLint { - fn check_expr(&mut self, cx: &LateContext<'_, '_>, expr: &Expr<'_>) { +impl LateLintPass<'_> for MyStructLint { + fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) { // Get type of `expr` let ty = cx.tables().expr_ty(expr); // Match its kind to enter its type @@ -56,8 +56,8 @@ Two noticeable items here: Starting with an `expr`, you can check whether it is calling a specific method `some_method`: ```rust -impl LateLintPass<'_, '_> for MyStructLint { - fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx hir::Expr<'_>) { +impl LateLintPass<'_> for MyStructLint { + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>) { if_chain! { // Check our expr is calling a method if let hir::ExprKind::MethodCall(path, _, _args) = &expr.kind; @@ -78,8 +78,8 @@ There are two ways to do this, depending if the target trait is part of lang ite ```rust use crate::utils::{implements_trait, match_trait_method, paths}; -impl LateLintPass<'_, '_> for MyStructLint { - fn check_expr(&mut self, cx: &LateContext<'_, '_>, expr: &Expr<'_>) { +impl LateLintPass<'_> for MyStructLint { + fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) { // 1. Using expression and Clippy's convenient method // we use `match_trait_method` function from Clippy's toolbox if match_trait_method(cx, expr, &paths::INTO) { @@ -112,8 +112,8 @@ To check if our type defines a method called `some_method`: ```rust use crate::utils::{is_type_diagnostic_item, return_ty}; -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MyTypeImpl { - fn check_impl_item(&mut self, cx: &LateContext<'a, 'tcx>, impl_item: &'tcx ImplItem<'_>) { +impl<'tcx> LateLintPass<'tcx> for MyTypeImpl { + fn check_impl_item(&mut self, cx: &LateContext<'tcx>, impl_item: &'tcx ImplItem<'_>) { if_chain! { // Check if item is a method/function if let ImplItemKind::Fn(ref signature, _) = impl_item.kind; diff --git a/tests/ui/outer_expn_data.fixed b/tests/ui/outer_expn_data.fixed index 999a19b289e18..b0b3498f057f7 100644 --- a/tests/ui/outer_expn_data.fixed +++ b/tests/ui/outer_expn_data.fixed @@ -19,8 +19,8 @@ declare_lint! { declare_lint_pass!(Pass => [TEST_LINT]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { - fn check_expr(&mut self, _cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) { +impl<'tcx> LateLintPass<'tcx> for Pass { + fn check_expr(&mut self, _cx: &LateContext<'tcx>, expr: &'tcx Expr) { let _ = expr.span.ctxt().outer_expn_data(); } } diff --git a/tests/ui/outer_expn_data.rs b/tests/ui/outer_expn_data.rs index 5405d475d1acc..55a3fed00d075 100644 --- a/tests/ui/outer_expn_data.rs +++ b/tests/ui/outer_expn_data.rs @@ -19,8 +19,8 @@ declare_lint! { declare_lint_pass!(Pass => [TEST_LINT]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { - fn check_expr(&mut self, _cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) { +impl<'tcx> LateLintPass<'tcx> for Pass { + fn check_expr(&mut self, _cx: &LateContext<'tcx>, expr: &'tcx Expr) { let _ = expr.span.ctxt().outer_expn().expn_data(); } } From 754bfb1dc89ed9a98b2f1b7d77b035e809b14031 Mon Sep 17 00:00:00 2001 From: ThibsG Date: Sun, 28 Jun 2020 12:14:04 +0200 Subject: [PATCH 23/99] Add configurable threshold for `type_repetition_in_bounds` lint --- clippy_lints/src/lib.rs | 5 +++-- clippy_lints/src/trait_bounds.rs | 18 +++++++++++++--- clippy_lints/src/utils/conf.rs | 2 ++ .../toml_unknown_key/conf_unknown_key.stderr | 2 +- tests/ui/type_repetition_in_bounds.rs | 21 ++++++++++++++++++- tests/ui/type_repetition_in_bounds.stderr | 18 +++++++++++----- 6 files changed, 54 insertions(+), 12 deletions(-) diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index d31a597b66ac6..38f8d007c72f9 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -996,7 +996,8 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: store.register_late_pass(|| box checked_conversions::CheckedConversions); store.register_late_pass(|| box integer_division::IntegerDivision); store.register_late_pass(|| box inherent_to_string::InherentToString); - store.register_late_pass(|| box trait_bounds::TraitBounds); + let max_trait_bounds = conf.max_trait_bounds; + store.register_late_pass(move || box trait_bounds::TraitBounds::new(max_trait_bounds)); store.register_late_pass(|| box comparison_chain::ComparisonChain); store.register_late_pass(|| box mut_key::MutableKeyType); store.register_late_pass(|| box modulo_arithmetic::ModuloArithmetic); @@ -1033,7 +1034,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: let array_size_threshold = conf.array_size_threshold; store.register_late_pass(move || box large_stack_arrays::LargeStackArrays::new(array_size_threshold)); store.register_late_pass(move || box large_const_arrays::LargeConstArrays::new(array_size_threshold)); - store.register_late_pass(move || box floating_point_arithmetic::FloatingPointArithmetic); + store.register_late_pass(|| box floating_point_arithmetic::FloatingPointArithmetic); store.register_early_pass(|| box as_conversions::AsConversions); store.register_early_pass(|| box utils::internal_lints::ProduceIce); store.register_late_pass(|| box let_underscore::LetUnderscore); diff --git a/clippy_lints/src/trait_bounds.rs b/clippy_lints/src/trait_bounds.rs index 9eb2079c3ca2d..650edbb4b11c7 100644 --- a/clippy_lints/src/trait_bounds.rs +++ b/clippy_lints/src/trait_bounds.rs @@ -5,9 +5,6 @@ use rustc_hir::{GenericBound, Generics, WherePredicate}; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::{declare_tool_lint, impl_lint_pass}; -#[derive(Copy, Clone)] -pub struct TraitBounds; - declare_clippy_lint! { /// **What it does:** This lint warns about unnecessary type repetitions in trait bounds /// @@ -29,6 +26,18 @@ declare_clippy_lint! { "Types are repeated unnecessary in trait bounds use `+` instead of using `T: _, T: _`" } +#[derive(Copy, Clone)] +pub struct TraitBounds { + max_trait_bounds: u64, +} + +impl TraitBounds { + #[must_use] + pub fn new(max_trait_bounds: u64) -> Self { + Self { max_trait_bounds } + } +} + impl_lint_pass!(TraitBounds => [TYPE_REPETITION_IN_BOUNDS]); impl<'tcx> LateLintPass<'tcx> for TraitBounds { @@ -45,6 +54,9 @@ impl<'tcx> LateLintPass<'tcx> for TraitBounds { let mut applicability = Applicability::MaybeIncorrect; for bound in gen.where_clause.predicates { if let WherePredicate::BoundPredicate(ref p) = bound { + if p.bounds.len() as u64 > self.max_trait_bounds { + return; + } let h = hash(&p.bounded_ty); if let Some(ref v) = map.insert(h, p.bounds.iter().collect::>()) { let mut hint_string = format!( diff --git a/clippy_lints/src/utils/conf.rs b/clippy_lints/src/utils/conf.rs index c41befbf147b8..de425211e38ef 100644 --- a/clippy_lints/src/utils/conf.rs +++ b/clippy_lints/src/utils/conf.rs @@ -156,6 +156,8 @@ define_Conf! { (array_size_threshold, "array_size_threshold": u64, 512_000), /// Lint: VEC_BOX. The size of the boxed type in bytes, where boxing in a `Vec` is allowed (vec_box_size_threshold, "vec_box_size_threshold": u64, 4096), + /// Lint: TYPE_REPETITION_IN_BOUNDS. The maximum number of bounds a trait can have to be linted + (max_trait_bounds, "max_trait_bounds": u64, 3), /// Lint: STRUCT_EXCESSIVE_BOOLS. The maximum number of bools a struct can have (max_struct_bools, "max_struct_bools": u64, 3), /// Lint: FN_PARAMS_EXCESSIVE_BOOLS. The maximum number of bools function parameters can have diff --git a/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr b/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr index 53970af41079d..6fbba01416a8d 100644 --- a/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr +++ b/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr @@ -1,4 +1,4 @@ -error: error reading Clippy's configuration file `$DIR/clippy.toml`: unknown field `foobar`, expected one of `blacklisted-names`, `cognitive-complexity-threshold`, `cyclomatic-complexity-threshold`, `doc-valid-idents`, `too-many-arguments-threshold`, `type-complexity-threshold`, `single-char-binding-names-threshold`, `too-large-for-stack`, `enum-variant-name-threshold`, `enum-variant-size-threshold`, `verbose-bit-mask-threshold`, `literal-representation-threshold`, `trivial-copy-size-limit`, `too-many-lines-threshold`, `array-size-threshold`, `vec-box-size-threshold`, `max-struct-bools`, `max-fn-params-bools`, `warn-on-all-wildcard-imports`, `third-party` at line 5 column 1 +error: error reading Clippy's configuration file `$DIR/clippy.toml`: unknown field `foobar`, expected one of `blacklisted-names`, `cognitive-complexity-threshold`, `cyclomatic-complexity-threshold`, `doc-valid-idents`, `too-many-arguments-threshold`, `type-complexity-threshold`, `single-char-binding-names-threshold`, `too-large-for-stack`, `enum-variant-name-threshold`, `enum-variant-size-threshold`, `verbose-bit-mask-threshold`, `literal-representation-threshold`, `trivial-copy-size-limit`, `too-many-lines-threshold`, `array-size-threshold`, `vec-box-size-threshold`, `max-trait-bounds`, `max-struct-bools`, `max-fn-params-bools`, `warn-on-all-wildcard-imports`, `third-party` at line 5 column 1 error: aborting due to previous error diff --git a/tests/ui/type_repetition_in_bounds.rs b/tests/ui/type_repetition_in_bounds.rs index 8b538be762b0c..60b994548b5c6 100644 --- a/tests/ui/type_repetition_in_bounds.rs +++ b/tests/ui/type_repetition_in_bounds.rs @@ -1,4 +1,6 @@ -#[deny(clippy::type_repetition_in_bounds)] +#![deny(clippy::type_repetition_in_bounds)] + +use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign}; pub fn foo(_t: T) where @@ -16,4 +18,21 @@ where unimplemented!(); } +trait LintBounds +where + Self: Clone, + Self: Copy + Default + Ord, + Self: Add + AddAssign + Sub + SubAssign, + Self: Mul + MulAssign + Div + DivAssign, +{ +} + +trait LotsOfBounds +where + Self: Clone + Copy + Default + Ord, + Self: Add + AddAssign + Sub + SubAssign, + Self: Mul + MulAssign + Div + DivAssign, +{ +} + fn main() {} diff --git a/tests/ui/type_repetition_in_bounds.stderr b/tests/ui/type_repetition_in_bounds.stderr index 4264e2e10bf17..6a1073a23f697 100644 --- a/tests/ui/type_repetition_in_bounds.stderr +++ b/tests/ui/type_repetition_in_bounds.stderr @@ -1,15 +1,23 @@ error: this type has already been used as a bound predicate - --> $DIR/type_repetition_in_bounds.rs:6:5 + --> $DIR/type_repetition_in_bounds.rs:8:5 | LL | T: Clone, | ^^^^^^^^ | note: the lint level is defined here - --> $DIR/type_repetition_in_bounds.rs:1:8 + --> $DIR/type_repetition_in_bounds.rs:1:9 | -LL | #[deny(clippy::type_repetition_in_bounds)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #![deny(clippy::type_repetition_in_bounds)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = help: consider combining the bounds: `T: Copy + Clone` -error: aborting due to previous error +error: this type has already been used as a bound predicate + --> $DIR/type_repetition_in_bounds.rs:24:5 + | +LL | Self: Copy + Default + Ord, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider combining the bounds: `Self: Clone + Copy + Default + Ord` + +error: aborting due to 2 previous errors From d5a8f03a350e8a392f0aa1c05707b503f549e90b Mon Sep 17 00:00:00 2001 From: ThibsG Date: Fri, 3 Jul 2020 10:29:14 +0200 Subject: [PATCH 24/99] Take generic args into account for bounded type --- clippy_lints/src/utils/hir_utils.rs | 19 ++++++++++++------- tests/ui/type_repetition_in_bounds.rs | 15 +++++++++++++++ tests/ui/type_repetition_in_bounds.stderr | 2 +- 3 files changed, 28 insertions(+), 8 deletions(-) diff --git a/clippy_lints/src/utils/hir_utils.rs b/clippy_lints/src/utils/hir_utils.rs index ae58f0a1521e6..34341594c1985 100644 --- a/clippy_lints/src/utils/hir_utils.rs +++ b/clippy_lints/src/utils/hir_utils.rs @@ -703,6 +703,7 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> { } for segment in path.segments { segment.ident.name.hash(&mut self.s); + self.hash_generic_args(segment.generic_args().args); } }, QPath::TypeRelative(ref ty, ref segment) => { @@ -711,13 +712,7 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> { }, }, TyKind::OpaqueDef(_, arg_list) => { - for arg in *arg_list { - match arg { - GenericArg::Lifetime(ref l) => self.hash_lifetime(l), - GenericArg::Type(ref ty) => self.hash_ty(&ty), - GenericArg::Const(ref ca) => self.hash_body(ca.value.body), - } - } + self.hash_generic_args(arg_list); }, TyKind::TraitObject(_, lifetime) => { self.hash_lifetime(lifetime); @@ -735,4 +730,14 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> { self.hash_expr(&self.cx.tcx.hir().body(body_id).value); self.maybe_typeck_tables = old_maybe_typeck_tables; } + + fn hash_generic_args(&mut self, arg_list: &[GenericArg<'_>]) { + for arg in arg_list { + match arg { + GenericArg::Lifetime(ref l) => self.hash_lifetime(l), + GenericArg::Type(ref ty) => self.hash_ty(&ty), + GenericArg::Const(ref ca) => self.hash_body(ca.value.body), + } + } + } } diff --git a/tests/ui/type_repetition_in_bounds.rs b/tests/ui/type_repetition_in_bounds.rs index 60b994548b5c6..9f1700567d1c4 100644 --- a/tests/ui/type_repetition_in_bounds.rs +++ b/tests/ui/type_repetition_in_bounds.rs @@ -18,6 +18,7 @@ where unimplemented!(); } +// Threshold test (see #4380) trait LintBounds where Self: Clone, @@ -35,4 +36,18 @@ where { } +// Generic distinction (see #4323) +pub struct Foo(A); +pub struct Bar { + a: Foo, + b: Foo, +} + +impl Unpin for Bar +where + Foo: Unpin, + Foo: Unpin, +{ +} + fn main() {} diff --git a/tests/ui/type_repetition_in_bounds.stderr b/tests/ui/type_repetition_in_bounds.stderr index 6a1073a23f697..148c19c7d0701 100644 --- a/tests/ui/type_repetition_in_bounds.stderr +++ b/tests/ui/type_repetition_in_bounds.stderr @@ -12,7 +12,7 @@ LL | #![deny(clippy::type_repetition_in_bounds)] = help: consider combining the bounds: `T: Copy + Clone` error: this type has already been used as a bound predicate - --> $DIR/type_repetition_in_bounds.rs:24:5 + --> $DIR/type_repetition_in_bounds.rs:25:5 | LL | Self: Copy + Default + Ord, | ^^^^^^^^^^^^^^^^^^^^^^^^^^ From 2d5930a3da7048d784489f28b44a769880b6ceff Mon Sep 17 00:00:00 2001 From: ThibsG Date: Fri, 3 Jul 2020 11:48:28 +0200 Subject: [PATCH 25/99] Don't lint for predicates generated in macros --- clippy_lints/src/trait_bounds.rs | 15 +++++++---- tests/ui/type_repetition_in_bounds.rs | 37 ++++++++++++++++++++------- 2 files changed, 38 insertions(+), 14 deletions(-) diff --git a/clippy_lints/src/trait_bounds.rs b/clippy_lints/src/trait_bounds.rs index 650edbb4b11c7..0ef70311fb1cd 100644 --- a/clippy_lints/src/trait_bounds.rs +++ b/clippy_lints/src/trait_bounds.rs @@ -1,4 +1,5 @@ use crate::utils::{in_macro, snippet, snippet_with_applicability, span_lint_and_help, SpanlessHash}; +use if_chain::if_chain; use rustc_data_structures::fx::FxHashMap; use rustc_errors::Applicability; use rustc_hir::{GenericBound, Generics, WherePredicate}; @@ -11,6 +12,8 @@ declare_clippy_lint! { /// **Why is this bad?** Repeating the type for every bound makes the code /// less readable than combining the bounds /// + /// **Known problems:** None. + /// /// **Example:** /// ```rust /// pub fn foo(t: T) where T: Copy, T: Clone {} @@ -53,12 +56,14 @@ impl<'tcx> LateLintPass<'tcx> for TraitBounds { let mut map = FxHashMap::default(); let mut applicability = Applicability::MaybeIncorrect; for bound in gen.where_clause.predicates { - if let WherePredicate::BoundPredicate(ref p) = bound { - if p.bounds.len() as u64 > self.max_trait_bounds { - return; - } + if_chain! { + if let WherePredicate::BoundPredicate(ref p) = bound; + if p.bounds.len() as u64 <= self.max_trait_bounds; + if !in_macro(p.span); let h = hash(&p.bounded_ty); - if let Some(ref v) = map.insert(h, p.bounds.iter().collect::>()) { + if let Some(ref v) = map.insert(h, p.bounds.iter().collect::>()); + + then { let mut hint_string = format!( "consider combining the bounds: `{}:", snippet(cx, p.bounded_ty.span, "_") diff --git a/tests/ui/type_repetition_in_bounds.rs b/tests/ui/type_repetition_in_bounds.rs index 9f1700567d1c4..766190f209977 100644 --- a/tests/ui/type_repetition_in_bounds.rs +++ b/tests/ui/type_repetition_in_bounds.rs @@ -37,17 +37,36 @@ where } // Generic distinction (see #4323) -pub struct Foo(A); -pub struct Bar { - a: Foo, - b: Foo, +mod issue4323 { + pub struct Foo(A); + pub struct Bar { + a: Foo, + b: Foo, + } + + impl Unpin for Bar + where + Foo: Unpin, + Foo: Unpin, + { + } } -impl Unpin for Bar -where - Foo: Unpin, - Foo: Unpin, -{ +// Extern macros shouldn't lint (see #4326) +extern crate serde; +mod issue4326 { + use serde::{Deserialize, Serialize}; + + trait Foo {} + impl Foo for String {} + + #[derive(Debug, Serialize, Deserialize)] + struct Bar + where + S: Foo, + { + foo: S, + } } fn main() {} From c3c402783f1d12852982f9dc734cc4c07b9fce33 Mon Sep 17 00:00:00 2001 From: Robert Sedlacek Date: Mon, 4 Nov 2019 19:39:03 +0100 Subject: [PATCH 26/99] Added restriction lint: pattern-type-mismatch --- CHANGELOG.md | 1 + clippy_lints/src/lib.rs | 4 + clippy_lints/src/pattern_type_mismatch.rs | 276 ++++++++++++++++++ src/lintlist/mod.rs | 7 + tests/ui/pattern_type_mismatch/mutability.rs | 40 +++ .../pattern_type_mismatch/mutability.stderr | 19 ++ .../pattern_alternatives.rs | 24 ++ .../pattern_alternatives.stderr | 27 ++ .../pattern_type_mismatch/pattern_structs.rs | 45 +++ .../pattern_structs.stderr | 67 +++++ .../pattern_type_mismatch/pattern_tuples.rs | 57 ++++ .../pattern_tuples.stderr | 83 ++++++ tests/ui/pattern_type_mismatch/syntax.rs | 146 +++++++++ tests/ui/pattern_type_mismatch/syntax.stderr | 78 +++++ 14 files changed, 874 insertions(+) create mode 100644 clippy_lints/src/pattern_type_mismatch.rs create mode 100644 tests/ui/pattern_type_mismatch/mutability.rs create mode 100644 tests/ui/pattern_type_mismatch/mutability.stderr create mode 100644 tests/ui/pattern_type_mismatch/pattern_alternatives.rs create mode 100644 tests/ui/pattern_type_mismatch/pattern_alternatives.stderr create mode 100644 tests/ui/pattern_type_mismatch/pattern_structs.rs create mode 100644 tests/ui/pattern_type_mismatch/pattern_structs.stderr create mode 100644 tests/ui/pattern_type_mismatch/pattern_tuples.rs create mode 100644 tests/ui/pattern_type_mismatch/pattern_tuples.stderr create mode 100644 tests/ui/pattern_type_mismatch/syntax.rs create mode 100644 tests/ui/pattern_type_mismatch/syntax.stderr diff --git a/CHANGELOG.md b/CHANGELOG.md index b88044d6ce84c..ed8f16e65bb9a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1588,6 +1588,7 @@ Released 2018-09-13 [`panicking_unwrap`]: https://rust-lang.github.io/rust-clippy/master/index.html#panicking_unwrap [`partialeq_ne_impl`]: https://rust-lang.github.io/rust-clippy/master/index.html#partialeq_ne_impl [`path_buf_push_overwrite`]: https://rust-lang.github.io/rust-clippy/master/index.html#path_buf_push_overwrite +[`pattern_type_mismatch`]: https://rust-lang.github.io/rust-clippy/master/index.html#pattern_type_mismatch [`possible_missing_comma`]: https://rust-lang.github.io/rust-clippy/master/index.html#possible_missing_comma [`precedence`]: https://rust-lang.github.io/rust-clippy/master/index.html#precedence [`print_literal`]: https://rust-lang.github.io/rust-clippy/master/index.html#print_literal diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index d31a597b66ac6..4890349999fa0 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -268,6 +268,7 @@ mod overflow_check_conditional; mod panic_unimplemented; mod partialeq_ne_impl; mod path_buf_push_overwrite; +pub mod pattern_type_mismatch; mod precedence; mod ptr; mod ptr_offset_with_cast; @@ -741,6 +742,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: &panic_unimplemented::UNREACHABLE, &partialeq_ne_impl::PARTIALEQ_NE_IMPL, &path_buf_push_overwrite::PATH_BUF_PUSH_OVERWRITE, + &pattern_type_mismatch::PATTERN_TYPE_MISMATCH, &precedence::PRECEDENCE, &ptr::CMP_NULL, &ptr::MUT_FROM_REF, @@ -1064,6 +1066,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: store.register_early_pass(|| box unnested_or_patterns::UnnestedOrPatterns); store.register_late_pass(|| box macro_use::MacroUseImports::default()); store.register_late_pass(|| box map_identity::MapIdentity); + store.register_late_pass(|| box pattern_type_mismatch::PatternTypeMismatch); store.register_group(true, "clippy::restriction", Some("clippy_restriction"), vec![ LintId::of(&arithmetic::FLOAT_ARITHMETIC), @@ -1097,6 +1100,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: LintId::of(&panic_unimplemented::TODO), LintId::of(&panic_unimplemented::UNIMPLEMENTED), LintId::of(&panic_unimplemented::UNREACHABLE), + LintId::of(&pattern_type_mismatch::PATTERN_TYPE_MISMATCH), LintId::of(&shadow::SHADOW_REUSE), LintId::of(&shadow::SHADOW_SAME), LintId::of(&strings::STRING_ADD), diff --git a/clippy_lints/src/pattern_type_mismatch.rs b/clippy_lints/src/pattern_type_mismatch.rs new file mode 100644 index 0000000000000..a07279c92b001 --- /dev/null +++ b/clippy_lints/src/pattern_type_mismatch.rs @@ -0,0 +1,276 @@ +use crate::utils::{last_path_segment, span_help_and_lint}; +use rustc::lint::in_external_macro; +use rustc::ty::subst::SubstsRef; +use rustc::ty::{AdtDef, FieldDef, Ty, TyKind, VariantDef}; +use rustc_hir::{ + intravisit, Body, Expr, ExprKind, FieldPat, FnDecl, HirId, LocalSource, MatchSource, Mutability, Pat, PatKind, + QPath, Stmt, StmtKind, +}; +use rustc_lint::{LateContext, LateLintPass, LintContext}; +use rustc_session::{declare_lint_pass, declare_tool_lint}; +use rustc_span::source_map::Span; + +declare_clippy_lint! { + /// **What it does:** Checks for patterns that aren't exact representations of the types + /// they are applied to. + /// + /// **Why is this bad?** It isn't bad in general. But in some contexts it can be desirable + /// because it increases ownership hints in the code, and will guard against some changes + /// in ownership. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// + /// ```rust,ignore + /// // Bad + /// let value = &Some(Box::new(23)); + /// match value { + /// Some(inner) => println!("{}", inner), + /// None => println!("none"), + /// } + /// + /// // Good + /// let value = &Some(Box::new(23)); + /// match *value { + /// Some(ref inner) => println!("{}", inner), + /// None => println!("none"), + /// } + /// ``` + pub PATTERN_TYPE_MISMATCH, + restriction, + "type of pattern does not match the expression type" +} + +declare_lint_pass!(PatternTypeMismatch => [PATTERN_TYPE_MISMATCH]); + +impl<'a, 'tcx> LateLintPass<'a, 'tcx> for PatternTypeMismatch { + fn check_stmt(&mut self, cx: &LateContext<'a, 'tcx>, stmt: &'tcx Stmt<'_>) { + if let StmtKind::Local(ref local) = stmt.kind { + if let Some(init) = &local.init { + if let Some(init_ty) = cx.tables.node_type_opt(init.hir_id) { + let pat = &local.pat; + if in_external_macro(cx.sess(), pat.span) { + return; + } + let deref_possible = match local.source { + LocalSource::Normal => DerefPossible::Possible, + _ => DerefPossible::Impossible, + }; + apply_lint(cx, pat, init_ty, deref_possible); + } + } + } + } + + fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) { + if let ExprKind::Match(ref expr, arms, source) = expr.kind { + match source { + MatchSource::Normal | MatchSource::IfLetDesugar { .. } | MatchSource::WhileLetDesugar => { + if let Some(expr_ty) = cx.tables.node_type_opt(expr.hir_id) { + 'pattern_checks: for arm in arms { + let pat = &arm.pat; + if in_external_macro(cx.sess(), pat.span) { + continue 'pattern_checks; + } + if apply_lint(cx, pat, expr_ty, DerefPossible::Possible) { + break 'pattern_checks; + } + } + } + }, + _ => (), + } + } + } + + fn check_fn( + &mut self, + cx: &LateContext<'a, 'tcx>, + _: intravisit::FnKind<'tcx>, + _: &'tcx FnDecl<'_>, + body: &'tcx Body<'_>, + _: Span, + hir_id: HirId, + ) { + if let Some(fn_sig) = cx.tables.liberated_fn_sigs().get(hir_id) { + for (param, ty) in body.params.iter().zip(fn_sig.inputs().iter()) { + apply_lint(cx, ¶m.pat, ty, DerefPossible::Impossible); + } + } + } +} + +#[derive(Debug, Clone, Copy)] +enum DerefPossible { + Possible, + Impossible, +} + +fn apply_lint<'a, 'tcx>( + cx: &LateContext<'a, 'tcx>, + pat: &Pat<'_>, + expr_ty: Ty<'tcx>, + deref_possible: DerefPossible, +) -> bool { + let maybe_mismatch = find_first_mismatch(cx, pat, expr_ty, Level::Top); + if let Some((span, mutability, level)) = maybe_mismatch { + span_help_and_lint( + cx, + PATTERN_TYPE_MISMATCH, + span, + "type of pattern does not match the expression type", + &format!( + "{}explicitly match against a `{}` pattern and adjust the enclosed variable bindings", + match (deref_possible, level) { + (DerefPossible::Possible, Level::Top) => "use `*` to dereference the match expression or ", + _ => "", + }, + match mutability { + Mutability::Mut => "&mut _", + Mutability::Not => "&_", + }, + ), + ); + true + } else { + false + } +} + +#[derive(Debug, Copy, Clone)] +enum Level { + Top, + Lower, +} + +#[allow(rustc::usage_of_ty_tykind)] +fn find_first_mismatch<'a, 'tcx>( + cx: &LateContext<'a, 'tcx>, + pat: &Pat<'_>, + ty: Ty<'tcx>, + level: Level, +) -> Option<(Span, Mutability, Level)> { + if let PatKind::Ref(ref sub_pat, _) = pat.kind { + if let TyKind::Ref(_, sub_ty, _) = ty.kind { + return find_first_mismatch(cx, sub_pat, sub_ty, Level::Lower); + } + } + + if let TyKind::Ref(_, _, mutability) = ty.kind { + if is_non_ref_pattern(&pat.kind) { + return Some((pat.span, mutability, level)); + } + } + + if let PatKind::Struct(ref qpath, ref field_pats, _) = pat.kind { + if let TyKind::Adt(ref adt_def, ref substs_ref) = ty.kind { + if let Some(variant) = get_variant(adt_def, qpath) { + let field_defs = &variant.fields; + return find_first_mismatch_in_struct(cx, field_pats, field_defs, substs_ref); + } + } + } + + if let PatKind::TupleStruct(ref qpath, ref pats, _) = pat.kind { + if let TyKind::Adt(ref adt_def, ref substs_ref) = ty.kind { + if let Some(variant) = get_variant(adt_def, qpath) { + let field_defs = &variant.fields; + let ty_iter = field_defs.iter().map(|field_def| field_def.ty(cx.tcx, substs_ref)); + return find_first_mismatch_in_tuple(cx, pats, ty_iter); + } + } + } + + if let PatKind::Tuple(ref pats, _) = pat.kind { + if let TyKind::Tuple(..) = ty.kind { + return find_first_mismatch_in_tuple(cx, pats, ty.tuple_fields()); + } + } + + if let PatKind::Or(sub_pats) = pat.kind { + for pat in sub_pats { + let maybe_mismatch = find_first_mismatch(cx, pat, ty, level); + if let Some(mismatch) = maybe_mismatch { + return Some(mismatch); + } + } + } + + None +} + +fn get_variant<'a>(adt_def: &'a AdtDef, qpath: &QPath<'_>) -> Option<&'a VariantDef> { + if adt_def.is_struct() { + if let Some(variant) = adt_def.variants.iter().next() { + return Some(variant); + } + } + + if adt_def.is_enum() { + let pat_ident = last_path_segment(qpath).ident; + for variant in &adt_def.variants { + if variant.ident == pat_ident { + return Some(variant); + } + } + } + + None +} + +fn find_first_mismatch_in_tuple<'a, 'tcx, I>( + cx: &LateContext<'a, 'tcx>, + pats: &[&Pat<'_>], + ty_iter_src: I, +) -> Option<(Span, Mutability, Level)> +where + I: IntoIterator>, +{ + let mut field_tys = ty_iter_src.into_iter(); + 'fields: for pat in pats { + let field_ty = if let Some(ty) = field_tys.next() { + ty + } else { + break 'fields; + }; + + let maybe_mismatch = find_first_mismatch(cx, pat, field_ty, Level::Lower); + if let Some(mismatch) = maybe_mismatch { + return Some(mismatch); + } + } + + None +} + +fn find_first_mismatch_in_struct<'a, 'tcx>( + cx: &LateContext<'a, 'tcx>, + field_pats: &[FieldPat<'_>], + field_defs: &[FieldDef], + substs_ref: SubstsRef<'tcx>, +) -> Option<(Span, Mutability, Level)> { + for field_pat in field_pats { + 'definitions: for field_def in field_defs { + if field_pat.ident == field_def.ident { + let field_ty = field_def.ty(cx.tcx, substs_ref); + let pat = &field_pat.pat; + let maybe_mismatch = find_first_mismatch(cx, pat, field_ty, Level::Lower); + if let Some(mismatch) = maybe_mismatch { + return Some(mismatch); + } + break 'definitions; + } + } + } + + None +} + +fn is_non_ref_pattern(pat_kind: &PatKind<'_>) -> bool { + match pat_kind { + PatKind::Struct(..) | PatKind::Tuple(..) | PatKind::TupleStruct(..) | PatKind::Path(..) => true, + PatKind::Or(sub_pats) => sub_pats.iter().any(|pat| is_non_ref_pattern(&pat.kind)), + _ => false, + } +} diff --git a/src/lintlist/mod.rs b/src/lintlist/mod.rs index a2998d7413047..6402efc252121 100644 --- a/src/lintlist/mod.rs +++ b/src/lintlist/mod.rs @@ -1697,6 +1697,13 @@ pub static ref ALL_LINTS: Vec = vec![ deprecation: None, module: "path_buf_push_overwrite", }, + Lint { + name: "pattern_type_mismatch", + group: "restriction", + desc: "type of pattern does not match the expression type", + deprecation: None, + module: "pattern_type_mismatch", + }, Lint { name: "possible_missing_comma", group: "correctness", diff --git a/tests/ui/pattern_type_mismatch/mutability.rs b/tests/ui/pattern_type_mismatch/mutability.rs new file mode 100644 index 0000000000000..9b4f2f1f57934 --- /dev/null +++ b/tests/ui/pattern_type_mismatch/mutability.rs @@ -0,0 +1,40 @@ +#![allow(clippy::all)] +#![warn(clippy::pattern_type_mismatch)] + +fn main() {} + +fn should_lint() { + let value = &Some(23); + match value { + Some(_) => (), + _ => (), + } + + let value = &mut Some(23); + match value { + Some(_) => (), + _ => (), + } +} + +fn should_not_lint() { + let value = &Some(23); + match value { + &Some(_) => (), + _ => (), + } + match *value { + Some(_) => (), + _ => (), + } + + let value = &mut Some(23); + match value { + &mut Some(_) => (), + _ => (), + } + match *value { + Some(_) => (), + _ => (), + } +} diff --git a/tests/ui/pattern_type_mismatch/mutability.stderr b/tests/ui/pattern_type_mismatch/mutability.stderr new file mode 100644 index 0000000000000..3421d568365cc --- /dev/null +++ b/tests/ui/pattern_type_mismatch/mutability.stderr @@ -0,0 +1,19 @@ +error: type of pattern does not match the expression type + --> $DIR/mutability.rs:9:9 + | +LL | Some(_) => (), + | ^^^^^^^ + | + = note: `-D clippy::pattern-type-mismatch` implied by `-D warnings` + = help: use `*` to dereference the match expression or explicitly match against a `&_` pattern and adjust the enclosed variable bindings + +error: type of pattern does not match the expression type + --> $DIR/mutability.rs:15:9 + | +LL | Some(_) => (), + | ^^^^^^^ + | + = help: use `*` to dereference the match expression or explicitly match against a `&mut _` pattern and adjust the enclosed variable bindings + +error: aborting due to 2 previous errors + diff --git a/tests/ui/pattern_type_mismatch/pattern_alternatives.rs b/tests/ui/pattern_type_mismatch/pattern_alternatives.rs new file mode 100644 index 0000000000000..065ea9fb9b5a4 --- /dev/null +++ b/tests/ui/pattern_type_mismatch/pattern_alternatives.rs @@ -0,0 +1,24 @@ +#![allow(clippy::all)] +#![warn(clippy::pattern_type_mismatch)] + +fn main() {} + +fn alternatives() { + enum Value<'a> { + Unused, + A(&'a Option), + B, + } + let ref_value = &Value::A(&Some(23)); + + // not ok + if let Value::B | Value::A(_) = ref_value {} + if let &Value::B | &Value::A(Some(_)) = ref_value {} + if let Value::B | Value::A(Some(_)) = *ref_value {} + + // ok + if let &Value::B | &Value::A(_) = ref_value {} + if let Value::B | Value::A(_) = *ref_value {} + if let &Value::B | &Value::A(&Some(_)) = ref_value {} + if let Value::B | Value::A(&Some(_)) = *ref_value {} +} diff --git a/tests/ui/pattern_type_mismatch/pattern_alternatives.stderr b/tests/ui/pattern_type_mismatch/pattern_alternatives.stderr new file mode 100644 index 0000000000000..d285c93782c67 --- /dev/null +++ b/tests/ui/pattern_type_mismatch/pattern_alternatives.stderr @@ -0,0 +1,27 @@ +error: type of pattern does not match the expression type + --> $DIR/pattern_alternatives.rs:15:12 + | +LL | if let Value::B | Value::A(_) = ref_value {} + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `-D clippy::pattern-type-mismatch` implied by `-D warnings` + = help: use `*` to dereference the match expression or explicitly match against a `&_` pattern and adjust the enclosed variable bindings + +error: type of pattern does not match the expression type + --> $DIR/pattern_alternatives.rs:16:34 + | +LL | if let &Value::B | &Value::A(Some(_)) = ref_value {} + | ^^^^^^^ + | + = help: explicitly match against a `&_` pattern and adjust the enclosed variable bindings + +error: type of pattern does not match the expression type + --> $DIR/pattern_alternatives.rs:17:32 + | +LL | if let Value::B | Value::A(Some(_)) = *ref_value {} + | ^^^^^^^ + | + = help: explicitly match against a `&_` pattern and adjust the enclosed variable bindings + +error: aborting due to 3 previous errors + diff --git a/tests/ui/pattern_type_mismatch/pattern_structs.rs b/tests/ui/pattern_type_mismatch/pattern_structs.rs new file mode 100644 index 0000000000000..417b1c107c55b --- /dev/null +++ b/tests/ui/pattern_type_mismatch/pattern_structs.rs @@ -0,0 +1,45 @@ +#![allow(clippy::all)] +#![warn(clippy::pattern_type_mismatch)] + +fn main() {} + +fn struct_types() { + struct Struct<'a> { + ref_inner: &'a Option, + } + let ref_value = &Struct { ref_inner: &Some(42) }; + + // not ok + let Struct { .. } = ref_value; + if let &Struct { ref_inner: Some(_) } = ref_value {} + if let Struct { ref_inner: Some(_) } = *ref_value {} + + // ok + let &Struct { .. } = ref_value; + let Struct { .. } = *ref_value; + if let &Struct { ref_inner: &Some(_) } = ref_value {} + if let Struct { ref_inner: &Some(_) } = *ref_value {} +} + +fn struct_enum_variants() { + enum StructEnum<'a> { + Empty, + Var { inner_ref: &'a Option }, + } + let ref_value = &StructEnum::Var { inner_ref: &Some(42) }; + + // not ok + if let StructEnum::Var { .. } = ref_value {} + if let StructEnum::Var { inner_ref: Some(_) } = ref_value {} + if let &StructEnum::Var { inner_ref: Some(_) } = ref_value {} + if let StructEnum::Var { inner_ref: Some(_) } = *ref_value {} + if let StructEnum::Empty = ref_value {} + + // ok + if let &StructEnum::Var { .. } = ref_value {} + if let StructEnum::Var { .. } = *ref_value {} + if let &StructEnum::Var { inner_ref: &Some(_) } = ref_value {} + if let StructEnum::Var { inner_ref: &Some(_) } = *ref_value {} + if let &StructEnum::Empty = ref_value {} + if let StructEnum::Empty = *ref_value {} +} diff --git a/tests/ui/pattern_type_mismatch/pattern_structs.stderr b/tests/ui/pattern_type_mismatch/pattern_structs.stderr new file mode 100644 index 0000000000000..d428e85b0c914 --- /dev/null +++ b/tests/ui/pattern_type_mismatch/pattern_structs.stderr @@ -0,0 +1,67 @@ +error: type of pattern does not match the expression type + --> $DIR/pattern_structs.rs:13:9 + | +LL | let Struct { .. } = ref_value; + | ^^^^^^^^^^^^^ + | + = note: `-D clippy::pattern-type-mismatch` implied by `-D warnings` + = help: use `*` to dereference the match expression or explicitly match against a `&_` pattern and adjust the enclosed variable bindings + +error: type of pattern does not match the expression type + --> $DIR/pattern_structs.rs:14:33 + | +LL | if let &Struct { ref_inner: Some(_) } = ref_value {} + | ^^^^^^^ + | + = help: explicitly match against a `&_` pattern and adjust the enclosed variable bindings + +error: type of pattern does not match the expression type + --> $DIR/pattern_structs.rs:15:32 + | +LL | if let Struct { ref_inner: Some(_) } = *ref_value {} + | ^^^^^^^ + | + = help: explicitly match against a `&_` pattern and adjust the enclosed variable bindings + +error: type of pattern does not match the expression type + --> $DIR/pattern_structs.rs:32:12 + | +LL | if let StructEnum::Var { .. } = ref_value {} + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = help: use `*` to dereference the match expression or explicitly match against a `&_` pattern and adjust the enclosed variable bindings + +error: type of pattern does not match the expression type + --> $DIR/pattern_structs.rs:33:12 + | +LL | if let StructEnum::Var { inner_ref: Some(_) } = ref_value {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: use `*` to dereference the match expression or explicitly match against a `&_` pattern and adjust the enclosed variable bindings + +error: type of pattern does not match the expression type + --> $DIR/pattern_structs.rs:34:42 + | +LL | if let &StructEnum::Var { inner_ref: Some(_) } = ref_value {} + | ^^^^^^^ + | + = help: explicitly match against a `&_` pattern and adjust the enclosed variable bindings + +error: type of pattern does not match the expression type + --> $DIR/pattern_structs.rs:35:41 + | +LL | if let StructEnum::Var { inner_ref: Some(_) } = *ref_value {} + | ^^^^^^^ + | + = help: explicitly match against a `&_` pattern and adjust the enclosed variable bindings + +error: type of pattern does not match the expression type + --> $DIR/pattern_structs.rs:36:12 + | +LL | if let StructEnum::Empty = ref_value {} + | ^^^^^^^^^^^^^^^^^ + | + = help: use `*` to dereference the match expression or explicitly match against a `&_` pattern and adjust the enclosed variable bindings + +error: aborting due to 8 previous errors + diff --git a/tests/ui/pattern_type_mismatch/pattern_tuples.rs b/tests/ui/pattern_type_mismatch/pattern_tuples.rs new file mode 100644 index 0000000000000..19504a051d8b1 --- /dev/null +++ b/tests/ui/pattern_type_mismatch/pattern_tuples.rs @@ -0,0 +1,57 @@ +#![allow(clippy::all)] +#![warn(clippy::pattern_type_mismatch)] + +fn main() {} + +fn tuple_types() { + struct TupleStruct<'a>(&'a Option); + let ref_value = &TupleStruct(&Some(42)); + + // not ok + let TupleStruct(_) = ref_value; + if let &TupleStruct(Some(_)) = ref_value {} + if let TupleStruct(Some(_)) = *ref_value {} + + // ok + let &TupleStruct(_) = ref_value; + let TupleStruct(_) = *ref_value; + if let &TupleStruct(&Some(_)) = ref_value {} + if let TupleStruct(&Some(_)) = *ref_value {} +} + +fn tuple_enum_variants() { + enum TupleEnum<'a> { + Empty, + Var(&'a Option), + } + let ref_value = &TupleEnum::Var(&Some(42)); + + // not ok + if let TupleEnum::Var(_) = ref_value {} + if let &TupleEnum::Var(Some(_)) = ref_value {} + if let TupleEnum::Var(Some(_)) = *ref_value {} + if let TupleEnum::Empty = ref_value {} + + // ok + if let &TupleEnum::Var(_) = ref_value {} + if let TupleEnum::Var(_) = *ref_value {} + if let &TupleEnum::Var(&Some(_)) = ref_value {} + if let TupleEnum::Var(&Some(_)) = *ref_value {} + if let &TupleEnum::Empty = ref_value {} + if let TupleEnum::Empty = *ref_value {} +} + +fn plain_tuples() { + let ref_value = &(&Some(23), &Some(42)); + + // not ok + let (_a, _b) = ref_value; + if let &(_a, Some(_)) = ref_value {} + if let (_a, Some(_)) = *ref_value {} + + // ok + let &(_a, _b) = ref_value; + let (_a, _b) = *ref_value; + if let &(_a, &Some(_)) = ref_value {} + if let (_a, &Some(_)) = *ref_value {} +} diff --git a/tests/ui/pattern_type_mismatch/pattern_tuples.stderr b/tests/ui/pattern_type_mismatch/pattern_tuples.stderr new file mode 100644 index 0000000000000..edd0074d00d3b --- /dev/null +++ b/tests/ui/pattern_type_mismatch/pattern_tuples.stderr @@ -0,0 +1,83 @@ +error: type of pattern does not match the expression type + --> $DIR/pattern_tuples.rs:11:9 + | +LL | let TupleStruct(_) = ref_value; + | ^^^^^^^^^^^^^^ + | + = note: `-D clippy::pattern-type-mismatch` implied by `-D warnings` + = help: use `*` to dereference the match expression or explicitly match against a `&_` pattern and adjust the enclosed variable bindings + +error: type of pattern does not match the expression type + --> $DIR/pattern_tuples.rs:12:25 + | +LL | if let &TupleStruct(Some(_)) = ref_value {} + | ^^^^^^^ + | + = help: explicitly match against a `&_` pattern and adjust the enclosed variable bindings + +error: type of pattern does not match the expression type + --> $DIR/pattern_tuples.rs:13:24 + | +LL | if let TupleStruct(Some(_)) = *ref_value {} + | ^^^^^^^ + | + = help: explicitly match against a `&_` pattern and adjust the enclosed variable bindings + +error: type of pattern does not match the expression type + --> $DIR/pattern_tuples.rs:30:12 + | +LL | if let TupleEnum::Var(_) = ref_value {} + | ^^^^^^^^^^^^^^^^^ + | + = help: use `*` to dereference the match expression or explicitly match against a `&_` pattern and adjust the enclosed variable bindings + +error: type of pattern does not match the expression type + --> $DIR/pattern_tuples.rs:31:28 + | +LL | if let &TupleEnum::Var(Some(_)) = ref_value {} + | ^^^^^^^ + | + = help: explicitly match against a `&_` pattern and adjust the enclosed variable bindings + +error: type of pattern does not match the expression type + --> $DIR/pattern_tuples.rs:32:27 + | +LL | if let TupleEnum::Var(Some(_)) = *ref_value {} + | ^^^^^^^ + | + = help: explicitly match against a `&_` pattern and adjust the enclosed variable bindings + +error: type of pattern does not match the expression type + --> $DIR/pattern_tuples.rs:33:12 + | +LL | if let TupleEnum::Empty = ref_value {} + | ^^^^^^^^^^^^^^^^ + | + = help: use `*` to dereference the match expression or explicitly match against a `&_` pattern and adjust the enclosed variable bindings + +error: type of pattern does not match the expression type + --> $DIR/pattern_tuples.rs:48:9 + | +LL | let (_a, _b) = ref_value; + | ^^^^^^^^ + | + = help: use `*` to dereference the match expression or explicitly match against a `&_` pattern and adjust the enclosed variable bindings + +error: type of pattern does not match the expression type + --> $DIR/pattern_tuples.rs:49:18 + | +LL | if let &(_a, Some(_)) = ref_value {} + | ^^^^^^^ + | + = help: explicitly match against a `&_` pattern and adjust the enclosed variable bindings + +error: type of pattern does not match the expression type + --> $DIR/pattern_tuples.rs:50:17 + | +LL | if let (_a, Some(_)) = *ref_value {} + | ^^^^^^^ + | + = help: explicitly match against a `&_` pattern and adjust the enclosed variable bindings + +error: aborting due to 10 previous errors + diff --git a/tests/ui/pattern_type_mismatch/syntax.rs b/tests/ui/pattern_type_mismatch/syntax.rs new file mode 100644 index 0000000000000..e89917c41e8c1 --- /dev/null +++ b/tests/ui/pattern_type_mismatch/syntax.rs @@ -0,0 +1,146 @@ +#![allow(clippy::all)] +#![warn(clippy::pattern_type_mismatch)] + +fn main() {} + +fn syntax_match() { + let ref_value = &Some(&Some(42)); + + // not ok + match ref_value { + Some(_) => (), + None => (), + } + + // ok + match ref_value { + &Some(_) => (), + &None => (), + } + match *ref_value { + Some(_) => (), + None => (), + } +} + +fn syntax_if_let() { + let ref_value = &Some(42); + + // not ok + if let Some(_) = ref_value {} + + // ok + if let &Some(_) = ref_value {} + if let Some(_) = *ref_value {} +} + +fn syntax_while_let() { + let ref_value = &Some(42); + + // not ok + while let Some(_) = ref_value { + break; + } + + // ok + while let &Some(_) = ref_value { + break; + } + while let Some(_) = *ref_value { + break; + } +} + +fn syntax_for() { + let ref_value = &Some(23); + let slice = &[(2, 3), (4, 2)]; + + // not ok + for (_a, _b) in slice.iter() {} + + // ok + for &(_a, _b) in slice.iter() {} +} + +fn syntax_let() { + let ref_value = &(2, 3); + + // not ok + let (_n, _m) = ref_value; + + // ok + let &(_n, _m) = ref_value; + let (_n, _m) = *ref_value; +} + +fn syntax_fn() { + // not ok + fn foo((_a, _b): &(i32, i32)) {} + + // ok + fn foo_ok_1(&(_a, _b): &(i32, i32)) {} +} + +fn syntax_closure() { + fn foo(f: F) + where + F: FnOnce(&(i32, i32)), + { + } + + // not ok + foo(|(_a, _b)| ()); + + // ok + foo(|&(_a, _b)| ()); +} + +fn macro_with_expression() { + macro_rules! matching_macro { + ($e:expr) => { + $e + }; + } + let value = &Some(23); + + // not ok + matching_macro!(match value { + Some(_) => (), + _ => (), + }); + + // ok + matching_macro!(match value { + &Some(_) => (), + _ => (), + }); + matching_macro!(match *value { + Some(_) => (), + _ => (), + }); +} + +fn macro_expansion() { + macro_rules! matching_macro { + ($e:expr) => { + // not ok + match $e { + Some(_) => (), + _ => (), + } + + // ok + match $e { + &Some(_) => (), + _ => (), + } + match *$e { + Some(_) => (), + _ => (), + } + }; + } + + let value = &Some(23); + matching_macro!(value); +} diff --git a/tests/ui/pattern_type_mismatch/syntax.stderr b/tests/ui/pattern_type_mismatch/syntax.stderr new file mode 100644 index 0000000000000..110e8421a5e27 --- /dev/null +++ b/tests/ui/pattern_type_mismatch/syntax.stderr @@ -0,0 +1,78 @@ +error: type of pattern does not match the expression type + --> $DIR/syntax.rs:11:9 + | +LL | Some(_) => (), + | ^^^^^^^ + | + = note: `-D clippy::pattern-type-mismatch` implied by `-D warnings` + = help: use `*` to dereference the match expression or explicitly match against a `&_` pattern and adjust the enclosed variable bindings + +error: type of pattern does not match the expression type + --> $DIR/syntax.rs:30:12 + | +LL | if let Some(_) = ref_value {} + | ^^^^^^^ + | + = help: use `*` to dereference the match expression or explicitly match against a `&_` pattern and adjust the enclosed variable bindings + +error: type of pattern does not match the expression type + --> $DIR/syntax.rs:41:15 + | +LL | while let Some(_) = ref_value { + | ^^^^^^^ + | + = help: use `*` to dereference the match expression or explicitly match against a `&_` pattern and adjust the enclosed variable bindings + +error: type of pattern does not match the expression type + --> $DIR/syntax.rs:59:9 + | +LL | for (_a, _b) in slice.iter() {} + | ^^^^^^^^ + | + = help: explicitly match against a `&_` pattern and adjust the enclosed variable bindings + +error: type of pattern does not match the expression type + --> $DIR/syntax.rs:69:9 + | +LL | let (_n, _m) = ref_value; + | ^^^^^^^^ + | + = help: use `*` to dereference the match expression or explicitly match against a `&_` pattern and adjust the enclosed variable bindings + +error: type of pattern does not match the expression type + --> $DIR/syntax.rs:78:12 + | +LL | fn foo((_a, _b): &(i32, i32)) {} + | ^^^^^^^^ + | + = help: explicitly match against a `&_` pattern and adjust the enclosed variable bindings + +error: type of pattern does not match the expression type + --> $DIR/syntax.rs:92:10 + | +LL | foo(|(_a, _b)| ()); + | ^^^^^^^^ + | + = help: explicitly match against a `&_` pattern and adjust the enclosed variable bindings + +error: type of pattern does not match the expression type + --> $DIR/syntax.rs:108:9 + | +LL | Some(_) => (), + | ^^^^^^^ + | + = help: use `*` to dereference the match expression or explicitly match against a `&_` pattern and adjust the enclosed variable bindings + +error: type of pattern does not match the expression type + --> $DIR/syntax.rs:128:17 + | +LL | Some(_) => (), + | ^^^^^^^ +... +LL | matching_macro!(value); + | ----------------------- in this macro invocation + | + = help: use `*` to dereference the match expression or explicitly match against a `&_` pattern and adjust the enclosed variable bindings + +error: aborting due to 9 previous errors + From 55877d7b4a6a2c713412db7b30ef79b2a252956e Mon Sep 17 00:00:00 2001 From: Robert Sedlacek Date: Sun, 9 Feb 2020 17:57:35 +0100 Subject: [PATCH 27/99] span_help_and_lint -> span_lint_and_help --- clippy_lints/src/pattern_type_mismatch.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clippy_lints/src/pattern_type_mismatch.rs b/clippy_lints/src/pattern_type_mismatch.rs index a07279c92b001..d3f65db1916e7 100644 --- a/clippy_lints/src/pattern_type_mismatch.rs +++ b/clippy_lints/src/pattern_type_mismatch.rs @@ -1,4 +1,4 @@ -use crate::utils::{last_path_segment, span_help_and_lint}; +use crate::utils::{last_path_segment, span_lint_and_help}; use rustc::lint::in_external_macro; use rustc::ty::subst::SubstsRef; use rustc::ty::{AdtDef, FieldDef, Ty, TyKind, VariantDef}; @@ -115,7 +115,7 @@ fn apply_lint<'a, 'tcx>( ) -> bool { let maybe_mismatch = find_first_mismatch(cx, pat, expr_ty, Level::Top); if let Some((span, mutability, level)) = maybe_mismatch { - span_help_and_lint( + span_lint_and_help( cx, PATTERN_TYPE_MISMATCH, span, From 346ee968bbe8925aa7961a3e2c99e7ef84c74623 Mon Sep 17 00:00:00 2001 From: Robert Sedlacek Date: Mon, 10 Feb 2020 22:19:19 +0100 Subject: [PATCH 28/99] Adjusted expected STDERR --- tests/ui/pattern_type_mismatch/syntax.stderr | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/ui/pattern_type_mismatch/syntax.stderr b/tests/ui/pattern_type_mismatch/syntax.stderr index 110e8421a5e27..5a5186bd4fcb3 100644 --- a/tests/ui/pattern_type_mismatch/syntax.stderr +++ b/tests/ui/pattern_type_mismatch/syntax.stderr @@ -73,6 +73,7 @@ LL | matching_macro!(value); | ----------------------- in this macro invocation | = help: use `*` to dereference the match expression or explicitly match against a `&_` pattern and adjust the enclosed variable bindings + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 9 previous errors From 6447507ab150ebd1787ca6af385db49dfdf45978 Mon Sep 17 00:00:00 2001 From: flip1995 Date: Mon, 8 Jun 2020 15:10:57 +0200 Subject: [PATCH 29/99] Fix rebase fallout --- clippy_lints/src/lib.rs | 2 +- clippy_lints/src/pattern_type_mismatch.rs | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index 4890349999fa0..3d8ce10aef398 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -268,7 +268,7 @@ mod overflow_check_conditional; mod panic_unimplemented; mod partialeq_ne_impl; mod path_buf_push_overwrite; -pub mod pattern_type_mismatch; +mod pattern_type_mismatch; mod precedence; mod ptr; mod ptr_offset_with_cast; diff --git a/clippy_lints/src/pattern_type_mismatch.rs b/clippy_lints/src/pattern_type_mismatch.rs index d3f65db1916e7..a6079a8b5bcfd 100644 --- a/clippy_lints/src/pattern_type_mismatch.rs +++ b/clippy_lints/src/pattern_type_mismatch.rs @@ -1,12 +1,12 @@ use crate::utils::{last_path_segment, span_lint_and_help}; -use rustc::lint::in_external_macro; -use rustc::ty::subst::SubstsRef; -use rustc::ty::{AdtDef, FieldDef, Ty, TyKind, VariantDef}; use rustc_hir::{ intravisit, Body, Expr, ExprKind, FieldPat, FnDecl, HirId, LocalSource, MatchSource, Mutability, Pat, PatKind, QPath, Stmt, StmtKind, }; use rustc_lint::{LateContext, LateLintPass, LintContext}; +use rustc_middle::lint::in_external_macro; +use rustc_middle::ty::subst::SubstsRef; +use rustc_middle::ty::{AdtDef, FieldDef, Ty, TyKind, VariantDef}; use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::source_map::Span; @@ -120,6 +120,7 @@ fn apply_lint<'a, 'tcx>( PATTERN_TYPE_MISMATCH, span, "type of pattern does not match the expression type", + None, &format!( "{}explicitly match against a `{}` pattern and adjust the enclosed variable bindings", match (deref_possible, level) { From 92ecc53691f3edd67526dca423a2b4083d12a221 Mon Sep 17 00:00:00 2001 From: Robert Sedlacek Date: Wed, 1 Jul 2020 15:49:06 +0200 Subject: [PATCH 30/99] Catching up with rustc changes --- clippy_lints/src/pattern_type_mismatch.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/clippy_lints/src/pattern_type_mismatch.rs b/clippy_lints/src/pattern_type_mismatch.rs index a6079a8b5bcfd..fcc9b16068fb9 100644 --- a/clippy_lints/src/pattern_type_mismatch.rs +++ b/clippy_lints/src/pattern_type_mismatch.rs @@ -48,7 +48,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for PatternTypeMismatch { fn check_stmt(&mut self, cx: &LateContext<'a, 'tcx>, stmt: &'tcx Stmt<'_>) { if let StmtKind::Local(ref local) = stmt.kind { if let Some(init) = &local.init { - if let Some(init_ty) = cx.tables.node_type_opt(init.hir_id) { + if let Some(init_ty) = cx.tables().node_type_opt(init.hir_id) { let pat = &local.pat; if in_external_macro(cx.sess(), pat.span) { return; @@ -67,7 +67,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for PatternTypeMismatch { if let ExprKind::Match(ref expr, arms, source) = expr.kind { match source { MatchSource::Normal | MatchSource::IfLetDesugar { .. } | MatchSource::WhileLetDesugar => { - if let Some(expr_ty) = cx.tables.node_type_opt(expr.hir_id) { + if let Some(expr_ty) = cx.tables().node_type_opt(expr.hir_id) { 'pattern_checks: for arm in arms { let pat = &arm.pat; if in_external_macro(cx.sess(), pat.span) { @@ -93,7 +93,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for PatternTypeMismatch { _: Span, hir_id: HirId, ) { - if let Some(fn_sig) = cx.tables.liberated_fn_sigs().get(hir_id) { + if let Some(fn_sig) = cx.tables().liberated_fn_sigs().get(hir_id) { for (param, ty) in body.params.iter().zip(fn_sig.inputs().iter()) { apply_lint(cx, ¶m.pat, ty, DerefPossible::Impossible); } From d617551a6a3830a5324898f2046b97aad8c6067a Mon Sep 17 00:00:00 2001 From: Robert Sedlacek Date: Wed, 1 Jul 2020 15:49:46 +0200 Subject: [PATCH 31/99] Expanded lint documentation --- clippy_lints/src/pattern_type_mismatch.rs | 39 +++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/clippy_lints/src/pattern_type_mismatch.rs b/clippy_lints/src/pattern_type_mismatch.rs index fcc9b16068fb9..9fa5860ba300d 100644 --- a/clippy_lints/src/pattern_type_mismatch.rs +++ b/clippy_lints/src/pattern_type_mismatch.rs @@ -14,6 +14,22 @@ declare_clippy_lint! { /// **What it does:** Checks for patterns that aren't exact representations of the types /// they are applied to. /// + /// To satisfy this lint, you will have to adjust either the expression that is matched + /// against or the pattern itself, as well as the bindings that are introduced by the + /// adjusted patterns. For matching you will have to either dereference the expression + /// with the `*` operator, or amend the patterns to explicitly match against `&` + /// or `&mut ` depending on the reference mutability. For the bindings you need + /// to use the inverse. You can leave them as plain bindings if you wish for the value + /// to be copied, but you must use `ref mut ` or `ref ` to construct + /// a reference into the matched structure. + /// + /// If you are looking for a way to learn about ownership semantics in more detail, it + /// is recommended to look at IDE options available to you to highlight types, lifetimes + /// and reference semantics in your code. The available tooling would expose these things + /// in a general way even outside of the various pattern matching mechanics. Of course + /// this lint can still be used to highlight areas of interest and ensure a good understanding + /// of ownership semantics. + /// /// **Why is this bad?** It isn't bad in general. But in some contexts it can be desirable /// because it increases ownership hints in the code, and will guard against some changes /// in ownership. @@ -22,6 +38,10 @@ declare_clippy_lint! { /// /// **Example:** /// + /// This example shows the basic adjustments necessary to satisfy the lint. Note how + /// the matched expression is explicitly dereferenced with `*` and the `inner` variable + /// is bound to a shared borrow via `ref inner`. + /// /// ```rust,ignore /// // Bad /// let value = &Some(Box::new(23)); @@ -37,6 +57,25 @@ declare_clippy_lint! { /// None => println!("none"), /// } /// ``` + /// + /// The following example demonstrates one of the advantages of the more verbose style. + /// Note how the second version uses `ref mut a` to explicitly declare `a` a shared mutable + /// borrow, while `b` is simply taken by value. This ensures that the loop body cannot + /// accidentally modify the wrong part of the structure. + /// + /// ```rust,ignore + /// // Bad + /// let mut values = vec![(2, 3), (3, 4)]; + /// for (a, b) in &mut values { + /// *a += *b; + /// } + /// + /// // Good + /// let mut values = vec![(2, 3), (3, 4)]; + /// for &mut (ref mut a, b) in &mut values { + /// *a += b; + /// } + /// ``` pub PATTERN_TYPE_MISMATCH, restriction, "type of pattern does not match the expression type" From aa4bee228f23b3e1a1d91ed3a4606af3c6b60895 Mon Sep 17 00:00:00 2001 From: Robert Sedlacek Date: Fri, 3 Jul 2020 18:20:19 +0200 Subject: [PATCH 32/99] LateContext has only one lifetime parameter now --- clippy_lints/src/pattern_type_mismatch.rs | 24 +++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/clippy_lints/src/pattern_type_mismatch.rs b/clippy_lints/src/pattern_type_mismatch.rs index 9fa5860ba300d..8587a79e8217e 100644 --- a/clippy_lints/src/pattern_type_mismatch.rs +++ b/clippy_lints/src/pattern_type_mismatch.rs @@ -83,8 +83,8 @@ declare_clippy_lint! { declare_lint_pass!(PatternTypeMismatch => [PATTERN_TYPE_MISMATCH]); -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for PatternTypeMismatch { - fn check_stmt(&mut self, cx: &LateContext<'a, 'tcx>, stmt: &'tcx Stmt<'_>) { +impl<'tcx> LateLintPass<'tcx> for PatternTypeMismatch { + fn check_stmt(&mut self, cx: &LateContext<'tcx>, stmt: &'tcx Stmt<'_>) { if let StmtKind::Local(ref local) = stmt.kind { if let Some(init) = &local.init { if let Some(init_ty) = cx.tables().node_type_opt(init.hir_id) { @@ -102,7 +102,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for PatternTypeMismatch { } } - fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) { + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { if let ExprKind::Match(ref expr, arms, source) = expr.kind { match source { MatchSource::Normal | MatchSource::IfLetDesugar { .. } | MatchSource::WhileLetDesugar => { @@ -125,7 +125,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for PatternTypeMismatch { fn check_fn( &mut self, - cx: &LateContext<'a, 'tcx>, + cx: &LateContext<'tcx>, _: intravisit::FnKind<'tcx>, _: &'tcx FnDecl<'_>, body: &'tcx Body<'_>, @@ -146,8 +146,8 @@ enum DerefPossible { Impossible, } -fn apply_lint<'a, 'tcx>( - cx: &LateContext<'a, 'tcx>, +fn apply_lint<'tcx>( + cx: &LateContext<'tcx>, pat: &Pat<'_>, expr_ty: Ty<'tcx>, deref_possible: DerefPossible, @@ -185,8 +185,8 @@ enum Level { } #[allow(rustc::usage_of_ty_tykind)] -fn find_first_mismatch<'a, 'tcx>( - cx: &LateContext<'a, 'tcx>, +fn find_first_mismatch<'tcx>( + cx: &LateContext<'tcx>, pat: &Pat<'_>, ty: Ty<'tcx>, level: Level, @@ -259,8 +259,8 @@ fn get_variant<'a>(adt_def: &'a AdtDef, qpath: &QPath<'_>) -> Option<&'a Variant None } -fn find_first_mismatch_in_tuple<'a, 'tcx, I>( - cx: &LateContext<'a, 'tcx>, +fn find_first_mismatch_in_tuple<'tcx, I>( + cx: &LateContext<'tcx>, pats: &[&Pat<'_>], ty_iter_src: I, ) -> Option<(Span, Mutability, Level)> @@ -284,8 +284,8 @@ where None } -fn find_first_mismatch_in_struct<'a, 'tcx>( - cx: &LateContext<'a, 'tcx>, +fn find_first_mismatch_in_struct<'tcx>( + cx: &LateContext<'tcx>, field_pats: &[FieldPat<'_>], field_defs: &[FieldDef], substs_ref: SubstsRef<'tcx>, From c0fd452840c7cc53b3396268f62ed2a0a2e8fef7 Mon Sep 17 00:00:00 2001 From: Robert Sedlacek Date: Fri, 3 Jul 2020 18:23:36 +0200 Subject: [PATCH 33/99] fmt fix --- clippy_lints/src/pattern_type_mismatch.rs | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/clippy_lints/src/pattern_type_mismatch.rs b/clippy_lints/src/pattern_type_mismatch.rs index 8587a79e8217e..a49dc87c0b47f 100644 --- a/clippy_lints/src/pattern_type_mismatch.rs +++ b/clippy_lints/src/pattern_type_mismatch.rs @@ -146,12 +146,7 @@ enum DerefPossible { Impossible, } -fn apply_lint<'tcx>( - cx: &LateContext<'tcx>, - pat: &Pat<'_>, - expr_ty: Ty<'tcx>, - deref_possible: DerefPossible, -) -> bool { +fn apply_lint<'tcx>(cx: &LateContext<'tcx>, pat: &Pat<'_>, expr_ty: Ty<'tcx>, deref_possible: DerefPossible) -> bool { let maybe_mismatch = find_first_mismatch(cx, pat, expr_ty, Level::Top); if let Some((span, mutability, level)) = maybe_mismatch { span_lint_and_help( From bf48a2d50d82cccac58d7c4c73700eaf66926aee Mon Sep 17 00:00:00 2001 From: JarredAllen Date: Thu, 5 Mar 2020 10:35:05 -0800 Subject: [PATCH 34/99] Lint for if let Some(x) = ... instead of Option::map_or --- CHANGELOG.md | 1 + clippy_lints/src/lib.rs | 5 + clippy_lints/src/option_if_let_else.rs | 202 +++++++++++++++++++++++++ src/lintlist/mod.rs | 7 + tests/ui/option_if_let_else.fixed | 48 ++++++ tests/ui/option_if_let_else.rs | 56 +++++++ tests/ui/option_if_let_else.stderr | 62 ++++++++ 7 files changed, 381 insertions(+) create mode 100644 clippy_lints/src/option_if_let_else.rs create mode 100644 tests/ui/option_if_let_else.fixed create mode 100644 tests/ui/option_if_let_else.rs create mode 100644 tests/ui/option_if_let_else.stderr diff --git a/CHANGELOG.md b/CHANGELOG.md index ed8f16e65bb9a..1a081bb85feab 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1577,6 +1577,7 @@ Released 2018-09-13 [`op_ref`]: https://rust-lang.github.io/rust-clippy/master/index.html#op_ref [`option_as_ref_deref`]: https://rust-lang.github.io/rust-clippy/master/index.html#option_as_ref_deref [`option_env_unwrap`]: https://rust-lang.github.io/rust-clippy/master/index.html#option_env_unwrap +[`option_if_let_else`]: https://rust-lang.github.io/rust-clippy/master/index.html#option_if_let_else [`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_option`]: https://rust-lang.github.io/rust-clippy/master/index.html#option_option diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index 1d5be893ffba2..cd91e7ceb32a8 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -264,6 +264,7 @@ mod non_copy_const; mod non_expressive_names; mod open_options; mod option_env_unwrap; +mod option_if_let_else; mod overflow_check_conditional; mod panic_unimplemented; mod partialeq_ne_impl; @@ -734,6 +735,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: &non_expressive_names::SIMILAR_NAMES, &open_options::NONSENSICAL_OPEN_OPTIONS, &option_env_unwrap::OPTION_ENV_UNWRAP, + &option_if_let_else::OPTION_IF_LET_ELSE, &overflow_check_conditional::OVERFLOW_CHECK_CONDITIONAL, &panic_unimplemented::PANIC, &panic_unimplemented::PANIC_PARAMS, @@ -1052,6 +1054,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: store.register_late_pass(|| box redundant_pub_crate::RedundantPubCrate::default()); store.register_late_pass(|| box unnamed_address::UnnamedAddress); store.register_late_pass(|| box dereference::Dereferencing); + store.register_late_pass(|| box option_if_let_else::OptionIfLetElse); store.register_late_pass(|| box future_not_send::FutureNotSend); store.register_late_pass(|| box utils::internal_lints::CollapsibleCalls); store.register_late_pass(|| box if_let_mutex::IfLetMutex); @@ -1369,6 +1372,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: LintId::of(&non_expressive_names::MANY_SINGLE_CHAR_NAMES), LintId::of(&open_options::NONSENSICAL_OPEN_OPTIONS), LintId::of(&option_env_unwrap::OPTION_ENV_UNWRAP), + LintId::of(&option_if_let_else::OPTION_IF_LET_ELSE), LintId::of(&overflow_check_conditional::OVERFLOW_CHECK_CONDITIONAL), LintId::of(&panic_unimplemented::PANIC_PARAMS), LintId::of(&partialeq_ne_impl::PARTIALEQ_NE_IMPL), @@ -1517,6 +1521,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: LintId::of(&new_without_default::NEW_WITHOUT_DEFAULT), LintId::of(&non_expressive_names::JUST_UNDERSCORES_AND_DIGITS), LintId::of(&non_expressive_names::MANY_SINGLE_CHAR_NAMES), + LintId::of(&option_if_let_else::OPTION_IF_LET_ELSE), LintId::of(&panic_unimplemented::PANIC_PARAMS), LintId::of(&ptr::CMP_NULL), LintId::of(&ptr::PTR_ARG), diff --git a/clippy_lints/src/option_if_let_else.rs b/clippy_lints/src/option_if_let_else.rs new file mode 100644 index 0000000000000..f092f1297c1bb --- /dev/null +++ b/clippy_lints/src/option_if_let_else.rs @@ -0,0 +1,202 @@ +use crate::utils::sugg::Sugg; +use crate::utils::{match_type, paths, span_lint_and_sugg}; +use if_chain::if_chain; + +use rustc_errors::Applicability; +use rustc_hir::intravisit::{NestedVisitorMap, Visitor}; +use rustc_hir::*; +use rustc_lint::{LateContext, LateLintPass}; +use rustc_middle::hir::map::Map; +use rustc_session::{declare_lint_pass, declare_tool_lint}; + +use std::marker::PhantomData; + +declare_clippy_lint! { + /// **What it does:** + /// Lints usage of `if let Some(v) = ... { y } else { x }` which is more + /// idiomatically done with `Option::map_or` (if the else bit is a simple + /// expression) or `Option::map_or_else` (if the else bit is a longer + /// block). + /// + /// **Why is this bad?** + /// Using the dedicated functions of the Option type is clearer and + /// more concise than an if let expression. + /// + /// **Known problems:** + /// This lint uses whether the block is just an expression or if it has + /// more statements to decide whether to use `Option::map_or` or + /// `Option::map_or_else`. If you have a single expression which calls + /// an expensive function, then it would be more efficient to use + /// `Option::map_or_else`, but this lint would suggest `Option::map_or`. + /// + /// Also, this lint uses a deliberately conservative metric for checking + /// if the inside of either body contains breaks or continues which will + /// cause it to not suggest a fix if either block contains a loop with + /// continues or breaks contained within the loop. + /// + /// **Example:** + /// + /// ```rust + /// # let optional: Option = Some(0); + /// let _ = if let Some(foo) = optional { + /// foo + /// } else { + /// 5 + /// }; + /// let _ = if let Some(foo) = optional { + /// foo + /// } else { + /// let y = do_complicated_function(); + /// y*y + /// }; + /// ``` + /// + /// should be + /// + /// ```rust + /// # let optional: Option = Some(0); + /// let _ = optional.map_or(5, |foo| foo); + /// let _ = optional.map_or_else(||{ + /// let y = do_complicated_function; + /// y*y + /// }, |foo| foo); + /// ``` + pub OPTION_IF_LET_ELSE, + style, + "reimplementation of Option::map_or" +} + +declare_lint_pass!(OptionIfLetElse => [OPTION_IF_LET_ELSE]); + +/// Returns true iff the given expression is the result of calling Result::ok +fn is_result_ok(cx: &LateContext<'_, '_>, expr: &'_ Expr<'_>) -> bool { + if_chain! { + if let ExprKind::MethodCall(ref path, _, &[ref receiver]) = &expr.kind; + if path.ident.name.to_ident_string() == "ok"; + if match_type(cx, &cx.tables.expr_ty(&receiver), &paths::RESULT); + then { + true + } else { + false + } + } +} + +/// A struct containing information about occurences of the +/// `if let Some(..) = .. else` construct that this lint detects. +struct OptionIfLetElseOccurence { + option: String, + method_sugg: String, + some_expr: String, + none_expr: String, +} + +struct ReturnBreakContinueVisitor<'tcx> { + seen_return_break_continue: bool, + phantom_data: PhantomData<&'tcx bool>, +} +impl<'tcx> ReturnBreakContinueVisitor<'tcx> { + fn new() -> ReturnBreakContinueVisitor<'tcx> { + ReturnBreakContinueVisitor { + seen_return_break_continue: false, + phantom_data: PhantomData, + } + } +} +impl<'tcx> Visitor<'tcx> for ReturnBreakContinueVisitor<'tcx> { + type Map = Map<'tcx>; + fn nested_visit_map(&mut self) -> NestedVisitorMap { + NestedVisitorMap::None + } + + fn visit_expr(&mut self, ex: &'tcx Expr<'tcx>) { + if self.seen_return_break_continue { + // No need to look farther if we've already seen one of them + return; + } + match &ex.kind { + ExprKind::Ret(..) | ExprKind::Break(..) | ExprKind::Continue(..) => { + self.seen_return_break_continue = true; + }, + // Something special could be done here to handle while or for loop + // desugaring, as this will detect a break if there's a while loop + // or a for loop inside the expression. + _ => { + rustc_hir::intravisit::walk_expr(self, ex); + }, + } + } +} + +fn contains_return_break_continue<'tcx>(expression: &'tcx Expr<'tcx>) -> bool { + let mut recursive_visitor: ReturnBreakContinueVisitor<'tcx> = ReturnBreakContinueVisitor::new(); + recursive_visitor.visit_expr(expression); + recursive_visitor.seen_return_break_continue +} + +/// If this expression is the option if let/else construct we're detecting, then +/// this function returns an OptionIfLetElseOccurence struct with details if +/// this construct is found, or None if this construct is not found. +fn detect_option_if_let_else<'a>(cx: &LateContext<'_, 'a>, expr: &'a Expr<'a>) -> Option { + //(String, String, String, String)> { + if_chain! { + if let ExprKind::Match(let_body, arms, MatchSource::IfLetDesugar{contains_else_clause: true}) = &expr.kind; + if arms.len() == 2; + if match_type(cx, &cx.tables.expr_ty(let_body), &paths::OPTION); + if !is_result_ok(cx, let_body); // Don't lint on Result::ok because a different lint does it already + if let PatKind::TupleStruct(_, &[inner_pat], _) = &arms[0].pat.kind; + if let PatKind::Binding(_, _, id, _) = &inner_pat.kind; + if !contains_return_break_continue(arms[0].body); + if !contains_return_break_continue(arms[1].body); + then { + let some_body = if let ExprKind::Block(Block { stmts: statements, expr: Some(expr), .. }, _) + = &arms[0].body.kind { + if let &[] = &statements { + expr + } else { + &arms[0].body + } + } else { + return None; + }; + let (none_body, method_sugg) = if let ExprKind::Block(Block { stmts: statements, expr: Some(expr), .. }, _) + = &arms[1].body.kind { + if let &[] = &statements { + (expr, "map_or") + } else { + (&arms[1].body, "map_or_else") + } + } else { + return None; + }; + let capture_name = id.name.to_ident_string(); + Some(OptionIfLetElseOccurence { + option: format!("{}", Sugg::hir(cx, let_body, "..")), + method_sugg: format!("{}", method_sugg), + some_expr: format!("|{}| {}", capture_name, Sugg::hir(cx, some_body, "..")), + none_expr: format!("{}{}", if method_sugg == "map_or" { "" } else { "|| " }, Sugg::hir(cx, none_body, "..")) + }) + } else { + None + } + } +} + +impl<'a, 'tcx> LateLintPass<'a, 'tcx> for OptionIfLetElse { + fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) { + if let Some(detection) = detect_option_if_let_else(cx, expr) { + span_lint_and_sugg( + cx, + OPTION_IF_LET_ELSE, + expr.span, + format!("use Option::{} instead of an if let/else", detection.method_sugg).as_str(), + "try", + format!( + "{}.{}({}, {})", + detection.option, detection.method_sugg, detection.none_expr, detection.some_expr + ), + Applicability::MachineApplicable, + ); + } + } +} diff --git a/src/lintlist/mod.rs b/src/lintlist/mod.rs index 6402efc252121..b499d565fa7f9 100644 --- a/src/lintlist/mod.rs +++ b/src/lintlist/mod.rs @@ -1620,6 +1620,13 @@ pub static ref ALL_LINTS: Vec = vec![ deprecation: None, module: "option_env_unwrap", }, + Lint { + name: "option_if_let_else", + group: "style", + desc: "reimplementation of Option::map_or", + deprecation: None, + module: "option_if_let_else", + }, Lint { name: "option_map_or_none", group: "style", diff --git a/tests/ui/option_if_let_else.fixed b/tests/ui/option_if_let_else.fixed new file mode 100644 index 0000000000000..3aa895120d196 --- /dev/null +++ b/tests/ui/option_if_let_else.fixed @@ -0,0 +1,48 @@ +// run-rustfix +#![warn(clippy::option_if_let_else)] + +fn bad1(string: Option<&str>) -> (bool, &str) { + string.map_or((false, "hello"), |x| (true, x)) +} + +fn longer_body(arg: Option) -> u32 { + arg.map_or(13, |x| { + let y = x * x; + y * y + }) +} + +fn test_map_or_else(arg: Option) { + let _ = arg.map_or_else(|| { + let mut y = 1; + y = (y + 2 / y) / 2; + y = (y + 2 / y) / 2; + y + }, |x| x * x * x * x); +} + +fn negative_tests(arg: Option) -> u32 { + let _ = if let Some(13) = arg { "unlucky" } else { "lucky" }; + for _ in 0..10 { + let _ = if let Some(x) = arg { + x + } else { + continue; + }; + } + let _ = if let Some(x) = arg { + return x; + } else { + 5 + }; + 7 +} + +fn main() { + let optional = Some(5); + let _ = optional.map_or(5, |x| x + 2); + let _ = bad1(None); + let _ = longer_body(None); + test_map_or_else(None); + let _ = negative_tests(None); +} diff --git a/tests/ui/option_if_let_else.rs b/tests/ui/option_if_let_else.rs new file mode 100644 index 0000000000000..7d029b0bcf48c --- /dev/null +++ b/tests/ui/option_if_let_else.rs @@ -0,0 +1,56 @@ +// run-rustfix +#![warn(clippy::option_if_let_else)] + +fn bad1(string: Option<&str>) -> (bool, &str) { + if let Some(x) = string { + (true, x) + } else { + (false, "hello") + } +} + +fn longer_body(arg: Option) -> u32 { + if let Some(x) = arg { + let y = x * x; + y * y + } else { + 13 + } +} + +fn test_map_or_else(arg: Option) { + let _ = if let Some(x) = arg { + x * x * x * x + } else { + let mut y = 1; + y = (y + 2 / y) / 2; + y = (y + 2 / y) / 2; + y + }; +} + +fn negative_tests(arg: Option) -> u32 { + let _ = if let Some(13) = arg { "unlucky" } else { "lucky" }; + for _ in 0..10 { + let _ = if let Some(x) = arg { + x + } else { + continue; + }; + } + let _ = if let Some(x) = arg { + return x; + } else { + 5 + }; + 7 +} + +fn main() { + let optional = Some(5); + let _ = if let Some(x) = optional { x + 2 } else { 5 }; + let _ = bad1(None); + let _ = longer_body(None); + test_map_or_else(None); + let _ = negative_tests(None); +} diff --git a/tests/ui/option_if_let_else.stderr b/tests/ui/option_if_let_else.stderr new file mode 100644 index 0000000000000..d6cf083673341 --- /dev/null +++ b/tests/ui/option_if_let_else.stderr @@ -0,0 +1,62 @@ +error: use Option::map_or instead of an if let/else + --> $DIR/option_if_let_else.rs:5:5 + | +LL | / if let Some(x) = string { +LL | | (true, x) +LL | | } else { +LL | | (false, "hello") +LL | | } + | |_____^ help: try: `string.map_or((false, "hello"), |x| (true, x))` + | + = note: `-D clippy::option-if-let-else` implied by `-D warnings` + +error: use Option::map_or instead of an if let/else + --> $DIR/option_if_let_else.rs:13:5 + | +LL | / if let Some(x) = arg { +LL | | let y = x * x; +LL | | y * y +LL | | } else { +LL | | 13 +LL | | } + | |_____^ + | +help: try + | +LL | arg.map_or(13, |x| { +LL | let y = x * x; +LL | y * y +LL | }) + | + +error: use Option::map_or_else instead of an if let/else + --> $DIR/option_if_let_else.rs:22:13 + | +LL | let _ = if let Some(x) = arg { + | _____________^ +LL | | x * x * x * x +LL | | } else { +LL | | let mut y = 1; +... | +LL | | y +LL | | }; + | |_____^ + | +help: try + | +LL | let _ = arg.map_or_else(|| { +LL | let mut y = 1; +LL | y = (y + 2 / y) / 2; +LL | y = (y + 2 / y) / 2; +LL | y +LL | }, |x| x * x * x * x); + | + +error: use Option::map_or instead of an if let/else + --> $DIR/option_if_let_else.rs:51:13 + | +LL | let _ = if let Some(x) = optional { x + 2 } else { 5 }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `optional.map_or(5, |x| x + 2)` + +error: aborting due to 4 previous errors + From 82f8d4d6f1645dd08b107c3ead9155412637739b Mon Sep 17 00:00:00 2001 From: JarredAllen Date: Sat, 25 Apr 2020 08:32:33 -0700 Subject: [PATCH 35/99] Stop linting on macros and correctly use braces for constructs --- clippy_lints/src/option_if_let_else.rs | 23 ++++++++++++++++++++--- tests/ui/option_if_let_else.fixed | 7 +++++++ tests/ui/option_if_let_else.rs | 11 +++++++++++ tests/ui/option_if_let_else.stderr | 19 +++++++++++++++---- 4 files changed, 53 insertions(+), 7 deletions(-) diff --git a/clippy_lints/src/option_if_let_else.rs b/clippy_lints/src/option_if_let_else.rs index f092f1297c1bb..1edec1cad6ec6 100644 --- a/clippy_lints/src/option_if_let_else.rs +++ b/clippy_lints/src/option_if_let_else.rs @@ -1,3 +1,4 @@ +use crate::utils; use crate::utils::sugg::Sugg; use crate::utils::{match_type, paths, span_lint_and_sugg}; use if_chain::if_chain; @@ -89,6 +90,7 @@ struct OptionIfLetElseOccurence { method_sugg: String, some_expr: String, none_expr: String, + wrap_braces: bool, } struct ReturnBreakContinueVisitor<'tcx> { @@ -140,6 +142,7 @@ fn contains_return_break_continue<'tcx>(expression: &'tcx Expr<'tcx>) -> bool { fn detect_option_if_let_else<'a>(cx: &LateContext<'_, 'a>, expr: &'a Expr<'a>) -> Option { //(String, String, String, String)> { if_chain! { + // if !utils::in_macro(expr.span); // Don't lint macros, because it behaves weirdly if let ExprKind::Match(let_body, arms, MatchSource::IfLetDesugar{contains_else_clause: true}) = &expr.kind; if arms.len() == 2; if match_type(cx, &cx.tables.expr_ty(let_body), &paths::OPTION); @@ -170,11 +173,23 @@ fn detect_option_if_let_else<'a>(cx: &LateContext<'_, 'a>, expr: &'a Expr<'a>) - return None; }; let capture_name = id.name.to_ident_string(); + let wrap_braces = utils::get_enclosing_block(cx, expr.hir_id).map_or(false, |parent| { + if_chain! { + if let Some(Expr { kind: ExprKind::Match(condition, arms, MatchSource::IfDesugar{contains_else_clause: true}|MatchSource::IfLetDesugar{contains_else_clause: true}), .. } ) = parent.expr; + if expr.hir_id == arms[1].body.hir_id; + then { + true + } else { + false + } + } + }); Some(OptionIfLetElseOccurence { option: format!("{}", Sugg::hir(cx, let_body, "..")), method_sugg: format!("{}", method_sugg), some_expr: format!("|{}| {}", capture_name, Sugg::hir(cx, some_body, "..")), - none_expr: format!("{}{}", if method_sugg == "map_or" { "" } else { "|| " }, Sugg::hir(cx, none_body, "..")) + none_expr: format!("{}{}", if method_sugg == "map_or" { "" } else { "|| " }, Sugg::hir(cx, none_body, "..")), + wrap_braces, }) } else { None @@ -192,8 +207,10 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for OptionIfLetElse { format!("use Option::{} instead of an if let/else", detection.method_sugg).as_str(), "try", format!( - "{}.{}({}, {})", - detection.option, detection.method_sugg, detection.none_expr, detection.some_expr + "{}{}.{}({}, {}){}", + if detection.wrap_braces { "{ " } else { "" }, + detection.option, detection.method_sugg, detection.none_expr, detection.some_expr, + if detection.wrap_braces { " }" } else { "" }, ), Applicability::MachineApplicable, ); diff --git a/tests/ui/option_if_let_else.fixed b/tests/ui/option_if_let_else.fixed index 3aa895120d196..343e099b2b77d 100644 --- a/tests/ui/option_if_let_else.fixed +++ b/tests/ui/option_if_let_else.fixed @@ -5,6 +5,12 @@ fn bad1(string: Option<&str>) -> (bool, &str) { string.map_or((false, "hello"), |x| (true, x)) } +fn bad2(string: Option<&str>) -> Option<(bool, &str)> { + if string.is_none() { + None + } else { string.map_or(Some((false, "")), |x| Some((true, x))) } +} + fn longer_body(arg: Option) -> u32 { arg.map_or(13, |x| { let y = x * x; @@ -42,6 +48,7 @@ fn main() { let optional = Some(5); let _ = optional.map_or(5, |x| x + 2); let _ = bad1(None); + let _ = bad2(None); let _ = longer_body(None); test_map_or_else(None); let _ = negative_tests(None); diff --git a/tests/ui/option_if_let_else.rs b/tests/ui/option_if_let_else.rs index 7d029b0bcf48c..b0c203f06375c 100644 --- a/tests/ui/option_if_let_else.rs +++ b/tests/ui/option_if_let_else.rs @@ -9,6 +9,16 @@ fn bad1(string: Option<&str>) -> (bool, &str) { } } +fn bad2(string: Option<&str>) -> Option<(bool, &str)> { + if string.is_none() { + None + } else if let Some(x) = string { + Some((true, x)) + } else { + Some((false, "")) + } +} + fn longer_body(arg: Option) -> u32 { if let Some(x) = arg { let y = x * x; @@ -50,6 +60,7 @@ fn main() { let optional = Some(5); let _ = if let Some(x) = optional { x + 2 } else { 5 }; let _ = bad1(None); + let _ = bad2(None); let _ = longer_body(None); test_map_or_else(None); let _ = negative_tests(None); diff --git a/tests/ui/option_if_let_else.stderr b/tests/ui/option_if_let_else.stderr index d6cf083673341..656cfb2f62ace 100644 --- a/tests/ui/option_if_let_else.stderr +++ b/tests/ui/option_if_let_else.stderr @@ -11,7 +11,18 @@ LL | | } = note: `-D clippy::option-if-let-else` implied by `-D warnings` error: use Option::map_or instead of an if let/else - --> $DIR/option_if_let_else.rs:13:5 + --> $DIR/option_if_let_else.rs:15:12 + | +LL | } else if let Some(x) = string { + | ____________^ +LL | | Some((true, x)) +LL | | } else { +LL | | Some((false, "")) +LL | | } + | |_____^ help: try: `{ string.map_or(Some((false, "")), |x| Some((true, x))) }` + +error: use Option::map_or instead of an if let/else + --> $DIR/option_if_let_else.rs:23:5 | LL | / if let Some(x) = arg { LL | | let y = x * x; @@ -30,7 +41,7 @@ LL | }) | error: use Option::map_or_else instead of an if let/else - --> $DIR/option_if_let_else.rs:22:13 + --> $DIR/option_if_let_else.rs:32:13 | LL | let _ = if let Some(x) = arg { | _____________^ @@ -53,10 +64,10 @@ LL | }, |x| x * x * x * x); | error: use Option::map_or instead of an if let/else - --> $DIR/option_if_let_else.rs:51:13 + --> $DIR/option_if_let_else.rs:61:13 | LL | let _ = if let Some(x) = optional { x + 2 } else { 5 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `optional.map_or(5, |x| x + 2)` -error: aborting due to 4 previous errors +error: aborting due to 5 previous errors From b85796fe3613e20a4af21933783a3d993bb8d7ad Mon Sep 17 00:00:00 2001 From: JarredAllen Date: Sat, 25 Apr 2020 09:08:23 -0700 Subject: [PATCH 36/99] Properly parenthesize to avoid operator precedence errors --- clippy_lints/src/option_if_let_else.rs | 25 ++++++++++++++++++++++--- tests/ui/option_if_let_else.fixed | 9 +++++++-- tests/ui/option_if_let_else.rs | 13 +++++++++++-- tests/ui/option_if_let_else.stderr | 16 +++++++++++++--- 4 files changed, 53 insertions(+), 10 deletions(-) diff --git a/clippy_lints/src/option_if_let_else.rs b/clippy_lints/src/option_if_let_else.rs index 1edec1cad6ec6..66971ee02620d 100644 --- a/clippy_lints/src/option_if_let_else.rs +++ b/clippy_lints/src/option_if_let_else.rs @@ -175,7 +175,12 @@ fn detect_option_if_let_else<'a>(cx: &LateContext<'_, 'a>, expr: &'a Expr<'a>) - let capture_name = id.name.to_ident_string(); let wrap_braces = utils::get_enclosing_block(cx, expr.hir_id).map_or(false, |parent| { if_chain! { - if let Some(Expr { kind: ExprKind::Match(condition, arms, MatchSource::IfDesugar{contains_else_clause: true}|MatchSource::IfLetDesugar{contains_else_clause: true}), .. } ) = parent.expr; + if let Some(Expr { kind: ExprKind::Match( + _, + arms, + MatchSource::IfDesugar{contains_else_clause: true} + | MatchSource::IfLetDesugar{contains_else_clause: true}), + .. } ) = parent.expr; if expr.hir_id == arms[1].body.hir_id; then { true @@ -184,8 +189,19 @@ fn detect_option_if_let_else<'a>(cx: &LateContext<'_, 'a>, expr: &'a Expr<'a>) - } } }); + let parens_around_option = match &let_body.kind { + ExprKind::Call(..) + | ExprKind::MethodCall(..) + | ExprKind::Loop(..) + | ExprKind::Match(..) + | ExprKind::Block(..) + | ExprKind::Field(..) + | ExprKind::Path(_) + => false, + _ => true, + }; Some(OptionIfLetElseOccurence { - option: format!("{}", Sugg::hir(cx, let_body, "..")), + option: format!("{}{}{}", if parens_around_option { "(" } else { "" }, Sugg::hir(cx, let_body, ".."), if parens_around_option { ")" } else { "" }), method_sugg: format!("{}", method_sugg), some_expr: format!("|{}| {}", capture_name, Sugg::hir(cx, some_body, "..")), none_expr: format!("{}{}", if method_sugg == "map_or" { "" } else { "|| " }, Sugg::hir(cx, none_body, "..")), @@ -209,7 +225,10 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for OptionIfLetElse { format!( "{}{}.{}({}, {}){}", if detection.wrap_braces { "{ " } else { "" }, - detection.option, detection.method_sugg, detection.none_expr, detection.some_expr, + detection.option, + detection.method_sugg, + detection.none_expr, + detection.some_expr, if detection.wrap_braces { " }" } else { "" }, ), Applicability::MachineApplicable, diff --git a/tests/ui/option_if_let_else.fixed b/tests/ui/option_if_let_else.fixed index 343e099b2b77d..80b162714acaa 100644 --- a/tests/ui/option_if_let_else.fixed +++ b/tests/ui/option_if_let_else.fixed @@ -5,12 +5,16 @@ fn bad1(string: Option<&str>) -> (bool, &str) { string.map_or((false, "hello"), |x| (true, x)) } -fn bad2(string: Option<&str>) -> Option<(bool, &str)> { +fn else_if_option(string: Option<&str>) -> Option<(bool, &str)> { if string.is_none() { None } else { string.map_or(Some((false, "")), |x| Some((true, x))) } } +fn unop_bad(string: &Option<&str>) -> usize { + (*string).map_or(0, |s| s.len()) +} + fn longer_body(arg: Option) -> u32 { arg.map_or(13, |x| { let y = x * x; @@ -48,7 +52,8 @@ fn main() { let optional = Some(5); let _ = optional.map_or(5, |x| x + 2); let _ = bad1(None); - let _ = bad2(None); + let _ = else_if_option(None); + let _ = unop_bad(&None); let _ = longer_body(None); test_map_or_else(None); let _ = negative_tests(None); diff --git a/tests/ui/option_if_let_else.rs b/tests/ui/option_if_let_else.rs index b0c203f06375c..7c43fbea373f3 100644 --- a/tests/ui/option_if_let_else.rs +++ b/tests/ui/option_if_let_else.rs @@ -9,7 +9,7 @@ fn bad1(string: Option<&str>) -> (bool, &str) { } } -fn bad2(string: Option<&str>) -> Option<(bool, &str)> { +fn else_if_option(string: Option<&str>) -> Option<(bool, &str)> { if string.is_none() { None } else if let Some(x) = string { @@ -19,6 +19,14 @@ fn bad2(string: Option<&str>) -> Option<(bool, &str)> { } } +fn unop_bad(string: &Option<&str>) -> usize { + if let Some(s) = *string { + s.len() + } else { + 0 + } +} + fn longer_body(arg: Option) -> u32 { if let Some(x) = arg { let y = x * x; @@ -60,7 +68,8 @@ fn main() { let optional = Some(5); let _ = if let Some(x) = optional { x + 2 } else { 5 }; let _ = bad1(None); - let _ = bad2(None); + let _ = else_if_option(None); + let _ = unop_bad(&None); let _ = longer_body(None); test_map_or_else(None); let _ = negative_tests(None); diff --git a/tests/ui/option_if_let_else.stderr b/tests/ui/option_if_let_else.stderr index 656cfb2f62ace..b932fe5975900 100644 --- a/tests/ui/option_if_let_else.stderr +++ b/tests/ui/option_if_let_else.stderr @@ -24,6 +24,16 @@ LL | | } error: use Option::map_or instead of an if let/else --> $DIR/option_if_let_else.rs:23:5 | +LL | / if let Some(s) = *string { +LL | | s.len() +LL | | } else { +LL | | 0 +LL | | } + | |_____^ help: try: `(*string).map_or(0, |s| s.len())` + +error: use Option::map_or instead of an if let/else + --> $DIR/option_if_let_else.rs:31:5 + | LL | / if let Some(x) = arg { LL | | let y = x * x; LL | | y * y @@ -41,7 +51,7 @@ LL | }) | error: use Option::map_or_else instead of an if let/else - --> $DIR/option_if_let_else.rs:32:13 + --> $DIR/option_if_let_else.rs:40:13 | LL | let _ = if let Some(x) = arg { | _____________^ @@ -64,10 +74,10 @@ LL | }, |x| x * x * x * x); | error: use Option::map_or instead of an if let/else - --> $DIR/option_if_let_else.rs:61:13 + --> $DIR/option_if_let_else.rs:69:13 | LL | let _ = if let Some(x) = optional { x + 2 } else { 5 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `optional.map_or(5, |x| x + 2)` -error: aborting due to 5 previous errors +error: aborting due to 6 previous errors From 88c8afdddff07adeff4c87431cbe8bc630a36d68 Mon Sep 17 00:00:00 2001 From: JarredAllen Date: Sat, 9 May 2020 20:20:57 -0700 Subject: [PATCH 37/99] Handle ref, mut, &, and &mut on the option --- clippy_lints/src/option_if_let_else.rs | 28 +++++--- tests/ui/option_if_let_else.fixed | 20 +++++- tests/ui/option_if_let_else.rs | 36 ++++++++-- tests/ui/option_if_let_else.stderr | 99 +++++++++++++++++++++++--- 4 files changed, 158 insertions(+), 25 deletions(-) diff --git a/clippy_lints/src/option_if_let_else.rs b/clippy_lints/src/option_if_let_else.rs index 66971ee02620d..4e501f4ca02ac 100644 --- a/clippy_lints/src/option_if_let_else.rs +++ b/clippy_lints/src/option_if_let_else.rs @@ -140,18 +140,24 @@ fn contains_return_break_continue<'tcx>(expression: &'tcx Expr<'tcx>) -> bool { /// this function returns an OptionIfLetElseOccurence struct with details if /// this construct is found, or None if this construct is not found. fn detect_option_if_let_else<'a>(cx: &LateContext<'_, 'a>, expr: &'a Expr<'a>) -> Option { - //(String, String, String, String)> { if_chain! { - // if !utils::in_macro(expr.span); // Don't lint macros, because it behaves weirdly + if !utils::in_macro(expr.span); // Don't lint macros, because it behaves weirdly if let ExprKind::Match(let_body, arms, MatchSource::IfLetDesugar{contains_else_clause: true}) = &expr.kind; if arms.len() == 2; - if match_type(cx, &cx.tables.expr_ty(let_body), &paths::OPTION); + // if type_is_option(cx, &cx.tables.expr_ty(let_body).kind); if !is_result_ok(cx, let_body); // Don't lint on Result::ok because a different lint does it already - if let PatKind::TupleStruct(_, &[inner_pat], _) = &arms[0].pat.kind; - if let PatKind::Binding(_, _, id, _) = &inner_pat.kind; + if let PatKind::TupleStruct(struct_qpath, &[inner_pat], _) = &arms[0].pat.kind; + if utils::match_qpath(struct_qpath, &paths::OPTION_SOME); + if let PatKind::Binding(bind_annotation, _, id, _) = &inner_pat.kind; if !contains_return_break_continue(arms[0].body); if !contains_return_break_continue(arms[1].body); then { + let (capture_mut, capture_ref, capture_ref_mut) = match bind_annotation { + BindingAnnotation::Unannotated => (false, false, false), + BindingAnnotation::Mutable => (true, false, false), + BindingAnnotation::Ref => (false, true, false), + BindingAnnotation::RefMut => (false, false, true), + }; let some_body = if let ExprKind::Block(Block { stmts: statements, expr: Some(expr), .. }, _) = &arms[0].body.kind { if let &[] = &statements { @@ -189,7 +195,7 @@ fn detect_option_if_let_else<'a>(cx: &LateContext<'_, 'a>, expr: &'a Expr<'a>) - } } }); - let parens_around_option = match &let_body.kind { + let (parens_around_option, as_ref, as_mut, let_body) = match &let_body.kind { ExprKind::Call(..) | ExprKind::MethodCall(..) | ExprKind::Loop(..) @@ -197,13 +203,15 @@ fn detect_option_if_let_else<'a>(cx: &LateContext<'_, 'a>, expr: &'a Expr<'a>) - | ExprKind::Block(..) | ExprKind::Field(..) | ExprKind::Path(_) - => false, - _ => true, + => (false, capture_ref, capture_ref_mut, let_body), + ExprKind::Unary(UnOp::UnDeref, expr) => (false, capture_ref, capture_ref_mut, expr), + ExprKind::AddrOf(_, mutability, expr) => (false, mutability == &Mutability::Not, mutability == &Mutability::Mut, expr), + _ => (true, capture_ref, capture_ref_mut, let_body), }; Some(OptionIfLetElseOccurence { - option: format!("{}{}{}", if parens_around_option { "(" } else { "" }, Sugg::hir(cx, let_body, ".."), if parens_around_option { ")" } else { "" }), + option: format!("{}{}{}{}", if parens_around_option { "(" } else { "" }, Sugg::hir(cx, let_body, ".."), if parens_around_option { ")" } else { "" }, if as_mut { ".as_mut()" } else if as_ref { ".as_ref()" } else { "" }), method_sugg: format!("{}", method_sugg), - some_expr: format!("|{}| {}", capture_name, Sugg::hir(cx, some_body, "..")), + some_expr: format!("|{}{}{}| {}", if false { "ref " } else { "" }, if capture_mut { "mut " } else { "" }, capture_name, Sugg::hir(cx, some_body, "..")), none_expr: format!("{}{}", if method_sugg == "map_or" { "" } else { "|| " }, Sugg::hir(cx, none_body, "..")), wrap_braces, }) diff --git a/tests/ui/option_if_let_else.fixed b/tests/ui/option_if_let_else.fixed index 80b162714acaa..695a460cc4edf 100644 --- a/tests/ui/option_if_let_else.fixed +++ b/tests/ui/option_if_let_else.fixed @@ -11,8 +11,22 @@ fn else_if_option(string: Option<&str>) -> Option<(bool, &str)> { } else { string.map_or(Some((false, "")), |x| Some((true, x))) } } -fn unop_bad(string: &Option<&str>) -> usize { - (*string).map_or(0, |s| s.len()) +fn unop_bad(string: &Option<&str>, mut num: Option) { + let _ = string.map_or(0, |s| s.len()); + let _ = num.as_ref().map_or(&0, |s| s); + let _ = num.as_mut().map_or(&mut 0, |s| { + *s += 1; + s + }); + let _ = num.as_ref().map_or(&0, |s| s); + let _ = num.map_or(0, |mut s| { + s += 1; + s + }); + let _ = num.as_mut().map_or(&mut 0, |s| { + *s += 1; + s + }); } fn longer_body(arg: Option) -> u32 { @@ -53,7 +67,7 @@ fn main() { let _ = optional.map_or(5, |x| x + 2); let _ = bad1(None); let _ = else_if_option(None); - let _ = unop_bad(&None); + unop_bad(&None, None); let _ = longer_body(None); test_map_or_else(None); let _ = negative_tests(None); diff --git a/tests/ui/option_if_let_else.rs b/tests/ui/option_if_let_else.rs index 7c43fbea373f3..6f9d506d3470b 100644 --- a/tests/ui/option_if_let_else.rs +++ b/tests/ui/option_if_let_else.rs @@ -19,12 +19,40 @@ fn else_if_option(string: Option<&str>) -> Option<(bool, &str)> { } } -fn unop_bad(string: &Option<&str>) -> usize { - if let Some(s) = *string { +fn unop_bad(string: &Option<&str>, mut num: Option) { + let _ = if let Some(s) = *string { s.len() } else { 0 - } + }; + let _ = if let Some(s) = &num { + s + } else { + &0 + }; + let _ = if let Some(s) = &mut num { + *s += 1; + s + } else { + &mut 0 + }; + let _ = if let Some(ref s) = num { + s + } else { + &0 + }; + let _ = if let Some(mut s) = num { + s += 1; + s + } else { + 0 + }; + let _ = if let Some(ref mut s) = num { + *s += 1; + s + } else { + &mut 0 + }; } fn longer_body(arg: Option) -> u32 { @@ -69,7 +97,7 @@ fn main() { let _ = if let Some(x) = optional { x + 2 } else { 5 }; let _ = bad1(None); let _ = else_if_option(None); - let _ = unop_bad(&None); + unop_bad(&None, None); let _ = longer_body(None); test_map_or_else(None); let _ = negative_tests(None); diff --git a/tests/ui/option_if_let_else.stderr b/tests/ui/option_if_let_else.stderr index b932fe5975900..9240d3edb27e9 100644 --- a/tests/ui/option_if_let_else.stderr +++ b/tests/ui/option_if_let_else.stderr @@ -22,17 +22,100 @@ LL | | } | |_____^ help: try: `{ string.map_or(Some((false, "")), |x| Some((true, x))) }` error: use Option::map_or instead of an if let/else - --> $DIR/option_if_let_else.rs:23:5 + --> $DIR/option_if_let_else.rs:23:13 | -LL | / if let Some(s) = *string { +LL | let _ = if let Some(s) = *string { + | _____________^ LL | | s.len() LL | | } else { LL | | 0 -LL | | } - | |_____^ help: try: `(*string).map_or(0, |s| s.len())` +LL | | }; + | |_____^ help: try: `string.map_or(0, |s| s.len())` + +error: use Option::map_or instead of an if let/else + --> $DIR/option_if_let_else.rs:28:13 + | +LL | let _ = if let Some(s) = &num { + | _____________^ +LL | | s +LL | | } else { +LL | | &0 +LL | | }; + | |_____^ help: try: `num.as_ref().map_or(&0, |s| s)` + +error: use Option::map_or instead of an if let/else + --> $DIR/option_if_let_else.rs:33:13 + | +LL | let _ = if let Some(s) = &mut num { + | _____________^ +LL | | *s += 1; +LL | | s +LL | | } else { +LL | | &mut 0 +LL | | }; + | |_____^ + | +help: try + | +LL | let _ = num.as_mut().map_or(&mut 0, |s| { +LL | *s += 1; +LL | s +LL | }); + | + +error: use Option::map_or instead of an if let/else + --> $DIR/option_if_let_else.rs:39:13 + | +LL | let _ = if let Some(ref s) = num { + | _____________^ +LL | | s +LL | | } else { +LL | | &0 +LL | | }; + | |_____^ help: try: `num.as_ref().map_or(&0, |s| s)` + +error: use Option::map_or instead of an if let/else + --> $DIR/option_if_let_else.rs:44:13 + | +LL | let _ = if let Some(mut s) = num { + | _____________^ +LL | | s += 1; +LL | | s +LL | | } else { +LL | | 0 +LL | | }; + | |_____^ + | +help: try + | +LL | let _ = num.map_or(0, |mut s| { +LL | s += 1; +LL | s +LL | }); + | + +error: use Option::map_or instead of an if let/else + --> $DIR/option_if_let_else.rs:50:13 + | +LL | let _ = if let Some(ref mut s) = num { + | _____________^ +LL | | *s += 1; +LL | | s +LL | | } else { +LL | | &mut 0 +LL | | }; + | |_____^ + | +help: try + | +LL | let _ = num.as_mut().map_or(&mut 0, |s| { +LL | *s += 1; +LL | s +LL | }); + | error: use Option::map_or instead of an if let/else - --> $DIR/option_if_let_else.rs:31:5 + --> $DIR/option_if_let_else.rs:59:5 | LL | / if let Some(x) = arg { LL | | let y = x * x; @@ -51,7 +134,7 @@ LL | }) | error: use Option::map_or_else instead of an if let/else - --> $DIR/option_if_let_else.rs:40:13 + --> $DIR/option_if_let_else.rs:68:13 | LL | let _ = if let Some(x) = arg { | _____________^ @@ -74,10 +157,10 @@ LL | }, |x| x * x * x * x); | error: use Option::map_or instead of an if let/else - --> $DIR/option_if_let_else.rs:69:13 + --> $DIR/option_if_let_else.rs:97:13 | LL | let _ = if let Some(x) = optional { x + 2 } else { 5 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `optional.map_or(5, |x| x + 2)` -error: aborting due to 6 previous errors +error: aborting due to 11 previous errors From f73b455b99694fbc5ddec38317f705f546729db2 Mon Sep 17 00:00:00 2001 From: JarredAllen Date: Sat, 9 May 2020 20:44:56 -0700 Subject: [PATCH 38/99] Refactoring --- clippy_lints/src/option_if_let_else.rs | 170 +++++++++++++++---------- tests/ui/option_if_let_else.rs | 18 +-- tests/ui/option_if_let_else.stderr | 43 ++----- 3 files changed, 123 insertions(+), 108 deletions(-) diff --git a/clippy_lints/src/option_if_let_else.rs b/clippy_lints/src/option_if_let_else.rs index 4e501f4ca02ac..208aa550765a4 100644 --- a/clippy_lints/src/option_if_let_else.rs +++ b/clippy_lints/src/option_if_let_else.rs @@ -5,7 +5,7 @@ use if_chain::if_chain; use rustc_errors::Applicability; use rustc_hir::intravisit::{NestedVisitorMap, Visitor}; -use rustc_hir::*; +use rustc_hir::{Arm, BindingAnnotation, Block, Expr, ExprKind, MatchSource, Mutability, PatKind, UnOp}; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::hir::map::Map; use rustc_session::{declare_lint_pass, declare_tool_lint}; @@ -69,17 +69,12 @@ declare_clippy_lint! { declare_lint_pass!(OptionIfLetElse => [OPTION_IF_LET_ELSE]); -/// Returns true iff the given expression is the result of calling Result::ok +/// Returns true iff the given expression is the result of calling `Result::ok` fn is_result_ok(cx: &LateContext<'_, '_>, expr: &'_ Expr<'_>) -> bool { - if_chain! { - if let ExprKind::MethodCall(ref path, _, &[ref receiver]) = &expr.kind; - if path.ident.name.to_ident_string() == "ok"; - if match_type(cx, &cx.tables.expr_ty(&receiver), &paths::RESULT); - then { - true - } else { - false - } + if let ExprKind::MethodCall(ref path, _, &[ref receiver]) = &expr.kind { + path.ident.name.to_ident_string() == "ok" && match_type(cx, &cx.tables.expr_ty(&receiver), &paths::RESULT) + } else { + false } } @@ -136,66 +131,108 @@ fn contains_return_break_continue<'tcx>(expression: &'tcx Expr<'tcx>) -> bool { recursive_visitor.seen_return_break_continue } +/// Extracts the body of a given arm. If the arm contains only an expression, +/// then it returns the expression. Otherwise, it returns the entire block +fn extract_body_from_arm<'a>(arm: &'a Arm<'a>) -> Option<&'a Expr<'a>> { + if let ExprKind::Block( + Block { + stmts: statements, + expr: Some(expr), + .. + }, + _, + ) = &arm.body.kind + { + if let [] = statements { + Some(&expr) + } else { + Some(&arm.body) + } + } else { + None + } +} + +/// If this is the else body of an if/else expression, then we need to wrap +/// it in curcly braces. Otherwise, we don't. +fn should_wrap_in_braces(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> bool { + utils::get_enclosing_block(cx, expr.hir_id).map_or(false, |parent| { + if let Some(Expr { + kind: + ExprKind::Match( + _, + arms, + MatchSource::IfDesugar { + contains_else_clause: true, + } + | MatchSource::IfLetDesugar { + contains_else_clause: true, + }, + ), + .. + }) = parent.expr + { + expr.hir_id == arms[1].body.hir_id + } else { + false + } + }) +} + +fn format_option_in_sugg( + cx: &LateContext<'_, '_>, + cond_expr: &Expr<'_>, + parens_around_option: bool, + as_ref: bool, + as_mut: bool, +) -> String { + format!( + "{}{}{}{}", + if parens_around_option { "(" } else { "" }, + Sugg::hir(cx, cond_expr, ".."), + if parens_around_option { ")" } else { "" }, + if as_mut { + ".as_mut()" + } else if as_ref { + ".as_ref()" + } else { + "" + } + ) +} + /// If this expression is the option if let/else construct we're detecting, then -/// this function returns an OptionIfLetElseOccurence struct with details if +/// this function returns an `OptionIfLetElseOccurence` struct with details if /// this construct is found, or None if this construct is not found. fn detect_option_if_let_else<'a>(cx: &LateContext<'_, 'a>, expr: &'a Expr<'a>) -> Option { if_chain! { if !utils::in_macro(expr.span); // Don't lint macros, because it behaves weirdly - if let ExprKind::Match(let_body, arms, MatchSource::IfLetDesugar{contains_else_clause: true}) = &expr.kind; + if let ExprKind::Match(cond_expr, arms, MatchSource::IfLetDesugar{contains_else_clause: true}) = &expr.kind; if arms.len() == 2; - // if type_is_option(cx, &cx.tables.expr_ty(let_body).kind); - if !is_result_ok(cx, let_body); // Don't lint on Result::ok because a different lint does it already + if !is_result_ok(cx, cond_expr); // Don't lint on Result::ok because a different lint does it already if let PatKind::TupleStruct(struct_qpath, &[inner_pat], _) = &arms[0].pat.kind; if utils::match_qpath(struct_qpath, &paths::OPTION_SOME); if let PatKind::Binding(bind_annotation, _, id, _) = &inner_pat.kind; if !contains_return_break_continue(arms[0].body); if !contains_return_break_continue(arms[1].body); then { - let (capture_mut, capture_ref, capture_ref_mut) = match bind_annotation { - BindingAnnotation::Unannotated => (false, false, false), - BindingAnnotation::Mutable => (true, false, false), - BindingAnnotation::Ref => (false, true, false), - BindingAnnotation::RefMut => (false, false, true), - }; - let some_body = if let ExprKind::Block(Block { stmts: statements, expr: Some(expr), .. }, _) - = &arms[0].body.kind { - if let &[] = &statements { - expr - } else { - &arms[0].body - } - } else { - return None; - }; - let (none_body, method_sugg) = if let ExprKind::Block(Block { stmts: statements, expr: Some(expr), .. }, _) - = &arms[1].body.kind { - if let &[] = &statements { - (expr, "map_or") - } else { - (&arms[1].body, "map_or_else") - } - } else { - return None; + let capture_mut = if bind_annotation == &BindingAnnotation::Mutable { "mut " } else { "" }; + let some_body = extract_body_from_arm(&arms[0])?; + let none_body = extract_body_from_arm(&arms[1])?; + let method_sugg = match &none_body.kind { + ExprKind::Block(..) => "map_or_else", + _ => "map_or", }; let capture_name = id.name.to_ident_string(); - let wrap_braces = utils::get_enclosing_block(cx, expr.hir_id).map_or(false, |parent| { - if_chain! { - if let Some(Expr { kind: ExprKind::Match( - _, - arms, - MatchSource::IfDesugar{contains_else_clause: true} - | MatchSource::IfLetDesugar{contains_else_clause: true}), - .. } ) = parent.expr; - if expr.hir_id == arms[1].body.hir_id; - then { - true - } else { - false - } - } - }); - let (parens_around_option, as_ref, as_mut, let_body) = match &let_body.kind { + let wrap_braces = should_wrap_in_braces(cx, expr); + let (as_ref, as_mut) = match &cond_expr.kind { + ExprKind::AddrOf(_, Mutability::Not, _) => (true, false), + ExprKind::AddrOf(_, Mutability::Mut, _) => (false, true), + _ => (bind_annotation == &BindingAnnotation::Ref, bind_annotation == &BindingAnnotation::RefMut), + }; + let parens_around_option = match &cond_expr.kind { + // Put parens around the option expression if not doing so might + // mess up the order of operations. ExprKind::Call(..) | ExprKind::MethodCall(..) | ExprKind::Loop(..) @@ -203,15 +240,20 @@ fn detect_option_if_let_else<'a>(cx: &LateContext<'_, 'a>, expr: &'a Expr<'a>) - | ExprKind::Block(..) | ExprKind::Field(..) | ExprKind::Path(_) - => (false, capture_ref, capture_ref_mut, let_body), - ExprKind::Unary(UnOp::UnDeref, expr) => (false, capture_ref, capture_ref_mut, expr), - ExprKind::AddrOf(_, mutability, expr) => (false, mutability == &Mutability::Not, mutability == &Mutability::Mut, expr), - _ => (true, capture_ref, capture_ref_mut, let_body), + | ExprKind::Unary(UnOp::UnDeref, _) + | ExprKind::AddrOf(..) + => false, + _ => true, + }; + let cond_expr = match &cond_expr.kind { + // Pointer dereferencing happens automatically, so we can omit it in the suggestion + ExprKind::Unary(UnOp::UnDeref, expr)|ExprKind::AddrOf(_, _, expr) => expr, + _ => cond_expr, }; Some(OptionIfLetElseOccurence { - option: format!("{}{}{}{}", if parens_around_option { "(" } else { "" }, Sugg::hir(cx, let_body, ".."), if parens_around_option { ")" } else { "" }, if as_mut { ".as_mut()" } else if as_ref { ".as_ref()" } else { "" }), - method_sugg: format!("{}", method_sugg), - some_expr: format!("|{}{}{}| {}", if false { "ref " } else { "" }, if capture_mut { "mut " } else { "" }, capture_name, Sugg::hir(cx, some_body, "..")), + option: format_option_in_sugg(cx, cond_expr, parens_around_option, as_ref, as_mut), + method_sugg: method_sugg.to_string(), + some_expr: format!("|{}{}| {}", capture_mut, capture_name, Sugg::hir(cx, some_body, "..")), none_expr: format!("{}{}", if method_sugg == "map_or" { "" } else { "|| " }, Sugg::hir(cx, none_body, "..")), wrap_braces, }) diff --git a/tests/ui/option_if_let_else.rs b/tests/ui/option_if_let_else.rs index 6f9d506d3470b..dee80d26bd976 100644 --- a/tests/ui/option_if_let_else.rs +++ b/tests/ui/option_if_let_else.rs @@ -20,27 +20,15 @@ fn else_if_option(string: Option<&str>) -> Option<(bool, &str)> { } fn unop_bad(string: &Option<&str>, mut num: Option) { - let _ = if let Some(s) = *string { - s.len() - } else { - 0 - }; - let _ = if let Some(s) = &num { - s - } else { - &0 - }; + let _ = if let Some(s) = *string { s.len() } else { 0 }; + let _ = if let Some(s) = &num { s } else { &0 }; let _ = if let Some(s) = &mut num { *s += 1; s } else { &mut 0 }; - let _ = if let Some(ref s) = num { - s - } else { - &0 - }; + let _ = if let Some(ref s) = num { s } else { &0 }; let _ = if let Some(mut s) = num { s += 1; s diff --git a/tests/ui/option_if_let_else.stderr b/tests/ui/option_if_let_else.stderr index 9240d3edb27e9..7005850efaf83 100644 --- a/tests/ui/option_if_let_else.stderr +++ b/tests/ui/option_if_let_else.stderr @@ -24,27 +24,17 @@ LL | | } error: use Option::map_or instead of an if let/else --> $DIR/option_if_let_else.rs:23:13 | -LL | let _ = if let Some(s) = *string { - | _____________^ -LL | | s.len() -LL | | } else { -LL | | 0 -LL | | }; - | |_____^ help: try: `string.map_or(0, |s| s.len())` +LL | let _ = if let Some(s) = *string { s.len() } else { 0 }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `string.map_or(0, |s| s.len())` error: use Option::map_or instead of an if let/else - --> $DIR/option_if_let_else.rs:28:13 + --> $DIR/option_if_let_else.rs:24:13 | -LL | let _ = if let Some(s) = &num { - | _____________^ -LL | | s -LL | | } else { -LL | | &0 -LL | | }; - | |_____^ help: try: `num.as_ref().map_or(&0, |s| s)` +LL | let _ = if let Some(s) = &num { s } else { &0 }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `num.as_ref().map_or(&0, |s| s)` error: use Option::map_or instead of an if let/else - --> $DIR/option_if_let_else.rs:33:13 + --> $DIR/option_if_let_else.rs:25:13 | LL | let _ = if let Some(s) = &mut num { | _____________^ @@ -64,18 +54,13 @@ LL | }); | error: use Option::map_or instead of an if let/else - --> $DIR/option_if_let_else.rs:39:13 + --> $DIR/option_if_let_else.rs:31:13 | -LL | let _ = if let Some(ref s) = num { - | _____________^ -LL | | s -LL | | } else { -LL | | &0 -LL | | }; - | |_____^ help: try: `num.as_ref().map_or(&0, |s| s)` +LL | let _ = if let Some(ref s) = num { s } else { &0 }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `num.as_ref().map_or(&0, |s| s)` error: use Option::map_or instead of an if let/else - --> $DIR/option_if_let_else.rs:44:13 + --> $DIR/option_if_let_else.rs:32:13 | LL | let _ = if let Some(mut s) = num { | _____________^ @@ -95,7 +80,7 @@ LL | }); | error: use Option::map_or instead of an if let/else - --> $DIR/option_if_let_else.rs:50:13 + --> $DIR/option_if_let_else.rs:38:13 | LL | let _ = if let Some(ref mut s) = num { | _____________^ @@ -115,7 +100,7 @@ LL | }); | error: use Option::map_or instead of an if let/else - --> $DIR/option_if_let_else.rs:59:5 + --> $DIR/option_if_let_else.rs:47:5 | LL | / if let Some(x) = arg { LL | | let y = x * x; @@ -134,7 +119,7 @@ LL | }) | error: use Option::map_or_else instead of an if let/else - --> $DIR/option_if_let_else.rs:68:13 + --> $DIR/option_if_let_else.rs:56:13 | LL | let _ = if let Some(x) = arg { | _____________^ @@ -157,7 +142,7 @@ LL | }, |x| x * x * x * x); | error: use Option::map_or instead of an if let/else - --> $DIR/option_if_let_else.rs:97:13 + --> $DIR/option_if_let_else.rs:85:13 | LL | let _ = if let Some(x) = optional { x + 2 } else { 5 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `optional.map_or(5, |x| x + 2)` From 7c4de9d3dee3a7e16118df5c1cd2080af7350d98 Mon Sep 17 00:00:00 2001 From: JarredAllen Date: Mon, 11 May 2020 17:52:47 -0700 Subject: [PATCH 39/99] Refactoring pt. 2 --- clippy_lints/src/option_if_let_else.rs | 33 ++++---------------------- 1 file changed, 5 insertions(+), 28 deletions(-) diff --git a/clippy_lints/src/option_if_let_else.rs b/clippy_lints/src/option_if_let_else.rs index 208aa550765a4..6e8d7515671fb 100644 --- a/clippy_lints/src/option_if_let_else.rs +++ b/clippy_lints/src/option_if_let_else.rs @@ -179,18 +179,10 @@ fn should_wrap_in_braces(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> bool { }) } -fn format_option_in_sugg( - cx: &LateContext<'_, '_>, - cond_expr: &Expr<'_>, - parens_around_option: bool, - as_ref: bool, - as_mut: bool, -) -> String { +fn format_option_in_sugg(cx: &LateContext<'_, '_>, cond_expr: &Expr<'_>, as_ref: bool, as_mut: bool) -> String { format!( - "{}{}{}{}", - if parens_around_option { "(" } else { "" }, - Sugg::hir(cx, cond_expr, ".."), - if parens_around_option { ")" } else { "" }, + "{}{}", + Sugg::hir(cx, cond_expr, "..").maybe_par(), if as_mut { ".as_mut()" } else if as_ref { @@ -230,28 +222,13 @@ fn detect_option_if_let_else<'a>(cx: &LateContext<'_, 'a>, expr: &'a Expr<'a>) - ExprKind::AddrOf(_, Mutability::Mut, _) => (false, true), _ => (bind_annotation == &BindingAnnotation::Ref, bind_annotation == &BindingAnnotation::RefMut), }; - let parens_around_option = match &cond_expr.kind { - // Put parens around the option expression if not doing so might - // mess up the order of operations. - ExprKind::Call(..) - | ExprKind::MethodCall(..) - | ExprKind::Loop(..) - | ExprKind::Match(..) - | ExprKind::Block(..) - | ExprKind::Field(..) - | ExprKind::Path(_) - | ExprKind::Unary(UnOp::UnDeref, _) - | ExprKind::AddrOf(..) - => false, - _ => true, - }; let cond_expr = match &cond_expr.kind { // Pointer dereferencing happens automatically, so we can omit it in the suggestion - ExprKind::Unary(UnOp::UnDeref, expr)|ExprKind::AddrOf(_, _, expr) => expr, + ExprKind::Unary(UnOp::UnDeref, expr) | ExprKind::AddrOf(_, _, expr) => expr, _ => cond_expr, }; Some(OptionIfLetElseOccurence { - option: format_option_in_sugg(cx, cond_expr, parens_around_option, as_ref, as_mut), + option: format_option_in_sugg(cx, cond_expr, as_ref, as_mut), method_sugg: method_sugg.to_string(), some_expr: format!("|{}{}| {}", capture_mut, capture_name, Sugg::hir(cx, some_body, "..")), none_expr: format!("{}{}", if method_sugg == "map_or" { "" } else { "|| " }, Sugg::hir(cx, none_body, "..")), From 5e20475e47d3db1d32a7649a7c3a107caba32a14 Mon Sep 17 00:00:00 2001 From: JarredAllen Date: Sun, 31 May 2020 15:34:10 -0700 Subject: [PATCH 40/99] Don't lint if contains a macro --- clippy_lints/src/option_if_let_else.rs | 28 +++++++++++++------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/clippy_lints/src/option_if_let_else.rs b/clippy_lints/src/option_if_let_else.rs index 6e8d7515671fb..be0c44cae343f 100644 --- a/clippy_lints/src/option_if_let_else.rs +++ b/clippy_lints/src/option_if_let_else.rs @@ -10,8 +10,6 @@ use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::hir::map::Map; use rustc_session::{declare_lint_pass, declare_tool_lint}; -use std::marker::PhantomData; - declare_clippy_lint! { /// **What it does:** /// Lints usage of `if let Some(v) = ... { y } else { x }` which is more @@ -88,19 +86,17 @@ struct OptionIfLetElseOccurence { wrap_braces: bool, } -struct ReturnBreakContinueVisitor<'tcx> { +struct ReturnBreakContinueMacroVisitor { seen_return_break_continue: bool, - phantom_data: PhantomData<&'tcx bool>, } -impl<'tcx> ReturnBreakContinueVisitor<'tcx> { - fn new() -> ReturnBreakContinueVisitor<'tcx> { - ReturnBreakContinueVisitor { +impl ReturnBreakContinueMacroVisitor { + fn new() -> ReturnBreakContinueMacroVisitor { + ReturnBreakContinueMacroVisitor { seen_return_break_continue: false, - phantom_data: PhantomData, } } } -impl<'tcx> Visitor<'tcx> for ReturnBreakContinueVisitor<'tcx> { +impl<'tcx> Visitor<'tcx> for ReturnBreakContinueMacroVisitor { type Map = Map<'tcx>; fn nested_visit_map(&mut self) -> NestedVisitorMap { NestedVisitorMap::None @@ -119,14 +115,18 @@ impl<'tcx> Visitor<'tcx> for ReturnBreakContinueVisitor<'tcx> { // desugaring, as this will detect a break if there's a while loop // or a for loop inside the expression. _ => { - rustc_hir::intravisit::walk_expr(self, ex); + if utils::in_macro(ex.span) { + self.seen_return_break_continue = true; + } else { + rustc_hir::intravisit::walk_expr(self, ex); + } }, } } } -fn contains_return_break_continue<'tcx>(expression: &'tcx Expr<'tcx>) -> bool { - let mut recursive_visitor: ReturnBreakContinueVisitor<'tcx> = ReturnBreakContinueVisitor::new(); +fn contains_return_break_continue_macro(expression: &Expr<'_>) -> bool { + let mut recursive_visitor = ReturnBreakContinueMacroVisitor::new(); recursive_visitor.visit_expr(expression); recursive_visitor.seen_return_break_continue } @@ -205,8 +205,8 @@ fn detect_option_if_let_else<'a>(cx: &LateContext<'_, 'a>, expr: &'a Expr<'a>) - if let PatKind::TupleStruct(struct_qpath, &[inner_pat], _) = &arms[0].pat.kind; if utils::match_qpath(struct_qpath, &paths::OPTION_SOME); if let PatKind::Binding(bind_annotation, _, id, _) = &inner_pat.kind; - if !contains_return_break_continue(arms[0].body); - if !contains_return_break_continue(arms[1].body); + if !contains_return_break_continue_macro(arms[0].body); + if !contains_return_break_continue_macro(arms[1].body); then { let capture_mut = if bind_annotation == &BindingAnnotation::Mutable { "mut " } else { "" }; let some_body = extract_body_from_arm(&arms[0])?; From 5150277a4f765bb113e163adc7eb495dcbb57129 Mon Sep 17 00:00:00 2001 From: JarredAllen Date: Sun, 31 May 2020 15:37:21 -0700 Subject: [PATCH 41/99] Used clippy to clean itself --- clippy_lints/src/attrs.rs | 14 ++----- clippy_lints/src/if_let_mutex.rs | 8 +--- clippy_lints/src/len_zero.rs | 8 +--- clippy_lints/src/literal_representation.rs | 7 ++-- clippy_lints/src/loops.rs | 26 +++--------- clippy_lints/src/methods/mod.rs | 6 +-- .../src/methods/unnecessary_filter_map.rs | 6 +-- clippy_lints/src/minmax.rs | 21 +++++----- clippy_lints/src/misc.rs | 8 +--- clippy_lints/src/option_if_let_else.rs | 4 +- clippy_lints/src/returns.rs | 9 +---- clippy_lints/src/shadow.rs | 10 ++--- clippy_lints/src/types.rs | 12 +++--- clippy_lints/src/use_self.rs | 8 +--- clippy_lints/src/utils/attrs.rs | 14 +++---- clippy_lints/src/utils/mod.rs | 40 ++++--------------- clippy_lints/src/utils/numeric_literal.rs | 6 +-- clippy_lints/src/utils/sugg.rs | 8 +--- clippy_lints/src/write.rs | 6 +-- 19 files changed, 67 insertions(+), 154 deletions(-) diff --git a/clippy_lints/src/attrs.rs b/clippy_lints/src/attrs.rs index 2d0855f689554..cfad9d79f2b75 100644 --- a/clippy_lints/src/attrs.rs +++ b/clippy_lints/src/attrs.rs @@ -481,15 +481,11 @@ fn is_relevant_trait(cx: &LateContext<'_>, item: &TraitItem<'_>) -> bool { } fn is_relevant_block(cx: &LateContext<'_>, tables: &ty::TypeckTables<'_>, block: &Block<'_>) -> bool { - if let Some(stmt) = block.stmts.first() { - match &stmt.kind { + block.stmts.first().map_or(block.expr.as_ref().map_or(false, |e| is_relevant_expr(cx, tables, e)), |stmt| match &stmt.kind { StmtKind::Local(_) => true, StmtKind::Expr(expr) | StmtKind::Semi(expr) => is_relevant_expr(cx, tables, expr), _ => false, - } - } else { - block.expr.as_ref().map_or(false, |e| is_relevant_expr(cx, tables, e)) - } + }) } fn is_relevant_expr(cx: &LateContext<'_>, tables: &ty::TypeckTables<'_>, expr: &Expr<'_>) -> bool { @@ -499,11 +495,7 @@ fn is_relevant_expr(cx: &LateContext<'_>, tables: &ty::TypeckTables<'_>, expr: & ExprKind::Ret(None) | ExprKind::Break(_, None) => false, ExprKind::Call(path_expr, _) => { if let ExprKind::Path(qpath) = &path_expr.kind { - if let Some(fun_id) = tables.qpath_res(qpath, path_expr.hir_id).opt_def_id() { - !match_def_path(cx, fun_id, &paths::BEGIN_PANIC) - } else { - true - } + tables.qpath_res(qpath, path_expr.hir_id).opt_def_id().map_or(true, |fun_id| !match_def_path(cx, fun_id, &paths::BEGIN_PANIC)) } else { true } diff --git a/clippy_lints/src/if_let_mutex.rs b/clippy_lints/src/if_let_mutex.rs index f911cb68ea579..7e44618e90eb1 100644 --- a/clippy_lints/src/if_let_mutex.rs +++ b/clippy_lints/src/if_let_mutex.rs @@ -135,13 +135,9 @@ impl<'tcx> Visitor<'tcx> for ArmVisitor<'_, 'tcx> { } } -impl<'tcx> ArmVisitor<'_, 'tcx> { +impl<'tcx, 'l> ArmVisitor<'tcx, 'l> { fn same_mutex(&self, cx: &LateContext<'_>, op_mutex: &Expr<'_>) -> bool { - if let Some(arm_mutex) = self.found_mutex { - SpanlessEq::new(cx).eq_expr(op_mutex, arm_mutex) - } else { - false - } + self.found_mutex.map_or(false, |arm_mutex| SpanlessEq::new(cx).eq_expr(op_mutex, arm_mutex)) } } diff --git a/clippy_lints/src/len_zero.rs b/clippy_lints/src/len_zero.rs index 26d96428771d6..f57fa830adcdd 100644 --- a/clippy_lints/src/len_zero.rs +++ b/clippy_lints/src/len_zero.rs @@ -303,14 +303,10 @@ fn has_is_empty(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { let ty = &walk_ptrs_ty(cx.tables().expr_ty(expr)); match ty.kind { ty::Dynamic(ref tt, ..) => { - if let Some(principal) = tt.principal() { - cx.tcx + tt.principal().map_or(false, |principal| cx.tcx .associated_items(principal.def_id()) .in_definition_order() - .any(|item| is_is_empty(cx, &item)) - } else { - false - } + .any(|item| is_is_empty(cx, &item))) }, ty::Projection(ref proj) => has_is_empty_impl(cx, proj.item_def_id), ty::Adt(id, _) => has_is_empty_impl(cx, id.did), diff --git a/clippy_lints/src/literal_representation.rs b/clippy_lints/src/literal_representation.rs index 7ba43562d7d44..ea2e23bd3a19e 100644 --- a/clippy_lints/src/literal_representation.rs +++ b/clippy_lints/src/literal_representation.rs @@ -264,10 +264,11 @@ impl LiteralDigitGrouping { let (part, mistyped_suffixes, missing_char) = if let Some((_, exponent)) = &mut num_lit.exponent { (exponent, &["32", "64"][..], 'f') - } else if let Some(fraction) = &mut num_lit.fraction { - (fraction, &["32", "64"][..], 'f') } else { - (&mut num_lit.integer, &["8", "16", "32", "64"][..], 'i') + num_lit.fraction.as_mut().map_or( + (&mut num_lit.integer, &["8", "16", "32", "64"][..], 'i'), + |fraction| (fraction, &["32", "64"][..], 'f') + ) }; let mut split = part.rsplit('_'); diff --git a/clippy_lints/src/loops.rs b/clippy_lints/src/loops.rs index d821b5134841e..8d48f39a0454a 100644 --- a/clippy_lints/src/loops.rs +++ b/clippy_lints/src/loops.rs @@ -687,11 +687,7 @@ fn never_loop_expr(expr: &Expr<'_>, main_loop_id: HirId) -> NeverLoopResult { } }, ExprKind::Break(_, ref e) | ExprKind::Ret(ref e) => { - if let Some(ref e) = *e { - combine_seq(never_loop_expr(e, main_loop_id), NeverLoopResult::AlwaysBreak) - } else { - NeverLoopResult::AlwaysBreak - } + e.as_ref().map_or(NeverLoopResult::AlwaysBreak, |e| combine_seq(never_loop_expr(e, main_loop_id), NeverLoopResult::AlwaysBreak)) }, ExprKind::InlineAsm(ref asm) => asm .operands @@ -1882,11 +1878,7 @@ fn is_iterable_array<'tcx>(ty: Ty<'tcx>, cx: &LateContext<'tcx>) -> bool { // IntoIterator is currently only implemented for array sizes <= 32 in rustc match ty.kind { ty::Array(_, n) => { - if let Some(val) = n.try_eval_usize(cx.tcx, cx.param_env) { - (0..=32).contains(&val) - } else { - false - } + n.try_eval_usize(cx.tcx, cx.param_env).map_or(false, |val| (0..=32).contains(&val)) }, _ => false, } @@ -1899,11 +1891,7 @@ fn extract_expr_from_first_stmt<'tcx>(block: &Block<'tcx>) -> Option<&'tcx Expr< return None; } if let StmtKind::Local(ref local) = block.stmts[0].kind { - if let Some(expr) = local.init { - Some(expr) - } else { - None - } + local.init.map(|expr| expr) } else { None } @@ -2023,15 +2011,11 @@ impl<'a, 'tcx> Visitor<'tcx> for InitializeVisitor<'a, 'tcx> { if let PatKind::Binding(.., ident, _) = local.pat.kind { self.name = Some(ident.name); - self.state = if let Some(ref init) = local.init { - if is_integer_const(&self.cx, init, 0) { + self.state = local.init.as_ref().map_or(VarState::Declared, |init| if is_integer_const(&self.cx, init, 0) { VarState::Warn } else { VarState::Declared - } - } else { - VarState::Declared - } + }) } } } diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index 160304865c560..ddad16e163e44 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -2461,11 +2461,7 @@ fn derefs_to_slice<'tcx>( ty::Adt(def, _) if def.is_box() => may_slice(cx, ty.boxed_ty()), ty::Adt(..) => is_type_diagnostic_item(cx, ty, sym!(vec_type)), ty::Array(_, size) => { - if let Some(size) = size.try_eval_usize(cx.tcx, cx.param_env) { - size < 32 - } else { - false - } + size.try_eval_usize(cx.tcx, cx.param_env).map_or(false, |size| size < 32) }, ty::Ref(_, inner, _) => may_slice(cx, inner), _ => false, diff --git a/clippy_lints/src/methods/unnecessary_filter_map.rs b/clippy_lints/src/methods/unnecessary_filter_map.rs index fdcba11054288..97909c97fc728 100644 --- a/clippy_lints/src/methods/unnecessary_filter_map.rs +++ b/clippy_lints/src/methods/unnecessary_filter_map.rs @@ -78,11 +78,7 @@ fn check_expression<'tcx>(cx: &LateContext<'tcx>, arg_id: hir::HirId, expr: &'tc (true, true) }, hir::ExprKind::Block(ref block, _) => { - if let Some(expr) = &block.expr { - check_expression(cx, arg_id, &expr) - } else { - (false, false) - } + block.expr.as_ref().map_or((false, false), |expr| check_expression(cx, arg_id, &expr)) }, hir::ExprKind::Match(_, arms, _) => { let mut found_mapping = false; diff --git a/clippy_lints/src/minmax.rs b/clippy_lints/src/minmax.rs index 0a2d577396a5f..a3d1a500aa7c9 100644 --- a/clippy_lints/src/minmax.rs +++ b/clippy_lints/src/minmax.rs @@ -86,16 +86,19 @@ fn fetch_const<'a>(cx: &LateContext<'_>, args: &'a [Expr<'a>], m: MinMax) -> Opt if args.len() != 2 { return None; } - if let Some(c) = constant_simple(cx, cx.tables(), &args[0]) { - if constant_simple(cx, cx.tables(), &args[1]).is_none() { - // otherwise ignore - Some((m, c, &args[1])) + constant_simple(cx, cx.tables, &args[0]).map_or_else( + || if let Some(c) = constant_simple(cx, cx.tables(), &args[1]) { + Some((m, c, &args[0])) } else { None + }, + |c| { + if constant_simple(cx, cx.tables, &args[1]).is_none() { + // otherwise ignore + Some((c, &args[1])) + } else { + None + } } - } else if let Some(c) = constant_simple(cx, cx.tables(), &args[1]) { - Some((m, c, &args[0])) - } else { - None - } + ).map(|(c, arg)| (m, c, arg)) } diff --git a/clippy_lints/src/misc.rs b/clippy_lints/src/misc.rs index 6a256627bd18e..5b0f9d6e3ec38 100644 --- a/clippy_lints/src/misc.rs +++ b/clippy_lints/src/misc.rs @@ -682,16 +682,12 @@ fn check_to_owned(cx: &LateContext<'_>, expr: &Expr<'_>, other: &Expr<'_>, left: /// `unused_variables`'s idea /// of what it means for an expression to be "used". fn is_used(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { - if let Some(parent) = get_parent_expr(cx, expr) { - match parent.kind { + get_parent_expr(cx, expr).map_or(true, |parent| match parent.kind { ExprKind::Assign(_, ref rhs, _) | ExprKind::AssignOp(_, _, ref rhs) => { SpanlessEq::new(cx).eq_expr(rhs, expr) }, _ => is_used(cx, parent), - } - } else { - true - } + }) } /// Tests whether an expression is in a macro expansion (e.g., something diff --git a/clippy_lints/src/option_if_let_else.rs b/clippy_lints/src/option_if_let_else.rs index be0c44cae343f..b6d08b8ae17a5 100644 --- a/clippy_lints/src/option_if_let_else.rs +++ b/clippy_lints/src/option_if_let_else.rs @@ -37,6 +37,7 @@ declare_clippy_lint! { /// /// ```rust /// # let optional: Option = Some(0); + /// # fn do_complicated_function() -> u32 { 5 }; /// let _ = if let Some(foo) = optional { /// foo /// } else { @@ -54,9 +55,10 @@ declare_clippy_lint! { /// /// ```rust /// # let optional: Option = Some(0); + /// # fn do_complicated_function() -> u32 { 5 }; /// let _ = optional.map_or(5, |foo| foo); /// let _ = optional.map_or_else(||{ - /// let y = do_complicated_function; + /// let y = do_complicated_function(); /// y*y /// }, |foo| foo); /// ``` diff --git a/clippy_lints/src/returns.rs b/clippy_lints/src/returns.rs index 3c93974417356..4d54e3117faf4 100644 --- a/clippy_lints/src/returns.rs +++ b/clippy_lints/src/returns.rs @@ -259,15 +259,10 @@ fn is_unit_expr(expr: &ast::Expr) -> bool { fn lint_unneeded_unit_return(cx: &EarlyContext<'_>, ty: &ast::Ty, span: Span) { let (ret_span, appl) = if let Ok(fn_source) = cx.sess().source_map().span_to_snippet(span.with_hi(ty.span.hi())) { - if let Some(rpos) = fn_source.rfind("->") { - #[allow(clippy::cast_possible_truncation)] - ( + fn_source.rfind("->").map_or((ty.span, Applicability::MaybeIncorrect), |rpos| ( ty.span.with_lo(BytePos(span.lo().0 + rpos as u32)), Applicability::MachineApplicable, - ) - } else { - (ty.span, Applicability::MaybeIncorrect) - } + )) } else { (ty.span, Applicability::MaybeIncorrect) }; diff --git a/clippy_lints/src/shadow.rs b/clippy_lints/src/shadow.rs index 7da47ee4ff94b..de94fb8714725 100644 --- a/clippy_lints/src/shadow.rs +++ b/clippy_lints/src/shadow.rs @@ -164,15 +164,11 @@ fn check_local<'tcx>(cx: &LateContext<'tcx>, local: &'tcx Local<'_>, bindings: & } fn is_binding(cx: &LateContext<'_>, pat_id: HirId) -> bool { - let var_ty = cx.tables().node_type_opt(pat_id); - if let Some(var_ty) = var_ty { - match var_ty.kind { + let var_ty = cx.tables.node_type_opt(pat_id); + var_ty.map_or(false, |var_ty| match var_ty.kind { ty::Adt(..) => false, _ => true, - } - } else { - false - } + }) } fn check_pat<'tcx>( diff --git a/clippy_lints/src/types.rs b/clippy_lints/src/types.rs index b1345f0de5e4b..df87c1b980254 100644 --- a/clippy_lints/src/types.rs +++ b/clippy_lints/src/types.rs @@ -1205,16 +1205,14 @@ fn span_lossless_lint(cx: &LateContext<'_>, expr: &Expr<'_>, op: &Expr<'_>, cast // has parens on the outside, they are no longer needed. let mut applicability = Applicability::MachineApplicable; let opt = snippet_opt(cx, op.span); - let sugg = if let Some(ref snip) = opt { - if should_strip_parens(op, snip) { + let sugg = opt.as_ref().map_or_else(|| { + applicability = Applicability::HasPlaceholders; + ".." + }, |snip| if should_strip_parens(op, snip) { &snip[1..snip.len() - 1] } else { snip.as_str() - } - } else { - applicability = Applicability::HasPlaceholders; - ".." - }; + }); span_lint_and_sugg( cx, diff --git a/clippy_lints/src/use_self.rs b/clippy_lints/src/use_self.rs index f85db1e2006e8..eac7ae2358e8c 100644 --- a/clippy_lints/src/use_self.rs +++ b/clippy_lints/src/use_self.rs @@ -167,14 +167,10 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf { if let TyKind::Path(QPath::Resolved(_, ref item_path)) = item_type.kind; then { let parameters = &item_path.segments.last().expect(SEGMENTS_MSG).args; - let should_check = if let Some(ref params) = *parameters { - !params.parenthesized && !params.args.iter().any(|arg| match arg { + let should_check = parameters.as_ref().map_or(true, |params| !params.parenthesized && !params.args.iter().any(|arg| match arg { GenericArg::Lifetime(_) => true, _ => false, - }) - } else { - true - }; + })); if should_check { let visitor = &mut UseSelfVisitor { diff --git a/clippy_lints/src/utils/attrs.rs b/clippy_lints/src/utils/attrs.rs index 4dcf6c105ec63..2d72f9c3fe172 100644 --- a/clippy_lints/src/utils/attrs.rs +++ b/clippy_lints/src/utils/attrs.rs @@ -65,8 +65,7 @@ pub fn get_attr<'a>( }; let attr_segments = &attr.path.segments; if attr_segments.len() == 2 && attr_segments[0].ident.to_string() == "clippy" { - if let Some(deprecation_status) = - BUILTIN_ATTRIBUTES + BUILTIN_ATTRIBUTES .iter() .find_map(|(builtin_name, deprecation_status)| { if *builtin_name == attr_segments[1].ident.to_string() { @@ -74,8 +73,10 @@ pub fn get_attr<'a>( } else { None } - }) - { + }).map_or_else(|| { + sess.span_err(attr_segments[1].ident.span, "Usage of unknown attribute"); + false + }, |deprecation_status| { let mut diag = sess.struct_span_err(attr_segments[1].ident.span, "Usage of deprecated attribute"); match *deprecation_status { DeprecationStatus::Deprecated => { @@ -97,10 +98,7 @@ pub fn get_attr<'a>( attr_segments[1].ident.to_string() == name }, } - } else { - sess.span_err(attr_segments[1].ident.span, "Usage of unknown attribute"); - false - } + }) } else { false } diff --git a/clippy_lints/src/utils/mod.rs b/clippy_lints/src/utils/mod.rs index 99ba7d64331cd..6f23e96800684 100644 --- a/clippy_lints/src/utils/mod.rs +++ b/clippy_lints/src/utils/mod.rs @@ -153,11 +153,7 @@ pub fn is_type_diagnostic_item(cx: &LateContext<'_>, ty: Ty<'_>, diag_item: Symb pub fn match_trait_method(cx: &LateContext<'_>, expr: &Expr<'_>, path: &[&str]) -> bool { let def_id = cx.tables().type_dependent_def_id(expr.hir_id).unwrap(); let trt_id = cx.tcx.trait_of_item(def_id); - if let Some(trt_id) = trt_id { - match_def_path(cx, trt_id, path) - } else { - false - } + trt_id.map_or(false, |trt_id| match_def_path(cx, trt_id, path)) } /// Checks if an expression references a variable of the given name. @@ -600,21 +596,13 @@ pub fn snippet_block_with_applicability<'a, T: LintContext>( /// // ^^^^^^^^^^ /// ``` pub fn first_line_of_span(cx: &T, span: Span) -> Span { - if let Some(first_char_pos) = first_char_in_first_line(cx, span) { - span.with_lo(first_char_pos) - } else { - span - } + first_char_in_first_line(cx, span).map_or(span, |first_char_pos| span.with_lo(first_char_pos)) } fn first_char_in_first_line(cx: &T, span: Span) -> Option { let line_span = line_span(cx, span); - if let Some(snip) = snippet_opt(cx, line_span) { - snip.find(|c: char| !c.is_whitespace()) - .map(|pos| line_span.lo() + BytePos::from_usize(pos)) - } else { - None - } + snippet_opt(cx, line_span).and_then(|snip| snip.find(|c: char| !c.is_whitespace()) + .map(|pos| line_span.lo() + BytePos::from_usize(pos))) } /// Returns the indentation of the line of a span @@ -626,11 +614,7 @@ fn first_char_in_first_line(cx: &T, span: Span) -> Option(cx: &T, span: Span) -> Option { - if let Some(snip) = snippet_opt(cx, line_span(cx, span)) { - snip.find(|c: char| !c.is_whitespace()) - } else { - None - } + snippet_opt(cx, line_span(cx, span)).and_then(|snip| snip.find(|c: char| !c.is_whitespace())) } /// Extends the span to the beginning of the spans line, incl. whitespaces. @@ -738,8 +722,7 @@ pub fn get_enclosing_block<'tcx>(cx: &LateContext<'tcx>, hir_id: HirId) -> Optio let enclosing_node = map .get_enclosing_scope(hir_id) .and_then(|enclosing_id| map.find(enclosing_id)); - if let Some(node) = enclosing_node { - match node { + enclosing_node.and_then(|node| match node { Node::Block(block) => Some(block), Node::Item(&Item { kind: ItemKind::Fn(_, _, eid), @@ -753,10 +736,7 @@ pub fn get_enclosing_block<'tcx>(cx: &LateContext<'tcx>, hir_id: HirId) -> Optio _ => None, }, _ => None, - } - } else { - None - } + }) } /// Returns the base type for HIR references and pointers. @@ -1328,11 +1308,7 @@ pub fn is_must_use_func_call(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { _ => None, }; - if let Some(did) = did { - must_use_attr(&cx.tcx.get_attrs(did)).is_some() - } else { - false - } + did.map_or(false, |did| must_use_attr(&cx.tcx.get_attrs(did)).is_some()) } pub fn is_no_std_crate(krate: &Crate<'_>) -> bool { diff --git a/clippy_lints/src/utils/numeric_literal.rs b/clippy_lints/src/utils/numeric_literal.rs index 99413153d49bb..7a79741b30bd0 100644 --- a/clippy_lints/src/utils/numeric_literal.rs +++ b/clippy_lints/src/utils/numeric_literal.rs @@ -200,12 +200,10 @@ impl<'a> NumericLiteral<'a> { fn split_suffix<'a>(src: &'a str, lit_kind: &LitKind) -> (&'a str, Option<&'a str>) { debug_assert!(lit_kind.is_numeric()); - if let Some(suffix_length) = lit_suffix_length(lit_kind) { + lit_suffix_length(lit_kind).map_or((src, None), |suffix_length| { let (unsuffixed, suffix) = src.split_at(src.len() - suffix_length); (unsuffixed, Some(suffix)) - } else { - (src, None) - } + }) } fn lit_suffix_length(lit_kind: &LitKind) -> Option { diff --git a/clippy_lints/src/utils/sugg.rs b/clippy_lints/src/utils/sugg.rs index 8fc97f2fd64ae..20bea3cbabe64 100644 --- a/clippy_lints/src/utils/sugg.rs +++ b/clippy_lints/src/utils/sugg.rs @@ -492,8 +492,7 @@ fn astbinop2assignop(op: ast::BinOp) -> AssocOp { /// before it on its line. fn indentation(cx: &T, span: Span) -> Option { let lo = cx.sess().source_map().lookup_char_pos(span.lo()); - if let Some(line) = lo.file.get_line(lo.line - 1 /* line numbers in `Loc` are 1-based */) { - if let Some((pos, _)) = line.char_indices().find(|&(_, c)| c != ' ' && c != '\t') { + lo.file.get_line(lo.line - 1 /* line numbers in `Loc` are 1-based */).and_then(|line| if let Some((pos, _)) = line.char_indices().find(|&(_, c)| c != ' ' && c != '\t') { // We can mix char and byte positions here because we only consider `[ \t]`. if lo.col == CharPos(pos) { Some(line[..pos].into()) @@ -502,10 +501,7 @@ fn indentation(cx: &T, span: Span) -> Option { } } else { None - } - } else { - None - } + }) } /// Convenience extension trait for `DiagnosticBuilder`. diff --git a/clippy_lints/src/write.rs b/clippy_lints/src/write.rs index 732f4b28e06e3..3b10b7b82a089 100644 --- a/clippy_lints/src/write.rs +++ b/clippy_lints/src/write.rs @@ -297,12 +297,10 @@ impl EarlyLintPass for Write { if let (Some(fmt_str), expr) = self.check_tts(cx, &mac.args.inner_tokens(), true) { if fmt_str.symbol == Symbol::intern("") { let mut applicability = Applicability::MachineApplicable; - let suggestion = if let Some(e) = expr { - snippet_with_applicability(cx, e.span, "v", &mut applicability) - } else { + let suggestion = expr.map_or_else(|| { applicability = Applicability::HasPlaceholders; Cow::Borrowed("v") - }; + }, |e| snippet_with_applicability(cx, e.span, "v", &mut Applicability::MachineApplicable)); span_lint_and_sugg( cx, From 93f0f5d37b45c648aebf87fe7e7379599ba3e726 Mon Sep 17 00:00:00 2001 From: JarredAllen Date: Fri, 12 Jun 2020 08:32:38 -0700 Subject: [PATCH 42/99] Last few tweaks --- CHANGELOG.md | 1 - clippy_lints/src/lib.rs | 3 +-- clippy_lints/src/minmax.rs | 3 +-- clippy_lints/src/option_if_let_else.rs | 2 +- clippy_lints/src/returns.rs | 9 +++++++-- src/lintlist/mod.rs | 2 +- 6 files changed, 11 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1a081bb85feab..01c0e4b0302a4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1491,7 +1491,6 @@ Released 2018-09-13 [`large_stack_arrays`]: https://rust-lang.github.io/rust-clippy/master/index.html#large_stack_arrays [`len_without_is_empty`]: https://rust-lang.github.io/rust-clippy/master/index.html#len_without_is_empty [`len_zero`]: https://rust-lang.github.io/rust-clippy/master/index.html#len_zero -[`let_and_return`]: https://rust-lang.github.io/rust-clippy/master/index.html#let_and_return [`let_underscore_lock`]: https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_lock [`let_underscore_must_use`]: https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_must_use [`let_unit_value`]: https://rust-lang.github.io/rust-clippy/master/index.html#let_unit_value diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index cd91e7ceb32a8..fe34e4390d659 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -1161,6 +1161,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: LintId::of(&needless_continue::NEEDLESS_CONTINUE), LintId::of(&needless_pass_by_value::NEEDLESS_PASS_BY_VALUE), LintId::of(&non_expressive_names::SIMILAR_NAMES), + LintId::of(&option_if_let_else::OPTION_IF_LET_ELSE), LintId::of(&ranges::RANGE_PLUS_ONE), LintId::of(&shadow::SHADOW_UNRELATED), LintId::of(&strings::STRING_ADD_ASSIGN), @@ -1372,7 +1373,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: LintId::of(&non_expressive_names::MANY_SINGLE_CHAR_NAMES), LintId::of(&open_options::NONSENSICAL_OPEN_OPTIONS), LintId::of(&option_env_unwrap::OPTION_ENV_UNWRAP), - LintId::of(&option_if_let_else::OPTION_IF_LET_ELSE), LintId::of(&overflow_check_conditional::OVERFLOW_CHECK_CONDITIONAL), LintId::of(&panic_unimplemented::PANIC_PARAMS), LintId::of(&partialeq_ne_impl::PARTIALEQ_NE_IMPL), @@ -1521,7 +1521,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: LintId::of(&new_without_default::NEW_WITHOUT_DEFAULT), LintId::of(&non_expressive_names::JUST_UNDERSCORES_AND_DIGITS), LintId::of(&non_expressive_names::MANY_SINGLE_CHAR_NAMES), - LintId::of(&option_if_let_else::OPTION_IF_LET_ELSE), LintId::of(&panic_unimplemented::PANIC_PARAMS), LintId::of(&ptr::CMP_NULL), LintId::of(&ptr::PTR_ARG), diff --git a/clippy_lints/src/minmax.rs b/clippy_lints/src/minmax.rs index a3d1a500aa7c9..6ec7f8cae5d75 100644 --- a/clippy_lints/src/minmax.rs +++ b/clippy_lints/src/minmax.rs @@ -99,6 +99,5 @@ fn fetch_const<'a>(cx: &LateContext<'_>, args: &'a [Expr<'a>], m: MinMax) -> Opt } else { None } - } - ).map(|(c, arg)| (m, c, arg)) + }) } diff --git a/clippy_lints/src/option_if_let_else.rs b/clippy_lints/src/option_if_let_else.rs index b6d08b8ae17a5..c877cc6fa8b8a 100644 --- a/clippy_lints/src/option_if_let_else.rs +++ b/clippy_lints/src/option_if_let_else.rs @@ -63,7 +63,7 @@ declare_clippy_lint! { /// }, |foo| foo); /// ``` pub OPTION_IF_LET_ELSE, - style, + pedantic, "reimplementation of Option::map_or" } diff --git a/clippy_lints/src/returns.rs b/clippy_lints/src/returns.rs index 4d54e3117faf4..3c93974417356 100644 --- a/clippy_lints/src/returns.rs +++ b/clippy_lints/src/returns.rs @@ -259,10 +259,15 @@ fn is_unit_expr(expr: &ast::Expr) -> bool { fn lint_unneeded_unit_return(cx: &EarlyContext<'_>, ty: &ast::Ty, span: Span) { let (ret_span, appl) = if let Ok(fn_source) = cx.sess().source_map().span_to_snippet(span.with_hi(ty.span.hi())) { - fn_source.rfind("->").map_or((ty.span, Applicability::MaybeIncorrect), |rpos| ( + if let Some(rpos) = fn_source.rfind("->") { + #[allow(clippy::cast_possible_truncation)] + ( ty.span.with_lo(BytePos(span.lo().0 + rpos as u32)), Applicability::MachineApplicable, - )) + ) + } else { + (ty.span, Applicability::MaybeIncorrect) + } } else { (ty.span, Applicability::MaybeIncorrect) }; diff --git a/src/lintlist/mod.rs b/src/lintlist/mod.rs index b499d565fa7f9..e681f47f949df 100644 --- a/src/lintlist/mod.rs +++ b/src/lintlist/mod.rs @@ -1622,7 +1622,7 @@ pub static ref ALL_LINTS: Vec = vec![ }, Lint { name: "option_if_let_else", - group: "style", + group: "pedantic", desc: "reimplementation of Option::map_or", deprecation: None, module: "option_if_let_else", From ccb999851aaa4d3e9cd97110bd6523a6c3df46fd Mon Sep 17 00:00:00 2001 From: JarredAllen Date: Thu, 25 Jun 2020 11:39:58 -0700 Subject: [PATCH 43/99] Fix compile error from library change --- CHANGELOG.md | 1 + clippy_lints/src/option_if_let_else.rs | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 01c0e4b0302a4..1a081bb85feab 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1491,6 +1491,7 @@ Released 2018-09-13 [`large_stack_arrays`]: https://rust-lang.github.io/rust-clippy/master/index.html#large_stack_arrays [`len_without_is_empty`]: https://rust-lang.github.io/rust-clippy/master/index.html#len_without_is_empty [`len_zero`]: https://rust-lang.github.io/rust-clippy/master/index.html#len_zero +[`let_and_return`]: https://rust-lang.github.io/rust-clippy/master/index.html#let_and_return [`let_underscore_lock`]: https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_lock [`let_underscore_must_use`]: https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_must_use [`let_unit_value`]: https://rust-lang.github.io/rust-clippy/master/index.html#let_unit_value diff --git a/clippy_lints/src/option_if_let_else.rs b/clippy_lints/src/option_if_let_else.rs index c877cc6fa8b8a..7e299dd5fd99f 100644 --- a/clippy_lints/src/option_if_let_else.rs +++ b/clippy_lints/src/option_if_let_else.rs @@ -71,7 +71,7 @@ declare_lint_pass!(OptionIfLetElse => [OPTION_IF_LET_ELSE]); /// Returns true iff the given expression is the result of calling `Result::ok` fn is_result_ok(cx: &LateContext<'_, '_>, expr: &'_ Expr<'_>) -> bool { - if let ExprKind::MethodCall(ref path, _, &[ref receiver]) = &expr.kind { + if let ExprKind::MethodCall(ref path, _, &[ref receiver], _) = &expr.kind { path.ident.name.to_ident_string() == "ok" && match_type(cx, &cx.tables.expr_ty(&receiver), &paths::RESULT) } else { false From 6ce981225b73d6c3514b0abb759a5282521a17d9 Mon Sep 17 00:00:00 2001 From: JarredAllen Date: Thu, 25 Jun 2020 11:58:47 -0700 Subject: [PATCH 44/99] Clean existing lint code to match new lint --- clippy_lints/src/attrs.rs | 14 ++-- clippy_lints/src/if_let_mutex.rs | 5 +- clippy_lints/src/len_zero.rs | 12 ++-- clippy_lints/src/literal_representation.rs | 10 +-- clippy_lints/src/loops.rs | 20 +++--- clippy_lints/src/methods/mod.rs | 6 +- .../src/methods/unnecessary_filter_map.rs | 7 +- clippy_lints/src/minmax.rs | 2 +- clippy_lints/src/misc.rs | 8 +-- clippy_lints/src/option_if_let_else.rs | 2 +- clippy_lints/src/returns.rs | 18 ++--- clippy_lints/src/shadow.rs | 6 +- clippy_lints/src/types.rs | 21 +++--- clippy_lints/src/use_self.rs | 7 +- clippy_lints/src/utils/attrs.rs | 65 ++++++++++--------- clippy_lints/src/utils/mod.rs | 32 ++++----- clippy_lints/src/utils/sugg.rs | 16 +++-- clippy_lints/src/write.rs | 11 ++-- 18 files changed, 147 insertions(+), 115 deletions(-) diff --git a/clippy_lints/src/attrs.rs b/clippy_lints/src/attrs.rs index cfad9d79f2b75..c4397560d7db1 100644 --- a/clippy_lints/src/attrs.rs +++ b/clippy_lints/src/attrs.rs @@ -480,12 +480,15 @@ fn is_relevant_trait(cx: &LateContext<'_>, item: &TraitItem<'_>) -> bool { } } -fn is_relevant_block(cx: &LateContext<'_>, tables: &ty::TypeckTables<'_>, block: &Block<'_>) -> bool { - block.stmts.first().map_or(block.expr.as_ref().map_or(false, |e| is_relevant_expr(cx, tables, e)), |stmt| match &stmt.kind { +fn is_relevant_block(cx: &LateContext<'_, '_>, tables: &ty::TypeckTables<'_>, block: &Block<'_>) -> bool { + block.stmts.first().map_or( + block.expr.as_ref().map_or(false, |e| is_relevant_expr(cx, tables, e)), + |stmt| match &stmt.kind { StmtKind::Local(_) => true, StmtKind::Expr(expr) | StmtKind::Semi(expr) => is_relevant_expr(cx, tables, expr), _ => false, - }) + }, + ) } fn is_relevant_expr(cx: &LateContext<'_>, tables: &ty::TypeckTables<'_>, expr: &Expr<'_>) -> bool { @@ -495,7 +498,10 @@ fn is_relevant_expr(cx: &LateContext<'_>, tables: &ty::TypeckTables<'_>, expr: & ExprKind::Ret(None) | ExprKind::Break(_, None) => false, ExprKind::Call(path_expr, _) => { if let ExprKind::Path(qpath) = &path_expr.kind { - tables.qpath_res(qpath, path_expr.hir_id).opt_def_id().map_or(true, |fun_id| !match_def_path(cx, fun_id, &paths::BEGIN_PANIC)) + tables + .qpath_res(qpath, path_expr.hir_id) + .opt_def_id() + .map_or(true, |fun_id| !match_def_path(cx, fun_id, &paths::BEGIN_PANIC)) } else { true } diff --git a/clippy_lints/src/if_let_mutex.rs b/clippy_lints/src/if_let_mutex.rs index 7e44618e90eb1..5426e14ead573 100644 --- a/clippy_lints/src/if_let_mutex.rs +++ b/clippy_lints/src/if_let_mutex.rs @@ -136,8 +136,9 @@ impl<'tcx> Visitor<'tcx> for ArmVisitor<'_, 'tcx> { } impl<'tcx, 'l> ArmVisitor<'tcx, 'l> { - fn same_mutex(&self, cx: &LateContext<'_>, op_mutex: &Expr<'_>) -> bool { - self.found_mutex.map_or(false, |arm_mutex| SpanlessEq::new(cx).eq_expr(op_mutex, arm_mutex)) + fn same_mutex(&self, cx: &LateContext<'_, '_>, op_mutex: &Expr<'_>) -> bool { + self.found_mutex + .map_or(false, |arm_mutex| SpanlessEq::new(cx).eq_expr(op_mutex, arm_mutex)) } } diff --git a/clippy_lints/src/len_zero.rs b/clippy_lints/src/len_zero.rs index f57fa830adcdd..1b09328ceabb0 100644 --- a/clippy_lints/src/len_zero.rs +++ b/clippy_lints/src/len_zero.rs @@ -302,12 +302,12 @@ fn has_is_empty(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { let ty = &walk_ptrs_ty(cx.tables().expr_ty(expr)); match ty.kind { - ty::Dynamic(ref tt, ..) => { - tt.principal().map_or(false, |principal| cx.tcx - .associated_items(principal.def_id()) - .in_definition_order() - .any(|item| is_is_empty(cx, &item))) - }, + ty::Dynamic(ref tt, ..) => tt.principal().map_or(false, |principal| { + cx.tcx + .associated_items(principal.def_id()) + .in_definition_order() + .any(|item| is_is_empty(cx, &item)) + }), ty::Projection(ref proj) => has_is_empty_impl(cx, proj.item_def_id), ty::Adt(id, _) => has_is_empty_impl(cx, id.did), ty::Array(..) | ty::Slice(..) | ty::Str => true, diff --git a/clippy_lints/src/literal_representation.rs b/clippy_lints/src/literal_representation.rs index ea2e23bd3a19e..a36fdca5d5de6 100644 --- a/clippy_lints/src/literal_representation.rs +++ b/clippy_lints/src/literal_representation.rs @@ -265,10 +265,12 @@ impl LiteralDigitGrouping { let (part, mistyped_suffixes, missing_char) = if let Some((_, exponent)) = &mut num_lit.exponent { (exponent, &["32", "64"][..], 'f') } else { - num_lit.fraction.as_mut().map_or( - (&mut num_lit.integer, &["8", "16", "32", "64"][..], 'i'), - |fraction| (fraction, &["32", "64"][..], 'f') - ) + num_lit + .fraction + .as_mut() + .map_or((&mut num_lit.integer, &["8", "16", "32", "64"][..], 'i'), |fraction| { + (fraction, &["32", "64"][..], 'f') + }) }; let mut split = part.rsplit('_'); diff --git a/clippy_lints/src/loops.rs b/clippy_lints/src/loops.rs index 8d48f39a0454a..b803d753b6d04 100644 --- a/clippy_lints/src/loops.rs +++ b/clippy_lints/src/loops.rs @@ -686,9 +686,9 @@ fn never_loop_expr(expr: &Expr<'_>, main_loop_id: HirId) -> NeverLoopResult { NeverLoopResult::AlwaysBreak } }, - ExprKind::Break(_, ref e) | ExprKind::Ret(ref e) => { - e.as_ref().map_or(NeverLoopResult::AlwaysBreak, |e| combine_seq(never_loop_expr(e, main_loop_id), NeverLoopResult::AlwaysBreak)) - }, + ExprKind::Break(_, ref e) | ExprKind::Ret(ref e) => e.as_ref().map_or(NeverLoopResult::AlwaysBreak, |e| { + combine_seq(never_loop_expr(e, main_loop_id), NeverLoopResult::AlwaysBreak) + }), ExprKind::InlineAsm(ref asm) => asm .operands .iter() @@ -1877,9 +1877,9 @@ fn is_ref_iterable_type(cx: &LateContext<'_>, e: &Expr<'_>) -> bool { fn is_iterable_array<'tcx>(ty: Ty<'tcx>, cx: &LateContext<'tcx>) -> bool { // IntoIterator is currently only implemented for array sizes <= 32 in rustc match ty.kind { - ty::Array(_, n) => { - n.try_eval_usize(cx.tcx, cx.param_env).map_or(false, |val| (0..=32).contains(&val)) - }, + ty::Array(_, n) => n + .try_eval_usize(cx.tcx, cx.param_env) + .map_or(false, |val| (0..=32).contains(&val)), _ => false, } } @@ -1891,7 +1891,7 @@ fn extract_expr_from_first_stmt<'tcx>(block: &Block<'tcx>) -> Option<&'tcx Expr< return None; } if let StmtKind::Local(ref local) = block.stmts[0].kind { - local.init.map(|expr| expr) + local.init //.map(|expr| expr) } else { None } @@ -2011,11 +2011,13 @@ impl<'a, 'tcx> Visitor<'tcx> for InitializeVisitor<'a, 'tcx> { if let PatKind::Binding(.., ident, _) = local.pat.kind { self.name = Some(ident.name); - self.state = local.init.as_ref().map_or(VarState::Declared, |init| if is_integer_const(&self.cx, init, 0) { + self.state = local.init.as_ref().map_or(VarState::Declared, |init| { + if is_integer_const(&self.cx, init, 0) { VarState::Warn } else { VarState::Declared - }) + } + }) } } } diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index ddad16e163e44..f1c8894c0ee29 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -2460,9 +2460,9 @@ fn derefs_to_slice<'tcx>( ty::Slice(_) => true, ty::Adt(def, _) if def.is_box() => may_slice(cx, ty.boxed_ty()), ty::Adt(..) => is_type_diagnostic_item(cx, ty, sym!(vec_type)), - ty::Array(_, size) => { - size.try_eval_usize(cx.tcx, cx.param_env).map_or(false, |size| size < 32) - }, + ty::Array(_, size) => size + .try_eval_usize(cx.tcx, cx.param_env) + .map_or(false, |size| size < 32), ty::Ref(_, inner, _) => may_slice(cx, inner), _ => false, } diff --git a/clippy_lints/src/methods/unnecessary_filter_map.rs b/clippy_lints/src/methods/unnecessary_filter_map.rs index 97909c97fc728..75e123eb5939d 100644 --- a/clippy_lints/src/methods/unnecessary_filter_map.rs +++ b/clippy_lints/src/methods/unnecessary_filter_map.rs @@ -77,9 +77,10 @@ fn check_expression<'tcx>(cx: &LateContext<'tcx>, arg_id: hir::HirId, expr: &'tc } (true, true) }, - hir::ExprKind::Block(ref block, _) => { - block.expr.as_ref().map_or((false, false), |expr| check_expression(cx, arg_id, &expr)) - }, + hir::ExprKind::Block(ref block, _) => block + .expr + .as_ref() + .map_or((false, false), |expr| check_expression(cx, arg_id, &expr)), hir::ExprKind::Match(_, arms, _) => { let mut found_mapping = false; let mut found_filtering = false; diff --git a/clippy_lints/src/minmax.rs b/clippy_lints/src/minmax.rs index 6ec7f8cae5d75..5eb8398d68e51 100644 --- a/clippy_lints/src/minmax.rs +++ b/clippy_lints/src/minmax.rs @@ -53,7 +53,7 @@ impl<'tcx> LateLintPass<'tcx> for MinMaxPass { } } -#[derive(PartialEq, Eq, Debug)] +#[derive(PartialEq, Eq, Debug, Clone, Copy)] enum MinMax { Min, Max, diff --git a/clippy_lints/src/misc.rs b/clippy_lints/src/misc.rs index 5b0f9d6e3ec38..3d4225f36a7d0 100644 --- a/clippy_lints/src/misc.rs +++ b/clippy_lints/src/misc.rs @@ -683,11 +683,9 @@ fn check_to_owned(cx: &LateContext<'_>, expr: &Expr<'_>, other: &Expr<'_>, left: /// of what it means for an expression to be "used". fn is_used(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { get_parent_expr(cx, expr).map_or(true, |parent| match parent.kind { - ExprKind::Assign(_, ref rhs, _) | ExprKind::AssignOp(_, _, ref rhs) => { - SpanlessEq::new(cx).eq_expr(rhs, expr) - }, - _ => is_used(cx, parent), - }) + ExprKind::Assign(_, ref rhs, _) | ExprKind::AssignOp(_, _, ref rhs) => SpanlessEq::new(cx).eq_expr(rhs, expr), + _ => is_used(cx, parent), + }) } /// Tests whether an expression is in a macro expansion (e.g., something diff --git a/clippy_lints/src/option_if_let_else.rs b/clippy_lints/src/option_if_let_else.rs index 7e299dd5fd99f..ab9ea76a83896 100644 --- a/clippy_lints/src/option_if_let_else.rs +++ b/clippy_lints/src/option_if_let_else.rs @@ -260,7 +260,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for OptionIfLetElse { detection.some_expr, if detection.wrap_braces { " }" } else { "" }, ), - Applicability::MachineApplicable, + Applicability::MaybeIncorrect, ); } } diff --git a/clippy_lints/src/returns.rs b/clippy_lints/src/returns.rs index 3c93974417356..faef7e724dd05 100644 --- a/clippy_lints/src/returns.rs +++ b/clippy_lints/src/returns.rs @@ -259,15 +259,15 @@ fn is_unit_expr(expr: &ast::Expr) -> bool { fn lint_unneeded_unit_return(cx: &EarlyContext<'_>, ty: &ast::Ty, span: Span) { let (ret_span, appl) = if let Ok(fn_source) = cx.sess().source_map().span_to_snippet(span.with_hi(ty.span.hi())) { - if let Some(rpos) = fn_source.rfind("->") { - #[allow(clippy::cast_possible_truncation)] - ( - ty.span.with_lo(BytePos(span.lo().0 + rpos as u32)), - Applicability::MachineApplicable, - ) - } else { - (ty.span, Applicability::MaybeIncorrect) - } + fn_source + .rfind("->") + .map_or((ty.span, Applicability::MaybeIncorrect), |rpos| { + ( + #[allow(clippy::cast_possible_truncation)] + ty.span.with_lo(BytePos(span.lo().0 + rpos as u32)), + Applicability::MachineApplicable, + ) + }) } else { (ty.span, Applicability::MaybeIncorrect) }; diff --git a/clippy_lints/src/shadow.rs b/clippy_lints/src/shadow.rs index de94fb8714725..f16db2df3a927 100644 --- a/clippy_lints/src/shadow.rs +++ b/clippy_lints/src/shadow.rs @@ -166,9 +166,9 @@ fn check_local<'tcx>(cx: &LateContext<'tcx>, local: &'tcx Local<'_>, bindings: & fn is_binding(cx: &LateContext<'_>, pat_id: HirId) -> bool { let var_ty = cx.tables.node_type_opt(pat_id); var_ty.map_or(false, |var_ty| match var_ty.kind { - ty::Adt(..) => false, - _ => true, - }) + ty::Adt(..) => false, + _ => true, + }) } fn check_pat<'tcx>( diff --git a/clippy_lints/src/types.rs b/clippy_lints/src/types.rs index df87c1b980254..d6f31a99bb36a 100644 --- a/clippy_lints/src/types.rs +++ b/clippy_lints/src/types.rs @@ -1205,14 +1205,19 @@ fn span_lossless_lint(cx: &LateContext<'_>, expr: &Expr<'_>, op: &Expr<'_>, cast // has parens on the outside, they are no longer needed. let mut applicability = Applicability::MachineApplicable; let opt = snippet_opt(cx, op.span); - let sugg = opt.as_ref().map_or_else(|| { - applicability = Applicability::HasPlaceholders; - ".." - }, |snip| if should_strip_parens(op, snip) { - &snip[1..snip.len() - 1] - } else { - snip.as_str() - }); + let sugg = opt.as_ref().map_or_else( + || { + applicability = Applicability::HasPlaceholders; + ".." + }, + |snip| { + if should_strip_parens(op, snip) { + &snip[1..snip.len() - 1] + } else { + snip.as_str() + } + }, + ); span_lint_and_sugg( cx, diff --git a/clippy_lints/src/use_self.rs b/clippy_lints/src/use_self.rs index eac7ae2358e8c..39a8c02087284 100644 --- a/clippy_lints/src/use_self.rs +++ b/clippy_lints/src/use_self.rs @@ -167,10 +167,13 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf { if let TyKind::Path(QPath::Resolved(_, ref item_path)) = item_type.kind; then { let parameters = &item_path.segments.last().expect(SEGMENTS_MSG).args; - let should_check = parameters.as_ref().map_or(true, |params| !params.parenthesized && !params.args.iter().any(|arg| match arg { + let should_check = parameters.as_ref().map_or( + true, + |params| !params.parenthesized && !params.args.iter().any(|arg| match arg { GenericArg::Lifetime(_) => true, _ => false, - })); + }) + ); if should_check { let visitor = &mut UseSelfVisitor { diff --git a/clippy_lints/src/utils/attrs.rs b/clippy_lints/src/utils/attrs.rs index 2d72f9c3fe172..4bb4b087c5566 100644 --- a/clippy_lints/src/utils/attrs.rs +++ b/clippy_lints/src/utils/attrs.rs @@ -66,39 +66,44 @@ pub fn get_attr<'a>( let attr_segments = &attr.path.segments; if attr_segments.len() == 2 && attr_segments[0].ident.to_string() == "clippy" { BUILTIN_ATTRIBUTES - .iter() - .find_map(|(builtin_name, deprecation_status)| { - if *builtin_name == attr_segments[1].ident.to_string() { - Some(deprecation_status) - } else { - None - } - }).map_or_else(|| { - sess.span_err(attr_segments[1].ident.span, "Usage of unknown attribute"); - false - }, |deprecation_status| { - let mut diag = sess.struct_span_err(attr_segments[1].ident.span, "Usage of deprecated attribute"); - match *deprecation_status { - DeprecationStatus::Deprecated => { - diag.emit(); - false - }, - DeprecationStatus::Replaced(new_name) => { - diag.span_suggestion( - attr_segments[1].ident.span, - "consider using", - new_name.to_string(), - Applicability::MachineApplicable, - ); - diag.emit(); + .iter() + .find_map(|(builtin_name, deprecation_status)| { + if *builtin_name == attr_segments[1].ident.to_string() { + Some(deprecation_status) + } else { + None + } + }) + .map_or_else( + || { + sess.span_err(attr_segments[1].ident.span, "Usage of unknown attribute"); false }, - DeprecationStatus::None => { - diag.cancel(); - attr_segments[1].ident.to_string() == name + |deprecation_status| { + let mut diag = + sess.struct_span_err(attr_segments[1].ident.span, "Usage of deprecated attribute"); + match *deprecation_status { + DeprecationStatus::Deprecated => { + diag.emit(); + false + }, + DeprecationStatus::Replaced(new_name) => { + diag.span_suggestion( + attr_segments[1].ident.span, + "consider using", + new_name.to_string(), + Applicability::MachineApplicable, + ); + diag.emit(); + false + }, + DeprecationStatus::None => { + diag.cancel(); + attr_segments[1].ident.to_string() == name + }, + } }, - } - }) + ) } else { false } diff --git a/clippy_lints/src/utils/mod.rs b/clippy_lints/src/utils/mod.rs index 6f23e96800684..3a3b79925ff9a 100644 --- a/clippy_lints/src/utils/mod.rs +++ b/clippy_lints/src/utils/mod.rs @@ -601,8 +601,10 @@ pub fn first_line_of_span(cx: &T, span: Span) -> Span { fn first_char_in_first_line(cx: &T, span: Span) -> Option { let line_span = line_span(cx, span); - snippet_opt(cx, line_span).and_then(|snip| snip.find(|c: char| !c.is_whitespace()) - .map(|pos| line_span.lo() + BytePos::from_usize(pos))) + snippet_opt(cx, line_span).and_then(|snip| { + snip.find(|c: char| !c.is_whitespace()) + .map(|pos| line_span.lo() + BytePos::from_usize(pos)) + }) } /// Returns the indentation of the line of a span @@ -723,20 +725,20 @@ pub fn get_enclosing_block<'tcx>(cx: &LateContext<'tcx>, hir_id: HirId) -> Optio .get_enclosing_scope(hir_id) .and_then(|enclosing_id| map.find(enclosing_id)); enclosing_node.and_then(|node| match node { - Node::Block(block) => Some(block), - Node::Item(&Item { - kind: ItemKind::Fn(_, _, eid), - .. - }) - | Node::ImplItem(&ImplItem { - kind: ImplItemKind::Fn(_, eid), - .. - }) => match cx.tcx.hir().body(eid).value.kind { - ExprKind::Block(ref block, _) => Some(block), - _ => None, - }, - _ => None, + Node::Block(block) => Some(block), + Node::Item(&Item { + kind: ItemKind::Fn(_, _, eid), + .. }) + | Node::ImplItem(&ImplItem { + kind: ImplItemKind::Fn(_, eid), + .. + }) => match cx.tcx.hir().body(eid).value.kind { + ExprKind::Block(ref block, _) => Some(block), + _ => None, + }, + _ => None, + }) } /// Returns the base type for HIR references and pointers. diff --git a/clippy_lints/src/utils/sugg.rs b/clippy_lints/src/utils/sugg.rs index 20bea3cbabe64..0ac7714fbeb79 100644 --- a/clippy_lints/src/utils/sugg.rs +++ b/clippy_lints/src/utils/sugg.rs @@ -492,15 +492,19 @@ fn astbinop2assignop(op: ast::BinOp) -> AssocOp { /// before it on its line. fn indentation(cx: &T, span: Span) -> Option { let lo = cx.sess().source_map().lookup_char_pos(span.lo()); - lo.file.get_line(lo.line - 1 /* line numbers in `Loc` are 1-based */).and_then(|line| if let Some((pos, _)) = line.char_indices().find(|&(_, c)| c != ' ' && c != '\t') { - // We can mix char and byte positions here because we only consider `[ \t]`. - if lo.col == CharPos(pos) { - Some(line[..pos].into()) + lo.file + .get_line(lo.line - 1 /* line numbers in `Loc` are 1-based */) + .and_then(|line| { + if let Some((pos, _)) = line.char_indices().find(|&(_, c)| c != ' ' && c != '\t') { + // We can mix char and byte positions here because we only consider `[ \t]`. + if lo.col == CharPos(pos) { + Some(line[..pos].into()) + } else { + None + } } else { None } - } else { - None }) } diff --git a/clippy_lints/src/write.rs b/clippy_lints/src/write.rs index 3b10b7b82a089..063f94582b9d1 100644 --- a/clippy_lints/src/write.rs +++ b/clippy_lints/src/write.rs @@ -297,10 +297,13 @@ impl EarlyLintPass for Write { if let (Some(fmt_str), expr) = self.check_tts(cx, &mac.args.inner_tokens(), true) { if fmt_str.symbol == Symbol::intern("") { let mut applicability = Applicability::MachineApplicable; - let suggestion = expr.map_or_else(|| { - applicability = Applicability::HasPlaceholders; - Cow::Borrowed("v") - }, |e| snippet_with_applicability(cx, e.span, "v", &mut Applicability::MachineApplicable)); + let suggestion = expr.map_or_else( + || { + applicability = Applicability::HasPlaceholders; + Cow::Borrowed("v") + }, + |e| snippet_with_applicability(cx, e.span, "v", &mut Applicability::MachineApplicable), + ); span_lint_and_sugg( cx, From 6e2d55c8db04a80f9c217f2089066b29302f62a9 Mon Sep 17 00:00:00 2001 From: JarredAllen Date: Sat, 27 Jun 2020 16:55:47 -0700 Subject: [PATCH 45/99] Update compile-test to follow new lint --- tests/compile-test.rs | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/tests/compile-test.rs b/tests/compile-test.rs index 99505fc6b29b2..eb6d495acbe20 100644 --- a/tests/compile-test.rs +++ b/tests/compile-test.rs @@ -12,19 +12,11 @@ use std::path::{Path, PathBuf}; mod cargo; fn host_lib() -> PathBuf { - if let Some(path) = option_env!("HOST_LIBS") { - PathBuf::from(path) - } else { - cargo::CARGO_TARGET_DIR.join(env!("PROFILE")) - } + option_env!("HOST_LIBS").map_or(cargo::CARGO_TARGET_DIR.join(env!("PROFILE")), PathBuf::from) } fn clippy_driver_path() -> PathBuf { - if let Some(path) = option_env!("CLIPPY_DRIVER_PATH") { - PathBuf::from(path) - } else { - cargo::TARGET_LIB.join("clippy-driver") - } + option_env!("CLIPPY_DRIVER_PATH").map_or(cargo::TARGET_LIB.join("clippy-driver"), PathBuf::from) } // When we'll want to use `extern crate ..` for a dependency that is used From 1c32263176d95ae47928d1955e44a4315ffcea2d Mon Sep 17 00:00:00 2001 From: JarredAllen Date: Wed, 1 Jul 2020 11:41:11 -0700 Subject: [PATCH 46/99] Formatted updates to lints --- clippy_lints/src/minmax.rs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/clippy_lints/src/minmax.rs b/clippy_lints/src/minmax.rs index 5eb8398d68e51..2e5f5f10f4b9e 100644 --- a/clippy_lints/src/minmax.rs +++ b/clippy_lints/src/minmax.rs @@ -87,10 +87,12 @@ fn fetch_const<'a>(cx: &LateContext<'_>, args: &'a [Expr<'a>], m: MinMax) -> Opt return None; } constant_simple(cx, cx.tables, &args[0]).map_or_else( - || if let Some(c) = constant_simple(cx, cx.tables(), &args[1]) { - Some((m, c, &args[0])) - } else { - None + || { + if let Some(c) = constant_simple(cx, cx.tables(), &args[1]) { + Some((m, c, &args[0])) + } else { + None + } }, |c| { if constant_simple(cx, cx.tables, &args[1]).is_none() { @@ -99,5 +101,6 @@ fn fetch_const<'a>(cx: &LateContext<'_>, args: &'a [Expr<'a>], m: MinMax) -> Opt } else { None } - }) + }, + ) } From c8f700ea697f74ef8f86891b050c859cf457e3ab Mon Sep 17 00:00:00 2001 From: JarredAllen Date: Fri, 3 Jul 2020 20:28:40 -0700 Subject: [PATCH 47/99] Fixed compile errors --- clippy_lints/src/attrs.rs | 2 +- clippy_lints/src/if_let_mutex.rs | 2 +- clippy_lints/src/minmax.rs | 14 ++++---------- clippy_lints/src/option_if_let_else.rs | 14 +++++++------- clippy_lints/src/shadow.rs | 2 +- 5 files changed, 14 insertions(+), 20 deletions(-) diff --git a/clippy_lints/src/attrs.rs b/clippy_lints/src/attrs.rs index c4397560d7db1..d68d0d8ccf58d 100644 --- a/clippy_lints/src/attrs.rs +++ b/clippy_lints/src/attrs.rs @@ -480,7 +480,7 @@ fn is_relevant_trait(cx: &LateContext<'_>, item: &TraitItem<'_>) -> bool { } } -fn is_relevant_block(cx: &LateContext<'_, '_>, tables: &ty::TypeckTables<'_>, block: &Block<'_>) -> bool { +fn is_relevant_block(cx: &LateContext<'_>, tables: &ty::TypeckTables<'_>, block: &Block<'_>) -> bool { block.stmts.first().map_or( block.expr.as_ref().map_or(false, |e| is_relevant_expr(cx, tables, e)), |stmt| match &stmt.kind { diff --git a/clippy_lints/src/if_let_mutex.rs b/clippy_lints/src/if_let_mutex.rs index 5426e14ead573..fbd2eeacc6ef5 100644 --- a/clippy_lints/src/if_let_mutex.rs +++ b/clippy_lints/src/if_let_mutex.rs @@ -136,7 +136,7 @@ impl<'tcx> Visitor<'tcx> for ArmVisitor<'_, 'tcx> { } impl<'tcx, 'l> ArmVisitor<'tcx, 'l> { - fn same_mutex(&self, cx: &LateContext<'_, '_>, op_mutex: &Expr<'_>) -> bool { + fn same_mutex(&self, cx: &LateContext<'_>, op_mutex: &Expr<'_>) -> bool { self.found_mutex .map_or(false, |arm_mutex| SpanlessEq::new(cx).eq_expr(op_mutex, arm_mutex)) } diff --git a/clippy_lints/src/minmax.rs b/clippy_lints/src/minmax.rs index 2e5f5f10f4b9e..c8aa98d348927 100644 --- a/clippy_lints/src/minmax.rs +++ b/clippy_lints/src/minmax.rs @@ -86,18 +86,12 @@ fn fetch_const<'a>(cx: &LateContext<'_>, args: &'a [Expr<'a>], m: MinMax) -> Opt if args.len() != 2 { return None; } - constant_simple(cx, cx.tables, &args[0]).map_or_else( - || { - if let Some(c) = constant_simple(cx, cx.tables(), &args[1]) { - Some((m, c, &args[0])) - } else { - None - } - }, + constant_simple(cx, cx.tables(), &args[0]).map_or_else( + || constant_simple(cx, cx.tables(), &args[1]).map(|c| (m, c, &args[0])), |c| { - if constant_simple(cx, cx.tables, &args[1]).is_none() { + if constant_simple(cx, cx.tables(), &args[1]).is_none() { // otherwise ignore - Some((c, &args[1])) + Some((m, c, &args[1])) } else { None } diff --git a/clippy_lints/src/option_if_let_else.rs b/clippy_lints/src/option_if_let_else.rs index ab9ea76a83896..8dbe58763bfb2 100644 --- a/clippy_lints/src/option_if_let_else.rs +++ b/clippy_lints/src/option_if_let_else.rs @@ -70,9 +70,9 @@ declare_clippy_lint! { declare_lint_pass!(OptionIfLetElse => [OPTION_IF_LET_ELSE]); /// Returns true iff the given expression is the result of calling `Result::ok` -fn is_result_ok(cx: &LateContext<'_, '_>, expr: &'_ Expr<'_>) -> bool { +fn is_result_ok(cx: &LateContext<'_>, expr: &'_ Expr<'_>) -> bool { if let ExprKind::MethodCall(ref path, _, &[ref receiver], _) = &expr.kind { - path.ident.name.to_ident_string() == "ok" && match_type(cx, &cx.tables.expr_ty(&receiver), &paths::RESULT) + path.ident.name.to_ident_string() == "ok" && match_type(cx, &cx.tables().expr_ty(&receiver), &paths::RESULT) } else { false } @@ -157,7 +157,7 @@ fn extract_body_from_arm<'a>(arm: &'a Arm<'a>) -> Option<&'a Expr<'a>> { /// If this is the else body of an if/else expression, then we need to wrap /// it in curcly braces. Otherwise, we don't. -fn should_wrap_in_braces(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> bool { +fn should_wrap_in_braces(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { utils::get_enclosing_block(cx, expr.hir_id).map_or(false, |parent| { if let Some(Expr { kind: @@ -181,7 +181,7 @@ fn should_wrap_in_braces(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> bool { }) } -fn format_option_in_sugg(cx: &LateContext<'_, '_>, cond_expr: &Expr<'_>, as_ref: bool, as_mut: bool) -> String { +fn format_option_in_sugg(cx: &LateContext<'_>, cond_expr: &Expr<'_>, as_ref: bool, as_mut: bool) -> String { format!( "{}{}", Sugg::hir(cx, cond_expr, "..").maybe_par(), @@ -198,7 +198,7 @@ fn format_option_in_sugg(cx: &LateContext<'_, '_>, cond_expr: &Expr<'_>, as_ref: /// If this expression is the option if let/else construct we're detecting, then /// this function returns an `OptionIfLetElseOccurence` struct with details if /// this construct is found, or None if this construct is not found. -fn detect_option_if_let_else<'a>(cx: &LateContext<'_, 'a>, expr: &'a Expr<'a>) -> Option { +fn detect_option_if_let_else(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option { if_chain! { if !utils::in_macro(expr.span); // Don't lint macros, because it behaves weirdly if let ExprKind::Match(cond_expr, arms, MatchSource::IfLetDesugar{contains_else_clause: true}) = &expr.kind; @@ -242,8 +242,8 @@ fn detect_option_if_let_else<'a>(cx: &LateContext<'_, 'a>, expr: &'a Expr<'a>) - } } -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for OptionIfLetElse { - fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) { +impl<'a> LateLintPass<'a> for OptionIfLetElse { + fn check_expr(&mut self, cx: &LateContext<'a>, expr: &Expr<'_>) { if let Some(detection) = detect_option_if_let_else(cx, expr) { span_lint_and_sugg( cx, diff --git a/clippy_lints/src/shadow.rs b/clippy_lints/src/shadow.rs index f16db2df3a927..4cdff63f1180a 100644 --- a/clippy_lints/src/shadow.rs +++ b/clippy_lints/src/shadow.rs @@ -164,7 +164,7 @@ fn check_local<'tcx>(cx: &LateContext<'tcx>, local: &'tcx Local<'_>, bindings: & } fn is_binding(cx: &LateContext<'_>, pat_id: HirId) -> bool { - let var_ty = cx.tables.node_type_opt(pat_id); + let var_ty = cx.tables().node_type_opt(pat_id); var_ty.map_or(false, |var_ty| match var_ty.kind { ty::Adt(..) => false, _ => true, From 3503247c11d80f0f17a36083878e6df114004d10 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Thu, 2 Jul 2020 20:52:40 -0400 Subject: [PATCH 48/99] Shrink ParamEnv to 16 bytes --- clippy_lints/src/needless_pass_by_value.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clippy_lints/src/needless_pass_by_value.rs b/clippy_lints/src/needless_pass_by_value.rs index 6954f0cc683f1..2c68ebc1f8a90 100644 --- a/clippy_lints/src/needless_pass_by_value.rs +++ b/clippy_lints/src/needless_pass_by_value.rs @@ -111,7 +111,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessPassByValue { let fn_def_id = cx.tcx.hir().local_def_id(hir_id); - let preds = traits::elaborate_predicates(cx.tcx, cx.param_env.caller_bounds.iter()) + let preds = traits::elaborate_predicates(cx.tcx, cx.param_env.caller_bounds().iter()) .filter(|p| !p.is_global()) .filter_map(|obligation| { if let ty::PredicateKind::Trait(poly_trait_ref, _) = obligation.predicate.kind() { From c478b5473d6623622d318d058477f5f09e2eeb52 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 3 Jul 2020 11:58:05 +0200 Subject: [PATCH 49/99] add as_ptr method to raw slices --- src/libcore/ptr/const_ptr.rs | 21 +++++++++++++++++++++ src/libcore/ptr/mut_ptr.rs | 21 +++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/src/libcore/ptr/const_ptr.rs b/src/libcore/ptr/const_ptr.rs index d1d7a71523822..f926befb4b323 100644 --- a/src/libcore/ptr/const_ptr.rs +++ b/src/libcore/ptr/const_ptr.rs @@ -826,6 +826,27 @@ impl *const [T] { // Only `std` can make this guarantee. unsafe { Repr { rust: self }.raw }.len } + + /// Returns a raw pointer to the slice's buffer. + /// + /// This is equivalent to casting `self` to `*const T`, but more type-safe. + /// + /// # Examples + /// + /// ```rust + /// #![feature(slice_ptr_ptr)] + /// + /// use std::ptr; + /// + /// let slice: *const [i8] = ptr::slice_from_raw_parts(ptr::null(), 3); + /// assert_eq!(slice.as_ptr(), 0 as *const i8); + /// ``` + #[inline] + #[unstable(feature = "slice_ptr_ptr", issue = "none")] + #[rustc_const_unstable(feature = "const_slice_ptr_ptr", issue = "none")] + pub const fn as_ptr(self) -> *const T { + self as *const T + } } // Equality for pointers diff --git a/src/libcore/ptr/mut_ptr.rs b/src/libcore/ptr/mut_ptr.rs index 7d4b6339b511f..7fc4805c9211b 100644 --- a/src/libcore/ptr/mut_ptr.rs +++ b/src/libcore/ptr/mut_ptr.rs @@ -1028,6 +1028,27 @@ impl *mut [T] { // Only `std` can make this guarantee. unsafe { Repr { rust_mut: self }.raw }.len } + + /// Returns a raw pointer to the slice's buffer. + /// + /// This is equivalent to casting `self` to `*mut T`, but more type-safe. + /// + /// # Examples + /// + /// ```rust + /// #![feature(slice_ptr_ptr)] + /// + /// use std::ptr; + /// + /// let slice: *mut [i8] = ptr::slice_from_raw_parts_mut(ptr::null_mut(), 3); + /// assert_eq!(slice.as_ptr(), 0 as *mut i8); + /// ``` + #[inline] + #[unstable(feature = "slice_ptr_ptr", issue = "none")] + #[rustc_const_unstable(feature = "const_slice_ptr_ptr", issue = "none")] + pub const fn as_ptr(self) -> *mut T { + self as *mut T + } } // Equality for pointers From 3b1d5e6d792fb47c9a95c4ea210ce88174f18b13 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 3 Jul 2020 12:04:36 +0200 Subject: [PATCH 50/99] call the mut version as_mut_ptr and also add an as_ptr-like method to NonNull slices --- src/libcore/lib.rs | 1 + src/libcore/ptr/mut_ptr.rs | 4 ++-- src/libcore/ptr/non_null.rs | 20 ++++++++++++++++++++ 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index 50c56434fa9a1..66a1bea0c44b5 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -93,6 +93,7 @@ #![feature(const_slice_ptr_len)] #![feature(const_type_name)] #![feature(const_likely)] +#![feature(const_slice_ptr_ptr)] #![feature(custom_inner_attributes)] #![feature(decl_macro)] #![feature(doc_cfg)] diff --git a/src/libcore/ptr/mut_ptr.rs b/src/libcore/ptr/mut_ptr.rs index 7fc4805c9211b..70a81f85da8f4 100644 --- a/src/libcore/ptr/mut_ptr.rs +++ b/src/libcore/ptr/mut_ptr.rs @@ -1041,12 +1041,12 @@ impl *mut [T] { /// use std::ptr; /// /// let slice: *mut [i8] = ptr::slice_from_raw_parts_mut(ptr::null_mut(), 3); - /// assert_eq!(slice.as_ptr(), 0 as *mut i8); + /// assert_eq!(slice.as_mut_ptr(), 0 as *mut i8); /// ``` #[inline] #[unstable(feature = "slice_ptr_ptr", issue = "none")] #[rustc_const_unstable(feature = "const_slice_ptr_ptr", issue = "none")] - pub const fn as_ptr(self) -> *mut T { + pub const fn as_mut_ptr(self) -> *mut T { self as *mut T } } diff --git a/src/libcore/ptr/non_null.rs b/src/libcore/ptr/non_null.rs index c2d31bfb6a4ee..3461d224c46b9 100644 --- a/src/libcore/ptr/non_null.rs +++ b/src/libcore/ptr/non_null.rs @@ -204,6 +204,26 @@ impl NonNull<[T]> { pub const fn len(self) -> usize { self.as_ptr().len() } + + /// Returns a non-null pointer to the slice's buffer. + /// + /// # Examples + /// + /// ```rust + /// #![feature(slice_ptr_ptr, nonnull_slice_from_raw_parts)] + /// + /// use std::ptr::NonNull; + /// + /// let slice: NonNull<[i8]> = NonNull::slice_from_raw_parts(NonNull::dangling(), 3); + /// assert_eq!(slice.as_non_null_ptr(), NonNull::new(1 as *mut i8).unwrap()); + /// ``` + #[inline] + #[unstable(feature = "slice_ptr_ptr", issue = "none")] + #[rustc_const_unstable(feature = "const_slice_ptr_ptr", issue = "none")] + pub const fn as_non_null_ptr(self) -> NonNull { + // SAFETY: We know `self` is non-null. + unsafe { NonNull::new_unchecked(self.as_ptr().as_mut_ptr()) } + } } #[stable(feature = "nonnull", since = "1.25.0")] From 90580c7b0e51050c892613664db79493df7a2af5 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 5 Jul 2020 18:02:00 +0200 Subject: [PATCH 51/99] make unchecked slice indexing helper methods use raw pointers --- src/libcore/slice/mod.rs | 111 ++++++++++++++-------------- src/libcore/str/mod.rs | 152 +++++++++++++++++++-------------------- 2 files changed, 134 insertions(+), 129 deletions(-) diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs index e7a2d7adedea0..88deeac00ff14 100644 --- a/src/libcore/slice/mod.rs +++ b/src/libcore/slice/mod.rs @@ -310,8 +310,10 @@ impl [T] { where I: SliceIndex, { - // SAFETY: the caller must uphold the safety requirements for `get_unchecked`. - unsafe { index.get_unchecked(self) } + // SAFETY: the caller must uphold most of the safety requirements for `get_unchecked`; + // the slice is dereferencable because `self` is a safe reference. + // The returned pointer is safe because impls of `SliceIndex` have to guarantee that it is. + unsafe { &*index.get_unchecked(self) } } /// Returns a mutable reference to an element or subslice, without doing @@ -342,8 +344,10 @@ impl [T] { where I: SliceIndex, { - // SAFETY: the caller must uphold the safety requirements for `get_unchecked_mut`. - unsafe { index.get_unchecked_mut(self) } + // SAFETY: the caller must uphold the safety requirements for `get_unchecked_mut`; + // the slice is dereferencable because `self` is a safe reference. + // The returned pointer is safe because impls of `SliceIndex` have to guarantee that it is. + unsafe { &mut *index.get_unchecked_mut(self) } } /// Returns a raw pointer to the slice's buffer. @@ -2910,6 +2914,9 @@ mod private_slice_index { } /// A helper trait used for indexing operations. +/// +/// Implementations of this trait have to promise that if the argument +/// to `get_(mut_)unchecked` is a safe reference, then so is the result. #[stable(feature = "slice_get_slice", since = "1.28.0")] #[rustc_on_unimplemented( on(T = "str", label = "string indices are ranges of `usize`",), @@ -2921,7 +2928,7 @@ see chapter in The Book : private_slice_index::Sealed { +pub unsafe trait SliceIndex: private_slice_index::Sealed { /// The output type returned by methods. #[stable(feature = "slice_get_slice", since = "1.28.0")] type Output: ?Sized; @@ -2938,21 +2945,21 @@ pub trait SliceIndex: private_slice_index::Sealed { /// Returns a shared reference to the output at this location, without /// performing any bounds checking. - /// Calling this method with an out-of-bounds index is *[undefined behavior]* - /// even if the resulting reference is not used. + /// Calling this method with an out-of-bounds index or a dangling `slice` pointer + /// is *[undefined behavior]* even if the resulting reference is not used. /// /// [undefined behavior]: ../../reference/behavior-considered-undefined.html #[unstable(feature = "slice_index_methods", issue = "none")] - unsafe fn get_unchecked(self, slice: &T) -> &Self::Output; + unsafe fn get_unchecked(self, slice: *const T) -> *const Self::Output; /// Returns a mutable reference to the output at this location, without /// performing any bounds checking. - /// Calling this method with an out-of-bounds index is *[undefined behavior]* - /// even if the resulting reference is not used. + /// Calling this method with an out-of-bounds index or a dangling `slice` pointer + /// is *[undefined behavior]* even if the resulting reference is not used. /// /// [undefined behavior]: ../../reference/behavior-considered-undefined.html #[unstable(feature = "slice_index_methods", issue = "none")] - unsafe fn get_unchecked_mut(self, slice: &mut T) -> &mut Self::Output; + unsafe fn get_unchecked_mut(self, slice: *mut T) -> *mut Self::Output; /// Returns a shared reference to the output at this location, panicking /// if out of bounds. @@ -2968,33 +2975,32 @@ pub trait SliceIndex: private_slice_index::Sealed { } #[stable(feature = "slice_get_slice_impls", since = "1.15.0")] -impl SliceIndex<[T]> for usize { +unsafe impl SliceIndex<[T]> for usize { type Output = T; #[inline] fn get(self, slice: &[T]) -> Option<&T> { - if self < slice.len() { unsafe { Some(self.get_unchecked(slice)) } } else { None } + if self < slice.len() { unsafe { Some(&*self.get_unchecked(slice)) } } else { None } } #[inline] fn get_mut(self, slice: &mut [T]) -> Option<&mut T> { - if self < slice.len() { unsafe { Some(self.get_unchecked_mut(slice)) } } else { None } + if self < slice.len() { unsafe { Some(&mut *self.get_unchecked_mut(slice)) } } else { None } } #[inline] - unsafe fn get_unchecked(self, slice: &[T]) -> &T { - // SAFETY: `slice` cannot be longer than `isize::MAX` and - // the caller guarantees that `self` is in bounds of `slice` - // so `self` cannot overflow an `isize`, so the call to `add` is safe. - // The obtained pointer comes from a reference which is guaranteed - // to be valid. - unsafe { &*slice.as_ptr().add(self) } + unsafe fn get_unchecked(self, slice: *const [T]) -> *const T { + // SAFETY: the caller guarantees that `slice` is not dangling, so it + // cannot be longer than `isize::MAX`. They also guarantee that + // `self` is in bounds of `slice` so `self` cannot overflow an `isize`, + // so the call to `add` is safe. + unsafe { slice.as_ptr().add(self) } } #[inline] - unsafe fn get_unchecked_mut(self, slice: &mut [T]) -> &mut T { + unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut T { // SAFETY: see comments for `get_unchecked` above. - unsafe { &mut *slice.as_mut_ptr().add(self) } + unsafe { slice.as_mut_ptr().add(self) } } #[inline] @@ -3011,7 +3017,7 @@ impl SliceIndex<[T]> for usize { } #[stable(feature = "slice_get_slice_impls", since = "1.15.0")] -impl SliceIndex<[T]> for ops::Range { +unsafe impl SliceIndex<[T]> for ops::Range { type Output = [T]; #[inline] @@ -3019,7 +3025,7 @@ impl SliceIndex<[T]> for ops::Range { if self.start > self.end || self.end > slice.len() { None } else { - unsafe { Some(self.get_unchecked(slice)) } + unsafe { Some(&*self.get_unchecked(slice)) } } } @@ -3028,24 +3034,25 @@ impl SliceIndex<[T]> for ops::Range { if self.start > self.end || self.end > slice.len() { None } else { - unsafe { Some(self.get_unchecked_mut(slice)) } + unsafe { Some(&mut *self.get_unchecked_mut(slice)) } } } #[inline] - unsafe fn get_unchecked(self, slice: &[T]) -> &[T] { - // SAFETY: `slice` cannot be longer than `isize::MAX` and - // the caller guarantees that `self` is in bounds of `slice` - // so `self` cannot overflow an `isize`, so the call to `add` is safe. - // Also, since the caller guarantees that `self` is in bounds of `slice`, - // `from_raw_parts` will give a subslice of `slice` which is always safe. - unsafe { from_raw_parts(slice.as_ptr().add(self.start), self.end - self.start) } + unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] { + // SAFETY: the caller guarantees that `slice` is not dangling, so it + // cannot be longer than `isize::MAX`. They also guarantee that + // `self` is in bounds of `slice` so `self` cannot overflow an `isize`, + // so the call to `add` is safe. + unsafe { ptr::slice_from_raw_parts(slice.as_ptr().add(self.start), self.end - self.start) } } #[inline] - unsafe fn get_unchecked_mut(self, slice: &mut [T]) -> &mut [T] { + unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] { // SAFETY: see comments for `get_unchecked` above. - unsafe { from_raw_parts_mut(slice.as_mut_ptr().add(self.start), self.end - self.start) } + unsafe { + ptr::slice_from_raw_parts_mut(slice.as_mut_ptr().add(self.start), self.end - self.start) + } } #[inline] @@ -3055,7 +3062,7 @@ impl SliceIndex<[T]> for ops::Range { } else if self.end > slice.len() { slice_index_len_fail(self.end, slice.len()); } - unsafe { self.get_unchecked(slice) } + unsafe { &*self.get_unchecked(slice) } } #[inline] @@ -3065,12 +3072,12 @@ impl SliceIndex<[T]> for ops::Range { } else if self.end > slice.len() { slice_index_len_fail(self.end, slice.len()); } - unsafe { self.get_unchecked_mut(slice) } + unsafe { &mut *self.get_unchecked_mut(slice) } } } #[stable(feature = "slice_get_slice_impls", since = "1.15.0")] -impl SliceIndex<[T]> for ops::RangeTo { +unsafe impl SliceIndex<[T]> for ops::RangeTo { type Output = [T]; #[inline] @@ -3084,13 +3091,13 @@ impl SliceIndex<[T]> for ops::RangeTo { } #[inline] - unsafe fn get_unchecked(self, slice: &[T]) -> &[T] { + unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] { // SAFETY: the caller has to uphold the safety contract for `get_unchecked`. unsafe { (0..self.end).get_unchecked(slice) } } #[inline] - unsafe fn get_unchecked_mut(self, slice: &mut [T]) -> &mut [T] { + unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] { // SAFETY: the caller has to uphold the safety contract for `get_unchecked_mut`. unsafe { (0..self.end).get_unchecked_mut(slice) } } @@ -3107,7 +3114,7 @@ impl SliceIndex<[T]> for ops::RangeTo { } #[stable(feature = "slice_get_slice_impls", since = "1.15.0")] -impl SliceIndex<[T]> for ops::RangeFrom { +unsafe impl SliceIndex<[T]> for ops::RangeFrom { type Output = [T]; #[inline] @@ -3121,13 +3128,13 @@ impl SliceIndex<[T]> for ops::RangeFrom { } #[inline] - unsafe fn get_unchecked(self, slice: &[T]) -> &[T] { + unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] { // SAFETY: the caller has to uphold the safety contract for `get_unchecked`. unsafe { (self.start..slice.len()).get_unchecked(slice) } } #[inline] - unsafe fn get_unchecked_mut(self, slice: &mut [T]) -> &mut [T] { + unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] { // SAFETY: the caller has to uphold the safety contract for `get_unchecked_mut`. unsafe { (self.start..slice.len()).get_unchecked_mut(slice) } } @@ -3144,7 +3151,7 @@ impl SliceIndex<[T]> for ops::RangeFrom { } #[stable(feature = "slice_get_slice_impls", since = "1.15.0")] -impl SliceIndex<[T]> for ops::RangeFull { +unsafe impl SliceIndex<[T]> for ops::RangeFull { type Output = [T]; #[inline] @@ -3158,12 +3165,12 @@ impl SliceIndex<[T]> for ops::RangeFull { } #[inline] - unsafe fn get_unchecked(self, slice: &[T]) -> &[T] { + unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] { slice } #[inline] - unsafe fn get_unchecked_mut(self, slice: &mut [T]) -> &mut [T] { + unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] { slice } @@ -3179,7 +3186,7 @@ impl SliceIndex<[T]> for ops::RangeFull { } #[stable(feature = "inclusive_range", since = "1.26.0")] -impl SliceIndex<[T]> for ops::RangeInclusive { +unsafe impl SliceIndex<[T]> for ops::RangeInclusive { type Output = [T]; #[inline] @@ -3197,13 +3204,13 @@ impl SliceIndex<[T]> for ops::RangeInclusive { } #[inline] - unsafe fn get_unchecked(self, slice: &[T]) -> &[T] { + unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] { // SAFETY: the caller has to uphold the safety contract for `get_unchecked`. unsafe { (*self.start()..self.end() + 1).get_unchecked(slice) } } #[inline] - unsafe fn get_unchecked_mut(self, slice: &mut [T]) -> &mut [T] { + unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] { // SAFETY: the caller has to uphold the safety contract for `get_unchecked_mut`. unsafe { (*self.start()..self.end() + 1).get_unchecked_mut(slice) } } @@ -3226,7 +3233,7 @@ impl SliceIndex<[T]> for ops::RangeInclusive { } #[stable(feature = "inclusive_range", since = "1.26.0")] -impl SliceIndex<[T]> for ops::RangeToInclusive { +unsafe impl SliceIndex<[T]> for ops::RangeToInclusive { type Output = [T]; #[inline] @@ -3240,13 +3247,13 @@ impl SliceIndex<[T]> for ops::RangeToInclusive { } #[inline] - unsafe fn get_unchecked(self, slice: &[T]) -> &[T] { + unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] { // SAFETY: the caller has to uphold the safety contract for `get_unchecked`. unsafe { (0..=self.end).get_unchecked(slice) } } #[inline] - unsafe fn get_unchecked_mut(self, slice: &mut [T]) -> &mut [T] { + unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] { // SAFETY: the caller has to uphold the safety contract for `get_unchecked_mut`. unsafe { (0..=self.end).get_unchecked_mut(slice) } } diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index 0014501d2c4d0..5c4134b0749b9 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -1731,7 +1731,8 @@ Section: Trait implementations mod traits { use crate::cmp::Ordering; use crate::ops; - use crate::slice::{self, SliceIndex}; + use crate::ptr; + use crate::slice::SliceIndex; /// Implements ordering of strings. /// @@ -1822,7 +1823,7 @@ mod traits { /// /// Equivalent to `&self[0 .. len]` or `&mut self[0 .. len]`. #[stable(feature = "str_checked_slicing", since = "1.20.0")] - impl SliceIndex for ops::RangeFull { + unsafe impl SliceIndex for ops::RangeFull { type Output = str; #[inline] fn get(self, slice: &str) -> Option<&Self::Output> { @@ -1833,11 +1834,11 @@ mod traits { Some(slice) } #[inline] - unsafe fn get_unchecked(self, slice: &str) -> &Self::Output { + unsafe fn get_unchecked(self, slice: *const str) -> *const Self::Output { slice } #[inline] - unsafe fn get_unchecked_mut(self, slice: &mut str) -> &mut Self::Output { + unsafe fn get_unchecked_mut(self, slice: *mut str) -> *mut Self::Output { slice } #[inline] @@ -1886,7 +1887,7 @@ mod traits { /// // &s[3 .. 100]; /// ``` #[stable(feature = "str_checked_slicing", since = "1.20.0")] - impl SliceIndex for ops::Range { + unsafe impl SliceIndex for ops::Range { type Output = str; #[inline] fn get(self, slice: &str) -> Option<&Self::Output> { @@ -1894,8 +1895,10 @@ mod traits { && slice.is_char_boundary(self.start) && slice.is_char_boundary(self.end) { - // SAFETY: just checked that `start` and `end` are on a char boundary. - Some(unsafe { self.get_unchecked(slice) }) + // SAFETY: just checked that `start` and `end` are on a char boundary, + // and we are passing in a safe reference, so the return value will also be one. + // We also checked char boundaries, so this is valid UTF-8. + Some(unsafe { &*self.get_unchecked(slice) }) } else { None } @@ -1907,34 +1910,28 @@ mod traits { && slice.is_char_boundary(self.end) { // SAFETY: just checked that `start` and `end` are on a char boundary. - Some(unsafe { self.get_unchecked_mut(slice) }) + // We know the pointer is unique because we got it from `slice`. + Some(unsafe { &mut *self.get_unchecked_mut(slice) }) } else { None } } #[inline] - unsafe fn get_unchecked(self, slice: &str) -> &Self::Output { + unsafe fn get_unchecked(self, slice: *const str) -> *const Self::Output { + let slice = slice as *const [u8]; // SAFETY: the caller guarantees that `self` is in bounds of `slice` // which satisfies all the conditions for `add`. let ptr = unsafe { slice.as_ptr().add(self.start) }; let len = self.end - self.start; - // SAFETY: as the caller guarantees that `self` is in bounds of `slice`, - // we can safely construct a subslice with `from_raw_parts` and use it - // since we return a shared thus immutable reference. - // The call to `from_utf8_unchecked` is safe since the data comes from - // a `str` which is guaranteed to be valid utf8, since the caller - // must guarantee that `self.start` and `self.end` are char boundaries. - unsafe { super::from_utf8_unchecked(slice::from_raw_parts(ptr, len)) } + ptr::slice_from_raw_parts(ptr, len) as *const str } #[inline] - unsafe fn get_unchecked_mut(self, slice: &mut str) -> &mut Self::Output { + unsafe fn get_unchecked_mut(self, slice: *mut str) -> *mut Self::Output { + let slice = slice as *mut [u8]; // SAFETY: see comments for `get_unchecked`. let ptr = unsafe { slice.as_mut_ptr().add(self.start) }; let len = self.end - self.start; - // SAFETY: mostly identical to the comments for `get_unchecked`, except that we - // can return a mutable reference since the caller passed a mutable reference - // and is thus guaranteed to have exclusive write access to `slice`. - unsafe { super::from_utf8_unchecked_mut(slice::from_raw_parts_mut(ptr, len)) } + ptr::slice_from_raw_parts_mut(ptr, len) as *mut str } #[inline] fn index(self, slice: &str) -> &Self::Output { @@ -1949,8 +1946,9 @@ mod traits { && slice.is_char_boundary(self.start) && slice.is_char_boundary(self.end) { - // SAFETY: just checked that `start` and `end` are on a char boundary. - unsafe { self.get_unchecked_mut(slice) } + // SAFETY: just checked that `start` and `end` are on a char boundary, + // and we are passing in a safe reference, so the return value will also be one. + unsafe { &mut *self.get_unchecked_mut(slice) } } else { super::slice_error_fail(slice, self.start, self.end) } @@ -1973,13 +1971,14 @@ mod traits { /// Panics if `end` does not point to the starting byte offset of a /// character (as defined by `is_char_boundary`), or if `end > len`. #[stable(feature = "str_checked_slicing", since = "1.20.0")] - impl SliceIndex for ops::RangeTo { + unsafe impl SliceIndex for ops::RangeTo { type Output = str; #[inline] fn get(self, slice: &str) -> Option<&Self::Output> { if slice.is_char_boundary(self.end) { - // SAFETY: just checked that `end` is on a char boundary. - Some(unsafe { self.get_unchecked(slice) }) + // SAFETY: just checked that `end` is on a char boundary, + // and we are passing in a safe reference, so the return value will also be one. + Some(unsafe { &*self.get_unchecked(slice) }) } else { None } @@ -1987,30 +1986,24 @@ mod traits { #[inline] fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> { if slice.is_char_boundary(self.end) { - // SAFETY: just checked that `end` is on a char boundary. - Some(unsafe { self.get_unchecked_mut(slice) }) + // SAFETY: just checked that `end` is on a char boundary, + // and we are passing in a safe reference, so the return value will also be one. + Some(unsafe { &mut *self.get_unchecked_mut(slice) }) } else { None } } #[inline] - unsafe fn get_unchecked(self, slice: &str) -> &Self::Output { + unsafe fn get_unchecked(self, slice: *const str) -> *const Self::Output { + let slice = slice as *const [u8]; let ptr = slice.as_ptr(); - // SAFETY: as the caller guarantees that `self` is in bounds of `slice`, - // we can safely construct a subslice with `from_raw_parts` and use it - // since we return a shared thus immutable reference. - // The call to `from_utf8_unchecked` is safe since the data comes from - // a `str` which is guaranteed to be valid utf8, since the caller - // must guarantee that `self.end` is a char boundary. - unsafe { super::from_utf8_unchecked(slice::from_raw_parts(ptr, self.end)) } + ptr::slice_from_raw_parts(ptr, self.end) as *const str } #[inline] - unsafe fn get_unchecked_mut(self, slice: &mut str) -> &mut Self::Output { + unsafe fn get_unchecked_mut(self, slice: *mut str) -> *mut Self::Output { + let slice = slice as *mut [u8]; let ptr = slice.as_mut_ptr(); - // SAFETY: mostly identical to `get_unchecked`, except that we can safely - // return a mutable reference since the caller passed a mutable reference - // and is thus guaranteed to have exclusive write access to `slice`. - unsafe { super::from_utf8_unchecked_mut(slice::from_raw_parts_mut(ptr, self.end)) } + ptr::slice_from_raw_parts_mut(ptr, self.end) as *mut str } #[inline] fn index(self, slice: &str) -> &Self::Output { @@ -2020,8 +2013,9 @@ mod traits { #[inline] fn index_mut(self, slice: &mut str) -> &mut Self::Output { if slice.is_char_boundary(self.end) { - // SAFETY: just checked that `end` is on a char boundary. - unsafe { self.get_unchecked_mut(slice) } + // SAFETY: just checked that `end` is on a char boundary, + // and we are passing in a safe reference, so the return value will also be one. + unsafe { &mut *self.get_unchecked_mut(slice) } } else { super::slice_error_fail(slice, 0, self.end) } @@ -2045,13 +2039,14 @@ mod traits { /// Panics if `begin` does not point to the starting byte offset of /// a character (as defined by `is_char_boundary`), or if `begin >= len`. #[stable(feature = "str_checked_slicing", since = "1.20.0")] - impl SliceIndex for ops::RangeFrom { + unsafe impl SliceIndex for ops::RangeFrom { type Output = str; #[inline] fn get(self, slice: &str) -> Option<&Self::Output> { if slice.is_char_boundary(self.start) { - // SAFETY: just checked that `start` is on a char boundary. - Some(unsafe { self.get_unchecked(slice) }) + // SAFETY: just checked that `start` is on a char boundary, + // and we are passing in a safe reference, so the return value will also be one. + Some(unsafe { &*self.get_unchecked(slice) }) } else { None } @@ -2059,35 +2054,29 @@ mod traits { #[inline] fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> { if slice.is_char_boundary(self.start) { - // SAFETY: just checked that `start` is on a char boundary. - Some(unsafe { self.get_unchecked_mut(slice) }) + // SAFETY: just checked that `start` is on a char boundary, + // and we are passing in a safe reference, so the return value will also be one. + Some(unsafe { &mut *self.get_unchecked_mut(slice) }) } else { None } } #[inline] - unsafe fn get_unchecked(self, slice: &str) -> &Self::Output { + unsafe fn get_unchecked(self, slice: *const str) -> *const Self::Output { + let slice = slice as *const [u8]; // SAFETY: the caller guarantees that `self` is in bounds of `slice` // which satisfies all the conditions for `add`. let ptr = unsafe { slice.as_ptr().add(self.start) }; let len = slice.len() - self.start; - // SAFETY: as the caller guarantees that `self` is in bounds of `slice`, - // we can safely construct a subslice with `from_raw_parts` and use it - // since we return a shared thus immutable reference. - // The call to `from_utf8_unchecked` is safe since the data comes from - // a `str` which is guaranteed to be valid utf8, since the caller - // must guarantee that `self.start` is a char boundary. - unsafe { super::from_utf8_unchecked(slice::from_raw_parts(ptr, len)) } + ptr::slice_from_raw_parts(ptr, len) as *const str } #[inline] - unsafe fn get_unchecked_mut(self, slice: &mut str) -> &mut Self::Output { + unsafe fn get_unchecked_mut(self, slice: *mut str) -> *mut Self::Output { + let slice = slice as *mut [u8]; // SAFETY: identical to `get_unchecked`. let ptr = unsafe { slice.as_mut_ptr().add(self.start) }; let len = slice.len() - self.start; - // SAFETY: mostly identical to `get_unchecked`, except that we can safely - // return a mutable reference since the caller passed a mutable reference - // and is thus guaranteed to have exclusive write access to `slice`. - unsafe { super::from_utf8_unchecked_mut(slice::from_raw_parts_mut(ptr, len)) } + ptr::slice_from_raw_parts_mut(ptr, len) as *mut str } #[inline] fn index(self, slice: &str) -> &Self::Output { @@ -2097,8 +2086,9 @@ mod traits { #[inline] fn index_mut(self, slice: &mut str) -> &mut Self::Output { if slice.is_char_boundary(self.start) { - // SAFETY: just checked that `start` is on a char boundary. - unsafe { self.get_unchecked_mut(slice) } + // SAFETY: just checked that `start` is on a char boundary, + // and we are passing in a safe reference, so the return value will also be one. + unsafe { &mut *self.get_unchecked_mut(slice) } } else { super::slice_error_fail(slice, self.start, slice.len()) } @@ -2122,7 +2112,7 @@ mod traits { /// to the ending byte offset of a character (`end + 1` is either a starting /// byte offset or equal to `len`), if `begin > end`, or if `end >= len`. #[stable(feature = "inclusive_range", since = "1.26.0")] - impl SliceIndex for ops::RangeInclusive { + unsafe impl SliceIndex for ops::RangeInclusive { type Output = str; #[inline] fn get(self, slice: &str) -> Option<&Self::Output> { @@ -2141,12 +2131,12 @@ mod traits { } } #[inline] - unsafe fn get_unchecked(self, slice: &str) -> &Self::Output { + unsafe fn get_unchecked(self, slice: *const str) -> *const Self::Output { // SAFETY: the caller must uphold the safety contract for `get_unchecked`. unsafe { (*self.start()..self.end() + 1).get_unchecked(slice) } } #[inline] - unsafe fn get_unchecked_mut(self, slice: &mut str) -> &mut Self::Output { + unsafe fn get_unchecked_mut(self, slice: *mut str) -> *mut Self::Output { // SAFETY: the caller must uphold the safety contract for `get_unchecked_mut`. unsafe { (*self.start()..self.end() + 1).get_unchecked_mut(slice) } } @@ -2181,7 +2171,7 @@ mod traits { /// (`end + 1` is either a starting byte offset as defined by /// `is_char_boundary`, or equal to `len`), or if `end >= len`. #[stable(feature = "inclusive_range", since = "1.26.0")] - impl SliceIndex for ops::RangeToInclusive { + unsafe impl SliceIndex for ops::RangeToInclusive { type Output = str; #[inline] fn get(self, slice: &str) -> Option<&Self::Output> { @@ -2192,12 +2182,12 @@ mod traits { if self.end == usize::MAX { None } else { (..self.end + 1).get_mut(slice) } } #[inline] - unsafe fn get_unchecked(self, slice: &str) -> &Self::Output { + unsafe fn get_unchecked(self, slice: *const str) -> *const Self::Output { // SAFETY: the caller must uphold the safety contract for `get_unchecked`. unsafe { (..self.end + 1).get_unchecked(slice) } } #[inline] - unsafe fn get_unchecked_mut(self, slice: &mut str) -> &mut Self::Output { + unsafe fn get_unchecked_mut(self, slice: *mut str) -> *mut Self::Output { // SAFETY: the caller must uphold the safety contract for `get_unchecked_mut`. unsafe { (..self.end + 1).get_unchecked_mut(slice) } } @@ -2560,8 +2550,10 @@ impl str { #[stable(feature = "str_checked_slicing", since = "1.20.0")] #[inline] pub unsafe fn get_unchecked>(&self, i: I) -> &I::Output { - // SAFETY: the caller must uphold the safety contract for `get_unchecked`. - unsafe { i.get_unchecked(self) } + // SAFETY: the caller must uphold the safety contract for `get_unchecked`; + // the slice is dereferencable because `self` is a safe reference. + // The returned pointer is safe because impls of `SliceIndex` have to guarantee that it is. + unsafe { &*i.get_unchecked(self) } } /// Returns a mutable, unchecked subslice of `str`. @@ -2593,8 +2585,10 @@ impl str { #[stable(feature = "str_checked_slicing", since = "1.20.0")] #[inline] pub unsafe fn get_unchecked_mut>(&mut self, i: I) -> &mut I::Output { - // SAFETY: the caller must uphold the safety contract for `get_unchecked_mut`. - unsafe { i.get_unchecked_mut(self) } + // SAFETY: the caller must uphold the safety contract for `get_unchecked_mut`; + // the slice is dereferencable because `self` is a safe reference. + // The returned pointer is safe because impls of `SliceIndex` have to guarantee that it is. + unsafe { &mut *i.get_unchecked_mut(self) } } /// Creates a string slice from another string slice, bypassing safety @@ -2644,8 +2638,10 @@ impl str { #[rustc_deprecated(since = "1.29.0", reason = "use `get_unchecked(begin..end)` instead")] #[inline] pub unsafe fn slice_unchecked(&self, begin: usize, end: usize) -> &str { - // SAFETY: the caller must uphold the safety contract for `get_unchecked`. - unsafe { (begin..end).get_unchecked(self) } + // SAFETY: the caller must uphold the safety contract for `get_unchecked`; + // the slice is dereferencable because `self` is a safe reference. + // The returned pointer is safe because impls of `SliceIndex` have to guarantee that it is. + unsafe { &*(begin..end).get_unchecked(self) } } /// Creates a string slice from another string slice, bypassing safety @@ -2676,8 +2672,10 @@ impl str { #[rustc_deprecated(since = "1.29.0", reason = "use `get_unchecked_mut(begin..end)` instead")] #[inline] pub unsafe fn slice_mut_unchecked(&mut self, begin: usize, end: usize) -> &mut str { - // SAFETY: the caller must uphold the safety contract for `get_unchecked_mut`. - unsafe { (begin..end).get_unchecked_mut(self) } + // SAFETY: the caller must uphold the safety contract for `get_unchecked_mut`; + // the slice is dereferencable because `self` is a safe reference. + // The returned pointer is safe because impls of `SliceIndex` have to guarantee that it is. + unsafe { &mut *(begin..end).get_unchecked_mut(self) } } /// Divide one string slice into two at an index. From 5f5c98bd8a27b5313d0b1a5830076139c562b6b6 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 5 Jul 2020 18:39:04 +0200 Subject: [PATCH 52/99] add (unchecked) indexing methods to raw pointers and NonNull --- src/libcore/lib.rs | 2 +- src/libcore/ptr/const_ptr.rs | 37 ++++++++++++++++++++++++++++---- src/libcore/ptr/mut_ptr.rs | 38 ++++++++++++++++++++++++++++----- src/libcore/ptr/non_null.rs | 41 +++++++++++++++++++++++++++++++----- 4 files changed, 103 insertions(+), 15 deletions(-) diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index 66a1bea0c44b5..1f906650dfa56 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -93,7 +93,6 @@ #![feature(const_slice_ptr_len)] #![feature(const_type_name)] #![feature(const_likely)] -#![feature(const_slice_ptr_ptr)] #![feature(custom_inner_attributes)] #![feature(decl_macro)] #![feature(doc_cfg)] @@ -149,6 +148,7 @@ #![feature(associated_type_bounds)] #![feature(const_type_id)] #![feature(const_caller_location)] +#![feature(slice_ptr_get)] #![feature(no_niche)] // rust-lang/rust#68303 #![feature(unsafe_block_in_unsafe_fn)] #![deny(unsafe_op_in_unsafe_fn)] diff --git a/src/libcore/ptr/const_ptr.rs b/src/libcore/ptr/const_ptr.rs index f926befb4b323..22c741d4651a5 100644 --- a/src/libcore/ptr/const_ptr.rs +++ b/src/libcore/ptr/const_ptr.rs @@ -2,6 +2,7 @@ use super::*; use crate::cmp::Ordering::{self, Equal, Greater, Less}; use crate::intrinsics; use crate::mem; +use crate::slice::SliceIndex; #[lang = "const_ptr"] impl *const T { @@ -834,19 +835,47 @@ impl *const [T] { /// # Examples /// /// ```rust - /// #![feature(slice_ptr_ptr)] - /// + /// #![feature(slice_ptr_get)] /// use std::ptr; /// /// let slice: *const [i8] = ptr::slice_from_raw_parts(ptr::null(), 3); /// assert_eq!(slice.as_ptr(), 0 as *const i8); /// ``` #[inline] - #[unstable(feature = "slice_ptr_ptr", issue = "none")] - #[rustc_const_unstable(feature = "const_slice_ptr_ptr", issue = "none")] + #[unstable(feature = "slice_ptr_get", issue = "none")] + #[rustc_const_unstable(feature = "slice_ptr_get", issue = "none")] pub const fn as_ptr(self) -> *const T { self as *const T } + + /// Returns a raw pointer to an element or subslice, without doing bounds + /// checking. + /// + /// Calling this method with an out-of-bounds index or when `self` is not dereferencable + /// is *[undefined behavior]* even if the resulting pointer is not used. + /// + /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html + /// + /// # Examples + /// + /// ``` + /// #![feature(slice_ptr_get)] + /// + /// let x = &[1, 2, 4] as *const [i32]; + /// + /// unsafe { + /// assert_eq!(x.get_unchecked(1), x.as_ptr().add(1)); + /// } + /// ``` + #[unstable(feature = "slice_ptr_get", issue = "none")] + #[inline] + pub unsafe fn get_unchecked(self, index: I) -> *const I::Output + where + I: SliceIndex<[T]>, + { + // SAFETY: the caller ensures that `self` is dereferencable and `index` in-bounds. + unsafe { index.get_unchecked(self) } + } } // Equality for pointers diff --git a/src/libcore/ptr/mut_ptr.rs b/src/libcore/ptr/mut_ptr.rs index 70a81f85da8f4..56bade706942a 100644 --- a/src/libcore/ptr/mut_ptr.rs +++ b/src/libcore/ptr/mut_ptr.rs @@ -1,6 +1,7 @@ use super::*; use crate::cmp::Ordering::{self, Equal, Greater, Less}; use crate::intrinsics; +use crate::slice::SliceIndex; #[lang = "mut_ptr"] impl *mut T { @@ -1014,7 +1015,6 @@ impl *mut [T] { /// /// ```rust /// #![feature(slice_ptr_len)] - /// /// use std::ptr; /// /// let slice: *mut [i8] = ptr::slice_from_raw_parts_mut(ptr::null_mut(), 3); @@ -1036,19 +1036,47 @@ impl *mut [T] { /// # Examples /// /// ```rust - /// #![feature(slice_ptr_ptr)] - /// + /// #![feature(slice_ptr_get)] /// use std::ptr; /// /// let slice: *mut [i8] = ptr::slice_from_raw_parts_mut(ptr::null_mut(), 3); /// assert_eq!(slice.as_mut_ptr(), 0 as *mut i8); /// ``` #[inline] - #[unstable(feature = "slice_ptr_ptr", issue = "none")] - #[rustc_const_unstable(feature = "const_slice_ptr_ptr", issue = "none")] + #[unstable(feature = "slice_ptr_get", issue = "none")] + #[rustc_const_unstable(feature = "slice_ptr_get", issue = "none")] pub const fn as_mut_ptr(self) -> *mut T { self as *mut T } + + /// Returns a raw pointer to an element or subslice, without doing bounds + /// checking. + /// + /// Calling this method with an out-of-bounds index or when `self` is not dereferencable + /// is *[undefined behavior]* even if the resulting pointer is not used. + /// + /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html + /// + /// # Examples + /// + /// ``` + /// #![feature(slice_ptr_get)] + /// + /// let x = &mut [1, 2, 4] as *mut [i32]; + /// + /// unsafe { + /// assert_eq!(x.get_unchecked_mut(1), x.as_mut_ptr().add(1)); + /// } + /// ``` + #[unstable(feature = "slice_ptr_get", issue = "none")] + #[inline] + pub unsafe fn get_unchecked_mut(self, index: I) -> *mut I::Output + where + I: SliceIndex<[T]>, + { + // SAFETY: the caller ensures that `self` is dereferencable and `index` in-bounds. + unsafe { index.get_unchecked_mut(self) } + } } // Equality for pointers diff --git a/src/libcore/ptr/non_null.rs b/src/libcore/ptr/non_null.rs index 3461d224c46b9..f59da631b46ab 100644 --- a/src/libcore/ptr/non_null.rs +++ b/src/libcore/ptr/non_null.rs @@ -6,6 +6,7 @@ use crate::marker::Unsize; use crate::mem; use crate::ops::{CoerceUnsized, DispatchFromDyn}; use crate::ptr::Unique; +use crate::slice::SliceIndex; /// `*mut T` but non-zero and covariant. /// @@ -192,7 +193,6 @@ impl NonNull<[T]> { /// /// ```rust /// #![feature(slice_ptr_len, nonnull_slice_from_raw_parts)] - /// /// use std::ptr::NonNull; /// /// let slice: NonNull<[i8]> = NonNull::slice_from_raw_parts(NonNull::dangling(), 3); @@ -210,20 +210,51 @@ impl NonNull<[T]> { /// # Examples /// /// ```rust - /// #![feature(slice_ptr_ptr, nonnull_slice_from_raw_parts)] - /// + /// #![feature(slice_ptr_get, nonnull_slice_from_raw_parts)] /// use std::ptr::NonNull; /// /// let slice: NonNull<[i8]> = NonNull::slice_from_raw_parts(NonNull::dangling(), 3); /// assert_eq!(slice.as_non_null_ptr(), NonNull::new(1 as *mut i8).unwrap()); /// ``` #[inline] - #[unstable(feature = "slice_ptr_ptr", issue = "none")] - #[rustc_const_unstable(feature = "const_slice_ptr_ptr", issue = "none")] + #[unstable(feature = "slice_ptr_get", issue = "none")] + #[rustc_const_unstable(feature = "slice_ptr_get", issue = "none")] pub const fn as_non_null_ptr(self) -> NonNull { // SAFETY: We know `self` is non-null. unsafe { NonNull::new_unchecked(self.as_ptr().as_mut_ptr()) } } + + /// Returns a raw pointer to an element or subslice, without doing bounds + /// checking. + /// + /// Calling this method with an out-of-bounds index or when `self` is not dereferencable + /// is *[undefined behavior]* even if the resulting pointer is not used. + /// + /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html + /// + /// # Examples + /// + /// ``` + /// #![feature(slice_ptr_get, nonnull_slice_from_raw_parts)] + /// use std::ptr::NonNull; + /// + /// let x = &mut [1, 2, 4]; + /// let x = NonNull::slice_from_raw_parts(NonNull::new(x.as_mut_ptr()).unwrap(), x.len()); + /// + /// unsafe { + /// assert_eq!(x.get_unchecked_mut(1).as_ptr(), x.as_non_null_ptr().as_ptr().add(1)); + /// } + /// ``` + #[unstable(feature = "slice_ptr_get", issue = "none")] + #[inline] + pub unsafe fn get_unchecked_mut(self, index: I) -> NonNull + where + I: SliceIndex<[T]>, + { + // SAFETY: the caller ensures that `self` is dereferencable and `index` in-bounds. + // As a consequence, the resulting pointer cannot be NULL. + unsafe { NonNull::new_unchecked(self.as_ptr().get_unchecked_mut(index)) } + } } #[stable(feature = "nonnull", since = "1.25.0")] From a6f1af75d71fcf8e029b78142370e7563798c503 Mon Sep 17 00:00:00 2001 From: Thiago Arrais Date: Fri, 3 Apr 2020 13:58:52 -0300 Subject: [PATCH 53/99] Lint for x.powi(2) => x * x --- clippy_lints/src/floating_point_arithmetic.rs | 27 ++++++++++++++++++- tests/ui/floating_point_log.fixed | 10 +++---- tests/ui/floating_point_log.rs | 10 +++---- tests/ui/floating_point_log.stderr | 20 +++++++------- tests/ui/floating_point_powf.fixed | 4 +-- tests/ui/floating_point_powf.rs | 4 +-- tests/ui/floating_point_powf.stderr | 8 +++--- tests/ui/floating_point_powi.fixed | 12 +++++++++ tests/ui/floating_point_powi.rs | 12 +++++++++ tests/ui/floating_point_powi.stderr | 16 +++++++++++ 10 files changed, 94 insertions(+), 29 deletions(-) create mode 100644 tests/ui/floating_point_powi.fixed create mode 100644 tests/ui/floating_point_powi.rs create mode 100644 tests/ui/floating_point_powi.stderr diff --git a/clippy_lints/src/floating_point_arithmetic.rs b/clippy_lints/src/floating_point_arithmetic.rs index 4efd068926796..e3ee4296119d2 100644 --- a/clippy_lints/src/floating_point_arithmetic.rs +++ b/clippy_lints/src/floating_point_arithmetic.rs @@ -1,6 +1,6 @@ use crate::consts::{ constant, constant_simple, Constant, - Constant::{F32, F64}, + Constant::{Int, F32, F64}, }; use crate::utils::{higher, numeric_literal, span_lint_and_sugg, sugg, SpanlessEq}; use if_chain::if_chain; @@ -293,6 +293,30 @@ fn check_powf(cx: &LateContext<'_>, expr: &Expr<'_>, args: &[Expr<'_>]) { } } +fn check_powi(cx: &LateContext<'_, '_>, expr: &Expr<'_>, args: &[Expr<'_>]) { + // Check argument + if let Some((value, _)) = constant(cx, cx.tables, &args[1]) { + let (lint, help, suggestion) = match value { + Int(2) => ( + IMPRECISE_FLOPS, + "square can be computed more accurately", + format!("{} * {}", Sugg::hir(cx, &args[0], ".."), Sugg::hir(cx, &args[0], "..")), + ), + _ => return, + }; + + span_lint_and_sugg( + cx, + lint, + expr.span, + help, + "consider using", + suggestion, + Applicability::MachineApplicable, + ); + } +} + // TODO: Lint expressions of the form `x.exp() - y` where y > 1 // and suggest usage of `x.exp_m1() - (y - 1)` instead fn check_expm1(cx: &LateContext<'_>, expr: &Expr<'_>) { @@ -489,6 +513,7 @@ impl<'tcx> LateLintPass<'tcx> for FloatingPointArithmetic { "ln" => check_ln1p(cx, expr, args), "log" => check_log_base(cx, expr, args), "powf" => check_powf(cx, expr, args), + "powi" => check_powi(cx, expr, args), _ => {}, } } diff --git a/tests/ui/floating_point_log.fixed b/tests/ui/floating_point_log.fixed index 42c5e5d2bae24..7dc7ee94affc0 100644 --- a/tests/ui/floating_point_log.fixed +++ b/tests/ui/floating_point_log.fixed @@ -25,11 +25,11 @@ fn check_ln1p() { let _ = 2.0f32.ln_1p(); let _ = x.ln_1p(); let _ = (x / 2.0).ln_1p(); - let _ = x.powi(2).ln_1p(); - let _ = (x.powi(2) / 2.0).ln_1p(); + let _ = x.powi(3).ln_1p(); + let _ = (x.powi(3) / 2.0).ln_1p(); let _ = ((std::f32::consts::E - 1.0)).ln_1p(); let _ = x.ln_1p(); - let _ = x.powi(2).ln_1p(); + let _ = x.powi(3).ln_1p(); let _ = (x + 2.0).ln_1p(); let _ = (x / 2.0).ln_1p(); // Cases where the lint shouldn't be applied @@ -43,9 +43,9 @@ fn check_ln1p() { let _ = 2.0f64.ln_1p(); let _ = x.ln_1p(); let _ = (x / 2.0).ln_1p(); - let _ = x.powi(2).ln_1p(); + let _ = x.powi(3).ln_1p(); let _ = x.ln_1p(); - let _ = x.powi(2).ln_1p(); + let _ = x.powi(3).ln_1p(); let _ = (x + 2.0).ln_1p(); let _ = (x / 2.0).ln_1p(); // Cases where the lint shouldn't be applied diff --git a/tests/ui/floating_point_log.rs b/tests/ui/floating_point_log.rs index 8be0d9ad56fc3..01181484e7dee 100644 --- a/tests/ui/floating_point_log.rs +++ b/tests/ui/floating_point_log.rs @@ -25,11 +25,11 @@ fn check_ln1p() { let _ = (1f32 + 2.0).ln(); let _ = (1.0 + x).ln(); let _ = (1.0 + x / 2.0).ln(); - let _ = (1.0 + x.powi(2)).ln(); - let _ = (1.0 + x.powi(2) / 2.0).ln(); + let _ = (1.0 + x.powi(3)).ln(); + let _ = (1.0 + x.powi(3) / 2.0).ln(); let _ = (1.0 + (std::f32::consts::E - 1.0)).ln(); let _ = (x + 1.0).ln(); - let _ = (x.powi(2) + 1.0).ln(); + let _ = (x.powi(3) + 1.0).ln(); let _ = (x + 2.0 + 1.0).ln(); let _ = (x / 2.0 + 1.0).ln(); // Cases where the lint shouldn't be applied @@ -43,9 +43,9 @@ fn check_ln1p() { let _ = (1f64 + 2.0).ln(); let _ = (1.0 + x).ln(); let _ = (1.0 + x / 2.0).ln(); - let _ = (1.0 + x.powi(2)).ln(); + let _ = (1.0 + x.powi(3)).ln(); let _ = (x + 1.0).ln(); - let _ = (x.powi(2) + 1.0).ln(); + let _ = (x.powi(3) + 1.0).ln(); let _ = (x + 2.0 + 1.0).ln(); let _ = (x / 2.0 + 1.0).ln(); // Cases where the lint shouldn't be applied diff --git a/tests/ui/floating_point_log.stderr b/tests/ui/floating_point_log.stderr index 943fbdb0b8323..900dc2b79336a 100644 --- a/tests/ui/floating_point_log.stderr +++ b/tests/ui/floating_point_log.stderr @@ -77,14 +77,14 @@ LL | let _ = (1.0 + x / 2.0).ln(); error: ln(1 + x) can be computed more accurately --> $DIR/floating_point_log.rs:28:13 | -LL | let _ = (1.0 + x.powi(2)).ln(); - | ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.powi(2).ln_1p()` +LL | let _ = (1.0 + x.powi(3)).ln(); + | ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.powi(3).ln_1p()` error: ln(1 + x) can be computed more accurately --> $DIR/floating_point_log.rs:29:13 | -LL | let _ = (1.0 + x.powi(2) / 2.0).ln(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(x.powi(2) / 2.0).ln_1p()` +LL | let _ = (1.0 + x.powi(3) / 2.0).ln(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(x.powi(3) / 2.0).ln_1p()` error: ln(1 + x) can be computed more accurately --> $DIR/floating_point_log.rs:30:13 @@ -101,8 +101,8 @@ LL | let _ = (x + 1.0).ln(); error: ln(1 + x) can be computed more accurately --> $DIR/floating_point_log.rs:32:13 | -LL | let _ = (x.powi(2) + 1.0).ln(); - | ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.powi(2).ln_1p()` +LL | let _ = (x.powi(3) + 1.0).ln(); + | ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.powi(3).ln_1p()` error: ln(1 + x) can be computed more accurately --> $DIR/floating_point_log.rs:33:13 @@ -143,8 +143,8 @@ LL | let _ = (1.0 + x / 2.0).ln(); error: ln(1 + x) can be computed more accurately --> $DIR/floating_point_log.rs:46:13 | -LL | let _ = (1.0 + x.powi(2)).ln(); - | ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.powi(2).ln_1p()` +LL | let _ = (1.0 + x.powi(3)).ln(); + | ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.powi(3).ln_1p()` error: ln(1 + x) can be computed more accurately --> $DIR/floating_point_log.rs:47:13 @@ -155,8 +155,8 @@ LL | let _ = (x + 1.0).ln(); error: ln(1 + x) can be computed more accurately --> $DIR/floating_point_log.rs:48:13 | -LL | let _ = (x.powi(2) + 1.0).ln(); - | ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.powi(2).ln_1p()` +LL | let _ = (x.powi(3) + 1.0).ln(); + | ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.powi(3).ln_1p()` error: ln(1 + x) can be computed more accurately --> $DIR/floating_point_log.rs:49:13 diff --git a/tests/ui/floating_point_powf.fixed b/tests/ui/floating_point_powf.fixed index 78a9d44829bb1..b0641a100cdc8 100644 --- a/tests/ui/floating_point_powf.fixed +++ b/tests/ui/floating_point_powf.fixed @@ -11,7 +11,7 @@ fn main() { let _ = (-3.1f32).exp(); let _ = x.sqrt(); let _ = x.cbrt(); - let _ = x.powi(2); + let _ = x.powi(3); let _ = x.powi(-2); let _ = x.powi(16_777_215); let _ = x.powi(-16_777_215); @@ -30,7 +30,7 @@ fn main() { let _ = (-3.1f64).exp(); let _ = x.sqrt(); let _ = x.cbrt(); - let _ = x.powi(2); + let _ = x.powi(3); let _ = x.powi(-2); let _ = x.powi(-2_147_483_648); let _ = x.powi(2_147_483_647); diff --git a/tests/ui/floating_point_powf.rs b/tests/ui/floating_point_powf.rs index dbc1cac5cb431..a0a2c973900f4 100644 --- a/tests/ui/floating_point_powf.rs +++ b/tests/ui/floating_point_powf.rs @@ -11,7 +11,7 @@ fn main() { let _ = std::f32::consts::E.powf(-3.1); let _ = x.powf(1.0 / 2.0); let _ = x.powf(1.0 / 3.0); - let _ = x.powf(2.0); + let _ = x.powf(3.0); let _ = x.powf(-2.0); let _ = x.powf(16_777_215.0); let _ = x.powf(-16_777_215.0); @@ -30,7 +30,7 @@ fn main() { let _ = std::f64::consts::E.powf(-3.1); let _ = x.powf(1.0 / 2.0); let _ = x.powf(1.0 / 3.0); - let _ = x.powf(2.0); + let _ = x.powf(3.0); let _ = x.powf(-2.0); let _ = x.powf(-2_147_483_648.0); let _ = x.powf(2_147_483_647.0); diff --git a/tests/ui/floating_point_powf.stderr b/tests/ui/floating_point_powf.stderr index ad5163f0079be..2422eb911e90a 100644 --- a/tests/ui/floating_point_powf.stderr +++ b/tests/ui/floating_point_powf.stderr @@ -53,8 +53,8 @@ LL | let _ = x.powf(1.0 / 3.0); error: exponentiation with integer powers can be computed more efficiently --> $DIR/floating_point_powf.rs:14:13 | -LL | let _ = x.powf(2.0); - | ^^^^^^^^^^^ help: consider using: `x.powi(2)` +LL | let _ = x.powf(3.0); + | ^^^^^^^^^^^ help: consider using: `x.powi(3)` error: exponentiation with integer powers can be computed more efficiently --> $DIR/floating_point_powf.rs:15:13 @@ -125,8 +125,8 @@ LL | let _ = x.powf(1.0 / 3.0); error: exponentiation with integer powers can be computed more efficiently --> $DIR/floating_point_powf.rs:33:13 | -LL | let _ = x.powf(2.0); - | ^^^^^^^^^^^ help: consider using: `x.powi(2)` +LL | let _ = x.powf(3.0); + | ^^^^^^^^^^^ help: consider using: `x.powi(3)` error: exponentiation with integer powers can be computed more efficiently --> $DIR/floating_point_powf.rs:34:13 diff --git a/tests/ui/floating_point_powi.fixed b/tests/ui/floating_point_powi.fixed new file mode 100644 index 0000000000000..0ce6f72535d1f --- /dev/null +++ b/tests/ui/floating_point_powi.fixed @@ -0,0 +1,12 @@ +// run-rustfix +#![warn(clippy::suboptimal_flops, clippy::imprecise_flops)] + +fn main() { + let one = 1; + let x = 3f32; + let _ = x * x; + let _ = x * x; + // Cases where the lint shouldn't be applied + let _ = x.powi(3); + let _ = x.powi(one + 1); +} diff --git a/tests/ui/floating_point_powi.rs b/tests/ui/floating_point_powi.rs new file mode 100644 index 0000000000000..c87e836bedd9d --- /dev/null +++ b/tests/ui/floating_point_powi.rs @@ -0,0 +1,12 @@ +// run-rustfix +#![warn(clippy::suboptimal_flops, clippy::imprecise_flops)] + +fn main() { + let one = 1; + let x = 3f32; + let _ = x.powi(2); + let _ = x.powi(1 + 1); + // Cases where the lint shouldn't be applied + let _ = x.powi(3); + let _ = x.powi(one + 1); +} diff --git a/tests/ui/floating_point_powi.stderr b/tests/ui/floating_point_powi.stderr new file mode 100644 index 0000000000000..ae7bbaa447386 --- /dev/null +++ b/tests/ui/floating_point_powi.stderr @@ -0,0 +1,16 @@ +error: square can be computed more accurately + --> $DIR/floating_point_powi.rs:7:13 + | +LL | let _ = x.powi(2); + | ^^^^^^^^^ help: consider using: `x * x` + | + = note: `-D clippy::imprecise-flops` implied by `-D warnings` + +error: square can be computed more accurately + --> $DIR/floating_point_powi.rs:8:13 + | +LL | let _ = x.powi(1 + 1); + | ^^^^^^^^^^^^^ help: consider using: `x * x` + +error: aborting due to 2 previous errors + From f62798454c8a7f9f2c3e87e0a913b3bd79b6d2ed Mon Sep 17 00:00:00 2001 From: Thiago Arrais Date: Mon, 25 May 2020 13:54:39 -0300 Subject: [PATCH 54/99] Lint (x * x + y * y).sqrt() => x.hypot(y) --- clippy_lints/src/floating_point_arithmetic.rs | 75 ++++++++++++++++++- tests/ui/floating_point_hypot.fixed | 13 ++++ tests/ui/floating_point_hypot.rs | 13 ++++ tests/ui/floating_point_hypot.stderr | 30 ++++++++ tests/ui/floating_point_mul_add.fixed | 5 ++ tests/ui/floating_point_mul_add.rs | 5 ++ tests/ui/floating_point_mul_add.stderr | 8 +- tests/ui/floating_point_powi.fixed | 7 +- tests/ui/floating_point_powi.rs | 7 +- tests/ui/floating_point_powi.stderr | 20 ++++- 10 files changed, 177 insertions(+), 6 deletions(-) create mode 100644 tests/ui/floating_point_hypot.fixed create mode 100644 tests/ui/floating_point_hypot.rs create mode 100644 tests/ui/floating_point_hypot.stderr diff --git a/clippy_lints/src/floating_point_arithmetic.rs b/clippy_lints/src/floating_point_arithmetic.rs index e3ee4296119d2..3b2e46a9a8529 100644 --- a/clippy_lints/src/floating_point_arithmetic.rs +++ b/clippy_lints/src/floating_point_arithmetic.rs @@ -2,10 +2,10 @@ use crate::consts::{ constant, constant_simple, Constant, Constant::{Int, F32, F64}, }; -use crate::utils::{higher, numeric_literal, span_lint_and_sugg, sugg, SpanlessEq}; +use crate::utils::{get_parent_expr, higher, numeric_literal, span_lint_and_sugg, sugg, SpanlessEq}; use if_chain::if_chain; use rustc_errors::Applicability; -use rustc_hir::{BinOpKind, Expr, ExprKind, UnOp}; +use rustc_hir::{BinOpKind, Expr, ExprKind, PathSegment, UnOp}; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty; use rustc_session::{declare_lint_pass, declare_tool_lint}; @@ -296,6 +296,17 @@ fn check_powf(cx: &LateContext<'_>, expr: &Expr<'_>, args: &[Expr<'_>]) { fn check_powi(cx: &LateContext<'_, '_>, expr: &Expr<'_>, args: &[Expr<'_>]) { // Check argument if let Some((value, _)) = constant(cx, cx.tables, &args[1]) { + // TODO: need more specific check. this is too wide. remember also to include tests + if let Some(parent) = get_parent_expr(cx, expr) { + if let Some(grandparent) = get_parent_expr(cx, parent) { + if let ExprKind::MethodCall(PathSegment { ident: method_name, .. }, _, args) = grandparent.kind { + if method_name.as_str() == "sqrt" && detect_hypot(cx, args).is_some() { + return; + } + } + } + } + let (lint, help, suggestion) = match value { Int(2) => ( IMPRECISE_FLOPS, @@ -317,6 +328,57 @@ fn check_powi(cx: &LateContext<'_, '_>, expr: &Expr<'_>, args: &[Expr<'_>]) { } } +fn detect_hypot(cx: &LateContext<'_, '_>, args: &[Expr<'_>]) -> Option { + if let ExprKind::Binary( + Spanned { + node: BinOpKind::Add, .. + }, + ref add_lhs, + ref add_rhs, + ) = args[0].kind + { + // check if expression of the form x * x + y * y + if_chain! { + if let ExprKind::Binary(Spanned { node: BinOpKind::Mul, .. }, ref lmul_lhs, ref lmul_rhs) = add_lhs.kind; + if let ExprKind::Binary(Spanned { node: BinOpKind::Mul, .. }, ref rmul_lhs, ref rmul_rhs) = add_rhs.kind; + if are_exprs_equal(cx, lmul_lhs, lmul_rhs); + if are_exprs_equal(cx, rmul_lhs, rmul_rhs); + then { + return Some(format!("{}.hypot({})", Sugg::hir(cx, &lmul_lhs, ".."), Sugg::hir(cx, &rmul_lhs, ".."))); + } + } + + // check if expression of the form x.powi(2) + y.powi(2) + if_chain! { + if let ExprKind::MethodCall(PathSegment { ident: lmethod_name, .. }, ref _lspan, ref largs) = add_lhs.kind; + if let ExprKind::MethodCall(PathSegment { ident: rmethod_name, .. }, ref _rspan, ref rargs) = add_rhs.kind; + if lmethod_name.as_str() == "powi" && rmethod_name.as_str() == "powi"; + if let Some((lvalue, _)) = constant(cx, cx.tables, &largs[1]); + if let Some((rvalue, _)) = constant(cx, cx.tables, &rargs[1]); + if Int(2) == lvalue && Int(2) == rvalue; + then { + return Some(format!("{}.hypot({})", Sugg::hir(cx, &largs[0], ".."), Sugg::hir(cx, &rargs[0], ".."))); + } + } + } + + None +} + +fn check_hypot(cx: &LateContext<'_, '_>, expr: &Expr<'_>, args: &[Expr<'_>]) { + if let Some(message) = detect_hypot(cx, args) { + span_lint_and_sugg( + cx, + IMPRECISE_FLOPS, + expr.span, + "hypotenuse can be computed more accurately", + "consider using", + message, + Applicability::MachineApplicable, + ); + } +} + // TODO: Lint expressions of the form `x.exp() - y` where y > 1 // and suggest usage of `x.exp_m1() - (y - 1)` instead fn check_expm1(cx: &LateContext<'_>, expr: &Expr<'_>) { @@ -368,6 +430,14 @@ fn check_mul_add(cx: &LateContext<'_>, expr: &Expr<'_>) { rhs, ) = &expr.kind { + if let Some(parent) = get_parent_expr(cx, expr) { + if let ExprKind::MethodCall(PathSegment { ident: method_name, .. }, _, args) = parent.kind { + if method_name.as_str() == "sqrt" && detect_hypot(cx, args).is_some() { + return; + } + } + } + let (recv, arg1, arg2) = if let Some((inner_lhs, inner_rhs)) = is_float_mul_expr(cx, lhs) { (inner_lhs, inner_rhs, rhs) } else if let Some((inner_lhs, inner_rhs)) = is_float_mul_expr(cx, rhs) { @@ -514,6 +584,7 @@ impl<'tcx> LateLintPass<'tcx> for FloatingPointArithmetic { "log" => check_log_base(cx, expr, args), "powf" => check_powf(cx, expr, args), "powi" => check_powi(cx, expr, args), + "sqrt" => check_hypot(cx, expr, args), _ => {}, } } diff --git a/tests/ui/floating_point_hypot.fixed b/tests/ui/floating_point_hypot.fixed new file mode 100644 index 0000000000000..f90695bc3fe7c --- /dev/null +++ b/tests/ui/floating_point_hypot.fixed @@ -0,0 +1,13 @@ +// run-rustfix +#![warn(clippy::suboptimal_flops, clippy::imprecise_flops)] + +fn main() { + let x = 3f32; + let y = 4f32; + let _ = x.hypot(y); + let _ = (x + 1f32).hypot(y); + let _ = x.hypot(y); + // Cases where the lint shouldn't be applied + let _ = x.mul_add(x, y * y).sqrt(); + let _ = x.mul_add(4f32, y * y).sqrt(); +} diff --git a/tests/ui/floating_point_hypot.rs b/tests/ui/floating_point_hypot.rs new file mode 100644 index 0000000000000..e7b048e262fa3 --- /dev/null +++ b/tests/ui/floating_point_hypot.rs @@ -0,0 +1,13 @@ +// run-rustfix +#![warn(clippy::suboptimal_flops, clippy::imprecise_flops)] + +fn main() { + let x = 3f32; + let y = 4f32; + let _ = (x * x + y * y).sqrt(); + let _ = ((x + 1f32) * (x + 1f32) + y * y).sqrt(); + let _ = (x.powi(2) + y.powi(2)).sqrt(); + // Cases where the lint shouldn't be applied + let _ = x.mul_add(x, y * y).sqrt(); + let _ = (x * 4f32 + y * y).sqrt(); +} diff --git a/tests/ui/floating_point_hypot.stderr b/tests/ui/floating_point_hypot.stderr new file mode 100644 index 0000000000000..fe1dfc7a4510d --- /dev/null +++ b/tests/ui/floating_point_hypot.stderr @@ -0,0 +1,30 @@ +error: hypotenuse can be computed more accurately + --> $DIR/floating_point_hypot.rs:7:13 + | +LL | let _ = (x * x + y * y).sqrt(); + | ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.hypot(y)` + | + = note: `-D clippy::imprecise-flops` implied by `-D warnings` + +error: hypotenuse can be computed more accurately + --> $DIR/floating_point_hypot.rs:8:13 + | +LL | let _ = ((x + 1f32) * (x + 1f32) + y * y).sqrt(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(x + 1f32).hypot(y)` + +error: hypotenuse can be computed more accurately + --> $DIR/floating_point_hypot.rs:9:13 + | +LL | let _ = (x.powi(2) + y.powi(2)).sqrt(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.hypot(y)` + +error: multiply and add expressions can be calculated more efficiently and accurately + --> $DIR/floating_point_hypot.rs:12:13 + | +LL | let _ = (x * 4f32 + y * y).sqrt(); + | ^^^^^^^^^^^^^^^^^^ help: consider using: `x.mul_add(4f32, y * y)` + | + = note: `-D clippy::suboptimal-flops` implied by `-D warnings` + +error: aborting due to 4 previous errors + diff --git a/tests/ui/floating_point_mul_add.fixed b/tests/ui/floating_point_mul_add.fixed index e343c37740da5..911700bab0040 100644 --- a/tests/ui/floating_point_mul_add.fixed +++ b/tests/ui/floating_point_mul_add.fixed @@ -18,4 +18,9 @@ fn main() { let _ = a.mul_add(b, c).mul_add(a.mul_add(b, c), a.mul_add(b, c)) + c; let _ = 1234.567_f64.mul_add(45.67834_f64, 0.0004_f64); + + let _ = a.mul_add(a, b).sqrt(); + + // Cases where the lint shouldn't be applied + let _ = (a * a + b * b).sqrt(); } diff --git a/tests/ui/floating_point_mul_add.rs b/tests/ui/floating_point_mul_add.rs index 810f929c8568b..d202385fc8ae7 100644 --- a/tests/ui/floating_point_mul_add.rs +++ b/tests/ui/floating_point_mul_add.rs @@ -18,4 +18,9 @@ fn main() { let _ = a.mul_add(b, c) * a.mul_add(b, c) + a.mul_add(b, c) + c; let _ = 1234.567_f64 * 45.67834_f64 + 0.0004_f64; + + let _ = (a * a + b).sqrt(); + + // Cases where the lint shouldn't be applied + let _ = (a * a + b * b).sqrt(); } diff --git a/tests/ui/floating_point_mul_add.stderr b/tests/ui/floating_point_mul_add.stderr index 2dfbf562d15fc..ac8d0c0cae068 100644 --- a/tests/ui/floating_point_mul_add.stderr +++ b/tests/ui/floating_point_mul_add.stderr @@ -54,5 +54,11 @@ error: multiply and add expressions can be calculated more efficiently and accur LL | let _ = 1234.567_f64 * 45.67834_f64 + 0.0004_f64; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `1234.567_f64.mul_add(45.67834_f64, 0.0004_f64)` -error: aborting due to 9 previous errors +error: multiply and add expressions can be calculated more efficiently and accurately + --> $DIR/floating_point_mul_add.rs:22:13 + | +LL | let _ = (a * a + b).sqrt(); + | ^^^^^^^^^^^ help: consider using: `a.mul_add(a, b)` + +error: aborting due to 10 previous errors diff --git a/tests/ui/floating_point_powi.fixed b/tests/ui/floating_point_powi.fixed index 0ce6f72535d1f..98766e68aaf6b 100644 --- a/tests/ui/floating_point_powi.fixed +++ b/tests/ui/floating_point_powi.fixed @@ -1,12 +1,17 @@ // run-rustfix -#![warn(clippy::suboptimal_flops, clippy::imprecise_flops)] +#![warn(clippy::imprecise_flops)] fn main() { let one = 1; let x = 3f32; let _ = x * x; let _ = x * x; + + let y = 4f32; + let _ = (x * x + y).sqrt(); + let _ = (x + y * y).sqrt(); // Cases where the lint shouldn't be applied let _ = x.powi(3); let _ = x.powi(one + 1); + let _ = x.hypot(y); } diff --git a/tests/ui/floating_point_powi.rs b/tests/ui/floating_point_powi.rs index c87e836bedd9d..3c4b636a3d845 100644 --- a/tests/ui/floating_point_powi.rs +++ b/tests/ui/floating_point_powi.rs @@ -1,12 +1,17 @@ // run-rustfix -#![warn(clippy::suboptimal_flops, clippy::imprecise_flops)] +#![warn(clippy::imprecise_flops)] fn main() { let one = 1; let x = 3f32; let _ = x.powi(2); let _ = x.powi(1 + 1); + + let y = 4f32; + let _ = (x.powi(2) + y).sqrt(); + let _ = (x + y.powi(2)).sqrt(); // Cases where the lint shouldn't be applied let _ = x.powi(3); let _ = x.powi(one + 1); + let _ = (x.powi(2) + y.powi(2)).sqrt(); } diff --git a/tests/ui/floating_point_powi.stderr b/tests/ui/floating_point_powi.stderr index ae7bbaa447386..f370e24bf0522 100644 --- a/tests/ui/floating_point_powi.stderr +++ b/tests/ui/floating_point_powi.stderr @@ -12,5 +12,23 @@ error: square can be computed more accurately LL | let _ = x.powi(1 + 1); | ^^^^^^^^^^^^^ help: consider using: `x * x` -error: aborting due to 2 previous errors +error: square can be computed more accurately + --> $DIR/floating_point_powi.rs:11:14 + | +LL | let _ = (x.powi(2) + y).sqrt(); + | ^^^^^^^^^ help: consider using: `x * x` + +error: square can be computed more accurately + --> $DIR/floating_point_powi.rs:12:18 + | +LL | let _ = (x + y.powi(2)).sqrt(); + | ^^^^^^^^^ help: consider using: `y * y` + +error: hypotenuse can be computed more accurately + --> $DIR/floating_point_powi.rs:16:13 + | +LL | let _ = (x.powi(2) + y.powi(2)).sqrt(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.hypot(y)` + +error: aborting due to 5 previous errors From 2e8a1be444afc6a9b5137d3e7e4fdcfcb1f89e0d Mon Sep 17 00:00:00 2001 From: robojumper Date: Sun, 5 Jul 2020 22:10:59 +0200 Subject: [PATCH 55/99] new lint: match_like_matches_macro --- CHANGELOG.md | 1 + clippy_lints/src/matches.rs | 395 +++++++++++++++++- .../src/redundant_pattern_matching.rs | 260 ------------ src/lintlist/mod.rs | 9 +- tests/ui/find_map.rs | 1 + tests/ui/find_map.stderr | 2 +- tests/ui/match_expr_like_matches_macro.fixed | 32 ++ tests/ui/match_expr_like_matches_macro.rs | 41 ++ tests/ui/match_expr_like_matches_macro.stderr | 42 ++ tests/ui/neg_cmp_op_on_partial_ord.rs | 2 +- tests/ui/question_mark.fixed | 5 +- tests/ui/question_mark.rs | 5 +- tests/ui/question_mark.stderr | 20 +- tests/ui/redundant_pattern_matching.fixed | 8 +- tests/ui/redundant_pattern_matching.rs | 8 +- tests/ui/redundant_pattern_matching.stderr | 56 +-- ...undant_pattern_matching_const_result.fixed | 2 +- ...redundant_pattern_matching_const_result.rs | 2 +- 18 files changed, 563 insertions(+), 328 deletions(-) delete mode 100644 clippy_lints/src/redundant_pattern_matching.rs create mode 100644 tests/ui/match_expr_like_matches_macro.fixed create mode 100644 tests/ui/match_expr_like_matches_macro.rs create mode 100644 tests/ui/match_expr_like_matches_macro.stderr diff --git a/CHANGELOG.md b/CHANGELOG.md index 1a081bb85feab..6261ca4879a53 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1513,6 +1513,7 @@ Released 2018-09-13 [`map_unwrap_or`]: https://rust-lang.github.io/rust-clippy/master/index.html#map_unwrap_or [`match_as_ref`]: https://rust-lang.github.io/rust-clippy/master/index.html#match_as_ref [`match_bool`]: https://rust-lang.github.io/rust-clippy/master/index.html#match_bool +[`match_like_matches_macro`]: https://rust-lang.github.io/rust-clippy/master/index.html#match_like_matches_macro [`match_on_vec_items`]: https://rust-lang.github.io/rust-clippy/master/index.html#match_on_vec_items [`match_overlapping_arm`]: https://rust-lang.github.io/rust-clippy/master/index.html#match_overlapping_arm [`match_ref_pats`]: https://rust-lang.github.io/rust-clippy/master/index.html#match_ref_pats diff --git a/clippy_lints/src/matches.rs b/clippy_lints/src/matches.rs index b754a45aa404f..34aa2981535dc 100644 --- a/clippy_lints/src/matches.rs +++ b/clippy_lints/src/matches.rs @@ -13,14 +13,14 @@ use rustc_ast::ast::LitKind; use rustc_errors::Applicability; use rustc_hir::def::CtorKind; use rustc_hir::{ - Arm, BindingAnnotation, Block, BorrowKind, Expr, ExprKind, Local, MatchSource, Mutability, Node, Pat, PatKind, - QPath, RangeEnd, + Arm, BindingAnnotation, Block, BorrowKind, Expr, ExprKind, Guard, Local, MatchSource, Mutability, Node, Pat, + PatKind, QPath, RangeEnd, }; use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_middle::lint::in_external_macro; use rustc_middle::ty::{self, Ty}; use rustc_session::{declare_tool_lint, impl_lint_pass}; -use rustc_span::source_map::Span; +use rustc_span::source_map::{Span, Spanned}; use std::cmp::Ordering; use std::collections::Bound; @@ -409,6 +409,67 @@ declare_clippy_lint! { "a match on a struct that binds all fields but still uses the wildcard pattern" } +declare_clippy_lint! { + /// **What it does:** Lint for redundant pattern matching over `Result` or + /// `Option` + /// + /// **Why is this bad?** It's more concise and clear to just use the proper + /// utility function + /// + /// **Known problems:** None. + /// + /// **Example:** + /// + /// ```rust + /// if let Ok(_) = Ok::(42) {} + /// if let Err(_) = Err::(42) {} + /// if let None = None::<()> {} + /// if let Some(_) = Some(42) {} + /// match Ok::(42) { + /// Ok(_) => true, + /// Err(_) => false, + /// }; + /// ``` + /// + /// The more idiomatic use would be: + /// + /// ```rust + /// if Ok::(42).is_ok() {} + /// if Err::(42).is_err() {} + /// if None::<()>.is_none() {} + /// if Some(42).is_some() {} + /// Ok::(42).is_ok(); + /// ``` + pub REDUNDANT_PATTERN_MATCHING, + style, + "use the proper utility function avoiding an `if let`" +} + +declare_clippy_lint! { + /// **What it does:** Checks for `match` expressions producing a `bool` that could be written using `matches!` + /// + /// **Why is this bad?** Readability and needless complexity. + /// + /// **Known problems:** This can turn an intentionally exhaustive match into a non-exhaustive one. + /// + /// **Example:** + /// ```rust + /// let x = Some(5); + /// + /// // Bad + /// let a = match x { + /// Some(0) => true, + /// _ => false, + /// }; + /// + /// // Good + /// let a = matches!(x, Some(5)); + /// ``` + pub MATCH_LIKE_MATCHES_MACRO, + style, + "a match that could be written with the matches! macro" +} + #[derive(Default)] pub struct Matches { infallible_destructuring_match_linted: bool, @@ -427,7 +488,9 @@ impl_lint_pass!(Matches => [ WILDCARD_IN_OR_PATTERNS, MATCH_SINGLE_BINDING, INFALLIBLE_DESTRUCTURING_MATCH, - REST_PAT_IN_FULLY_BOUND_STRUCTS + REST_PAT_IN_FULLY_BOUND_STRUCTS, + REDUNDANT_PATTERN_MATCHING, + MATCH_LIKE_MATCHES_MACRO ]); impl<'tcx> LateLintPass<'tcx> for Matches { @@ -435,6 +498,11 @@ impl<'tcx> LateLintPass<'tcx> for Matches { if in_external_macro(cx.sess(), expr.span) { return; } + + if !redundant_pattern_match::check(cx, expr) { + check_match_like_matches(cx, expr); + } + if let ExprKind::Match(ref ex, ref arms, MatchSource::Normal) = expr.kind { check_single_match(cx, ex, arms, expr); check_match_bool(cx, ex, arms, expr); @@ -802,13 +870,8 @@ fn check_wild_enum_match(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>]) // Some simple checks for exhaustive patterns. // There is a room for improvements to detect more cases, // but it can be more expensive to do so. - let is_pattern_exhaustive = |pat: &&Pat<'_>| { - if let PatKind::Wild | PatKind::Binding(.., None) = pat.kind { - true - } else { - false - } - }; + let is_pattern_exhaustive = + |pat: &&Pat<'_>| matches!(pat.kind, PatKind::Wild | PatKind::Binding(.., None)); if patterns.iter().all(is_pattern_exhaustive) { missing_variants.retain(|e| e.ctor_def_id != Some(p.res.def_id())); } @@ -989,6 +1052,78 @@ fn check_wild_in_or_pats(cx: &LateContext<'_>, arms: &[Arm<'_>]) { } } +/// Lint a `match` or `if let .. { .. } else { .. }` expr that could be replaced by `matches!` +fn check_match_like_matches<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { + if let ExprKind::Match(ex, arms, ref match_source) = &expr.kind { + match match_source { + MatchSource::Normal => find_matches_sugg(cx, ex, arms, expr, false), + MatchSource::IfLetDesugar { .. } => find_matches_sugg(cx, ex, arms, expr, true), + _ => return, + } + } +} + +/// Lint a `match` or desugared `if let` for replacement by `matches!` +fn find_matches_sugg(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>], expr: &Expr<'_>, desugared: bool) { + if_chain! { + if arms.len() == 2; + if cx.tables().expr_ty(expr).is_bool(); + if let Some(first) = find_bool_lit(&arms[0].body.kind, desugared); + if let Some(second) = find_bool_lit(&arms[1].body.kind, desugared); + if first != second; + then { + let mut applicability = Applicability::MachineApplicable; + + let pat_and_guard = if let Some(Guard::If(g)) = arms[0].guard { + format!("{} if {}", snippet_with_applicability(cx, arms[0].pat.span, "..", &mut applicability), snippet_with_applicability(cx, g.span, "..", &mut applicability)) + } else { + format!("{}", snippet_with_applicability(cx, arms[0].pat.span, "..", &mut applicability)) + }; + span_lint_and_sugg( + cx, + MATCH_LIKE_MATCHES_MACRO, + expr.span, + &format!("{} expression looks like `matches!` macro", if desugared { "if let .. else" } else { "match" }), + "try this", + format!( + "{}matches!({}, {})", + if first { "" } else { "!" }, + snippet_with_applicability(cx, ex.span, "..", &mut applicability), + pat_and_guard, + ), + applicability, + ) + } + } +} + +/// Extract a `bool` or `{ bool }` +fn find_bool_lit(ex: &ExprKind<'_>, desugared: bool) -> Option { + match ex { + ExprKind::Lit(Spanned { + node: LitKind::Bool(b), .. + }) => Some(*b), + ExprKind::Block( + rustc_hir::Block { + stmts: &[], + expr: Some(exp), + .. + }, + _, + ) if desugared => { + if let ExprKind::Lit(Spanned { + node: LitKind::Bool(b), .. + }) = exp.kind + { + Some(b) + } else { + None + } + }, + _ => None, + } +} + fn check_match_single_binding<'a>(cx: &LateContext<'a>, ex: &Expr<'a>, arms: &[Arm<'_>], expr: &Expr<'_>) { if in_macro(expr.span) || arms.len() != 1 || is_refutable(cx, arms[0].pat) { return; @@ -1179,10 +1314,7 @@ fn is_unit_expr(expr: &Expr<'_>) -> bool { // Checks if arm has the form `None => None` fn is_none_arm(arm: &Arm<'_>) -> bool { - match arm.pat.kind { - PatKind::Path(ref path) if match_qpath(path, &paths::OPTION_NONE) => true, - _ => false, - } + matches!(arm.pat.kind, PatKind::Path(ref path) if match_qpath(path, &paths::OPTION_NONE)) } // Checks if arm has the form `Some(ref v) => Some(v)` (checks for `ref` and `ref mut`) @@ -1293,6 +1425,239 @@ where None } +mod redundant_pattern_match { + use super::REDUNDANT_PATTERN_MATCHING; + use crate::utils::{in_constant, match_qpath, match_trait_method, paths, snippet, span_lint_and_then}; + use if_chain::if_chain; + use rustc_ast::ast::LitKind; + use rustc_errors::Applicability; + use rustc_hir::{Arm, Expr, ExprKind, HirId, MatchSource, PatKind, QPath}; + use rustc_lint::LateContext; + use rustc_middle::ty; + use rustc_mir::const_eval::is_const_fn; + use rustc_span::source_map::Symbol; + + pub fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) -> bool { + if let ExprKind::Match(op, arms, ref match_source) = &expr.kind { + match match_source { + MatchSource::Normal => find_sugg_for_match(cx, expr, op, arms), + MatchSource::IfLetDesugar { .. } => find_sugg_for_if_let(cx, expr, op, arms, "if"), + MatchSource::WhileLetDesugar => find_sugg_for_if_let(cx, expr, op, arms, "while"), + _ => false, + } + } else { + false + } + } + + fn find_sugg_for_if_let<'tcx>( + cx: &LateContext<'tcx>, + expr: &'tcx Expr<'_>, + op: &Expr<'_>, + arms: &[Arm<'_>], + keyword: &'static str, + ) -> bool { + fn find_suggestion(cx: &LateContext<'_>, hir_id: HirId, path: &QPath<'_>) -> Option<&'static str> { + if match_qpath(path, &paths::RESULT_OK) && can_suggest(cx, hir_id, sym!(result_type), "is_ok") { + return Some("is_ok()"); + } + if match_qpath(path, &paths::RESULT_ERR) && can_suggest(cx, hir_id, sym!(result_type), "is_err") { + return Some("is_err()"); + } + if match_qpath(path, &paths::OPTION_SOME) && can_suggest(cx, hir_id, sym!(option_type), "is_some") { + return Some("is_some()"); + } + if match_qpath(path, &paths::OPTION_NONE) && can_suggest(cx, hir_id, sym!(option_type), "is_none") { + return Some("is_none()"); + } + None + } + + let hir_id = expr.hir_id; + let good_method = match arms[0].pat.kind { + PatKind::TupleStruct(ref path, ref patterns, _) if patterns.len() == 1 => { + if let PatKind::Wild = patterns[0].kind { + find_suggestion(cx, hir_id, path) + } else { + None + } + }, + PatKind::Path(ref path) => find_suggestion(cx, hir_id, path), + _ => None, + }; + let good_method = match good_method { + Some(method) => method, + None => return false, + }; + + // check that `while_let_on_iterator` lint does not trigger + if_chain! { + if keyword == "while"; + if let ExprKind::MethodCall(method_path, _, _, _) = op.kind; + if method_path.ident.name == sym!(next); + if match_trait_method(cx, op, &paths::ITERATOR); + then { + return false; + } + } + + span_lint_and_then( + cx, + REDUNDANT_PATTERN_MATCHING, + arms[0].pat.span, + &format!("redundant pattern matching, consider using `{}`", good_method), + |diag| { + // while let ... = ... { ... } + // ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + let expr_span = expr.span; + + // while let ... = ... { ... } + // ^^^ + let op_span = op.span.source_callsite(); + + // while let ... = ... { ... } + // ^^^^^^^^^^^^^^^^^^^ + let span = expr_span.until(op_span.shrink_to_hi()); + diag.span_suggestion( + span, + "try this", + format!("{} {}.{}", keyword, snippet(cx, op_span, "_"), good_method), + Applicability::MachineApplicable, // snippet + ); + }, + ); + true + } + + fn find_sugg_for_match<'tcx>( + cx: &LateContext<'tcx>, + expr: &'tcx Expr<'_>, + op: &Expr<'_>, + arms: &[Arm<'_>], + ) -> bool { + if arms.len() == 2 { + let node_pair = (&arms[0].pat.kind, &arms[1].pat.kind); + + let hir_id = expr.hir_id; + let found_good_method = match node_pair { + ( + PatKind::TupleStruct(ref path_left, ref patterns_left, _), + PatKind::TupleStruct(ref path_right, ref patterns_right, _), + ) if patterns_left.len() == 1 && patterns_right.len() == 1 => { + if let (PatKind::Wild, PatKind::Wild) = (&patterns_left[0].kind, &patterns_right[0].kind) { + find_good_method_for_match( + arms, + path_left, + path_right, + &paths::RESULT_OK, + &paths::RESULT_ERR, + "is_ok()", + "is_err()", + || can_suggest(cx, hir_id, sym!(result_type), "is_ok"), + || can_suggest(cx, hir_id, sym!(result_type), "is_err"), + ) + } else { + None + } + }, + (PatKind::TupleStruct(ref path_left, ref patterns, _), PatKind::Path(ref path_right)) + | (PatKind::Path(ref path_left), PatKind::TupleStruct(ref path_right, ref patterns, _)) + if patterns.len() == 1 => + { + if let PatKind::Wild = patterns[0].kind { + find_good_method_for_match( + arms, + path_left, + path_right, + &paths::OPTION_SOME, + &paths::OPTION_NONE, + "is_some()", + "is_none()", + || can_suggest(cx, hir_id, sym!(option_type), "is_some"), + || can_suggest(cx, hir_id, sym!(option_type), "is_none"), + ) + } else { + None + } + }, + _ => None, + }; + + if let Some(good_method) = found_good_method { + span_lint_and_then( + cx, + REDUNDANT_PATTERN_MATCHING, + expr.span, + &format!("redundant pattern matching, consider using `{}`", good_method), + |diag| { + let span = expr.span.to(op.span); + diag.span_suggestion( + span, + "try this", + format!("{}.{}", snippet(cx, op.span, "_"), good_method), + Applicability::MaybeIncorrect, // snippet + ); + }, + ); + return true; + } + } + false + } + + #[allow(clippy::too_many_arguments)] + fn find_good_method_for_match<'a>( + arms: &[Arm<'_>], + path_left: &QPath<'_>, + path_right: &QPath<'_>, + expected_left: &[&str], + expected_right: &[&str], + should_be_left: &'a str, + should_be_right: &'a str, + can_suggest_left: impl Fn() -> bool, + can_suggest_right: impl Fn() -> bool, + ) -> Option<&'a str> { + let body_node_pair = if match_qpath(path_left, expected_left) && match_qpath(path_right, expected_right) { + (&(*arms[0].body).kind, &(*arms[1].body).kind) + } else if match_qpath(path_right, expected_left) && match_qpath(path_left, expected_right) { + (&(*arms[1].body).kind, &(*arms[0].body).kind) + } else { + return None; + }; + + match body_node_pair { + (ExprKind::Lit(ref lit_left), ExprKind::Lit(ref lit_right)) => match (&lit_left.node, &lit_right.node) { + (LitKind::Bool(true), LitKind::Bool(false)) if can_suggest_left() => Some(should_be_left), + (LitKind::Bool(false), LitKind::Bool(true)) if can_suggest_right() => Some(should_be_right), + _ => None, + }, + _ => None, + } + } + + fn can_suggest(cx: &LateContext<'_>, hir_id: HirId, diag_item: Symbol, name: &str) -> bool { + if !in_constant(cx, hir_id) { + return true; + } + + // Avoid suggesting calls to non-`const fn`s in const contexts, see #5697. + cx.tcx + .get_diagnostic_item(diag_item) + .and_then(|def_id| { + cx.tcx.inherent_impls(def_id).iter().find_map(|imp| { + cx.tcx + .associated_items(*imp) + .in_definition_order() + .find_map(|item| match item.kind { + ty::AssocKind::Fn if item.ident.name.as_str() == name => Some(item.def_id), + _ => None, + }) + }) + }) + .map_or(false, |def_id| is_const_fn(cx.tcx, def_id)) + } +} + #[test] fn test_overlapping() { use rustc_span::source_map::DUMMY_SP; diff --git a/clippy_lints/src/redundant_pattern_matching.rs b/clippy_lints/src/redundant_pattern_matching.rs deleted file mode 100644 index d8d16efb978a5..0000000000000 --- a/clippy_lints/src/redundant_pattern_matching.rs +++ /dev/null @@ -1,260 +0,0 @@ -use crate::utils::{in_constant, match_qpath, match_trait_method, paths, snippet, span_lint_and_then}; -use if_chain::if_chain; -use rustc_ast::ast::LitKind; -use rustc_errors::Applicability; -use rustc_hir::{Arm, Expr, ExprKind, HirId, MatchSource, PatKind, QPath}; -use rustc_lint::{LateContext, LateLintPass}; -use rustc_middle::ty; -use rustc_mir::const_eval::is_const_fn; -use rustc_session::{declare_lint_pass, declare_tool_lint}; -use rustc_span::source_map::Symbol; - -declare_clippy_lint! { - /// **What it does:** Lint for redundant pattern matching over `Result` or - /// `Option` - /// - /// **Why is this bad?** It's more concise and clear to just use the proper - /// utility function - /// - /// **Known problems:** None. - /// - /// **Example:** - /// - /// ```rust - /// if let Ok(_) = Ok::(42) {} - /// if let Err(_) = Err::(42) {} - /// if let None = None::<()> {} - /// if let Some(_) = Some(42) {} - /// match Ok::(42) { - /// Ok(_) => true, - /// Err(_) => false, - /// }; - /// ``` - /// - /// The more idiomatic use would be: - /// - /// ```rust - /// if Ok::(42).is_ok() {} - /// if Err::(42).is_err() {} - /// if None::<()>.is_none() {} - /// if Some(42).is_some() {} - /// Ok::(42).is_ok(); - /// ``` - pub REDUNDANT_PATTERN_MATCHING, - style, - "use the proper utility function avoiding an `if let`" -} - -declare_lint_pass!(RedundantPatternMatching => [REDUNDANT_PATTERN_MATCHING]); - -impl<'tcx> LateLintPass<'tcx> for RedundantPatternMatching { - fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { - if let ExprKind::Match(op, arms, ref match_source) = &expr.kind { - match match_source { - MatchSource::Normal => find_sugg_for_match(cx, expr, op, arms), - MatchSource::IfLetDesugar { .. } => find_sugg_for_if_let(cx, expr, op, arms, "if"), - MatchSource::WhileLetDesugar => find_sugg_for_if_let(cx, expr, op, arms, "while"), - _ => return, - } - } - } -} - -fn find_sugg_for_if_let<'tcx>( - cx: &LateContext<'tcx>, - expr: &'tcx Expr<'_>, - op: &Expr<'_>, - arms: &[Arm<'_>], - keyword: &'static str, -) { - fn find_suggestion(cx: &LateContext<'_>, hir_id: HirId, path: &QPath<'_>) -> Option<&'static str> { - if match_qpath(path, &paths::RESULT_OK) && can_suggest(cx, hir_id, sym!(result_type), "is_ok") { - return Some("is_ok()"); - } - if match_qpath(path, &paths::RESULT_ERR) && can_suggest(cx, hir_id, sym!(result_type), "is_err") { - return Some("is_err()"); - } - if match_qpath(path, &paths::OPTION_SOME) && can_suggest(cx, hir_id, sym!(option_type), "is_some") { - return Some("is_some()"); - } - if match_qpath(path, &paths::OPTION_NONE) && can_suggest(cx, hir_id, sym!(option_type), "is_none") { - return Some("is_none()"); - } - None - } - - let hir_id = expr.hir_id; - let good_method = match arms[0].pat.kind { - PatKind::TupleStruct(ref path, ref patterns, _) if patterns.len() == 1 => { - if let PatKind::Wild = patterns[0].kind { - find_suggestion(cx, hir_id, path) - } else { - None - } - }, - PatKind::Path(ref path) => find_suggestion(cx, hir_id, path), - _ => None, - }; - let good_method = match good_method { - Some(method) => method, - None => return, - }; - - // check that `while_let_on_iterator` lint does not trigger - if_chain! { - if keyword == "while"; - if let ExprKind::MethodCall(method_path, _, _, _) = op.kind; - if method_path.ident.name == sym!(next); - if match_trait_method(cx, op, &paths::ITERATOR); - then { - return; - } - } - - span_lint_and_then( - cx, - REDUNDANT_PATTERN_MATCHING, - arms[0].pat.span, - &format!("redundant pattern matching, consider using `{}`", good_method), - |diag| { - // while let ... = ... { ... } - // ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - let expr_span = expr.span; - - // while let ... = ... { ... } - // ^^^ - let op_span = op.span.source_callsite(); - - // while let ... = ... { ... } - // ^^^^^^^^^^^^^^^^^^^ - let span = expr_span.until(op_span.shrink_to_hi()); - diag.span_suggestion( - span, - "try this", - format!("{} {}.{}", keyword, snippet(cx, op_span, "_"), good_method), - Applicability::MachineApplicable, // snippet - ); - }, - ); -} - -fn find_sugg_for_match<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, op: &Expr<'_>, arms: &[Arm<'_>]) { - if arms.len() == 2 { - let node_pair = (&arms[0].pat.kind, &arms[1].pat.kind); - - let hir_id = expr.hir_id; - let found_good_method = match node_pair { - ( - PatKind::TupleStruct(ref path_left, ref patterns_left, _), - PatKind::TupleStruct(ref path_right, ref patterns_right, _), - ) if patterns_left.len() == 1 && patterns_right.len() == 1 => { - if let (PatKind::Wild, PatKind::Wild) = (&patterns_left[0].kind, &patterns_right[0].kind) { - find_good_method_for_match( - arms, - path_left, - path_right, - &paths::RESULT_OK, - &paths::RESULT_ERR, - "is_ok()", - "is_err()", - || can_suggest(cx, hir_id, sym!(result_type), "is_ok"), - || can_suggest(cx, hir_id, sym!(result_type), "is_err"), - ) - } else { - None - } - }, - (PatKind::TupleStruct(ref path_left, ref patterns, _), PatKind::Path(ref path_right)) - | (PatKind::Path(ref path_left), PatKind::TupleStruct(ref path_right, ref patterns, _)) - if patterns.len() == 1 => - { - if let PatKind::Wild = patterns[0].kind { - find_good_method_for_match( - arms, - path_left, - path_right, - &paths::OPTION_SOME, - &paths::OPTION_NONE, - "is_some()", - "is_none()", - || can_suggest(cx, hir_id, sym!(option_type), "is_some"), - || can_suggest(cx, hir_id, sym!(option_type), "is_none"), - ) - } else { - None - } - }, - _ => None, - }; - - if let Some(good_method) = found_good_method { - span_lint_and_then( - cx, - REDUNDANT_PATTERN_MATCHING, - expr.span, - &format!("redundant pattern matching, consider using `{}`", good_method), - |diag| { - let span = expr.span.to(op.span); - diag.span_suggestion( - span, - "try this", - format!("{}.{}", snippet(cx, op.span, "_"), good_method), - Applicability::MaybeIncorrect, // snippet - ); - }, - ); - } - } -} - -#[allow(clippy::too_many_arguments)] -fn find_good_method_for_match<'a>( - arms: &[Arm<'_>], - path_left: &QPath<'_>, - path_right: &QPath<'_>, - expected_left: &[&str], - expected_right: &[&str], - should_be_left: &'a str, - should_be_right: &'a str, - can_suggest_left: impl Fn() -> bool, - can_suggest_right: impl Fn() -> bool, -) -> Option<&'a str> { - let body_node_pair = if match_qpath(path_left, expected_left) && match_qpath(path_right, expected_right) { - (&(*arms[0].body).kind, &(*arms[1].body).kind) - } else if match_qpath(path_right, expected_left) && match_qpath(path_left, expected_right) { - (&(*arms[1].body).kind, &(*arms[0].body).kind) - } else { - return None; - }; - - match body_node_pair { - (ExprKind::Lit(ref lit_left), ExprKind::Lit(ref lit_right)) => match (&lit_left.node, &lit_right.node) { - (LitKind::Bool(true), LitKind::Bool(false)) if can_suggest_left() => Some(should_be_left), - (LitKind::Bool(false), LitKind::Bool(true)) if can_suggest_right() => Some(should_be_right), - _ => None, - }, - _ => None, - } -} - -fn can_suggest(cx: &LateContext<'_>, hir_id: HirId, diag_item: Symbol, name: &str) -> bool { - if !in_constant(cx, hir_id) { - return true; - } - - // Avoid suggesting calls to non-`const fn`s in const contexts, see #5697. - cx.tcx - .get_diagnostic_item(diag_item) - .and_then(|def_id| { - cx.tcx.inherent_impls(def_id).iter().find_map(|imp| { - cx.tcx - .associated_items(*imp) - .in_definition_order() - .find_map(|item| match item.kind { - ty::AssocKind::Fn if item.ident.name.as_str() == name => Some(item.def_id), - _ => None, - }) - }) - }) - .map_or(false, |def_id| is_const_fn(cx.tcx, def_id)) -} diff --git a/src/lintlist/mod.rs b/src/lintlist/mod.rs index e681f47f949df..888b475548461 100644 --- a/src/lintlist/mod.rs +++ b/src/lintlist/mod.rs @@ -1179,6 +1179,13 @@ pub static ref ALL_LINTS: Vec = vec![ deprecation: None, module: "matches", }, + Lint { + name: "match_like_matches_macro", + group: "style", + desc: "a match that could be written with the matches! macro", + deprecation: None, + module: "matches", + }, Lint { name: "match_on_vec_items", group: "pedantic", @@ -1856,7 +1863,7 @@ pub static ref ALL_LINTS: Vec = vec![ group: "style", desc: "use the proper utility function avoiding an `if let`", deprecation: None, - module: "redundant_pattern_matching", + module: "matches", }, Lint { name: "redundant_pub_crate", diff --git a/tests/ui/find_map.rs b/tests/ui/find_map.rs index c28cca144ca3f..88d3b0e749001 100644 --- a/tests/ui/find_map.rs +++ b/tests/ui/find_map.rs @@ -19,6 +19,7 @@ fn main() { let _: Option = a.iter().find(|s| s.parse::().is_ok()).map(|s| s.parse().unwrap()); + #[allow(clippy::match_like_matches_macro)] let _: Option = desserts_of_the_week .iter() .find(|dessert| match *dessert { diff --git a/tests/ui/find_map.stderr b/tests/ui/find_map.stderr index 92f40fe6f1fb2..f279850fef8af 100644 --- a/tests/ui/find_map.stderr +++ b/tests/ui/find_map.stderr @@ -8,7 +8,7 @@ LL | let _: Option = a.iter().find(|s| s.parse::().is_ok()).map(|s = help: this is more succinctly expressed by calling `.find_map(..)` instead error: called `find(p).map(q)` on an `Iterator` - --> $DIR/find_map.rs:22:29 + --> $DIR/find_map.rs:23:29 | LL | let _: Option = desserts_of_the_week | _____________________________^ diff --git a/tests/ui/match_expr_like_matches_macro.fixed b/tests/ui/match_expr_like_matches_macro.fixed new file mode 100644 index 0000000000000..2d1ac8836d63f --- /dev/null +++ b/tests/ui/match_expr_like_matches_macro.fixed @@ -0,0 +1,32 @@ +// run-rustfix + +#![warn(clippy::match_like_matches_macro)] + +fn main() { + let x = Some(5); + + // Lint + let _y = matches!(x, Some(0)); + + // Turn into is_none + let _z = x.is_none(); + + // Lint + let _z = !matches!(x, Some(r) if r == 0); + + // Lint + let _zz = matches!(x, Some(5)); + + // No lint + let _a = match x { + Some(_) => false, + None => false, + }; + + // No lint + let _a = match x { + Some(0) => false, + Some(_) => true, + None => false, + }; +} diff --git a/tests/ui/match_expr_like_matches_macro.rs b/tests/ui/match_expr_like_matches_macro.rs new file mode 100644 index 0000000000000..376abf9244eaf --- /dev/null +++ b/tests/ui/match_expr_like_matches_macro.rs @@ -0,0 +1,41 @@ +// run-rustfix + +#![warn(clippy::match_like_matches_macro)] + +fn main() { + let x = Some(5); + + // Lint + let _y = match x { + Some(0) => true, + _ => false, + }; + + // Turn into is_none + let _z = match x { + Some(_) => false, + None => true, + }; + + // Lint + let _z = match x { + Some(r) if r == 0 => false, + _ => true, + }; + + // Lint + let _zz = if let Some(5) = x { true } else { false }; + + // No lint + let _a = match x { + Some(_) => false, + None => false, + }; + + // No lint + let _a = match x { + Some(0) => false, + Some(_) => true, + None => false, + }; +} diff --git a/tests/ui/match_expr_like_matches_macro.stderr b/tests/ui/match_expr_like_matches_macro.stderr new file mode 100644 index 0000000000000..0b32af039a8cc --- /dev/null +++ b/tests/ui/match_expr_like_matches_macro.stderr @@ -0,0 +1,42 @@ +error: match expression looks like `matches!` macro + --> $DIR/match_expr_like_matches_macro.rs:9:14 + | +LL | let _y = match x { + | ______________^ +LL | | Some(0) => true, +LL | | _ => false, +LL | | }; + | |_____^ help: try this: `matches!(x, Some(0))` + | + = note: `-D clippy::match-like-matches-macro` implied by `-D warnings` + +error: redundant pattern matching, consider using `is_none()` + --> $DIR/match_expr_like_matches_macro.rs:15:14 + | +LL | let _z = match x { + | ______________^ +LL | | Some(_) => false, +LL | | None => true, +LL | | }; + | |_____^ help: try this: `x.is_none()` + | + = note: `-D clippy::redundant-pattern-matching` implied by `-D warnings` + +error: match expression looks like `matches!` macro + --> $DIR/match_expr_like_matches_macro.rs:21:14 + | +LL | let _z = match x { + | ______________^ +LL | | Some(r) if r == 0 => false, +LL | | _ => true, +LL | | }; + | |_____^ help: try this: `!matches!(x, Some(r) if r == 0)` + +error: if let .. else expression looks like `matches!` macro + --> $DIR/match_expr_like_matches_macro.rs:27:15 + | +LL | let _zz = if let Some(5) = x { true } else { false }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `matches!(x, Some(5))` + +error: aborting due to 4 previous errors + diff --git a/tests/ui/neg_cmp_op_on_partial_ord.rs b/tests/ui/neg_cmp_op_on_partial_ord.rs index ca70e3b7148ef..0cee0a28fc7cd 100644 --- a/tests/ui/neg_cmp_op_on_partial_ord.rs +++ b/tests/ui/neg_cmp_op_on_partial_ord.rs @@ -4,7 +4,7 @@ use std::cmp::Ordering; -#[allow(clippy::unnested_or_patterns)] +#[allow(clippy::unnested_or_patterns, clippy::match_like_matches_macro)] #[warn(clippy::neg_cmp_op_on_partial_ord)] fn main() { let a_value = 1.0; diff --git a/tests/ui/question_mark.fixed b/tests/ui/question_mark.fixed index 11dff94a28865..bd13cf1bdfaf6 100644 --- a/tests/ui/question_mark.fixed +++ b/tests/ui/question_mark.fixed @@ -23,10 +23,7 @@ pub enum SeemsOption { impl SeemsOption { pub fn is_none(&self) -> bool { - match *self { - SeemsOption::None => true, - SeemsOption::Some(_) => false, - } + matches!(*self, SeemsOption::None) } } diff --git a/tests/ui/question_mark.rs b/tests/ui/question_mark.rs index 1d0ee82b4f778..94479e685551c 100644 --- a/tests/ui/question_mark.rs +++ b/tests/ui/question_mark.rs @@ -25,10 +25,7 @@ pub enum SeemsOption { impl SeemsOption { pub fn is_none(&self) -> bool { - match *self { - SeemsOption::None => true, - SeemsOption::Some(_) => false, - } + matches!(*self, SeemsOption::None) } } diff --git a/tests/ui/question_mark.stderr b/tests/ui/question_mark.stderr index 502615fb175a1..be323035d6ccd 100644 --- a/tests/ui/question_mark.stderr +++ b/tests/ui/question_mark.stderr @@ -9,7 +9,7 @@ LL | | } = note: `-D clippy::question-mark` implied by `-D warnings` error: this block may be rewritten with the `?` operator - --> $DIR/question_mark.rs:50:9 + --> $DIR/question_mark.rs:47:9 | LL | / if (self.opt).is_none() { LL | | return None; @@ -17,7 +17,7 @@ LL | | } | |_________^ help: replace it with: `(self.opt)?;` error: this block may be rewritten with the `?` operator - --> $DIR/question_mark.rs:54:9 + --> $DIR/question_mark.rs:51:9 | LL | / if self.opt.is_none() { LL | | return None @@ -25,7 +25,7 @@ LL | | } | |_________^ help: replace it with: `self.opt?;` error: this block may be rewritten with the `?` operator - --> $DIR/question_mark.rs:58:17 + --> $DIR/question_mark.rs:55:17 | LL | let _ = if self.opt.is_none() { | _________________^ @@ -36,7 +36,7 @@ LL | | }; | |_________^ help: replace it with: `Some(self.opt?)` error: this if-let-else may be rewritten with the `?` operator - --> $DIR/question_mark.rs:64:17 + --> $DIR/question_mark.rs:61:17 | LL | let _ = if let Some(x) = self.opt { | _________________^ @@ -47,7 +47,7 @@ LL | | }; | |_________^ help: replace it with: `self.opt?` error: this block may be rewritten with the `?` operator - --> $DIR/question_mark.rs:81:9 + --> $DIR/question_mark.rs:78:9 | LL | / if self.opt.is_none() { LL | | return None; @@ -55,7 +55,7 @@ LL | | } | |_________^ help: replace it with: `self.opt.as_ref()?;` error: this block may be rewritten with the `?` operator - --> $DIR/question_mark.rs:89:9 + --> $DIR/question_mark.rs:86:9 | LL | / if self.opt.is_none() { LL | | return None; @@ -63,7 +63,7 @@ LL | | } | |_________^ help: replace it with: `self.opt.as_ref()?;` error: this block may be rewritten with the `?` operator - --> $DIR/question_mark.rs:97:9 + --> $DIR/question_mark.rs:94:9 | LL | / if self.opt.is_none() { LL | | return None; @@ -71,7 +71,7 @@ LL | | } | |_________^ help: replace it with: `self.opt.as_ref()?;` error: this if-let-else may be rewritten with the `?` operator - --> $DIR/question_mark.rs:104:26 + --> $DIR/question_mark.rs:101:26 | LL | let v: &Vec<_> = if let Some(ref v) = self.opt { | __________________________^ @@ -82,7 +82,7 @@ LL | | }; | |_________^ help: replace it with: `self.opt.as_ref()?` error: this if-let-else may be rewritten with the `?` operator - --> $DIR/question_mark.rs:114:17 + --> $DIR/question_mark.rs:111:17 | LL | let v = if let Some(v) = self.opt { | _________________^ @@ -93,7 +93,7 @@ LL | | }; | |_________^ help: replace it with: `self.opt?` error: this block may be rewritten with the `?` operator - --> $DIR/question_mark.rs:129:5 + --> $DIR/question_mark.rs:126:5 | LL | / if f().is_none() { LL | | return None; diff --git a/tests/ui/redundant_pattern_matching.fixed b/tests/ui/redundant_pattern_matching.fixed index 8b4e2d21331cd..ce8582d2b221c 100644 --- a/tests/ui/redundant_pattern_matching.fixed +++ b/tests/ui/redundant_pattern_matching.fixed @@ -2,7 +2,13 @@ #![warn(clippy::all)] #![warn(clippy::redundant_pattern_matching)] -#![allow(clippy::unit_arg, unused_must_use, clippy::needless_bool, deprecated)] +#![allow( + clippy::unit_arg, + unused_must_use, + clippy::needless_bool, + clippy::match_like_matches_macro, + deprecated +)] fn main() { if Ok::(42).is_ok() {} diff --git a/tests/ui/redundant_pattern_matching.rs b/tests/ui/redundant_pattern_matching.rs index b0904e41b6f43..a3a9aa40e3b9c 100644 --- a/tests/ui/redundant_pattern_matching.rs +++ b/tests/ui/redundant_pattern_matching.rs @@ -2,7 +2,13 @@ #![warn(clippy::all)] #![warn(clippy::redundant_pattern_matching)] -#![allow(clippy::unit_arg, unused_must_use, clippy::needless_bool, deprecated)] +#![allow( + clippy::unit_arg, + unused_must_use, + clippy::needless_bool, + clippy::match_like_matches_macro, + deprecated +)] fn main() { if let Ok(_) = Ok::(42) {} diff --git a/tests/ui/redundant_pattern_matching.stderr b/tests/ui/redundant_pattern_matching.stderr index 51a6f4350d32c..25d1476062e7f 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:8:12 + --> $DIR/redundant_pattern_matching.rs:14:12 | LL | if let Ok(_) = Ok::(42) {} | -------^^^^^--------------------- help: try this: `if Ok::(42).is_ok()` @@ -7,67 +7,67 @@ 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:10:12 + --> $DIR/redundant_pattern_matching.rs:16:12 | LL | if let Err(_) = Err::(42) {} | -------^^^^^^---------------------- help: try this: `if Err::(42).is_err()` error: redundant pattern matching, consider using `is_none()` - --> $DIR/redundant_pattern_matching.rs:12:12 + --> $DIR/redundant_pattern_matching.rs:18:12 | LL | if let None = None::<()> {} | -------^^^^------------- help: try this: `if None::<()>.is_none()` error: redundant pattern matching, consider using `is_some()` - --> $DIR/redundant_pattern_matching.rs:14:12 + --> $DIR/redundant_pattern_matching.rs:20:12 | LL | if let Some(_) = Some(42) {} | -------^^^^^^^----------- help: try this: `if Some(42).is_some()` error: redundant pattern matching, consider using `is_some()` - --> $DIR/redundant_pattern_matching.rs:16:12 + --> $DIR/redundant_pattern_matching.rs:22:12 | LL | if let Some(_) = Some(42) { | -------^^^^^^^----------- help: try this: `if Some(42).is_some()` error: redundant pattern matching, consider using `is_some()` - --> $DIR/redundant_pattern_matching.rs:22:15 + --> $DIR/redundant_pattern_matching.rs:28:15 | LL | while let Some(_) = Some(42) {} | ----------^^^^^^^----------- help: try this: `while Some(42).is_some()` error: redundant pattern matching, consider using `is_none()` - --> $DIR/redundant_pattern_matching.rs:24:15 + --> $DIR/redundant_pattern_matching.rs:30:15 | LL | while let None = Some(42) {} | ----------^^^^----------- help: try this: `while Some(42).is_none()` error: redundant pattern matching, consider using `is_none()` - --> $DIR/redundant_pattern_matching.rs:26:15 + --> $DIR/redundant_pattern_matching.rs:32:15 | LL | while let None = None::<()> {} | ----------^^^^------------- help: try this: `while None::<()>.is_none()` error: redundant pattern matching, consider using `is_ok()` - --> $DIR/redundant_pattern_matching.rs:28:15 + --> $DIR/redundant_pattern_matching.rs:34:15 | LL | while let Ok(_) = Ok::(10) {} | ----------^^^^^--------------------- help: try this: `while Ok::(10).is_ok()` error: redundant pattern matching, consider using `is_err()` - --> $DIR/redundant_pattern_matching.rs:30:15 + --> $DIR/redundant_pattern_matching.rs:36:15 | LL | while let Err(_) = Ok::(10) {} | ----------^^^^^^--------------------- help: try this: `while Ok::(10).is_err()` error: redundant pattern matching, consider using `is_some()` - --> $DIR/redundant_pattern_matching.rs:33:15 + --> $DIR/redundant_pattern_matching.rs:39:15 | LL | while let Some(_) = v.pop() { | ----------^^^^^^^---------- help: try this: `while v.pop().is_some()` error: redundant pattern matching, consider using `is_ok()` - --> $DIR/redundant_pattern_matching.rs:49:5 + --> $DIR/redundant_pattern_matching.rs:55:5 | LL | / match Ok::(42) { LL | | Ok(_) => true, @@ -76,7 +76,7 @@ LL | | }; | |_____^ help: try this: `Ok::(42).is_ok()` error: redundant pattern matching, consider using `is_err()` - --> $DIR/redundant_pattern_matching.rs:54:5 + --> $DIR/redundant_pattern_matching.rs:60:5 | LL | / match Ok::(42) { LL | | Ok(_) => false, @@ -85,7 +85,7 @@ LL | | }; | |_____^ help: try this: `Ok::(42).is_err()` error: redundant pattern matching, consider using `is_err()` - --> $DIR/redundant_pattern_matching.rs:59:5 + --> $DIR/redundant_pattern_matching.rs:65:5 | LL | / match Err::(42) { LL | | Ok(_) => false, @@ -94,7 +94,7 @@ LL | | }; | |_____^ help: try this: `Err::(42).is_err()` error: redundant pattern matching, consider using `is_ok()` - --> $DIR/redundant_pattern_matching.rs:64:5 + --> $DIR/redundant_pattern_matching.rs:70:5 | LL | / match Err::(42) { LL | | Ok(_) => true, @@ -103,7 +103,7 @@ LL | | }; | |_____^ help: try this: `Err::(42).is_ok()` error: redundant pattern matching, consider using `is_some()` - --> $DIR/redundant_pattern_matching.rs:69:5 + --> $DIR/redundant_pattern_matching.rs:75:5 | LL | / match Some(42) { LL | | Some(_) => true, @@ -112,7 +112,7 @@ LL | | }; | |_____^ help: try this: `Some(42).is_some()` error: redundant pattern matching, consider using `is_none()` - --> $DIR/redundant_pattern_matching.rs:74:5 + --> $DIR/redundant_pattern_matching.rs:80:5 | LL | / match None::<()> { LL | | Some(_) => false, @@ -121,7 +121,7 @@ LL | | }; | |_____^ help: try this: `None::<()>.is_none()` error: redundant pattern matching, consider using `is_none()` - --> $DIR/redundant_pattern_matching.rs:79:13 + --> $DIR/redundant_pattern_matching.rs:85:13 | LL | let _ = match None::<()> { | _____________^ @@ -131,61 +131,61 @@ LL | | }; | |_____^ help: try this: `None::<()>.is_none()` error: redundant pattern matching, consider using `is_ok()` - --> $DIR/redundant_pattern_matching.rs:84:20 + --> $DIR/redundant_pattern_matching.rs:90:20 | LL | let _ = if let Ok(_) = Ok::(4) { true } else { false }; | -------^^^^^--------------------- help: try this: `if Ok::(4).is_ok()` error: redundant pattern matching, consider using `is_some()` - --> $DIR/redundant_pattern_matching.rs:87:20 + --> $DIR/redundant_pattern_matching.rs:93:20 | LL | let x = if let Some(_) = opt { true } else { false }; | -------^^^^^^^------ help: try this: `if opt.is_some()` error: redundant pattern matching, consider using `is_some()` - --> $DIR/redundant_pattern_matching.rs:93:20 + --> $DIR/redundant_pattern_matching.rs:99:20 | LL | let _ = if let Some(_) = gen_opt() { | -------^^^^^^^------------ help: try this: `if gen_opt().is_some()` error: redundant pattern matching, consider using `is_none()` - --> $DIR/redundant_pattern_matching.rs:95:19 + --> $DIR/redundant_pattern_matching.rs:101:19 | LL | } else if let None = gen_opt() { | -------^^^^------------ help: try this: `if gen_opt().is_none()` error: redundant pattern matching, consider using `is_ok()` - --> $DIR/redundant_pattern_matching.rs:97:19 + --> $DIR/redundant_pattern_matching.rs:103:19 | LL | } else if let Ok(_) = gen_res() { | -------^^^^^------------ help: try this: `if gen_res().is_ok()` error: redundant pattern matching, consider using `is_err()` - --> $DIR/redundant_pattern_matching.rs:99:19 + --> $DIR/redundant_pattern_matching.rs:105:19 | LL | } else if let Err(_) = gen_res() { | -------^^^^^^------------ help: try this: `if gen_res().is_err()` error: redundant pattern matching, consider using `is_some()` - --> $DIR/redundant_pattern_matching.rs:132:19 + --> $DIR/redundant_pattern_matching.rs:138:19 | LL | while let Some(_) = r#try!(result_opt()) {} | ----------^^^^^^^----------------------- help: try this: `while r#try!(result_opt()).is_some()` error: redundant pattern matching, consider using `is_some()` - --> $DIR/redundant_pattern_matching.rs:133:16 + --> $DIR/redundant_pattern_matching.rs:139:16 | LL | if let Some(_) = r#try!(result_opt()) {} | -------^^^^^^^----------------------- help: try this: `if r#try!(result_opt()).is_some()` error: redundant pattern matching, consider using `is_some()` - --> $DIR/redundant_pattern_matching.rs:139:12 + --> $DIR/redundant_pattern_matching.rs:145:12 | LL | if let Some(_) = m!() {} | -------^^^^^^^------- help: try this: `if m!().is_some()` error: redundant pattern matching, consider using `is_some()` - --> $DIR/redundant_pattern_matching.rs:140:15 + --> $DIR/redundant_pattern_matching.rs:146:15 | LL | while let Some(_) = m!() {} | ----------^^^^^^^------- help: try this: `while m!().is_some()` diff --git a/tests/ui/redundant_pattern_matching_const_result.fixed b/tests/ui/redundant_pattern_matching_const_result.fixed index 8a81e92f04a73..de3fe00d5fa68 100644 --- a/tests/ui/redundant_pattern_matching_const_result.fixed +++ b/tests/ui/redundant_pattern_matching_const_result.fixed @@ -2,7 +2,7 @@ #![feature(const_result)] #![warn(clippy::redundant_pattern_matching)] -#![allow(unused)] +#![allow(clippy::match_like_matches_macro, unused)] // Test that results are linted with the feature enabled. diff --git a/tests/ui/redundant_pattern_matching_const_result.rs b/tests/ui/redundant_pattern_matching_const_result.rs index 1cd515441d13a..b77969d53d92d 100644 --- a/tests/ui/redundant_pattern_matching_const_result.rs +++ b/tests/ui/redundant_pattern_matching_const_result.rs @@ -2,7 +2,7 @@ #![feature(const_result)] #![warn(clippy::redundant_pattern_matching)] -#![allow(unused)] +#![allow(clippy::match_like_matches_macro, unused)] // Test that results are linted with the feature enabled. From 0c8afa39ce8b2e7f0f9be7fc33fe3993d9bc3c53 Mon Sep 17 00:00:00 2001 From: Thiago Arrais Date: Mon, 1 Jun 2020 18:32:52 -0300 Subject: [PATCH 56/99] Lint x.log(b) / y.log(b) => x.log(y) --- clippy_lints/src/floating_point_arithmetic.rs | 65 ++++++++++++++++--- tests/ui/floating_point_logbase.fixed | 16 +++++ tests/ui/floating_point_logbase.rs | 16 +++++ tests/ui/floating_point_logbase.stderr | 28 ++++++++ 4 files changed, 115 insertions(+), 10 deletions(-) create mode 100644 tests/ui/floating_point_logbase.fixed create mode 100644 tests/ui/floating_point_logbase.rs create mode 100644 tests/ui/floating_point_logbase.stderr diff --git a/clippy_lints/src/floating_point_arithmetic.rs b/clippy_lints/src/floating_point_arithmetic.rs index 3b2e46a9a8529..9f241c2c3a2b2 100644 --- a/clippy_lints/src/floating_point_arithmetic.rs +++ b/clippy_lints/src/floating_point_arithmetic.rs @@ -293,13 +293,13 @@ fn check_powf(cx: &LateContext<'_>, expr: &Expr<'_>, args: &[Expr<'_>]) { } } -fn check_powi(cx: &LateContext<'_, '_>, expr: &Expr<'_>, args: &[Expr<'_>]) { +fn check_powi(cx: &LateContext<'_>, expr: &Expr<'_>, args: &[Expr<'_>]) { // Check argument - if let Some((value, _)) = constant(cx, cx.tables, &args[1]) { + if let Some((value, _)) = constant(cx, cx.tables(), &args[1]) { // TODO: need more specific check. this is too wide. remember also to include tests if let Some(parent) = get_parent_expr(cx, expr) { if let Some(grandparent) = get_parent_expr(cx, parent) { - if let ExprKind::MethodCall(PathSegment { ident: method_name, .. }, _, args) = grandparent.kind { + if let ExprKind::MethodCall(PathSegment { ident: method_name, .. }, _, args, _) = grandparent.kind { if method_name.as_str() == "sqrt" && detect_hypot(cx, args).is_some() { return; } @@ -328,7 +328,7 @@ fn check_powi(cx: &LateContext<'_, '_>, expr: &Expr<'_>, args: &[Expr<'_>]) { } } -fn detect_hypot(cx: &LateContext<'_, '_>, args: &[Expr<'_>]) -> Option { +fn detect_hypot(cx: &LateContext<'_>, args: &[Expr<'_>]) -> Option { if let ExprKind::Binary( Spanned { node: BinOpKind::Add, .. @@ -350,11 +350,11 @@ fn detect_hypot(cx: &LateContext<'_, '_>, args: &[Expr<'_>]) -> Option { // check if expression of the form x.powi(2) + y.powi(2) if_chain! { - if let ExprKind::MethodCall(PathSegment { ident: lmethod_name, .. }, ref _lspan, ref largs) = add_lhs.kind; - if let ExprKind::MethodCall(PathSegment { ident: rmethod_name, .. }, ref _rspan, ref rargs) = add_rhs.kind; + if let ExprKind::MethodCall(PathSegment { ident: lmethod_name, .. }, ref _lspan, ref largs, _) = add_lhs.kind; + if let ExprKind::MethodCall(PathSegment { ident: rmethod_name, .. }, ref _rspan, ref rargs, _) = add_rhs.kind; if lmethod_name.as_str() == "powi" && rmethod_name.as_str() == "powi"; - if let Some((lvalue, _)) = constant(cx, cx.tables, &largs[1]); - if let Some((rvalue, _)) = constant(cx, cx.tables, &rargs[1]); + if let Some((lvalue, _)) = constant(cx, cx.tables(), &largs[1]); + if let Some((rvalue, _)) = constant(cx, cx.tables(), &rargs[1]); if Int(2) == lvalue && Int(2) == rvalue; then { return Some(format!("{}.hypot({})", Sugg::hir(cx, &largs[0], ".."), Sugg::hir(cx, &rargs[0], ".."))); @@ -365,7 +365,7 @@ fn detect_hypot(cx: &LateContext<'_, '_>, args: &[Expr<'_>]) -> Option { None } -fn check_hypot(cx: &LateContext<'_, '_>, expr: &Expr<'_>, args: &[Expr<'_>]) { +fn check_hypot(cx: &LateContext<'_>, expr: &Expr<'_>, args: &[Expr<'_>]) { if let Some(message) = detect_hypot(cx, args) { span_lint_and_sugg( cx, @@ -431,7 +431,7 @@ fn check_mul_add(cx: &LateContext<'_>, expr: &Expr<'_>) { ) = &expr.kind { if let Some(parent) = get_parent_expr(cx, expr) { - if let ExprKind::MethodCall(PathSegment { ident: method_name, .. }, _, args) = parent.kind { + if let ExprKind::MethodCall(PathSegment { ident: method_name, .. }, _, args, _) = parent.kind { if method_name.as_str() == "sqrt" && detect_hypot(cx, args).is_some() { return; } @@ -573,6 +573,50 @@ fn check_custom_abs(cx: &LateContext<'_>, expr: &Expr<'_>) { } } +fn are_same_base_logs(cx: &LateContext<'_>, expr_a: &Expr<'_>, expr_b: &Expr<'_>) -> bool { + if_chain! { + if let ExprKind::MethodCall(PathSegment { ident: method_name_a, .. }, _, ref args_a, _) = expr_a.kind; + if let ExprKind::MethodCall(PathSegment { ident: method_name_b, .. }, _, ref args_b, _) = expr_b.kind; + then { + return method_name_a.as_str() == method_name_b.as_str() && + args_a.len() == args_b.len() && + ( + ["ln", "log2", "log10"].contains(&&*method_name_a.as_str()) || + method_name_a.as_str() == "log" && args_a.len() == 2 && are_exprs_equal(cx, &args_a[1], &args_b[1]) + ); + } + } + + false +} + +fn check_log_division(cx: &LateContext<'_>, expr: &Expr<'_>) { + // check if expression of the form x.logN() / y.logN() + if_chain! { + if let ExprKind::Binary( + Spanned { + node: BinOpKind::Div, .. + }, + lhs, + rhs, + ) = &expr.kind; + if are_same_base_logs(cx, lhs, rhs); + if let ExprKind::MethodCall(_, _, ref largs, _) = lhs.kind; + if let ExprKind::MethodCall(_, _, ref rargs, _) = rhs.kind; + then { + span_lint_and_sugg( + cx, + SUBOPTIMAL_FLOPS, + expr.span, + "division of logarithms can be calculated more efficiently and accurately", + "consider using", + format!("{}.log({})", Sugg::hir(cx, &largs[0], ".."), Sugg::hir(cx, &rargs[0], ".."),), + Applicability::MachineApplicable, + ); + } + } +} + impl<'tcx> LateLintPass<'tcx> for FloatingPointArithmetic { fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { if let ExprKind::MethodCall(ref path, _, args, _) = &expr.kind { @@ -592,6 +636,7 @@ impl<'tcx> LateLintPass<'tcx> for FloatingPointArithmetic { check_expm1(cx, expr); check_mul_add(cx, expr); check_custom_abs(cx, expr); + check_log_division(cx, expr); } } } diff --git a/tests/ui/floating_point_logbase.fixed b/tests/ui/floating_point_logbase.fixed new file mode 100644 index 0000000000000..13962a272d455 --- /dev/null +++ b/tests/ui/floating_point_logbase.fixed @@ -0,0 +1,16 @@ +// run-rustfix +#![warn(clippy::suboptimal_flops)] + +fn main() { + let x = 3f32; + let y = 5f32; + let _ = x.log(y); + let _ = x.log(y); + let _ = x.log(y); + let _ = x.log(y); + // Cases where the lint shouldn't be applied + let _ = x.ln() / y.powf(3.2); + let _ = x.powf(3.2) / y.powf(3.2); + let _ = x.powf(3.2) / y.ln(); + let _ = x.log(5f32) / y.log(7f32); +} diff --git a/tests/ui/floating_point_logbase.rs b/tests/ui/floating_point_logbase.rs new file mode 100644 index 0000000000000..26bc20d5370b1 --- /dev/null +++ b/tests/ui/floating_point_logbase.rs @@ -0,0 +1,16 @@ +// run-rustfix +#![warn(clippy::suboptimal_flops)] + +fn main() { + let x = 3f32; + let y = 5f32; + let _ = x.ln() / y.ln(); + let _ = x.log2() / y.log2(); + let _ = x.log10() / y.log10(); + let _ = x.log(5f32) / y.log(5f32); + // Cases where the lint shouldn't be applied + let _ = x.ln() / y.powf(3.2); + let _ = x.powf(3.2) / y.powf(3.2); + let _ = x.powf(3.2) / y.ln(); + let _ = x.log(5f32) / y.log(7f32); +} diff --git a/tests/ui/floating_point_logbase.stderr b/tests/ui/floating_point_logbase.stderr new file mode 100644 index 0000000000000..fa956b9139eb8 --- /dev/null +++ b/tests/ui/floating_point_logbase.stderr @@ -0,0 +1,28 @@ +error: division of logarithms can be calculated more efficiently and accurately + --> $DIR/floating_point_logbase.rs:7:13 + | +LL | let _ = x.ln() / y.ln(); + | ^^^^^^^^^^^^^^^ help: consider using: `x.log(y)` + | + = note: `-D clippy::suboptimal-flops` implied by `-D warnings` + +error: division of logarithms can be calculated more efficiently and accurately + --> $DIR/floating_point_logbase.rs:8:13 + | +LL | let _ = x.log2() / y.log2(); + | ^^^^^^^^^^^^^^^^^^^ help: consider using: `x.log(y)` + +error: division of logarithms can be calculated more efficiently and accurately + --> $DIR/floating_point_logbase.rs:9:13 + | +LL | let _ = x.log10() / y.log10(); + | ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.log(y)` + +error: division of logarithms can be calculated more efficiently and accurately + --> $DIR/floating_point_logbase.rs:10:13 + | +LL | let _ = x.log(5f32) / y.log(5f32); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.log(y)` + +error: aborting due to 4 previous errors + From 1740dda76386aff7205b2a709a32c95e8cbc0d57 Mon Sep 17 00:00:00 2001 From: robojumper Date: Sun, 5 Jul 2020 22:11:19 +0200 Subject: [PATCH 57/99] fix match_like_matches_macro in clippy --- clippy_lints/src/assign_ops.rs | 1 + clippy_lints/src/comparison_chain.rs | 5 +--- clippy_lints/src/eq_op.rs | 30 +++++++++++------------ clippy_lints/src/escape.rs | 5 +--- clippy_lints/src/eta_reduction.rs | 5 +--- clippy_lints/src/formatting.rs | 12 ++------- clippy_lints/src/functions.rs | 8 +----- clippy_lints/src/lib.rs | 11 +++++---- clippy_lints/src/lifetimes.rs | 16 ++++++------ clippy_lints/src/loops.rs | 10 ++------ clippy_lints/src/methods/mod.rs | 16 ++++-------- clippy_lints/src/misc.rs | 7 +----- clippy_lints/src/misc_early.rs | 18 +++++--------- clippy_lints/src/missing_inline.rs | 9 ++++--- clippy_lints/src/new_without_default.rs | 10 +++++--- clippy_lints/src/non_copy_const.rs | 8 +++--- clippy_lints/src/precedence.rs | 10 ++------ clippy_lints/src/regex.rs | 7 +----- clippy_lints/src/shadow.rs | 5 +--- clippy_lints/src/temporary_assignment.rs | 8 +----- clippy_lints/src/types.rs | 29 ++++++---------------- clippy_lints/src/unnamed_address.rs | 14 ++++------- clippy_lints/src/use_self.rs | 6 ++--- clippy_lints/src/utils/ast_utils.rs | 5 +--- clippy_lints/src/utils/mod.rs | 11 ++------- clippy_lints/src/utils/numeric_literal.rs | 2 +- src/driver.rs | 9 ++----- 27 files changed, 91 insertions(+), 186 deletions(-) diff --git a/clippy_lints/src/assign_ops.rs b/clippy_lints/src/assign_ops.rs index bc6e868823f77..3d48bf739ebe6 100644 --- a/clippy_lints/src/assign_ops.rs +++ b/clippy_lints/src/assign_ops.rs @@ -237,6 +237,7 @@ fn is_commutative(op: hir::BinOpKind) -> bool { use rustc_hir::BinOpKind::{ Add, And, BitAnd, BitOr, BitXor, Div, Eq, Ge, Gt, Le, Lt, Mul, Ne, Or, Rem, Shl, Shr, Sub, }; + #[allow(clippy::match_like_matches_macro)] match op { Add | Mul | And | Or | BitXor | BitAnd | BitOr | Eq | Ne => true, Sub | Div | Rem | Shl | Shr | Lt | Le | Ge | Gt => false, diff --git a/clippy_lints/src/comparison_chain.rs b/clippy_lints/src/comparison_chain.rs index 26476af4cb629..25ccabc1c883e 100644 --- a/clippy_lints/src/comparison_chain.rs +++ b/clippy_lints/src/comparison_chain.rs @@ -122,8 +122,5 @@ impl<'tcx> LateLintPass<'tcx> for ComparisonChain { } fn kind_is_cmp(kind: BinOpKind) -> bool { - match kind { - BinOpKind::Lt | BinOpKind::Gt | BinOpKind::Eq => true, - _ => false, - } + matches!(kind, BinOpKind::Lt | BinOpKind::Gt | BinOpKind::Eq) } diff --git a/clippy_lints/src/eq_op.rs b/clippy_lints/src/eq_op.rs index ca921dcfdfe92..7839908fe4c91 100644 --- a/clippy_lints/src/eq_op.rs +++ b/clippy_lints/src/eq_op.rs @@ -214,20 +214,20 @@ impl<'tcx> LateLintPass<'tcx> for EqOp { } fn is_valid_operator(op: BinOp) -> bool { - match op.node { + matches!( + op.node, BinOpKind::Sub - | BinOpKind::Div - | BinOpKind::Eq - | BinOpKind::Lt - | BinOpKind::Le - | BinOpKind::Gt - | BinOpKind::Ge - | BinOpKind::Ne - | BinOpKind::And - | BinOpKind::Or - | BinOpKind::BitXor - | BinOpKind::BitAnd - | BinOpKind::BitOr => true, - _ => false, - } + | BinOpKind::Div + | BinOpKind::Eq + | BinOpKind::Lt + | BinOpKind::Le + | BinOpKind::Gt + | BinOpKind::Ge + | BinOpKind::Ne + | BinOpKind::And + | BinOpKind::Or + | BinOpKind::BitXor + | BinOpKind::BitAnd + | BinOpKind::BitOr + ) } diff --git a/clippy_lints/src/escape.rs b/clippy_lints/src/escape.rs index d40cdfcca9f66..32fc01149d881 100644 --- a/clippy_lints/src/escape.rs +++ b/clippy_lints/src/escape.rs @@ -105,10 +105,7 @@ fn is_argument(map: rustc_middle::hir::map::Map<'_>, id: HirId) -> bool { _ => return false, } - match map.find(map.get_parent_node(id)) { - Some(Node::Param(_)) => true, - _ => false, - } + matches!(map.find(map.get_parent_node(id)), Some(Node::Param(_))) } impl<'a, 'tcx> Delegate<'tcx> for EscapeDelegate<'a, 'tcx> { diff --git a/clippy_lints/src/eta_reduction.rs b/clippy_lints/src/eta_reduction.rs index ceed6a74c4fcc..fb26b9fc27d25 100644 --- a/clippy_lints/src/eta_reduction.rs +++ b/clippy_lints/src/eta_reduction.rs @@ -175,10 +175,7 @@ fn get_ufcs_type_name(cx: &LateContext<'_>, method_def_id: def_id::DefId, self_a fn match_borrow_depth(lhs: Ty<'_>, rhs: Ty<'_>) -> bool { match (&lhs.kind, &rhs.kind) { (ty::Ref(_, t1, mut1), ty::Ref(_, t2, mut2)) => mut1 == mut2 && match_borrow_depth(&t1, &t2), - (l, r) => match (l, r) { - (ty::Ref(_, _, _), _) | (_, ty::Ref(_, _, _)) => false, - (_, _) => true, - }, + (l, r) => !matches!((l, r), (ty::Ref(_, _, _), _) | (_, ty::Ref(_, _, _))), } } diff --git a/clippy_lints/src/formatting.rs b/clippy_lints/src/formatting.rs index 156246fb8bbb0..1bd16e6cce53a 100644 --- a/clippy_lints/src/formatting.rs +++ b/clippy_lints/src/formatting.rs @@ -305,18 +305,10 @@ fn check_missing_else(cx: &EarlyContext<'_>, first: &Expr, second: &Expr) { } fn is_block(expr: &Expr) -> bool { - if let ExprKind::Block(..) = expr.kind { - true - } else { - false - } + matches!(expr.kind, ExprKind::Block(..)) } /// Check if the expression is an `if` or `if let` fn is_if(expr: &Expr) -> bool { - if let ExprKind::If(..) = expr.kind { - true - } else { - false - } + matches!(expr.kind, ExprKind::If(..)) } diff --git a/clippy_lints/src/functions.rs b/clippy_lints/src/functions.rs index 3f030dd84225b..63133a4872a3e 100644 --- a/clippy_lints/src/functions.rs +++ b/clippy_lints/src/functions.rs @@ -645,13 +645,7 @@ fn is_mutated_static(cx: &LateContext<'_>, e: &hir::Expr<'_>) -> bool { use hir::ExprKind::{Field, Index, Path}; match e.kind { - Path(ref qpath) => { - if let Res::Local(_) = qpath_res(cx, qpath, e.hir_id) { - false - } else { - true - } - }, + Path(ref qpath) => !matches!(qpath_res(cx, qpath, e.hir_id), Res::Local(_)), Field(ref inner, _) | Index(ref inner, _) => is_mutated_static(cx, inner), _ => false, } diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index fe34e4390d659..c4f1af8f4e414 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -277,7 +277,6 @@ mod question_mark; mod ranges; mod redundant_clone; mod redundant_field_names; -mod redundant_pattern_matching; mod redundant_pub_crate; mod redundant_static_lifetimes; mod reference; @@ -623,11 +622,13 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: &matches::INFALLIBLE_DESTRUCTURING_MATCH, &matches::MATCH_AS_REF, &matches::MATCH_BOOL, + &matches::MATCH_LIKE_MATCHES_MACRO, &matches::MATCH_OVERLAPPING_ARM, &matches::MATCH_REF_PATS, &matches::MATCH_SINGLE_BINDING, &matches::MATCH_WILDCARD_FOR_SINGLE_VARIANTS, &matches::MATCH_WILD_ERR_ARM, + &matches::REDUNDANT_PATTERN_MATCHING, &matches::REST_PAT_IN_FULLY_BOUND_STRUCTS, &matches::SINGLE_MATCH, &matches::SINGLE_MATCH_ELSE, @@ -757,7 +758,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: &ranges::REVERSED_EMPTY_RANGES, &redundant_clone::REDUNDANT_CLONE, &redundant_field_names::REDUNDANT_FIELD_NAMES, - &redundant_pattern_matching::REDUNDANT_PATTERN_MATCHING, &redundant_pub_crate::REDUNDANT_PUB_CRATE, &redundant_static_lifetimes::REDUNDANT_STATIC_LIFETIMES, &reference::DEREF_ADDROF, @@ -956,7 +956,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: store.register_late_pass(|| box missing_doc::MissingDoc::new()); store.register_late_pass(|| box missing_inline::MissingInline); store.register_late_pass(|| box if_let_some_result::OkIfLet); - store.register_late_pass(|| box redundant_pattern_matching::RedundantPatternMatching); store.register_late_pass(|| box partialeq_ne_impl::PartialEqNeImpl); store.register_late_pass(|| box unused_io_amount::UnusedIoAmount); let enum_variant_size_threshold = conf.enum_variant_size_threshold; @@ -1295,9 +1294,11 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: LintId::of(&map_unit_fn::RESULT_MAP_UNIT_FN), LintId::of(&matches::INFALLIBLE_DESTRUCTURING_MATCH), LintId::of(&matches::MATCH_AS_REF), + LintId::of(&matches::MATCH_LIKE_MATCHES_MACRO), LintId::of(&matches::MATCH_OVERLAPPING_ARM), LintId::of(&matches::MATCH_REF_PATS), LintId::of(&matches::MATCH_SINGLE_BINDING), + LintId::of(&matches::REDUNDANT_PATTERN_MATCHING), LintId::of(&matches::SINGLE_MATCH), LintId::of(&matches::WILDCARD_IN_OR_PATTERNS), LintId::of(&mem_discriminant::MEM_DISCRIMINANT_NON_ENUM), @@ -1387,7 +1388,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: LintId::of(&ranges::REVERSED_EMPTY_RANGES), LintId::of(&redundant_clone::REDUNDANT_CLONE), LintId::of(&redundant_field_names::REDUNDANT_FIELD_NAMES), - LintId::of(&redundant_pattern_matching::REDUNDANT_PATTERN_MATCHING), LintId::of(&redundant_static_lifetimes::REDUNDANT_STATIC_LIFETIMES), LintId::of(&reference::DEREF_ADDROF), LintId::of(&reference::REF_IN_DEREF), @@ -1488,8 +1488,10 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: LintId::of(&manual_non_exhaustive::MANUAL_NON_EXHAUSTIVE), LintId::of(&map_clone::MAP_CLONE), LintId::of(&matches::INFALLIBLE_DESTRUCTURING_MATCH), + LintId::of(&matches::MATCH_LIKE_MATCHES_MACRO), LintId::of(&matches::MATCH_OVERLAPPING_ARM), LintId::of(&matches::MATCH_REF_PATS), + LintId::of(&matches::REDUNDANT_PATTERN_MATCHING), LintId::of(&matches::SINGLE_MATCH), LintId::of(&mem_replace::MEM_REPLACE_OPTION_WITH_NONE), LintId::of(&mem_replace::MEM_REPLACE_WITH_DEFAULT), @@ -1526,7 +1528,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: LintId::of(&ptr::PTR_ARG), LintId::of(&question_mark::QUESTION_MARK), LintId::of(&redundant_field_names::REDUNDANT_FIELD_NAMES), - LintId::of(&redundant_pattern_matching::REDUNDANT_PATTERN_MATCHING), LintId::of(&redundant_static_lifetimes::REDUNDANT_STATIC_LIFETIMES), LintId::of(®ex::TRIVIAL_REGEX), LintId::of(&returns::NEEDLESS_RETURN), diff --git a/clippy_lints/src/lifetimes.rs b/clippy_lints/src/lifetimes.rs index a79f94855bdab..168f9f953e4d8 100644 --- a/clippy_lints/src/lifetimes.rs +++ b/clippy_lints/src/lifetimes.rs @@ -129,10 +129,10 @@ fn check_fn_inner<'tcx>( } let mut bounds_lts = Vec::new(); - let types = generics.params.iter().filter(|param| match param.kind { - GenericParamKind::Type { .. } => true, - _ => false, - }); + let types = generics + .params + .iter() + .filter(|param| matches!(param.kind, GenericParamKind::Type { .. })); for typ in types { for bound in typ.bounds { let mut visitor = RefVisitor::new(cx); @@ -337,10 +337,10 @@ impl<'a, 'tcx> RefVisitor<'a, 'tcx> { fn collect_anonymous_lifetimes(&mut self, qpath: &QPath<'_>, ty: &Ty<'_>) { if let Some(ref last_path_segment) = last_path_segment(qpath).args { if !last_path_segment.parenthesized - && !last_path_segment.args.iter().any(|arg| match arg { - GenericArg::Lifetime(_) => true, - _ => false, - }) + && !last_path_segment + .args + .iter() + .any(|arg| matches!(arg, GenericArg::Lifetime(_))) { let hir_id = ty.hir_id; match self.cx.qpath_res(qpath, hir_id) { diff --git a/clippy_lints/src/loops.rs b/clippy_lints/src/loops.rs index b803d753b6d04..396bb65910903 100644 --- a/clippy_lints/src/loops.rs +++ b/clippy_lints/src/loops.rs @@ -2091,17 +2091,11 @@ fn var_def_id(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option { } fn is_loop(expr: &Expr<'_>) -> bool { - match expr.kind { - ExprKind::Loop(..) => true, - _ => false, - } + matches!(expr.kind, ExprKind::Loop(..)) } fn is_conditional(expr: &Expr<'_>) -> bool { - match expr.kind { - ExprKind::Match(..) => true, - _ => false, - } + matches!(expr.kind, ExprKind::Match(..)) } fn is_nested(cx: &LateContext<'_>, match_expr: &Expr<'_>, iter_expr: &Expr<'_>) -> bool { diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index f1c8894c0ee29..4c595029ff7bc 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -1844,10 +1844,10 @@ fn lint_expect_fun_call( ty::Ref(ty::ReStatic, ..) ) }), - hir::ExprKind::Path(ref p) => match cx.qpath_res(p, arg.hir_id) { - hir::def::Res::Def(hir::def::DefKind::Const | hir::def::DefKind::Static, _) => true, - _ => false, - }, + hir::ExprKind::Path(ref p) => matches!( + cx.qpath_res(p, arg.hir_id), + hir::def::Res::Def(hir::def::DefKind::Const | hir::def::DefKind::Static, _) + ), _ => false, } } @@ -2028,13 +2028,7 @@ fn lint_clone_on_copy(cx: &LateContext<'_>, expr: &hir::Expr<'_>, arg: &hir::Exp .tables() .expr_adjustments(arg) .iter() - .filter(|adj| { - if let ty::adjustment::Adjust::Deref(_) = adj.kind { - true - } else { - false - } - }) + .filter(|adj| matches!(adj.kind, ty::adjustment::Adjust::Deref(_))) .count(); let derefs: String = iter::repeat('*').take(deref_count).collect(); snip = Some(("try dereferencing it", format!("{}{}", derefs, snippet))); diff --git a/clippy_lints/src/misc.rs b/clippy_lints/src/misc.rs index 3d4225f36a7d0..400f4b609af7f 100644 --- a/clippy_lints/src/misc.rs +++ b/clippy_lints/src/misc.rs @@ -694,12 +694,7 @@ fn in_attributes_expansion(expr: &Expr<'_>) -> bool { use rustc_span::hygiene::MacroKind; if expr.span.from_expansion() { let data = expr.span.ctxt().outer_expn_data(); - - if let ExpnKind::Macro(MacroKind::Attr, _) = data.kind { - true - } else { - false - } + matches!(data.kind, ExpnKind::Macro(MacroKind::Attr, _)) } else { false } diff --git a/clippy_lints/src/misc_early.rs b/clippy_lints/src/misc_early.rs index ad39e59d0678a..b84a1a3fe2494 100644 --- a/clippy_lints/src/misc_early.rs +++ b/clippy_lints/src/misc_early.rs @@ -641,28 +641,22 @@ fn check_unneeded_wildcard_pattern(cx: &EarlyContext<'_>, pat: &Pat) { ); } - #[allow(clippy::trivially_copy_pass_by_ref)] - fn is_wild>(pat: &&P) -> bool { - if let PatKind::Wild = pat.kind { - true - } else { - false - } - } - if let Some(rest_index) = patterns.iter().position(|pat| pat.is_rest()) { if let Some((left_index, left_pat)) = patterns[..rest_index] .iter() .rev() - .take_while(is_wild) + .take_while(|pat| matches!(pat.kind, PatKind::Wild)) .enumerate() .last() { span_lint(cx, left_pat.span.until(patterns[rest_index].span), left_index == 0); } - if let Some((right_index, right_pat)) = - patterns[rest_index + 1..].iter().take_while(is_wild).enumerate().last() + if let Some((right_index, right_pat)) = patterns[rest_index + 1..] + .iter() + .take_while(|pat| matches!(pat.kind, PatKind::Wild)) + .enumerate() + .last() { span_lint( cx, diff --git a/clippy_lints/src/missing_inline.rs b/clippy_lints/src/missing_inline.rs index bf80b62afe6e0..9c96267353701 100644 --- a/clippy_lints/src/missing_inline.rs +++ b/clippy_lints/src/missing_inline.rs @@ -71,10 +71,11 @@ fn check_missing_inline_attrs(cx: &LateContext<'_>, attrs: &[ast::Attribute], sp fn is_executable(cx: &LateContext<'_>) -> bool { use rustc_session::config::CrateType; - cx.tcx.sess.crate_types().iter().any(|t: &CrateType| match t { - CrateType::Executable => true, - _ => false, - }) + cx.tcx + .sess + .crate_types() + .iter() + .any(|t: &CrateType| matches!(t, CrateType::Executable)) } declare_lint_pass!(MissingInline => [MISSING_INLINE_IN_PUBLIC_ITEMS]); diff --git a/clippy_lints/src/new_without_default.rs b/clippy_lints/src/new_without_default.rs index 2597f5f6f17e2..621ebdef2f0b1 100644 --- a/clippy_lints/src/new_without_default.rs +++ b/clippy_lints/src/new_without_default.rs @@ -80,10 +80,12 @@ impl<'tcx> LateLintPass<'tcx> for NewWithoutDefault { // can't be implemented for unsafe new return; } - if impl_item.generics.params.iter().any(|gen| match gen.kind { - hir::GenericParamKind::Type { .. } => true, - _ => false, - }) { + if impl_item + .generics + .params + .iter() + .any(|gen| matches!(gen.kind, hir::GenericParamKind::Type { .. })) + { // when the result of `new()` depends on a type parameter we should not require // an // impl of `Default` diff --git a/clippy_lints/src/non_copy_const.rs b/clippy_lints/src/non_copy_const.rs index c11a2ff9ee07e..a3521c31a6be6 100644 --- a/clippy_lints/src/non_copy_const.rs +++ b/clippy_lints/src/non_copy_const.rs @@ -238,10 +238,10 @@ impl<'tcx> LateLintPass<'tcx> for NonCopyConst { let ty = if needs_check_adjustment { let adjustments = cx.tables().expr_adjustments(dereferenced_expr); - if let Some(i) = adjustments.iter().position(|adj| match adj.kind { - Adjust::Borrow(_) | Adjust::Deref(_) => true, - _ => false, - }) { + if let Some(i) = adjustments + .iter() + .position(|adj| matches!(adj.kind, Adjust::Borrow(_) | Adjust::Deref(_))) + { if i == 0 { cx.tables().expr_ty(dereferenced_expr) } else { diff --git a/clippy_lints/src/precedence.rs b/clippy_lints/src/precedence.rs index 7dce23dd22306..04be96aa64cf5 100644 --- a/clippy_lints/src/precedence.rs +++ b/clippy_lints/src/precedence.rs @@ -148,17 +148,11 @@ fn is_arith_expr(expr: &Expr) -> bool { #[must_use] fn is_bit_op(op: BinOpKind) -> bool { use rustc_ast::ast::BinOpKind::{BitAnd, BitOr, BitXor, Shl, Shr}; - match op { - BitXor | BitAnd | BitOr | Shl | Shr => true, - _ => false, - } + matches!(op, BitXor | BitAnd | BitOr | Shl | Shr) } #[must_use] fn is_arith_op(op: BinOpKind) -> bool { use rustc_ast::ast::BinOpKind::{Add, Div, Mul, Rem, Sub}; - match op { - Add | Sub | Mul | Div | Rem => true, - _ => false, - } + matches!(op, Add | Sub | Mul | Div | Rem) } diff --git a/clippy_lints/src/regex.rs b/clippy_lints/src/regex.rs index d8c8eff2c853f..f204a0ffb2c7b 100644 --- a/clippy_lints/src/regex.rs +++ b/clippy_lints/src/regex.rs @@ -99,12 +99,7 @@ fn is_trivial_regex(s: ®ex_syntax::hir::Hir) -> Option<&'static str> { use regex_syntax::hir::Anchor::{EndText, StartText}; use regex_syntax::hir::HirKind::{Alternation, Anchor, Concat, Empty, Literal}; - let is_literal = |e: &[regex_syntax::hir::Hir]| { - e.iter().all(|e| match *e.kind() { - Literal(_) => true, - _ => false, - }) - }; + let is_literal = |e: &[regex_syntax::hir::Hir]| e.iter().all(|e| matches!(*e.kind(), Literal(_))); match *s.kind() { Empty | Anchor(_) => Some("the regex is unlikely to be useful as it is"), diff --git a/clippy_lints/src/shadow.rs b/clippy_lints/src/shadow.rs index 4cdff63f1180a..194786c5c4145 100644 --- a/clippy_lints/src/shadow.rs +++ b/clippy_lints/src/shadow.rs @@ -165,10 +165,7 @@ fn check_local<'tcx>(cx: &LateContext<'tcx>, local: &'tcx Local<'_>, bindings: & fn is_binding(cx: &LateContext<'_>, pat_id: HirId) -> bool { let var_ty = cx.tables().node_type_opt(pat_id); - var_ty.map_or(false, |var_ty| match var_ty.kind { - ty::Adt(..) => false, - _ => true, - }) + var_ty.map_or(false, |var_ty| !matches!(var_ty.kind, ty::Adt(..))) } fn check_pat<'tcx>( diff --git a/clippy_lints/src/temporary_assignment.rs b/clippy_lints/src/temporary_assignment.rs index 509bbfd27c1a5..1aeff1baa362e 100644 --- a/clippy_lints/src/temporary_assignment.rs +++ b/clippy_lints/src/temporary_assignment.rs @@ -25,13 +25,7 @@ declare_clippy_lint! { fn is_temporary(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { match &expr.kind { ExprKind::Struct(..) | ExprKind::Tup(..) => true, - ExprKind::Path(qpath) => { - if let Res::Def(DefKind::Const, ..) = cx.qpath_res(qpath, expr.hir_id) { - true - } else { - false - } - }, + ExprKind::Path(qpath) => matches!(cx.qpath_res(qpath, expr.hir_id), Res::Def(DefKind::Const, ..)), _ => false, } } diff --git a/clippy_lints/src/types.rs b/clippy_lints/src/types.rs index d6f31a99bb36a..71207caecf585 100644 --- a/clippy_lints/src/types.rs +++ b/clippy_lints/src/types.rs @@ -775,11 +775,7 @@ impl<'tcx> LateLintPass<'tcx> for UnitArg { .iter() .filter(|arg| { if is_unit(cx.tables().expr_ty(arg)) && !is_unit_literal(arg) { - if let ExprKind::Match(.., MatchSource::TryDesugar) = &arg.kind { - false - } else { - true - } + !matches!(&arg.kind, ExprKind::Match(.., MatchSource::TryDesugar)) } else { false } @@ -899,17 +895,11 @@ fn is_questionmark_desugar_marked_call(expr: &Expr<'_>) -> bool { } fn is_unit(ty: Ty<'_>) -> bool { - match ty.kind { - ty::Tuple(slice) if slice.is_empty() => true, - _ => false, - } + matches!(ty.kind, ty::Tuple(slice) if slice.is_empty()) } fn is_unit_literal(expr: &Expr<'_>) -> bool { - match expr.kind { - ExprKind::Tup(ref slice) if slice.is_empty() => true, - _ => false, - } + matches!(expr.kind, ExprKind::Tup(ref slice) if slice.is_empty()) } declare_clippy_lint! { @@ -1154,10 +1144,7 @@ fn int_ty_to_nbits(typ: Ty<'_>, tcx: TyCtxt<'_>) -> u64 { } fn is_isize_or_usize(typ: Ty<'_>) -> bool { - match typ.kind { - ty::Int(IntTy::Isize) | ty::Uint(UintTy::Usize) => true, - _ => false, - } + matches!(typ.kind, ty::Int(IntTy::Isize) | ty::Uint(UintTy::Usize)) } fn span_precision_loss_lint(cx: &LateContext<'_>, expr: &Expr<'_>, cast_from: Ty<'_>, cast_to_f64: bool) { @@ -1737,10 +1724,10 @@ impl<'tcx> Visitor<'tcx> for TypeComplexityVisitor { TyKind::TraitObject(ref param_bounds, _) => { let has_lifetime_parameters = param_bounds.iter().any(|bound| { - bound.bound_generic_params.iter().any(|gen| match gen.kind { - GenericParamKind::Lifetime { .. } => true, - _ => false, - }) + bound + .bound_generic_params + .iter() + .any(|gen| matches!(gen.kind, GenericParamKind::Lifetime { .. })) }); if has_lifetime_parameters { // complex trait bounds like A<'a, 'b> diff --git a/clippy_lints/src/unnamed_address.rs b/clippy_lints/src/unnamed_address.rs index b9aa202b328f6..25d136e564d3e 100644 --- a/clippy_lints/src/unnamed_address.rs +++ b/clippy_lints/src/unnamed_address.rs @@ -58,10 +58,10 @@ declare_lint_pass!(UnnamedAddress => [FN_ADDRESS_COMPARISONS, VTABLE_ADDRESS_COM impl LateLintPass<'_> for UnnamedAddress { fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) { fn is_comparison(binop: BinOpKind) -> bool { - match binop { - BinOpKind::Eq | BinOpKind::Lt | BinOpKind::Le | BinOpKind::Ne | BinOpKind::Ge | BinOpKind::Gt => true, - _ => false, - } + matches!( + binop, + BinOpKind::Eq | BinOpKind::Lt | BinOpKind::Le | BinOpKind::Ne | BinOpKind::Ge | BinOpKind::Gt + ) } fn is_trait_ptr(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { @@ -72,11 +72,7 @@ impl LateLintPass<'_> for UnnamedAddress { } fn is_fn_def(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { - if let ty::FnDef(..) = cx.tables().expr_ty(expr).kind { - true - } else { - false - } + matches!(cx.tables().expr_ty(expr).kind, ty::FnDef(..)) } if_chain! { diff --git a/clippy_lints/src/use_self.rs b/clippy_lints/src/use_self.rs index 39a8c02087284..776c6bc57ca6f 100644 --- a/clippy_lints/src/use_self.rs +++ b/clippy_lints/src/use_self.rs @@ -169,10 +169,8 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf { let parameters = &item_path.segments.last().expect(SEGMENTS_MSG).args; let should_check = parameters.as_ref().map_or( true, - |params| !params.parenthesized && !params.args.iter().any(|arg| match arg { - GenericArg::Lifetime(_) => true, - _ => false, - }) + |params| !params.parenthesized + &&!params.args.iter().any(|arg| matches!(arg, GenericArg::Lifetime(_))) ); if should_check { diff --git a/clippy_lints/src/utils/ast_utils.rs b/clippy_lints/src/utils/ast_utils.rs index e19a79dd8dad1..58c1103da9f7d 100755 --- a/clippy_lints/src/utils/ast_utils.rs +++ b/clippy_lints/src/utils/ast_utils.rs @@ -387,10 +387,7 @@ pub fn eq_use_tree_kind(l: &UseTreeKind, r: &UseTreeKind) -> bool { } pub fn eq_defaultness(l: Defaultness, r: Defaultness) -> bool { - match (l, r) { - (Defaultness::Final, Defaultness::Final) | (Defaultness::Default(_), Defaultness::Default(_)) => true, - _ => false, - } + matches!((l, r), (Defaultness::Final, Defaultness::Final) | (Defaultness::Default(_), Defaultness::Default(_))) } pub fn eq_vis(l: &Visibility, r: &Visibility) -> bool { diff --git a/clippy_lints/src/utils/mod.rs b/clippy_lints/src/utils/mod.rs index 3a3b79925ff9a..0b4cba3fc42dc 100644 --- a/clippy_lints/src/utils/mod.rs +++ b/clippy_lints/src/utils/mod.rs @@ -102,11 +102,7 @@ pub fn in_constant(cx: &LateContext<'_>, id: HirId) -> bool { #[must_use] pub fn in_macro(span: Span) -> bool { if span.from_expansion() { - if let ExpnKind::Desugaring(..) = span.ctxt().outer_expn_data().kind { - false - } else { - true - } + !matches!(span.ctxt().outer_expn_data().kind, ExpnKind::Desugaring(..)) } else { false } @@ -127,10 +123,7 @@ pub fn is_present_in_source(cx: &T, span: Span) -> bool { /// Checks if given pattern is a wildcard (`_`) pub fn is_wild<'tcx>(pat: &impl std::ops::Deref>) -> bool { - match pat.kind { - PatKind::Wild => true, - _ => false, - } + matches!(pat.kind, PatKind::Wild) } /// Checks if type is struct, enum or union type with the given def path. diff --git a/clippy_lints/src/utils/numeric_literal.rs b/clippy_lints/src/utils/numeric_literal.rs index 7a79741b30bd0..87cb454f654bc 100644 --- a/clippy_lints/src/utils/numeric_literal.rs +++ b/clippy_lints/src/utils/numeric_literal.rs @@ -51,7 +51,7 @@ impl<'a> NumericLiteral<'a> { pub fn from_lit_kind(src: &'a str, lit_kind: &LitKind) -> Option> { if lit_kind.is_numeric() && src.chars().next().map_or(false, |c| c.is_digit(10)) { let (unsuffixed, suffix) = split_suffix(&src, lit_kind); - let float = if let LitKind::Float(..) = lit_kind { true } else { false }; + let float = matches!(lit_kind, LitKind::Float(..)); Some(NumericLiteral::new(unsuffixed, suffix, float)) } else { None diff --git a/src/driver.rs b/src/driver.rs index decd3a79cce18..47315fa64cd80 100644 --- a/src/driver.rs +++ b/src/driver.rs @@ -382,13 +382,8 @@ pub fn main() { let should_describe_lints = || { let args: Vec<_> = env::args().collect(); - args.windows(2).any(|args| { - args[1] == "help" - && match args[0].as_str() { - "-W" | "-A" | "-D" | "-F" => true, - _ => false, - } - }) + args.windows(2) + .any(|args| args[1] == "help" && matches!(args[0].as_str(), "-W" | "-A" | "-D" | "-F")) }; if !wrapper_mode && should_describe_lints() { From 076ec872ce122403f3c75f20c773c64b194a5891 Mon Sep 17 00:00:00 2001 From: Thiago Arrais Date: Wed, 10 Jun 2020 13:52:00 -0300 Subject: [PATCH 58/99] Lint for to_radians and to_degrees --- clippy_lints/src/floating_point_arithmetic.rs | 64 ++++++++++++++++++- tests/ui/floating_point_rad.fixed | 13 ++++ tests/ui/floating_point_rad.rs | 13 ++++ tests/ui/floating_point_rad.stderr | 16 +++++ 4 files changed, 104 insertions(+), 2 deletions(-) create mode 100644 tests/ui/floating_point_rad.fixed create mode 100644 tests/ui/floating_point_rad.rs create mode 100644 tests/ui/floating_point_rad.stderr diff --git a/clippy_lints/src/floating_point_arithmetic.rs b/clippy_lints/src/floating_point_arithmetic.rs index 9f241c2c3a2b2..d88e47f396cf8 100644 --- a/clippy_lints/src/floating_point_arithmetic.rs +++ b/clippy_lints/src/floating_point_arithmetic.rs @@ -350,8 +350,18 @@ fn detect_hypot(cx: &LateContext<'_>, args: &[Expr<'_>]) -> Option { // check if expression of the form x.powi(2) + y.powi(2) if_chain! { - if let ExprKind::MethodCall(PathSegment { ident: lmethod_name, .. }, ref _lspan, ref largs, _) = add_lhs.kind; - if let ExprKind::MethodCall(PathSegment { ident: rmethod_name, .. }, ref _rspan, ref rargs, _) = add_rhs.kind; + if let ExprKind::MethodCall( + PathSegment { ident: lmethod_name, .. }, + ref _lspan, + ref largs, + _ + ) = add_lhs.kind; + if let ExprKind::MethodCall( + PathSegment { ident: rmethod_name, .. }, + ref _rspan, + ref rargs, + _ + ) = add_rhs.kind; if lmethod_name.as_str() == "powi" && rmethod_name.as_str() == "powi"; if let Some((lvalue, _)) = constant(cx, cx.tables(), &largs[1]); if let Some((rvalue, _)) = constant(cx, cx.tables(), &rargs[1]); @@ -617,6 +627,55 @@ fn check_log_division(cx: &LateContext<'_>, expr: &Expr<'_>) { } } +fn check_radians(cx: &LateContext<'_>, expr: &Expr<'_>) { + if_chain! { + if let ExprKind::Binary( + Spanned { + node: BinOpKind::Div, .. + }, + div_lhs, + div_rhs, + ) = &expr.kind; + if let ExprKind::Binary( + Spanned { + node: BinOpKind::Mul, .. + }, + mul_lhs, + mul_rhs, + ) = &div_lhs.kind; + if let Some((rvalue, _)) = constant(cx, cx.tables(), div_rhs); + if let Some((lvalue, _)) = constant(cx, cx.tables(), mul_rhs); + then { + if (F32(f32_consts::PI) == rvalue || F64(f64_consts::PI) == rvalue) && + (F32(180_f32) == lvalue || F64(180_f64) == lvalue) + { + span_lint_and_sugg( + cx, + IMPRECISE_FLOPS, + expr.span, + "conversion to degrees can be done more accurately", + "consider using", + format!("{}.to_degrees()", Sugg::hir(cx, &mul_lhs, "..")), + Applicability::MachineApplicable, + ); + } else if + (F32(180_f32) == rvalue || F64(180_f64) == rvalue) && + (F32(f32_consts::PI) == lvalue || F64(f64_consts::PI) == lvalue) + { + span_lint_and_sugg( + cx, + IMPRECISE_FLOPS, + expr.span, + "conversion to radians can be done more accurately", + "consider using", + format!("{}.to_radians()", Sugg::hir(cx, &mul_lhs, "..")), + Applicability::MachineApplicable, + ); + } + } + } +} + impl<'tcx> LateLintPass<'tcx> for FloatingPointArithmetic { fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { if let ExprKind::MethodCall(ref path, _, args, _) = &expr.kind { @@ -637,6 +696,7 @@ impl<'tcx> LateLintPass<'tcx> for FloatingPointArithmetic { check_mul_add(cx, expr); check_custom_abs(cx, expr); check_log_division(cx, expr); + check_radians(cx, expr); } } } diff --git a/tests/ui/floating_point_rad.fixed b/tests/ui/floating_point_rad.fixed new file mode 100644 index 0000000000000..64461417a6a11 --- /dev/null +++ b/tests/ui/floating_point_rad.fixed @@ -0,0 +1,13 @@ +// run-rustfix +#![warn(clippy::imprecise_flops)] + +fn main() { + let x = 3f32; + let _ = x.to_degrees(); + let _ = x.to_radians(); + // Cases where the lint shouldn't be applied + let _ = x * 90f32 / std::f32::consts::PI; + let _ = x * std::f32::consts::PI / 90f32; + let _ = x * 180f32 / std::f32::consts::E; + let _ = x * std::f32::consts::E / 180f32; +} diff --git a/tests/ui/floating_point_rad.rs b/tests/ui/floating_point_rad.rs new file mode 100644 index 0000000000000..9046f184b3e52 --- /dev/null +++ b/tests/ui/floating_point_rad.rs @@ -0,0 +1,13 @@ +// run-rustfix +#![warn(clippy::imprecise_flops)] + +fn main() { + let x = 3f32; + let _ = x * 180f32 / std::f32::consts::PI; + let _ = x * std::f32::consts::PI / 180f32; + // Cases where the lint shouldn't be applied + let _ = x * 90f32 / std::f32::consts::PI; + let _ = x * std::f32::consts::PI / 90f32; + let _ = x * 180f32 / std::f32::consts::E; + let _ = x * std::f32::consts::E / 180f32; +} diff --git a/tests/ui/floating_point_rad.stderr b/tests/ui/floating_point_rad.stderr new file mode 100644 index 0000000000000..81e8182151377 --- /dev/null +++ b/tests/ui/floating_point_rad.stderr @@ -0,0 +1,16 @@ +error: conversion to degrees can be done more accurately + --> $DIR/floating_point_rad.rs:6:13 + | +LL | let _ = x * 180f32 / std::f32::consts::PI; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.to_degrees()` + | + = note: `-D clippy::imprecise-flops` implied by `-D warnings` + +error: conversion to radians can be done more accurately + --> $DIR/floating_point_rad.rs:7:13 + | +LL | let _ = x * std::f32::consts::PI / 180f32; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.to_radians()` + +error: aborting due to 2 previous errors + From f5596826fa59035e6c57d8968df0d61f69c2537b Mon Sep 17 00:00:00 2001 From: Thiago Arrais Date: Mon, 15 Jun 2020 13:55:12 -0300 Subject: [PATCH 59/99] Better copy for lint message Since x.log(y) is actually implemented as x.ln() / y.ln() --- clippy_lints/src/floating_point_arithmetic.rs | 2 +- tests/ui/floating_point_logbase.stderr | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/clippy_lints/src/floating_point_arithmetic.rs b/clippy_lints/src/floating_point_arithmetic.rs index d88e47f396cf8..b1e258f4b160a 100644 --- a/clippy_lints/src/floating_point_arithmetic.rs +++ b/clippy_lints/src/floating_point_arithmetic.rs @@ -618,7 +618,7 @@ fn check_log_division(cx: &LateContext<'_>, expr: &Expr<'_>) { cx, SUBOPTIMAL_FLOPS, expr.span, - "division of logarithms can be calculated more efficiently and accurately", + "log base can be expressed more clearly", "consider using", format!("{}.log({})", Sugg::hir(cx, &largs[0], ".."), Sugg::hir(cx, &rargs[0], ".."),), Applicability::MachineApplicable, diff --git a/tests/ui/floating_point_logbase.stderr b/tests/ui/floating_point_logbase.stderr index fa956b9139eb8..78354c2f62d43 100644 --- a/tests/ui/floating_point_logbase.stderr +++ b/tests/ui/floating_point_logbase.stderr @@ -1,4 +1,4 @@ -error: division of logarithms can be calculated more efficiently and accurately +error: log base can be expressed more clearly --> $DIR/floating_point_logbase.rs:7:13 | LL | let _ = x.ln() / y.ln(); @@ -6,19 +6,19 @@ LL | let _ = x.ln() / y.ln(); | = note: `-D clippy::suboptimal-flops` implied by `-D warnings` -error: division of logarithms can be calculated more efficiently and accurately +error: log base can be expressed more clearly --> $DIR/floating_point_logbase.rs:8:13 | LL | let _ = x.log2() / y.log2(); | ^^^^^^^^^^^^^^^^^^^ help: consider using: `x.log(y)` -error: division of logarithms can be calculated more efficiently and accurately +error: log base can be expressed more clearly --> $DIR/floating_point_logbase.rs:9:13 | LL | let _ = x.log10() / y.log10(); | ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.log(y)` -error: division of logarithms can be calculated more efficiently and accurately +error: log base can be expressed more clearly --> $DIR/floating_point_logbase.rs:10:13 | LL | let _ = x.log(5f32) / y.log(5f32); From db7bc6b3bd0e58c8fbf7507713a4214299f39c36 Mon Sep 17 00:00:00 2001 From: Thiago Arrais Date: Mon, 15 Jun 2020 13:59:44 -0300 Subject: [PATCH 60/99] Place radian lints under suboptimal_flops --- clippy_lints/src/floating_point_arithmetic.rs | 4 ++-- tests/ui/floating_point_rad.fixed | 2 +- tests/ui/floating_point_rad.rs | 2 +- tests/ui/floating_point_rad.stderr | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/clippy_lints/src/floating_point_arithmetic.rs b/clippy_lints/src/floating_point_arithmetic.rs index b1e258f4b160a..beb0b234408bc 100644 --- a/clippy_lints/src/floating_point_arithmetic.rs +++ b/clippy_lints/src/floating_point_arithmetic.rs @@ -651,7 +651,7 @@ fn check_radians(cx: &LateContext<'_>, expr: &Expr<'_>) { { span_lint_and_sugg( cx, - IMPRECISE_FLOPS, + SUBOPTIMAL_FLOPS, expr.span, "conversion to degrees can be done more accurately", "consider using", @@ -664,7 +664,7 @@ fn check_radians(cx: &LateContext<'_>, expr: &Expr<'_>) { { span_lint_and_sugg( cx, - IMPRECISE_FLOPS, + SUBOPTIMAL_FLOPS, expr.span, "conversion to radians can be done more accurately", "consider using", diff --git a/tests/ui/floating_point_rad.fixed b/tests/ui/floating_point_rad.fixed index 64461417a6a11..92480c5db8be4 100644 --- a/tests/ui/floating_point_rad.fixed +++ b/tests/ui/floating_point_rad.fixed @@ -1,5 +1,5 @@ // run-rustfix -#![warn(clippy::imprecise_flops)] +#![warn(clippy::suboptimal_flops)] fn main() { let x = 3f32; diff --git a/tests/ui/floating_point_rad.rs b/tests/ui/floating_point_rad.rs index 9046f184b3e52..062e7c3fdc17a 100644 --- a/tests/ui/floating_point_rad.rs +++ b/tests/ui/floating_point_rad.rs @@ -1,5 +1,5 @@ // run-rustfix -#![warn(clippy::imprecise_flops)] +#![warn(clippy::suboptimal_flops)] fn main() { let x = 3f32; diff --git a/tests/ui/floating_point_rad.stderr b/tests/ui/floating_point_rad.stderr index 81e8182151377..a6ffdca64eefe 100644 --- a/tests/ui/floating_point_rad.stderr +++ b/tests/ui/floating_point_rad.stderr @@ -4,7 +4,7 @@ error: conversion to degrees can be done more accurately LL | let _ = x * 180f32 / std::f32::consts::PI; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.to_degrees()` | - = note: `-D clippy::imprecise-flops` implied by `-D warnings` + = note: `-D clippy::suboptimal-flops` implied by `-D warnings` error: conversion to radians can be done more accurately --> $DIR/floating_point_rad.rs:7:13 From 6dc066fdb9103122cd918b1b38e26fa6edbc7e2e Mon Sep 17 00:00:00 2001 From: Thiago Arrais Date: Wed, 17 Jun 2020 13:43:11 -0300 Subject: [PATCH 61/99] Includes TODO comment for hypot lint --- tests/ui/floating_point_hypot.fixed | 5 +++-- tests/ui/floating_point_hypot.rs | 3 ++- tests/ui/floating_point_hypot.stderr | 10 +--------- 3 files changed, 6 insertions(+), 12 deletions(-) diff --git a/tests/ui/floating_point_hypot.fixed b/tests/ui/floating_point_hypot.fixed index f90695bc3fe7c..bbe411b3f4884 100644 --- a/tests/ui/floating_point_hypot.fixed +++ b/tests/ui/floating_point_hypot.fixed @@ -1,5 +1,5 @@ // run-rustfix -#![warn(clippy::suboptimal_flops, clippy::imprecise_flops)] +#![warn(clippy::imprecise_flops)] fn main() { let x = 3f32; @@ -8,6 +8,7 @@ fn main() { let _ = (x + 1f32).hypot(y); let _ = x.hypot(y); // Cases where the lint shouldn't be applied + // TODO: linting this adds some complexity, but could be done let _ = x.mul_add(x, y * y).sqrt(); - let _ = x.mul_add(4f32, y * y).sqrt(); + let _ = (x * 4f32 + y * y).sqrt(); } diff --git a/tests/ui/floating_point_hypot.rs b/tests/ui/floating_point_hypot.rs index e7b048e262fa3..586fd170ea145 100644 --- a/tests/ui/floating_point_hypot.rs +++ b/tests/ui/floating_point_hypot.rs @@ -1,5 +1,5 @@ // run-rustfix -#![warn(clippy::suboptimal_flops, clippy::imprecise_flops)] +#![warn(clippy::imprecise_flops)] fn main() { let x = 3f32; @@ -8,6 +8,7 @@ fn main() { let _ = ((x + 1f32) * (x + 1f32) + y * y).sqrt(); let _ = (x.powi(2) + y.powi(2)).sqrt(); // Cases where the lint shouldn't be applied + // TODO: linting this adds some complexity, but could be done let _ = x.mul_add(x, y * y).sqrt(); let _ = (x * 4f32 + y * y).sqrt(); } diff --git a/tests/ui/floating_point_hypot.stderr b/tests/ui/floating_point_hypot.stderr index fe1dfc7a4510d..42069d9ee9efb 100644 --- a/tests/ui/floating_point_hypot.stderr +++ b/tests/ui/floating_point_hypot.stderr @@ -18,13 +18,5 @@ error: hypotenuse can be computed more accurately LL | let _ = (x.powi(2) + y.powi(2)).sqrt(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.hypot(y)` -error: multiply and add expressions can be calculated more efficiently and accurately - --> $DIR/floating_point_hypot.rs:12:13 - | -LL | let _ = (x * 4f32 + y * y).sqrt(); - | ^^^^^^^^^^^^^^^^^^ help: consider using: `x.mul_add(4f32, y * y)` - | - = note: `-D clippy::suboptimal-flops` implied by `-D warnings` - -error: aborting due to 4 previous errors +error: aborting due to 3 previous errors From 6be9491eace540d341f3b8dbf775a10e25f6431a Mon Sep 17 00:00:00 2001 From: Thiago Arrais Date: Mon, 22 Jun 2020 14:16:27 -0300 Subject: [PATCH 62/99] Reclassify powi(2) lint under suboptimal_flops --- clippy_lints/src/floating_point_arithmetic.rs | 69 ++++++++++++------- tests/ui/floating_point_powi.fixed | 10 +-- tests/ui/floating_point_powi.rs | 4 +- tests/ui/floating_point_powi.stderr | 38 +++++----- 4 files changed, 75 insertions(+), 46 deletions(-) diff --git a/clippy_lints/src/floating_point_arithmetic.rs b/clippy_lints/src/floating_point_arithmetic.rs index beb0b234408bc..11bd0ae23aa3e 100644 --- a/clippy_lints/src/floating_point_arithmetic.rs +++ b/clippy_lints/src/floating_point_arithmetic.rs @@ -294,37 +294,56 @@ fn check_powf(cx: &LateContext<'_>, expr: &Expr<'_>, args: &[Expr<'_>]) { } fn check_powi(cx: &LateContext<'_>, expr: &Expr<'_>, args: &[Expr<'_>]) { - // Check argument if let Some((value, _)) = constant(cx, cx.tables(), &args[1]) { - // TODO: need more specific check. this is too wide. remember also to include tests - if let Some(parent) = get_parent_expr(cx, expr) { - if let Some(grandparent) = get_parent_expr(cx, parent) { - if let ExprKind::MethodCall(PathSegment { ident: method_name, .. }, _, args, _) = grandparent.kind { - if method_name.as_str() == "sqrt" && detect_hypot(cx, args).is_some() { - return; + if value == Int(2) { + if let Some(parent) = get_parent_expr(cx, expr) { + if let Some(grandparent) = get_parent_expr(cx, parent) { + if let ExprKind::MethodCall(PathSegment { ident: method_name, .. }, _, args, _) = grandparent.kind { + if method_name.as_str() == "sqrt" && detect_hypot(cx, args).is_some() { + return; + } } } + + if let ExprKind::Binary( + Spanned { + node: BinOpKind::Add, .. + }, + ref lhs, + ref rhs, + ) = parent.kind + { + let other_addend = if lhs.hir_id == expr.hir_id { rhs } else { lhs }; + + span_lint_and_sugg( + cx, + SUBOPTIMAL_FLOPS, + parent.span, + "square can be computed more efficiently", + "consider using", + format!( + "{}.mul_add({}, {})", + Sugg::hir(cx, &args[0], ".."), + Sugg::hir(cx, &args[0], ".."), + Sugg::hir(cx, &other_addend, ".."), + ), + Applicability::MachineApplicable, + ); + + return; + } } - } - let (lint, help, suggestion) = match value { - Int(2) => ( - IMPRECISE_FLOPS, - "square can be computed more accurately", + span_lint_and_sugg( + cx, + SUBOPTIMAL_FLOPS, + expr.span, + "square can be computed more efficiently", + "consider using", format!("{} * {}", Sugg::hir(cx, &args[0], ".."), Sugg::hir(cx, &args[0], "..")), - ), - _ => return, - }; - - span_lint_and_sugg( - cx, - lint, - expr.span, - help, - "consider using", - suggestion, - Applicability::MachineApplicable, - ); + Applicability::MachineApplicable, + ); + } } } diff --git a/tests/ui/floating_point_powi.fixed b/tests/ui/floating_point_powi.fixed index 98766e68aaf6b..56762400593b5 100644 --- a/tests/ui/floating_point_powi.fixed +++ b/tests/ui/floating_point_powi.fixed @@ -1,5 +1,5 @@ // run-rustfix -#![warn(clippy::imprecise_flops)] +#![warn(clippy::suboptimal_flops)] fn main() { let one = 1; @@ -8,10 +8,12 @@ fn main() { let _ = x * x; let y = 4f32; - let _ = (x * x + y).sqrt(); - let _ = (x + y * y).sqrt(); + let _ = x.mul_add(x, y); + let _ = y.mul_add(y, x); + let _ = x.mul_add(x, y).sqrt(); + let _ = y.mul_add(y, x).sqrt(); // Cases where the lint shouldn't be applied let _ = x.powi(3); let _ = x.powi(one + 1); - let _ = x.hypot(y); + let _ = (x.powi(2) + y.powi(2)).sqrt(); } diff --git a/tests/ui/floating_point_powi.rs b/tests/ui/floating_point_powi.rs index 3c4b636a3d845..1f800e4628dca 100644 --- a/tests/ui/floating_point_powi.rs +++ b/tests/ui/floating_point_powi.rs @@ -1,5 +1,5 @@ // run-rustfix -#![warn(clippy::imprecise_flops)] +#![warn(clippy::suboptimal_flops)] fn main() { let one = 1; @@ -8,6 +8,8 @@ fn main() { let _ = x.powi(1 + 1); let y = 4f32; + let _ = x.powi(2) + y; + let _ = x + y.powi(2); let _ = (x.powi(2) + y).sqrt(); let _ = (x + y.powi(2)).sqrt(); // Cases where the lint shouldn't be applied diff --git a/tests/ui/floating_point_powi.stderr b/tests/ui/floating_point_powi.stderr index f370e24bf0522..d5a5f1bcca101 100644 --- a/tests/ui/floating_point_powi.stderr +++ b/tests/ui/floating_point_powi.stderr @@ -1,34 +1,40 @@ -error: square can be computed more accurately +error: square can be computed more efficiently --> $DIR/floating_point_powi.rs:7:13 | LL | let _ = x.powi(2); | ^^^^^^^^^ help: consider using: `x * x` | - = note: `-D clippy::imprecise-flops` implied by `-D warnings` + = note: `-D clippy::suboptimal-flops` implied by `-D warnings` -error: square can be computed more accurately +error: square can be computed more efficiently --> $DIR/floating_point_powi.rs:8:13 | LL | let _ = x.powi(1 + 1); | ^^^^^^^^^^^^^ help: consider using: `x * x` -error: square can be computed more accurately - --> $DIR/floating_point_powi.rs:11:14 +error: square can be computed more efficiently + --> $DIR/floating_point_powi.rs:11:13 | -LL | let _ = (x.powi(2) + y).sqrt(); - | ^^^^^^^^^ help: consider using: `x * x` +LL | let _ = x.powi(2) + y; + | ^^^^^^^^^^^^^ help: consider using: `x.mul_add(x, y)` -error: square can be computed more accurately - --> $DIR/floating_point_powi.rs:12:18 +error: square can be computed more efficiently + --> $DIR/floating_point_powi.rs:12:13 | -LL | let _ = (x + y.powi(2)).sqrt(); - | ^^^^^^^^^ help: consider using: `y * y` +LL | let _ = x + y.powi(2); + | ^^^^^^^^^^^^^ help: consider using: `y.mul_add(y, x)` + +error: square can be computed more efficiently + --> $DIR/floating_point_powi.rs:13:13 + | +LL | let _ = (x.powi(2) + y).sqrt(); + | ^^^^^^^^^^^^^^^ help: consider using: `x.mul_add(x, y)` -error: hypotenuse can be computed more accurately - --> $DIR/floating_point_powi.rs:16:13 +error: square can be computed more efficiently + --> $DIR/floating_point_powi.rs:14:13 | -LL | let _ = (x.powi(2) + y.powi(2)).sqrt(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.hypot(y)` +LL | let _ = (x + y.powi(2)).sqrt(); + | ^^^^^^^^^^^^^^^ help: consider using: `y.mul_add(y, x)` -error: aborting due to 5 previous errors +error: aborting due to 6 previous errors From 3065201eb3a0c4976de7ef5b5b924afde1b18325 Mon Sep 17 00:00:00 2001 From: Thiago Arrais Date: Mon, 6 Jul 2020 13:14:52 -0300 Subject: [PATCH 63/99] =?UTF-8?q?Includes=20TODO=20for=20constants=20equiv?= =?UTF-8?q?alent=20to=20=CF=80/180?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- clippy_lints/src/floating_point_arithmetic.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/clippy_lints/src/floating_point_arithmetic.rs b/clippy_lints/src/floating_point_arithmetic.rs index 11bd0ae23aa3e..3087d6a940a86 100644 --- a/clippy_lints/src/floating_point_arithmetic.rs +++ b/clippy_lints/src/floating_point_arithmetic.rs @@ -665,6 +665,7 @@ fn check_radians(cx: &LateContext<'_>, expr: &Expr<'_>) { if let Some((rvalue, _)) = constant(cx, cx.tables(), div_rhs); if let Some((lvalue, _)) = constant(cx, cx.tables(), mul_rhs); then { + // TODO: also check for constant values near PI/180 or 180/PI if (F32(f32_consts::PI) == rvalue || F64(f64_consts::PI) == rvalue) && (F32(180_f32) == lvalue || F64(180_f64) == lvalue) { From 5307cb5614e7498f069bb634ab293e176e63c67f Mon Sep 17 00:00:00 2001 From: Takayuki Nakata Date: Sat, 4 Jul 2020 22:50:03 +0900 Subject: [PATCH 64/99] Add a lint for `.repeat(1)` fix #3028. --- CHANGELOG.md | 1 + clippy_lints/src/lib.rs | 5 ++ clippy_lints/src/repeat_once.rs | 126 ++++++++++++++++++++++++++++++++ src/lintlist/mod.rs | 7 ++ tests/ui/repeat_once.fixed | 16 ++++ tests/ui/repeat_once.rs | 16 ++++ tests/ui/repeat_once.stderr | 40 ++++++++++ 7 files changed, 211 insertions(+) create mode 100644 clippy_lints/src/repeat_once.rs create mode 100644 tests/ui/repeat_once.fixed create mode 100644 tests/ui/repeat_once.rs create mode 100644 tests/ui/repeat_once.stderr diff --git a/CHANGELOG.md b/CHANGELOG.md index 1a081bb85feab..c5bbaac0df647 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1616,6 +1616,7 @@ Released 2018-09-13 [`redundant_static_lifetimes`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_static_lifetimes [`ref_in_deref`]: https://rust-lang.github.io/rust-clippy/master/index.html#ref_in_deref [`regex_macro`]: https://rust-lang.github.io/rust-clippy/master/index.html#regex_macro +[`repeat_once`]: https://rust-lang.github.io/rust-clippy/master/index.html#repeat_once [`replace_consts`]: https://rust-lang.github.io/rust-clippy/master/index.html#replace_consts [`rest_pat_in_fully_bound_structs`]: https://rust-lang.github.io/rust-clippy/master/index.html#rest_pat_in_fully_bound_structs [`result_map_or_into_option`]: https://rust-lang.github.io/rust-clippy/master/index.html#result_map_or_into_option diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index fe34e4390d659..0f362dbf86bf6 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -282,6 +282,7 @@ mod redundant_pub_crate; mod redundant_static_lifetimes; mod reference; mod regex; +mod repeat_once; mod returns; mod serde_api; mod shadow; @@ -764,6 +765,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: &reference::REF_IN_DEREF, ®ex::INVALID_REGEX, ®ex::TRIVIAL_REGEX, + &repeat_once::REPEAT_ONCE, &returns::NEEDLESS_RETURN, &returns::UNUSED_UNIT, &serde_api::SERDE_API_MISUSE, @@ -1071,6 +1073,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: store.register_late_pass(|| box macro_use::MacroUseImports::default()); store.register_late_pass(|| box map_identity::MapIdentity); store.register_late_pass(|| box pattern_type_mismatch::PatternTypeMismatch); + store.register_late_pass(|| box repeat_once::RepeatOnce); store.register_group(true, "clippy::restriction", Some("clippy_restriction"), vec![ LintId::of(&arithmetic::FLOAT_ARITHMETIC), @@ -1393,6 +1396,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: LintId::of(&reference::REF_IN_DEREF), LintId::of(®ex::INVALID_REGEX), LintId::of(®ex::TRIVIAL_REGEX), + LintId::of(&repeat_once::REPEAT_ONCE), LintId::of(&returns::NEEDLESS_RETURN), LintId::of(&returns::UNUSED_UNIT), LintId::of(&serde_api::SERDE_API_MISUSE), @@ -1602,6 +1606,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: LintId::of(&ranges::RANGE_ZIP_WITH_LEN), LintId::of(&reference::DEREF_ADDROF), LintId::of(&reference::REF_IN_DEREF), + LintId::of(&repeat_once::REPEAT_ONCE), LintId::of(&swap::MANUAL_SWAP), LintId::of(&temporary_assignment::TEMPORARY_ASSIGNMENT), LintId::of(&transmute::CROSSPOINTER_TRANSMUTE), diff --git a/clippy_lints/src/repeat_once.rs b/clippy_lints/src/repeat_once.rs new file mode 100644 index 0000000000000..af3c948ec82c1 --- /dev/null +++ b/clippy_lints/src/repeat_once.rs @@ -0,0 +1,126 @@ +use crate::consts::{miri_to_const, Constant}; +use crate::utils::{in_macro, is_type_diagnostic_item, snippet, span_lint_and_sugg, walk_ptrs_ty}; +use if_chain::if_chain; +use rustc_ast::ast::LitKind; +use rustc_errors::Applicability; +use rustc_hir::def::{DefKind, Res}; +use rustc_hir::{Expr, ExprKind}; +use rustc_lint::{LateContext, LateLintPass}; +use rustc_middle::ty::{self, Ty}; +use rustc_session::{declare_lint_pass, declare_tool_lint}; + +declare_clippy_lint! { + /// **What it does:** Checks for usage of `.repeat(1)` and suggest the following method for each types. + /// - `.to_string()` for `str` + /// - `.clone()` for `String` + /// - `.to_vec()` for `slice` + /// + /// **Why is this bad?** For example, `String.repeat(1)` is equivalent to `.clone()`. If cloning the string is the intention behind thi, `clone()` should be used. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// + /// ```rust + /// fn main() { + /// let x = String::from("hello world").repeat(1); + /// } + /// ``` + /// Use instead: + /// ```rust + /// fn main() { + /// let x = String::from("hello world").clone(); + /// } + /// ``` + pub REPEAT_ONCE, + complexity, + "using `.repeat(1)` instead of `String.clone()`, `str.to_string()` or `slice.to_vec()` " +} + +declare_lint_pass!(RepeatOnce => [REPEAT_ONCE]); + +impl<'tcx> LateLintPass<'tcx> for RepeatOnce { + fn check_expr(&mut self, cx: &LateContext<'_>, expr: &'tcx Expr<'_>) { + if_chain! { + if let ExprKind::MethodCall(ref path, _, ref args, _) = expr.kind; + if path.ident.name == sym!(repeat); + if is_once(cx, &args[1]) && !in_macro(args[0].span); + then { + let ty = walk_ptrs_ty(cx.tables().expr_ty(&args[0])); + if is_str(ty){ + span_lint_and_sugg( + cx, + REPEAT_ONCE, + expr.span, + "calling `repeat(1)` on str", + "consider using `.to_string()` instead", + format!("{}.to_string()", snippet(cx, args[0].span, r#""...""#)), + Applicability::MachineApplicable, + ); + } else if is_slice(ty) { + span_lint_and_sugg( + cx, + REPEAT_ONCE, + expr.span, + "calling `repeat(1)` on slice", + "consider using `.to_vec()` instead", + format!("{}.to_vec()", snippet(cx, args[0].span, r#""...""#)), + Applicability::MachineApplicable, + ); + } else if is_type_diagnostic_item(cx, ty, sym!(string_type)) { + span_lint_and_sugg( + cx, + REPEAT_ONCE, + expr.span, + "calling `repeat(1)` on a string literal", + "consider using `.clone()` instead", + format!("{}.clone()", snippet(cx, args[0].span, r#""...""#)), + Applicability::MachineApplicable, + ); + } + } + } + } +} + +fn is_once<'tcx>(cx: &LateContext<'_>, expr: &'tcx Expr<'_>) -> bool { + match expr.kind { + ExprKind::Lit(ref lit) => { + if let LitKind::Int(ref lit_content, _) = lit.node { + *lit_content == 1 + } else { + false + } + }, + ExprKind::Path(rustc_hir::QPath::Resolved(None, path)) => { + if let Res::Def(DefKind::Const, def_id) = path.res { + let ty = cx.tcx.type_of(def_id); + let con = cx + .tcx + .const_eval_poly(def_id) + .ok() + .map(|val| rustc_middle::ty::Const::from_value(cx.tcx, val, ty)) + .unwrap(); + let con = miri_to_const(con); + con == Some(Constant::Int(1)) + } else { + false + } + }, + _ => false, + } +} + +fn is_str(ty: Ty<'_>) -> bool { + match ty.kind { + ty::Str => true, + _ => false, + } +} + +fn is_slice(ty: Ty<'_>) -> bool { + match ty.kind { + ty::Slice(..) | ty::Array(..) => true, + _ => false, + } +} diff --git a/src/lintlist/mod.rs b/src/lintlist/mod.rs index e681f47f949df..078924d3f9bb8 100644 --- a/src/lintlist/mod.rs +++ b/src/lintlist/mod.rs @@ -1879,6 +1879,13 @@ pub static ref ALL_LINTS: Vec = vec![ deprecation: None, module: "reference", }, + Lint { + name: "repeat_once", + group: "complexity", + desc: "using `.repeat(1)` instead of `String.clone()`, `str.to_string()` or `slice.to_vec()` ", + deprecation: None, + module: "repeat_once", + }, Lint { name: "rest_pat_in_fully_bound_structs", group: "restriction", diff --git a/tests/ui/repeat_once.fixed b/tests/ui/repeat_once.fixed new file mode 100644 index 0000000000000..a637c22fbcd26 --- /dev/null +++ b/tests/ui/repeat_once.fixed @@ -0,0 +1,16 @@ +// run-rustfix +#![warn(clippy::repeat_once)] +#[allow(unused, clippy::many_single_char_names, clippy::redundant_clone)] +fn main() { + const N: usize = 1; + let s = "str"; + let string = "String".to_string(); + let slice = [1; 5]; + + let a = [1; 5].to_vec(); + let b = slice.to_vec(); + let c = "hello".to_string(); + let d = "hi".to_string(); + let e = s.to_string(); + let f = string.clone(); +} diff --git a/tests/ui/repeat_once.rs b/tests/ui/repeat_once.rs new file mode 100644 index 0000000000000..d99ca1b5b55d4 --- /dev/null +++ b/tests/ui/repeat_once.rs @@ -0,0 +1,16 @@ +// run-rustfix +#![warn(clippy::repeat_once)] +#[allow(unused, clippy::many_single_char_names, clippy::redundant_clone)] +fn main() { + const N: usize = 1; + let s = "str"; + let string = "String".to_string(); + let slice = [1; 5]; + + let a = [1; 5].repeat(1); + let b = slice.repeat(1); + let c = "hello".repeat(N); + let d = "hi".repeat(1); + let e = s.repeat(1); + let f = string.repeat(1); +} diff --git a/tests/ui/repeat_once.stderr b/tests/ui/repeat_once.stderr new file mode 100644 index 0000000000000..915eea3bfc6b8 --- /dev/null +++ b/tests/ui/repeat_once.stderr @@ -0,0 +1,40 @@ +error: calling `repeat(1)` on slice + --> $DIR/repeat_once.rs:10:13 + | +LL | let a = [1; 5].repeat(1); + | ^^^^^^^^^^^^^^^^ help: consider using `.to_vec()` instead: `[1; 5].to_vec()` + | + = note: `-D clippy::repeat-once` implied by `-D warnings` + +error: calling `repeat(1)` on slice + --> $DIR/repeat_once.rs:11:13 + | +LL | let b = slice.repeat(1); + | ^^^^^^^^^^^^^^^ help: consider using `.to_vec()` instead: `slice.to_vec()` + +error: calling `repeat(1)` on str + --> $DIR/repeat_once.rs:12:13 + | +LL | let c = "hello".repeat(N); + | ^^^^^^^^^^^^^^^^^ help: consider using `.to_string()` instead: `"hello".to_string()` + +error: calling `repeat(1)` on str + --> $DIR/repeat_once.rs:13:13 + | +LL | let d = "hi".repeat(1); + | ^^^^^^^^^^^^^^ help: consider using `.to_string()` instead: `"hi".to_string()` + +error: calling `repeat(1)` on str + --> $DIR/repeat_once.rs:14:13 + | +LL | let e = s.repeat(1); + | ^^^^^^^^^^^ help: consider using `.to_string()` instead: `s.to_string()` + +error: calling `repeat(1)` on a string literal + --> $DIR/repeat_once.rs:15:13 + | +LL | let f = string.repeat(1); + | ^^^^^^^^^^^^^^^^ help: consider using `.clone()` instead: `string.clone()` + +error: aborting due to 6 previous errors + From 37d75da266443dd4253ceedebd692ba77dd72e03 Mon Sep 17 00:00:00 2001 From: robojumper Date: Wed, 8 Jul 2020 18:04:51 +0200 Subject: [PATCH 65/99] make match_like_matches_macro only apply to matches with a wildcard --- clippy_lints/src/assign_ops.rs | 1 - clippy_lints/src/matches.rs | 41 +++++++++---------- tests/ui/match_expr_like_matches_macro.fixed | 14 ++++--- tests/ui/match_expr_like_matches_macro.rs | 17 +++++--- tests/ui/match_expr_like_matches_macro.stderr | 28 +++++++++---- tests/ui/question_mark.fixed | 5 ++- tests/ui/question_mark.rs | 5 ++- tests/ui/question_mark.stderr | 20 ++++----- 8 files changed, 77 insertions(+), 54 deletions(-) diff --git a/clippy_lints/src/assign_ops.rs b/clippy_lints/src/assign_ops.rs index 3d48bf739ebe6..bc6e868823f77 100644 --- a/clippy_lints/src/assign_ops.rs +++ b/clippy_lints/src/assign_ops.rs @@ -237,7 +237,6 @@ fn is_commutative(op: hir::BinOpKind) -> bool { use rustc_hir::BinOpKind::{ Add, And, BitAnd, BitOr, BitXor, Div, Eq, Ge, Gt, Le, Lt, Mul, Ne, Or, Rem, Shl, Shr, Sub, }; - #[allow(clippy::match_like_matches_macro)] match op { Add | Mul | And | Or | BitXor | BitAnd | BitOr | Eq | Ne => true, Sub | Div | Rem | Shl | Shr | Lt | Le | Ge | Gt => false, diff --git a/clippy_lints/src/matches.rs b/clippy_lints/src/matches.rs index 34aa2981535dc..aeabb99a30d11 100644 --- a/clippy_lints/src/matches.rs +++ b/clippy_lints/src/matches.rs @@ -446,11 +446,12 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// **What it does:** Checks for `match` expressions producing a `bool` that could be written using `matches!` + /// **What it does:** Checks for `match` or `if let` expressions producing a + /// `bool` that could be written using `matches!` /// /// **Why is this bad?** Readability and needless complexity. /// - /// **Known problems:** This can turn an intentionally exhaustive match into a non-exhaustive one. + /// **Known problems:** None /// /// **Example:** /// ```rust @@ -462,8 +463,14 @@ declare_clippy_lint! { /// _ => false, /// }; /// + /// let a = if let Some(0) = x { + /// true + /// } else { + /// false + /// }; + /// /// // Good - /// let a = matches!(x, Some(5)); + /// let a = matches!(x, Some(0)); /// ``` pub MATCH_LIKE_MATCHES_MACRO, style, @@ -499,9 +506,8 @@ impl<'tcx> LateLintPass<'tcx> for Matches { return; } - if !redundant_pattern_match::check(cx, expr) { - check_match_like_matches(cx, expr); - } + redundant_pattern_match::check(cx, expr); + check_match_like_matches(cx, expr); if let ExprKind::Match(ref ex, ref arms, MatchSource::Normal) = expr.kind { check_single_match(cx, ex, arms, expr); @@ -1068,6 +1074,7 @@ fn find_matches_sugg(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>], expr if_chain! { if arms.len() == 2; if cx.tables().expr_ty(expr).is_bool(); + if is_wild(&arms[1].pat); if let Some(first) = find_bool_lit(&arms[0].body.kind, desugared); if let Some(second) = find_bool_lit(&arms[1].body.kind, desugared); if first != second; @@ -1437,16 +1444,14 @@ mod redundant_pattern_match { use rustc_mir::const_eval::is_const_fn; use rustc_span::source_map::Symbol; - pub fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) -> bool { + pub fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { if let ExprKind::Match(op, arms, ref match_source) = &expr.kind { match match_source { MatchSource::Normal => find_sugg_for_match(cx, expr, op, arms), MatchSource::IfLetDesugar { .. } => find_sugg_for_if_let(cx, expr, op, arms, "if"), MatchSource::WhileLetDesugar => find_sugg_for_if_let(cx, expr, op, arms, "while"), - _ => false, + _ => {}, } - } else { - false } } @@ -1456,7 +1461,7 @@ mod redundant_pattern_match { op: &Expr<'_>, arms: &[Arm<'_>], keyword: &'static str, - ) -> bool { + ) { fn find_suggestion(cx: &LateContext<'_>, hir_id: HirId, path: &QPath<'_>) -> Option<&'static str> { if match_qpath(path, &paths::RESULT_OK) && can_suggest(cx, hir_id, sym!(result_type), "is_ok") { return Some("is_ok()"); @@ -1487,7 +1492,7 @@ mod redundant_pattern_match { }; let good_method = match good_method { Some(method) => method, - None => return false, + None => return, }; // check that `while_let_on_iterator` lint does not trigger @@ -1497,7 +1502,7 @@ mod redundant_pattern_match { if method_path.ident.name == sym!(next); if match_trait_method(cx, op, &paths::ITERATOR); then { - return false; + return; } } @@ -1526,15 +1531,9 @@ mod redundant_pattern_match { ); }, ); - true } - fn find_sugg_for_match<'tcx>( - cx: &LateContext<'tcx>, - expr: &'tcx Expr<'_>, - op: &Expr<'_>, - arms: &[Arm<'_>], - ) -> bool { + fn find_sugg_for_match<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, op: &Expr<'_>, arms: &[Arm<'_>]) { if arms.len() == 2 { let node_pair = (&arms[0].pat.kind, &arms[1].pat.kind); @@ -1599,10 +1598,8 @@ mod redundant_pattern_match { ); }, ); - return true; } } - false } #[allow(clippy::too_many_arguments)] diff --git a/tests/ui/match_expr_like_matches_macro.fixed b/tests/ui/match_expr_like_matches_macro.fixed index 2d1ac8836d63f..f3e19092480ad 100644 --- a/tests/ui/match_expr_like_matches_macro.fixed +++ b/tests/ui/match_expr_like_matches_macro.fixed @@ -1,6 +1,7 @@ // run-rustfix #![warn(clippy::match_like_matches_macro)] +#![allow(unreachable_patterns)] fn main() { let x = Some(5); @@ -8,25 +9,28 @@ fn main() { // Lint let _y = matches!(x, Some(0)); + // Lint + let _w = matches!(x, Some(_)); + // Turn into is_none let _z = x.is_none(); // Lint - let _z = !matches!(x, Some(r) if r == 0); + let _zz = !matches!(x, Some(r) if r == 0); // Lint - let _zz = matches!(x, Some(5)); + let _zzz = matches!(x, Some(5)); // No lint let _a = match x { Some(_) => false, - None => false, + _ => false, }; // No lint - let _a = match x { + let _ab = match x { Some(0) => false, - Some(_) => true, + _ => true, None => false, }; } diff --git a/tests/ui/match_expr_like_matches_macro.rs b/tests/ui/match_expr_like_matches_macro.rs index 376abf9244eaf..fbae7c18b9239 100644 --- a/tests/ui/match_expr_like_matches_macro.rs +++ b/tests/ui/match_expr_like_matches_macro.rs @@ -1,6 +1,7 @@ // run-rustfix #![warn(clippy::match_like_matches_macro)] +#![allow(unreachable_patterns)] fn main() { let x = Some(5); @@ -11,6 +12,12 @@ fn main() { _ => false, }; + // Lint + let _w = match x { + Some(_) => true, + _ => false, + }; + // Turn into is_none let _z = match x { Some(_) => false, @@ -18,24 +25,24 @@ fn main() { }; // Lint - let _z = match x { + let _zz = match x { Some(r) if r == 0 => false, _ => true, }; // Lint - let _zz = if let Some(5) = x { true } else { false }; + let _zzz = if let Some(5) = x { true } else { false }; // No lint let _a = match x { Some(_) => false, - None => false, + _ => false, }; // No lint - let _a = match x { + let _ab = match x { Some(0) => false, - Some(_) => true, + _ => true, None => false, }; } diff --git a/tests/ui/match_expr_like_matches_macro.stderr b/tests/ui/match_expr_like_matches_macro.stderr index 0b32af039a8cc..4668f8565a656 100644 --- a/tests/ui/match_expr_like_matches_macro.stderr +++ b/tests/ui/match_expr_like_matches_macro.stderr @@ -1,5 +1,5 @@ error: match expression looks like `matches!` macro - --> $DIR/match_expr_like_matches_macro.rs:9:14 + --> $DIR/match_expr_like_matches_macro.rs:10:14 | LL | let _y = match x { | ______________^ @@ -10,8 +10,18 @@ LL | | }; | = note: `-D clippy::match-like-matches-macro` implied by `-D warnings` +error: match expression looks like `matches!` macro + --> $DIR/match_expr_like_matches_macro.rs:16:14 + | +LL | let _w = match x { + | ______________^ +LL | | Some(_) => true, +LL | | _ => false, +LL | | }; + | |_____^ help: try this: `matches!(x, Some(_))` + error: redundant pattern matching, consider using `is_none()` - --> $DIR/match_expr_like_matches_macro.rs:15:14 + --> $DIR/match_expr_like_matches_macro.rs:22:14 | LL | let _z = match x { | ______________^ @@ -23,20 +33,20 @@ LL | | }; = note: `-D clippy::redundant-pattern-matching` implied by `-D warnings` error: match expression looks like `matches!` macro - --> $DIR/match_expr_like_matches_macro.rs:21:14 + --> $DIR/match_expr_like_matches_macro.rs:28:15 | -LL | let _z = match x { - | ______________^ +LL | let _zz = match x { + | _______________^ LL | | Some(r) if r == 0 => false, LL | | _ => true, LL | | }; | |_____^ help: try this: `!matches!(x, Some(r) if r == 0)` error: if let .. else expression looks like `matches!` macro - --> $DIR/match_expr_like_matches_macro.rs:27:15 + --> $DIR/match_expr_like_matches_macro.rs:34:16 | -LL | let _zz = if let Some(5) = x { true } else { false }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `matches!(x, Some(5))` +LL | let _zzz = if let Some(5) = x { true } else { false }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `matches!(x, Some(5))` -error: aborting due to 4 previous errors +error: aborting due to 5 previous errors diff --git a/tests/ui/question_mark.fixed b/tests/ui/question_mark.fixed index bd13cf1bdfaf6..11dff94a28865 100644 --- a/tests/ui/question_mark.fixed +++ b/tests/ui/question_mark.fixed @@ -23,7 +23,10 @@ pub enum SeemsOption { impl SeemsOption { pub fn is_none(&self) -> bool { - matches!(*self, SeemsOption::None) + match *self { + SeemsOption::None => true, + SeemsOption::Some(_) => false, + } } } diff --git a/tests/ui/question_mark.rs b/tests/ui/question_mark.rs index 94479e685551c..1d0ee82b4f778 100644 --- a/tests/ui/question_mark.rs +++ b/tests/ui/question_mark.rs @@ -25,7 +25,10 @@ pub enum SeemsOption { impl SeemsOption { pub fn is_none(&self) -> bool { - matches!(*self, SeemsOption::None) + match *self { + SeemsOption::None => true, + SeemsOption::Some(_) => false, + } } } diff --git a/tests/ui/question_mark.stderr b/tests/ui/question_mark.stderr index be323035d6ccd..502615fb175a1 100644 --- a/tests/ui/question_mark.stderr +++ b/tests/ui/question_mark.stderr @@ -9,7 +9,7 @@ LL | | } = note: `-D clippy::question-mark` implied by `-D warnings` error: this block may be rewritten with the `?` operator - --> $DIR/question_mark.rs:47:9 + --> $DIR/question_mark.rs:50:9 | LL | / if (self.opt).is_none() { LL | | return None; @@ -17,7 +17,7 @@ LL | | } | |_________^ help: replace it with: `(self.opt)?;` error: this block may be rewritten with the `?` operator - --> $DIR/question_mark.rs:51:9 + --> $DIR/question_mark.rs:54:9 | LL | / if self.opt.is_none() { LL | | return None @@ -25,7 +25,7 @@ LL | | } | |_________^ help: replace it with: `self.opt?;` error: this block may be rewritten with the `?` operator - --> $DIR/question_mark.rs:55:17 + --> $DIR/question_mark.rs:58:17 | LL | let _ = if self.opt.is_none() { | _________________^ @@ -36,7 +36,7 @@ LL | | }; | |_________^ help: replace it with: `Some(self.opt?)` error: this if-let-else may be rewritten with the `?` operator - --> $DIR/question_mark.rs:61:17 + --> $DIR/question_mark.rs:64:17 | LL | let _ = if let Some(x) = self.opt { | _________________^ @@ -47,7 +47,7 @@ LL | | }; | |_________^ help: replace it with: `self.opt?` error: this block may be rewritten with the `?` operator - --> $DIR/question_mark.rs:78:9 + --> $DIR/question_mark.rs:81:9 | LL | / if self.opt.is_none() { LL | | return None; @@ -55,7 +55,7 @@ LL | | } | |_________^ help: replace it with: `self.opt.as_ref()?;` error: this block may be rewritten with the `?` operator - --> $DIR/question_mark.rs:86:9 + --> $DIR/question_mark.rs:89:9 | LL | / if self.opt.is_none() { LL | | return None; @@ -63,7 +63,7 @@ LL | | } | |_________^ help: replace it with: `self.opt.as_ref()?;` error: this block may be rewritten with the `?` operator - --> $DIR/question_mark.rs:94:9 + --> $DIR/question_mark.rs:97:9 | LL | / if self.opt.is_none() { LL | | return None; @@ -71,7 +71,7 @@ LL | | } | |_________^ help: replace it with: `self.opt.as_ref()?;` error: this if-let-else may be rewritten with the `?` operator - --> $DIR/question_mark.rs:101:26 + --> $DIR/question_mark.rs:104:26 | LL | let v: &Vec<_> = if let Some(ref v) = self.opt { | __________________________^ @@ -82,7 +82,7 @@ LL | | }; | |_________^ help: replace it with: `self.opt.as_ref()?` error: this if-let-else may be rewritten with the `?` operator - --> $DIR/question_mark.rs:111:17 + --> $DIR/question_mark.rs:114:17 | LL | let v = if let Some(v) = self.opt { | _________________^ @@ -93,7 +93,7 @@ LL | | }; | |_________^ help: replace it with: `self.opt?` error: this block may be rewritten with the `?` operator - --> $DIR/question_mark.rs:126:5 + --> $DIR/question_mark.rs:129:5 | LL | / if f().is_none() { LL | | return None; From db1c946aaa02e1192d271dbcfe4598d726806108 Mon Sep 17 00:00:00 2001 From: Eduardo Broto Date: Tue, 30 Jun 2020 21:48:34 +0200 Subject: [PATCH 66/99] unnecessary_sort_by: avoid linting if key borrows --- clippy_lints/src/let_and_return.rs | 21 ++--------- clippy_lints/src/unnecessary_sort_by.rs | 48 +++++++++++++++---------- clippy_lints/src/utils/mod.rs | 15 ++++++++ tests/ui/unnecessary_sort_by.fixed | 46 +++++++++++++++++++++--- tests/ui/unnecessary_sort_by.rs | 46 +++++++++++++++++++++--- 5 files changed, 131 insertions(+), 45 deletions(-) diff --git a/clippy_lints/src/let_and_return.rs b/clippy_lints/src/let_and_return.rs index ddc41f89f8dec..fa560ffb980c8 100644 --- a/clippy_lints/src/let_and_return.rs +++ b/clippy_lints/src/let_and_return.rs @@ -1,6 +1,5 @@ use if_chain::if_chain; use rustc_errors::Applicability; -use rustc_hir::def_id::DefId; use rustc_hir::intravisit::{walk_expr, NestedVisitorMap, Visitor}; use rustc_hir::{Block, Expr, ExprKind, PatKind, StmtKind}; use rustc_lint::{LateContext, LateLintPass, LintContext}; @@ -9,7 +8,7 @@ use rustc_middle::lint::in_external_macro; use rustc_middle::ty::subst::GenericArgKind; use rustc_session::{declare_lint_pass, declare_tool_lint}; -use crate::utils::{in_macro, match_qpath, snippet_opt, span_lint_and_then}; +use crate::utils::{fn_def_id, in_macro, match_qpath, snippet_opt, span_lint_and_then}; declare_clippy_lint! { /// **What it does:** Checks for `let`-bindings, which are subsequently @@ -97,22 +96,6 @@ struct BorrowVisitor<'a, 'tcx> { borrows: bool, } -impl BorrowVisitor<'_, '_> { - fn fn_def_id(&self, expr: &Expr<'_>) -> Option { - match &expr.kind { - ExprKind::MethodCall(..) => self.cx.tables().type_dependent_def_id(expr.hir_id), - ExprKind::Call( - Expr { - kind: ExprKind::Path(qpath), - .. - }, - .., - ) => self.cx.qpath_res(qpath, expr.hir_id).opt_def_id(), - _ => None, - } - } -} - impl<'tcx> Visitor<'tcx> for BorrowVisitor<'_, 'tcx> { type Map = Map<'tcx>; @@ -121,7 +104,7 @@ impl<'tcx> Visitor<'tcx> for BorrowVisitor<'_, 'tcx> { return; } - if let Some(def_id) = self.fn_def_id(expr) { + if let Some(def_id) = fn_def_id(self.cx, expr) { self.borrows = self .cx .tcx diff --git a/clippy_lints/src/unnecessary_sort_by.rs b/clippy_lints/src/unnecessary_sort_by.rs index d940776817ca0..91c1789a2ffb1 100644 --- a/clippy_lints/src/unnecessary_sort_by.rs +++ b/clippy_lints/src/unnecessary_sort_by.rs @@ -5,24 +5,23 @@ use if_chain::if_chain; use rustc_errors::Applicability; use rustc_hir::{Expr, ExprKind, Mutability, Param, Pat, PatKind, Path, PathSegment, QPath}; use rustc_lint::{LateContext, LateLintPass}; +use rustc_middle::ty::{self, subst::GenericArgKind}; use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::symbol::Ident; declare_clippy_lint! { /// **What it does:** - /// Detects when people use `Vec::sort_by` and pass in a function + /// Detects uses of `Vec::sort_by` passing in a closure /// which compares the two arguments, either directly or indirectly. /// /// **Why is this bad?** /// It is more clear to use `Vec::sort_by_key` (or `Vec::sort` if - /// possible) than to use `Vec::sort_by` and and a more complicated + /// possible) than to use `Vec::sort_by` and a more complicated /// closure. /// /// **Known problems:** - /// If the suggested `Vec::sort_by_key` uses Reverse and it isn't - /// imported by a use statement in the current frame, then a `use` - /// statement that imports it will need to be added (which this lint - /// can't do). + /// If the suggested `Vec::sort_by_key` uses Reverse and it isn't already + /// imported by a use statement, then it will need to be added manually. /// /// **Example:** /// @@ -201,28 +200,41 @@ fn detect_lint(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option { }; let vec_name = Sugg::hir(cx, &args[0], "..").to_string(); let unstable = name == "sort_unstable_by"; + if_chain! { if let ExprKind::Path(QPath::Resolved(_, Path { segments: [PathSegment { ident: left_name, .. }], .. })) = &left_expr.kind; if left_name == left_ident; then { - Some(LintTrigger::Sort(SortDetection { vec_name, unstable })) - } - else { - Some(LintTrigger::SortByKey(SortByKeyDetection { - vec_name, - unstable, - closure_arg, - closure_body, - reverse - })) + return Some(LintTrigger::Sort(SortDetection { vec_name, unstable })) + } else { + if !key_returns_borrow(cx, left_expr) { + return Some(LintTrigger::SortByKey(SortByKeyDetection { + vec_name, + unstable, + closure_arg, + closure_body, + reverse + })) + } } } - } else { - None } } + + None +} + +fn key_returns_borrow(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { + if let Some(def_id) = utils::fn_def_id(cx, expr) { + let output = cx.tcx.fn_sig(def_id).output(); + let ty = output.skip_binder(); + return matches!(ty.kind, ty::Ref(..)) + || ty.walk().any(|arg| matches!(arg.unpack(), GenericArgKind::Lifetime(_))); + } + + false } impl LateLintPass<'_> for UnnecessarySortBy { diff --git a/clippy_lints/src/utils/mod.rs b/clippy_lints/src/utils/mod.rs index 3a3b79925ff9a..93075b9f0b508 100644 --- a/clippy_lints/src/utils/mod.rs +++ b/clippy_lints/src/utils/mod.rs @@ -1363,6 +1363,21 @@ pub fn fn_has_unsatisfiable_preds(cx: &LateContext<'_>, did: DefId) -> bool { ) } +/// Returns the `DefId` of the callee if the given expression is a function or method call. +pub fn fn_def_id(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option { + match &expr.kind { + ExprKind::MethodCall(..) => cx.tables().type_dependent_def_id(expr.hir_id), + ExprKind::Call( + Expr { + kind: ExprKind::Path(qpath), + .. + }, + .., + ) => cx.tables().qpath_res(qpath, expr.hir_id).opt_def_id(), + _ => None, + } +} + pub fn run_lints(cx: &LateContext<'_>, lints: &[&'static Lint], id: HirId) -> bool { lints.iter().any(|lint| { matches!( diff --git a/tests/ui/unnecessary_sort_by.fixed b/tests/ui/unnecessary_sort_by.fixed index 779fd57707ad4..c017d1cf9a468 100644 --- a/tests/ui/unnecessary_sort_by.fixed +++ b/tests/ui/unnecessary_sort_by.fixed @@ -2,11 +2,11 @@ use std::cmp::Reverse; -fn id(x: isize) -> isize { - x -} +fn unnecessary_sort_by() { + fn id(x: isize) -> isize { + x + } -fn main() { let mut vec: Vec = vec![3, 6, 1, 2, 5]; // Forward examples vec.sort(); @@ -24,3 +24,41 @@ fn main() { vec.sort_by(|_, b| b.cmp(c)); vec.sort_unstable_by(|a, _| a.cmp(c)); } + +// Should not be linted to avoid hitting https://github.com/rust-lang/rust/issues/34162 +mod issue_5754 { + struct Test(String); + + #[derive(PartialOrd, Ord, PartialEq, Eq)] + struct Wrapper<'a>(&'a str); + + impl Test { + fn name(&self) -> &str { + &self.0 + } + + fn wrapped(&self) -> Wrapper<'_> { + Wrapper(&self.0) + } + } + + pub fn test() { + let mut args: Vec = vec![]; + + // Forward + args.sort_by(|a, b| a.name().cmp(b.name())); + args.sort_by(|a, b| a.wrapped().cmp(&b.wrapped())); + args.sort_unstable_by(|a, b| a.name().cmp(b.name())); + args.sort_unstable_by(|a, b| a.wrapped().cmp(&b.wrapped())); + // Reverse + args.sort_by(|a, b| b.name().cmp(a.name())); + args.sort_by(|a, b| b.wrapped().cmp(&a.wrapped())); + args.sort_unstable_by(|a, b| b.name().cmp(a.name())); + args.sort_unstable_by(|a, b| b.wrapped().cmp(&a.wrapped())); + } +} + +fn main() { + unnecessary_sort_by(); + issue_5754::test(); +} diff --git a/tests/ui/unnecessary_sort_by.rs b/tests/ui/unnecessary_sort_by.rs index 0485a5630afef..1929c72b2f2cd 100644 --- a/tests/ui/unnecessary_sort_by.rs +++ b/tests/ui/unnecessary_sort_by.rs @@ -2,11 +2,11 @@ use std::cmp::Reverse; -fn id(x: isize) -> isize { - x -} +fn unnecessary_sort_by() { + fn id(x: isize) -> isize { + x + } -fn main() { let mut vec: Vec = vec![3, 6, 1, 2, 5]; // Forward examples vec.sort_by(|a, b| a.cmp(b)); @@ -24,3 +24,41 @@ fn main() { vec.sort_by(|_, b| b.cmp(c)); vec.sort_unstable_by(|a, _| a.cmp(c)); } + +// Should not be linted to avoid hitting https://github.com/rust-lang/rust/issues/34162 +mod issue_5754 { + struct Test(String); + + #[derive(PartialOrd, Ord, PartialEq, Eq)] + struct Wrapper<'a>(&'a str); + + impl Test { + fn name(&self) -> &str { + &self.0 + } + + fn wrapped(&self) -> Wrapper<'_> { + Wrapper(&self.0) + } + } + + pub fn test() { + let mut args: Vec = vec![]; + + // Forward + args.sort_by(|a, b| a.name().cmp(b.name())); + args.sort_by(|a, b| a.wrapped().cmp(&b.wrapped())); + args.sort_unstable_by(|a, b| a.name().cmp(b.name())); + args.sort_unstable_by(|a, b| a.wrapped().cmp(&b.wrapped())); + // Reverse + args.sort_by(|a, b| b.name().cmp(a.name())); + args.sort_by(|a, b| b.wrapped().cmp(&a.wrapped())); + args.sort_unstable_by(|a, b| b.name().cmp(a.name())); + args.sort_unstable_by(|a, b| b.wrapped().cmp(&a.wrapped())); + } +} + +fn main() { + unnecessary_sort_by(); + issue_5754::test(); +} From dac19e3afccc63ff976bcf0a5ee385bdd0e075d5 Mon Sep 17 00:00:00 2001 From: Tim Nielens Date: Tue, 7 Jul 2020 00:35:51 +0200 Subject: [PATCH 67/99] single_match_else - single expr/stmt else block corner case --- clippy_lints/src/matches.rs | 20 +++++++----- tests/ui/single_match_else.rs | 51 +++++++++++++++++++++++++++++++ tests/ui/single_match_else.stderr | 44 ++++++++++++++++++++++++-- 3 files changed, 106 insertions(+), 9 deletions(-) diff --git a/clippy_lints/src/matches.rs b/clippy_lints/src/matches.rs index b754a45aa404f..a6cc1097441cd 100644 --- a/clippy_lints/src/matches.rs +++ b/clippy_lints/src/matches.rs @@ -530,16 +530,22 @@ fn check_single_match(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>], exp // the lint noisy in unnecessary situations return; } - let els = remove_blocks(&arms[1].body); - let els = if is_unit_expr(els) { + let els = arms[1].body; + let els = if is_unit_expr(remove_blocks(els)) { None - } else if let ExprKind::Block(_, _) = els.kind { - // matches with blocks that contain statements are prettier as `if let + else` - Some(els) + } else if let ExprKind::Block(Block { stmts, expr: block_expr, .. }, _) = els.kind { + if stmts.len() == 1 && block_expr.is_none() || stmts.is_empty() && block_expr.is_some() { + // single statement/expr "else" block, don't lint + return; + } else { + // block with 2+ statements or 1 expr and 1+ statement + Some(els) + } } else { - // allow match arms with just expressions - return; + // not a block, don't lint + return; }; + let ty = cx.tables().expr_ty(ex); if ty.kind != ty::Bool || is_allowed(cx, MATCH_BOOL, ex.hir_id) { check_single_match_single_pattern(cx, ex, arms, expr, els); diff --git a/tests/ui/single_match_else.rs b/tests/ui/single_match_else.rs index 34193be0b75e4..b624a41a29b2d 100644 --- a/tests/ui/single_match_else.rs +++ b/tests/ui/single_match_else.rs @@ -1,4 +1,6 @@ #![warn(clippy::single_match_else)] +#![allow(clippy::needless_return)] +#![allow(clippy::no_effect)] enum ExprNode { ExprAddrOf, @@ -30,6 +32,55 @@ macro_rules! unwrap_addr { }; } +#[rustfmt::skip] fn main() { unwrap_addr!(ExprNode::Unicorns); + + // + // don't lint single exprs/statements + // + + // don't lint here + match Some(1) { + Some(a) => println!("${:?}", a), + None => return, + } + + // don't lint here + match Some(1) { + Some(a) => println!("${:?}", a), + None => { + return + }, + } + + // don't lint here + match Some(1) { + Some(a) => println!("${:?}", a), + None => { + return; + }, + } + + // + // lint multiple exprs/statements "else" blocks + // + + // lint here + match Some(1) { + Some(a) => println!("${:?}", a), + None => { + println!("else block"); + return + }, + } + + // lint here + match Some(1) { + Some(a) => println!("${:?}", a), + None => { + println!("else block"); + return; + }, + } } diff --git a/tests/ui/single_match_else.stderr b/tests/ui/single_match_else.stderr index 59861d46eb34c..3a07c2ec54262 100644 --- a/tests/ui/single_match_else.stderr +++ b/tests/ui/single_match_else.stderr @@ -1,5 +1,5 @@ error: you seem to be trying to use match for destructuring a single pattern. Consider using `if let` - --> $DIR/single_match_else.rs:12:5 + --> $DIR/single_match_else.rs:14:5 | LL | / match ExprNode::Butterflies { LL | | ExprNode::ExprAddrOf => Some(&NODE), @@ -19,5 +19,45 @@ LL | None LL | } | -error: aborting due to previous error +error: you seem to be trying to use match for destructuring a single pattern. Consider using `if let` + --> $DIR/single_match_else.rs:70:5 + | +LL | / match Some(1) { +LL | | Some(a) => println!("${:?}", a), +LL | | None => { +LL | | println!("else block"); +LL | | return +LL | | }, +LL | | } + | |_____^ + | +help: try this + | +LL | if let Some(a) = Some(1) { println!("${:?}", a) } else { +LL | println!("else block"); +LL | return +LL | } + | + +error: you seem to be trying to use match for destructuring a single pattern. Consider using `if let` + --> $DIR/single_match_else.rs:79:5 + | +LL | / match Some(1) { +LL | | Some(a) => println!("${:?}", a), +LL | | None => { +LL | | println!("else block"); +LL | | return; +LL | | }, +LL | | } + | |_____^ + | +help: try this + | +LL | if let Some(a) = Some(1) { println!("${:?}", a) } else { +LL | println!("else block"); +LL | return; +LL | } + | + +error: aborting due to 3 previous errors From c79c6888a5509184112b774a56cfc5ca9f9f1e2b Mon Sep 17 00:00:00 2001 From: Takayuki Nakata Date: Thu, 9 Jul 2020 22:07:15 +0900 Subject: [PATCH 68/99] Fix a broken link in CONTRIBUTING.md --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 9f7bdcb1be7e5..69a734e4ee4c2 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -245,7 +245,7 @@ this to work, you will need the fix of `git subtree` available [here][gitgitgadget-pr]. [gitgitgadget-pr]: https://github.com/gitgitgadget/git/pull/493 -[subtree]: https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md#external-dependencies-subtree +[subtree]: https://rustc-dev-guide.rust-lang.org/contributing.html#external-dependencies-subtree [`rust-lang/rust`]: https://github.com/rust-lang/rust ## Issue and PR triage From cf91c54cc6e20462bf6c5c63a3ab0b6afe8b7f0e Mon Sep 17 00:00:00 2001 From: Tamir Duberstein Date: Tue, 7 Jul 2020 11:12:44 -0400 Subject: [PATCH 69/99] Avoid "whitelist" Other terms are more inclusive and precise. --- clippy_lints/src/attrs.rs | 4 ++-- clippy_lints/src/eq_op.rs | 2 +- clippy_lints/src/needless_pass_by_value.rs | 4 ++-- clippy_lints/src/non_expressive_names.rs | 18 +++++++++--------- clippy_lints/src/precedence.rs | 4 ++-- clippy_lints/src/types.rs | 4 ++-- .../{whitelist => third-party}/clippy.toml | 0 .../conf_allowlisted.rs} | 0 tests/ui/needless_pass_by_value.rs | 2 +- tests/ui/neg_cmp_op_on_partial_ord.rs | 2 +- 10 files changed, 20 insertions(+), 20 deletions(-) rename tests/ui/crashes/{whitelist => third-party}/clippy.toml (100%) rename tests/ui/crashes/{whitelist/conf_whitelisted.rs => third-party/conf_allowlisted.rs} (100%) diff --git a/clippy_lints/src/attrs.rs b/clippy_lints/src/attrs.rs index 2505ff32fe523..3f7d6ba646770 100644 --- a/clippy_lints/src/attrs.rs +++ b/clippy_lints/src/attrs.rs @@ -72,7 +72,7 @@ declare_clippy_lint! { /// **What it does:** Checks for `extern crate` and `use` items annotated with /// lint attributes. /// - /// This lint whitelists `#[allow(unused_imports)]`, `#[allow(deprecated)]` and + /// This lint permits `#[allow(unused_imports)]`, `#[allow(deprecated)]` and /// `#[allow(unreachable_pub)]` on `use` items and `#[allow(unused_imports)]` on /// `extern crate` items with a `#[macro_use]` attribute. /// @@ -294,7 +294,7 @@ impl<'tcx> LateLintPass<'tcx> for Attributes { if let Some(ident) = attr.ident() { match &*ident.as_str() { "allow" | "warn" | "deny" | "forbid" => { - // whitelist `unused_imports`, `deprecated` and `unreachable_pub` for `use` items + // permit `unused_imports`, `deprecated` and `unreachable_pub` for `use` items // and `unused_imports` for `extern crate` items with `macro_use` for lint in lint_list { match item.kind { diff --git a/clippy_lints/src/eq_op.rs b/clippy_lints/src/eq_op.rs index ca921dcfdfe92..cbc93d772dd91 100644 --- a/clippy_lints/src/eq_op.rs +++ b/clippy_lints/src/eq_op.rs @@ -16,7 +16,7 @@ declare_clippy_lint! { /// **Known problems:** False negatives: We had some false positives regarding /// calls (notably [racer](https://github.com/phildawes/racer) had one instance /// of `x.pop() && x.pop()`), so we removed matching any function or method - /// calls. We may introduce a whitelist of known pure functions in the future. + /// calls. We may introduce a list of known pure functions in the future. /// /// **Example:** /// ```rust diff --git a/clippy_lints/src/needless_pass_by_value.rs b/clippy_lints/src/needless_pass_by_value.rs index 5d47f9425e3ef..29e5d4d166498 100644 --- a/clippy_lints/src/needless_pass_by_value.rs +++ b/clippy_lints/src/needless_pass_by_value.rs @@ -100,7 +100,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue { // Allow `Borrow` or functions to be taken by value let borrow_trait = need!(get_trait_def_id(cx, &paths::BORROW_TRAIT)); - let whitelisted_traits = [ + let allowed_traits = [ need!(cx.tcx.lang_items().fn_trait()), need!(cx.tcx.lang_items().fn_once_trait()), need!(cx.tcx.lang_items().fn_mut_trait()), @@ -184,7 +184,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue { if !is_self(arg); if !ty.is_mutable_ptr(); if !is_copy(cx, ty); - if !whitelisted_traits.iter().any(|&t| implements_trait(cx, ty, t, &[])); + if !allowed_traits.iter().any(|&t| implements_trait(cx, ty, t, &[])); if !implements_borrow_trait; if !all_borrowable_trait; diff --git a/clippy_lints/src/non_expressive_names.rs b/clippy_lints/src/non_expressive_names.rs index 5f14fe97afefa..7128fee9bcf51 100644 --- a/clippy_lints/src/non_expressive_names.rs +++ b/clippy_lints/src/non_expressive_names.rs @@ -78,7 +78,7 @@ struct ExistingName { interned: SymbolStr, span: Span, len: usize, - whitelist: &'static [&'static str], + exemptions: &'static [&'static str], } struct SimilarNamesLocalVisitor<'a, 'tcx> { @@ -117,7 +117,7 @@ impl<'a, 'tcx> SimilarNamesLocalVisitor<'a, 'tcx> { // this list contains lists of names that are allowed to be similar // the assumption is that no name is ever contained in multiple lists. #[rustfmt::skip] -const WHITELIST: &[&[&str]] = &[ +const ALLOWED_TO_BE_SIMILAR: &[&[&str]] = &[ &["parsed", "parser"], &["lhs", "rhs"], &["tx", "rx"], @@ -156,17 +156,17 @@ impl<'a, 'tcx, 'b> Visitor<'tcx> for SimilarNamesNameVisitor<'a, 'tcx, 'b> { } #[must_use] -fn get_whitelist(interned_name: &str) -> Option<&'static [&'static str]> { - for &allow in WHITELIST { - if whitelisted(interned_name, allow) { - return Some(allow); +fn get_exemptions(interned_name: &str) -> Option<&'static [&'static str]> { + for &list in ALLOWED_TO_BE_SIMILAR { + if allowed_to_be_similar(interned_name, list) { + return Some(list); } } None } #[must_use] -fn whitelisted(interned_name: &str, list: &[&str]) -> bool { +fn allowed_to_be_similar(interned_name: &str, list: &[&str]) -> bool { list.iter() .any(|&name| interned_name.starts_with(name) || interned_name.ends_with(name)) } @@ -212,7 +212,7 @@ impl<'a, 'tcx, 'b> SimilarNamesNameVisitor<'a, 'tcx, 'b> { return; } for existing_name in &self.0.names { - if whitelisted(&interned_name, existing_name.whitelist) { + if allowed_to_be_similar(&interned_name, existing_name.exemptions) { continue; } let mut split_at = None; @@ -301,7 +301,7 @@ impl<'a, 'tcx, 'b> SimilarNamesNameVisitor<'a, 'tcx, 'b> { return; } self.0.names.push(ExistingName { - whitelist: get_whitelist(&interned_name).unwrap_or(&[]), + exemptions: get_exemptions(&interned_name).unwrap_or(&[]), interned: interned_name, span: ident.span, len: count, diff --git a/clippy_lints/src/precedence.rs b/clippy_lints/src/precedence.rs index 7dce23dd22306..23793678fa0e2 100644 --- a/clippy_lints/src/precedence.rs +++ b/clippy_lints/src/precedence.rs @@ -5,7 +5,7 @@ use rustc_lint::{EarlyContext, EarlyLintPass}; use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::source_map::Spanned; -const ODD_FUNCTIONS_WHITELIST: [&str; 14] = [ +const ALLOWED_ODD_FUNCTIONS: [&str; 14] = [ "asin", "asinh", "atan", @@ -109,7 +109,7 @@ impl EarlyLintPass for Precedence { if let ExprKind::Lit(ref lit) = slf.kind { match lit.kind { LitKind::Int(..) | LitKind::Float(..) => { - if ODD_FUNCTIONS_WHITELIST + if ALLOWED_ODD_FUNCTIONS .iter() .any(|odd_function| **odd_function == *path_segment_str) { diff --git a/clippy_lints/src/types.rs b/clippy_lints/src/types.rs index b1345f0de5e4b..68f51f0afdccd 100644 --- a/clippy_lints/src/types.rs +++ b/clippy_lints/src/types.rs @@ -1256,7 +1256,7 @@ fn check_loss_of_sign(cx: &LateContext<'_>, expr: &Expr<'_>, op: &Expr<'_>, cast // don't lint for the result of methods that always return non-negative values if let ExprKind::MethodCall(ref path, _, _, _) = op.kind { let mut method_name = path.ident.name.as_str(); - let whitelisted_methods = ["abs", "checked_abs", "rem_euclid", "checked_rem_euclid"]; + let allowed_methods = ["abs", "checked_abs", "rem_euclid", "checked_rem_euclid"]; if_chain! { if method_name == "unwrap"; @@ -1267,7 +1267,7 @@ fn check_loss_of_sign(cx: &LateContext<'_>, expr: &Expr<'_>, op: &Expr<'_>, cast } } - if whitelisted_methods.iter().any(|&name| method_name == name) { + if allowed_methods.iter().any(|&name| method_name == name) { return; } } diff --git a/tests/ui/crashes/whitelist/clippy.toml b/tests/ui/crashes/third-party/clippy.toml similarity index 100% rename from tests/ui/crashes/whitelist/clippy.toml rename to tests/ui/crashes/third-party/clippy.toml diff --git a/tests/ui/crashes/whitelist/conf_whitelisted.rs b/tests/ui/crashes/third-party/conf_allowlisted.rs similarity index 100% rename from tests/ui/crashes/whitelist/conf_whitelisted.rs rename to tests/ui/crashes/third-party/conf_allowlisted.rs diff --git a/tests/ui/needless_pass_by_value.rs b/tests/ui/needless_pass_by_value.rs index e93a7fe2985b3..7a9ba55590dce 100644 --- a/tests/ui/needless_pass_by_value.rs +++ b/tests/ui/needless_pass_by_value.rs @@ -116,7 +116,7 @@ extern "C" fn ext(x: MaybeUninit) -> usize { unsafe { x.assume_init() } } -// whitelist RangeArgument +// exempt RangeArgument fn range>(range: T) { let _ = range.start_bound(); } diff --git a/tests/ui/neg_cmp_op_on_partial_ord.rs b/tests/ui/neg_cmp_op_on_partial_ord.rs index ca70e3b7148ef..0b47119527247 100644 --- a/tests/ui/neg_cmp_op_on_partial_ord.rs +++ b/tests/ui/neg_cmp_op_on_partial_ord.rs @@ -57,6 +57,6 @@ fn main() { // The macro always negates the result of the given comparison in its // internal check which automatically triggered the lint. As it's an // external macro there was no chance to do anything about it which led - // to a whitelisting of all external macros. + // to an exempting of all external macros. assert!(a_value < another_value); } From 298a1fa3bd8ec04350b1bff6a6d92e34abf2e198 Mon Sep 17 00:00:00 2001 From: Christian Duerr Date: Fri, 26 Jun 2020 17:03:10 +0200 Subject: [PATCH 70/99] Move range_minus_one to pedantic This moves the range_minus_one lint to the pedantic category, so there will not be any warnings emitted by default. This should work around problems where the suggestion is impossible to resolve due to the range consumer only accepting a specific range implementation, rather than the `RangeBounds` trait (see #3307). While it is possible to work around this by extracting the boundary into a variable, I don't think clippy should encourage people to disable or work around lints, but instead the lints should be fixable. So hopefully this will help until a proper implementation checks what the range is used for. --- clippy_lints/src/ranges.rs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/clippy_lints/src/ranges.rs b/clippy_lints/src/ranges.rs index c164ec9aaf173..dd608de5723e2 100644 --- a/clippy_lints/src/ranges.rs +++ b/clippy_lints/src/ranges.rs @@ -52,6 +52,11 @@ declare_clippy_lint! { /// exclusive ranges, because they essentially add an extra branch that /// LLVM may fail to hoist out of the loop. /// + /// This will cause a warning that cannot be fixed if the consumer of the + /// range only accepts a specific range type, instead of the generic + /// `RangeBounds` trait + /// ([#3307](https://github.com/rust-lang/rust-clippy/issues/3307)). + /// /// **Example:** /// ```rust,ignore /// for x..(y+1) { .. } @@ -72,7 +77,10 @@ declare_clippy_lint! { /// **Why is this bad?** The code is more readable with an exclusive range /// like `x..y`. /// - /// **Known problems:** None. + /// **Known problems:** This will cause a warning that cannot be fixed if + /// the consumer of the range only accepts a specific range type, instead of + /// the generic `RangeBounds` trait + /// ([#3307](https://github.com/rust-lang/rust-clippy/issues/3307)). /// /// **Example:** /// ```rust,ignore @@ -83,7 +91,7 @@ declare_clippy_lint! { /// for x..y { .. } /// ``` pub RANGE_MINUS_ONE, - complexity, + pedantic, "`x..=(y-1)` reads better as `x..y`" } From ba2a85dadc61bbfeb483ca0d05ddfda213da1329 Mon Sep 17 00:00:00 2001 From: Christian Duerr Date: Fri, 3 Jul 2020 21:09:32 +0200 Subject: [PATCH 71/99] 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 fe34e4390d659..4d9776018cf45 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -1162,6 +1162,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: LintId::of(&needless_pass_by_value::NEEDLESS_PASS_BY_VALUE), LintId::of(&non_expressive_names::SIMILAR_NAMES), LintId::of(&option_if_let_else::OPTION_IF_LET_ELSE), + LintId::of(&ranges::RANGE_MINUS_ONE), LintId::of(&ranges::RANGE_PLUS_ONE), LintId::of(&shadow::SHADOW_UNRELATED), LintId::of(&strings::STRING_ADD_ASSIGN), @@ -1382,7 +1383,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: LintId::of(&ptr::PTR_ARG), LintId::of(&ptr_offset_with_cast::PTR_OFFSET_WITH_CAST), LintId::of(&question_mark::QUESTION_MARK), - LintId::of(&ranges::RANGE_MINUS_ONE), LintId::of(&ranges::RANGE_ZIP_WITH_LEN), LintId::of(&ranges::REVERSED_EMPTY_RANGES), LintId::of(&redundant_clone::REDUNDANT_CLONE), @@ -1598,7 +1598,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: LintId::of(&partialeq_ne_impl::PARTIALEQ_NE_IMPL), LintId::of(&precedence::PRECEDENCE), LintId::of(&ptr_offset_with_cast::PTR_OFFSET_WITH_CAST), - LintId::of(&ranges::RANGE_MINUS_ONE), LintId::of(&ranges::RANGE_ZIP_WITH_LEN), LintId::of(&reference::DEREF_ADDROF), LintId::of(&reference::REF_IN_DEREF), diff --git a/src/lintlist/mod.rs b/src/lintlist/mod.rs index e681f47f949df..c20793ecd3ec7 100644 --- a/src/lintlist/mod.rs +++ b/src/lintlist/mod.rs @@ -1783,7 +1783,7 @@ pub static ref ALL_LINTS: Vec = vec![ }, Lint { name: "range_minus_one", - group: "complexity", + group: "pedantic", desc: "`x..=(y-1)` reads better as `x..y`", deprecation: None, module: "ranges", From 780a4c87de88d7f747c7847b71c90c8268fe4b66 Mon Sep 17 00:00:00 2001 From: Takayuki Nakata Date: Fri, 10 Jul 2020 23:53:15 +0900 Subject: [PATCH 72/99] Fix typo --- clippy_lints/src/repeat_once.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clippy_lints/src/repeat_once.rs b/clippy_lints/src/repeat_once.rs index af3c948ec82c1..436374d7c5458 100644 --- a/clippy_lints/src/repeat_once.rs +++ b/clippy_lints/src/repeat_once.rs @@ -15,7 +15,7 @@ declare_clippy_lint! { /// - `.clone()` for `String` /// - `.to_vec()` for `slice` /// - /// **Why is this bad?** For example, `String.repeat(1)` is equivalent to `.clone()`. If cloning the string is the intention behind thi, `clone()` should be used. + /// **Why is this bad?** For example, `String.repeat(1)` is equivalent to `.clone()`. If cloning the string is the intention behind this, `clone()` should be used. /// /// **Known problems:** None. /// From b3c719608d2c969323714517837f0c68aca23d81 Mon Sep 17 00:00:00 2001 From: Christian Duerr Date: Fri, 10 Jul 2020 17:23:03 +0200 Subject: [PATCH 73/99] Fix test failures --- tests/ui/range_plus_minus_one.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/ui/range_plus_minus_one.rs b/tests/ui/range_plus_minus_one.rs index 3cfed4125b35c..7d034117547ca 100644 --- a/tests/ui/range_plus_minus_one.rs +++ b/tests/ui/range_plus_minus_one.rs @@ -7,6 +7,7 @@ fn f() -> usize { } #[warn(clippy::range_plus_one)] +#[warn(clippy::range_minus_one)] fn main() { for _ in 0..2 {} for _ in 0..=2 {} From afa4148cc6dee0f9e0ca5b33f2511b9305d84fcb Mon Sep 17 00:00:00 2001 From: Christian Duerr Date: Fri, 10 Jul 2020 17:53:01 +0200 Subject: [PATCH 74/99] Fix tests a bit more --- tests/ui/range_plus_minus_one.fixed | 1 + tests/ui/range_plus_minus_one.stderr | 18 +++++++++--------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/tests/ui/range_plus_minus_one.fixed b/tests/ui/range_plus_minus_one.fixed index 6b40211409974..19b253b0fe2c6 100644 --- a/tests/ui/range_plus_minus_one.fixed +++ b/tests/ui/range_plus_minus_one.fixed @@ -7,6 +7,7 @@ fn f() -> usize { } #[warn(clippy::range_plus_one)] +#[warn(clippy::range_minus_one)] fn main() { for _ in 0..2 {} for _ in 0..=2 {} diff --git a/tests/ui/range_plus_minus_one.stderr b/tests/ui/range_plus_minus_one.stderr index f72943a04f252..fb4f1658597a5 100644 --- a/tests/ui/range_plus_minus_one.stderr +++ b/tests/ui/range_plus_minus_one.stderr @@ -1,5 +1,5 @@ error: an inclusive range would be more readable - --> $DIR/range_plus_minus_one.rs:14:14 + --> $DIR/range_plus_minus_one.rs:15:14 | LL | for _ in 0..3 + 1 {} | ^^^^^^^^ help: use: `0..=3` @@ -7,25 +7,25 @@ LL | for _ in 0..3 + 1 {} = note: `-D clippy::range-plus-one` implied by `-D warnings` error: an inclusive range would be more readable - --> $DIR/range_plus_minus_one.rs:17:14 + --> $DIR/range_plus_minus_one.rs:18:14 | LL | for _ in 0..1 + 5 {} | ^^^^^^^^ help: use: `0..=5` error: an inclusive range would be more readable - --> $DIR/range_plus_minus_one.rs:20:14 + --> $DIR/range_plus_minus_one.rs:21:14 | LL | for _ in 1..1 + 1 {} | ^^^^^^^^ help: use: `1..=1` error: an inclusive range would be more readable - --> $DIR/range_plus_minus_one.rs:26:14 + --> $DIR/range_plus_minus_one.rs:27:14 | LL | for _ in 0..(1 + f()) {} | ^^^^^^^^^^^^ help: use: `0..=f()` error: an exclusive range would be more readable - --> $DIR/range_plus_minus_one.rs:30:13 + --> $DIR/range_plus_minus_one.rs:31:13 | LL | let _ = ..=11 - 1; | ^^^^^^^^^ help: use: `..11` @@ -33,25 +33,25 @@ LL | let _ = ..=11 - 1; = note: `-D clippy::range-minus-one` implied by `-D warnings` error: an exclusive range would be more readable - --> $DIR/range_plus_minus_one.rs:31:13 + --> $DIR/range_plus_minus_one.rs:32:13 | LL | let _ = ..=(11 - 1); | ^^^^^^^^^^^ help: use: `..11` error: an inclusive range would be more readable - --> $DIR/range_plus_minus_one.rs:32:13 + --> $DIR/range_plus_minus_one.rs:33:13 | LL | let _ = (1..11 + 1); | ^^^^^^^^^^^ help: use: `(1..=11)` error: an inclusive range would be more readable - --> $DIR/range_plus_minus_one.rs:33:13 + --> $DIR/range_plus_minus_one.rs:34:13 | LL | let _ = (f() + 1)..(f() + 1); | ^^^^^^^^^^^^^^^^^^^^ help: use: `((f() + 1)..=f())` error: an inclusive range would be more readable - --> $DIR/range_plus_minus_one.rs:37:14 + --> $DIR/range_plus_minus_one.rs:38:14 | LL | for _ in 1..ONE + ONE {} | ^^^^^^^^^^^^ help: use: `1..=ONE` From 23d7b3f6f1a345ad95f0812c85613627164b6c39 Mon Sep 17 00:00:00 2001 From: Erik Desjardins Date: Fri, 10 Jul 2020 19:02:10 -0400 Subject: [PATCH 75/99] Remove an unwrap in layout computation --- src/librustc_middle/ty/layout.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/librustc_middle/ty/layout.rs b/src/librustc_middle/ty/layout.rs index 39b8566e7a873..efdb5f27afb2a 100644 --- a/src/librustc_middle/ty/layout.rs +++ b/src/librustc_middle/ty/layout.rs @@ -774,12 +774,12 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { (present_variants.next(), present_variants.next()) }; let present_first = match present_first { - present_first @ Some(_) => present_first, + Some(present_first) => present_first, // Uninhabited because it has no variants, or only absent ones. None if def.is_enum() => return tcx.layout_raw(param_env.and(tcx.types.never)), // If it's a struct, still compute a layout so that we can still compute the // field offsets. - None => Some(VariantIdx::new(0)), + None => VariantIdx::new(0), }; let is_struct = !def.is_enum() || @@ -791,7 +791,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { // Struct, or univariant enum equivalent to a struct. // (Typechecking will reject discriminant-sizing attrs.) - let v = present_first.unwrap(); + let v = present_first; let kind = if def.is_enum() || variants[v].is_empty() { StructKind::AlwaysSized } else { From 1eb0053dcddcb55e46f8ba5b4083f7a3f5872be0 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Fri, 30 Aug 2019 02:01:04 +0200 Subject: [PATCH 76/99] Stabilize `transmute` in constants and statics but not const fn --- tests/ui/missing_const_for_fn/could_be_const.stderr | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/tests/ui/missing_const_for_fn/could_be_const.stderr b/tests/ui/missing_const_for_fn/could_be_const.stderr index 8dde56cd79f44..74d32b8a1aa93 100644 --- a/tests/ui/missing_const_for_fn/could_be_const.stderr +++ b/tests/ui/missing_const_for_fn/could_be_const.stderr @@ -57,14 +57,6 @@ LL | | t LL | | } | |_^ -error: this could be a `const fn` - --> $DIR/could_be_const.rs:48:1 - | -LL | / fn sub(x: u32) -> usize { -LL | | unsafe { transmute(&x) } -LL | | } - | |_^ - error: this could be a `const fn` --> $DIR/could_be_const.rs:67:9 | @@ -73,5 +65,5 @@ LL | | B LL | | } | |_________^ -error: aborting due to 9 previous errors +error: aborting due to 8 previous errors From 1b3bc16533a3e701616648920603c10674eb653b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Sat, 11 Jul 2020 12:28:21 +0200 Subject: [PATCH 77/99] Fix out of bounds access by checking length equality BEFORE accessing by index. Fixes #5780 --- clippy_lints/src/unnested_or_patterns.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clippy_lints/src/unnested_or_patterns.rs b/clippy_lints/src/unnested_or_patterns.rs index 169a486d1eb94..502bf0c427954 100644 --- a/clippy_lints/src/unnested_or_patterns.rs +++ b/clippy_lints/src/unnested_or_patterns.rs @@ -400,8 +400,8 @@ fn extend_with_matching( /// Are the patterns in `ps1` and `ps2` equal save for `ps1[idx]` compared to `ps2[idx]`? fn eq_pre_post(ps1: &[P], ps2: &[P], idx: usize) -> bool { - ps1[idx].is_rest() == ps2[idx].is_rest() // Avoid `[x, ..] | [x, 0]` => `[x, .. | 0]`. - && ps1.len() == ps2.len() + ps1.len() == ps2.len() + && ps1[idx].is_rest() == ps2[idx].is_rest() // Avoid `[x, ..] | [x, 0]` => `[x, .. | 0]`. && over(&ps1[..idx], &ps2[..idx], |l, r| eq_pat(l, r)) && over(&ps1[idx + 1..], &ps2[idx + 1..], |l, r| eq_pat(l, r)) } From 905b5ad80aca3e4a6d9d5f124978b0278ccdd48e Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sat, 11 Jul 2020 17:20:33 -0400 Subject: [PATCH 78/99] don't mark linux kernel module targets as a unix environment --- src/librustc_target/spec/linux_kernel_base.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/librustc_target/spec/linux_kernel_base.rs b/src/librustc_target/spec/linux_kernel_base.rs index 201d6a0fff93b..6d929d1244789 100644 --- a/src/librustc_target/spec/linux_kernel_base.rs +++ b/src/librustc_target/spec/linux_kernel_base.rs @@ -17,7 +17,6 @@ pub fn opts() -> TargetOptions { needs_plt: true, relro_level: RelroLevel::Full, relocation_model: RelocModel::Static, - target_family: Some("unix".to_string()), pre_link_args, ..Default::default() From 2c5f8ab582badb5b45124bcab01597cae46c7e61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Sat, 11 Jul 2020 23:42:56 +0200 Subject: [PATCH 79/99] fix phrase in new_lint issue template --- .github/ISSUE_TEMPLATE/new_lint.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/new_lint.md b/.github/ISSUE_TEMPLATE/new_lint.md index 70445d7ef2503..98fd0df685fdb 100644 --- a/.github/ISSUE_TEMPLATE/new_lint.md +++ b/.github/ISSUE_TEMPLATE/new_lint.md @@ -12,7 +12,7 @@ labels: L-lint - Kind: *See for list of lint kinds* -*What benefit of this lint over old code?* +*What is the advantage of the recommended code over the original code* For example: - Remove bounce checking inserted by ... From 9a8b516de046ac909f22f0280e1a8a0d87ba0d06 Mon Sep 17 00:00:00 2001 From: Lzu Tao Date: Fri, 10 Jul 2020 15:59:25 +0000 Subject: [PATCH 80/99] Sorting feature attributes in std --- src/libstd/lib.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index bd585d39c242f..16a4b38a1ae33 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -242,8 +242,8 @@ #![feature(atomic_mut_ptr)] #![feature(box_syntax)] #![feature(c_variadic)] -#![feature(cfg_accessible)] #![feature(can_vector)] +#![feature(cfg_accessible)] #![feature(cfg_target_has_atomic)] #![feature(cfg_target_thread_local)] #![feature(char_error_internals)] @@ -276,8 +276,8 @@ #![feature(hashmap_internals)] #![feature(int_error_internals)] #![feature(int_error_matching)] -#![feature(into_future)] #![feature(integer_atomics)] +#![feature(into_future)] #![feature(lang_items)] #![feature(libc)] #![feature(link_args)] @@ -286,6 +286,7 @@ #![feature(log_syntax)] #![feature(maybe_uninit_ref)] #![feature(maybe_uninit_slice)] +#![feature(min_specialization)] #![feature(needs_panic_runtime)] #![feature(negative_impls)] #![feature(never_type)] @@ -305,7 +306,6 @@ #![feature(shrink_to)] #![feature(slice_concat_ext)] #![feature(slice_internals)] -#![feature(min_specialization)] #![feature(staged_api)] #![feature(std_internals)] #![feature(stdsimd)] From ff5e1078fc911c6ca97c64fbaefe7a2aebedbb0d Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 12 Jul 2020 12:48:43 +0200 Subject: [PATCH 81/99] assign tracking issue --- src/libcore/ptr/const_ptr.rs | 6 +++--- src/libcore/ptr/mut_ptr.rs | 6 +++--- src/libcore/ptr/non_null.rs | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/libcore/ptr/const_ptr.rs b/src/libcore/ptr/const_ptr.rs index 22c741d4651a5..39d4aca636a05 100644 --- a/src/libcore/ptr/const_ptr.rs +++ b/src/libcore/ptr/const_ptr.rs @@ -842,8 +842,8 @@ impl *const [T] { /// assert_eq!(slice.as_ptr(), 0 as *const i8); /// ``` #[inline] - #[unstable(feature = "slice_ptr_get", issue = "none")] - #[rustc_const_unstable(feature = "slice_ptr_get", issue = "none")] + #[unstable(feature = "slice_ptr_get", issue = "74265")] + #[rustc_const_unstable(feature = "slice_ptr_get", issue = "74265")] pub const fn as_ptr(self) -> *const T { self as *const T } @@ -867,7 +867,7 @@ impl *const [T] { /// assert_eq!(x.get_unchecked(1), x.as_ptr().add(1)); /// } /// ``` - #[unstable(feature = "slice_ptr_get", issue = "none")] + #[unstable(feature = "slice_ptr_get", issue = "74265")] #[inline] pub unsafe fn get_unchecked(self, index: I) -> *const I::Output where diff --git a/src/libcore/ptr/mut_ptr.rs b/src/libcore/ptr/mut_ptr.rs index 56bade706942a..644465d7d17f8 100644 --- a/src/libcore/ptr/mut_ptr.rs +++ b/src/libcore/ptr/mut_ptr.rs @@ -1043,8 +1043,8 @@ impl *mut [T] { /// assert_eq!(slice.as_mut_ptr(), 0 as *mut i8); /// ``` #[inline] - #[unstable(feature = "slice_ptr_get", issue = "none")] - #[rustc_const_unstable(feature = "slice_ptr_get", issue = "none")] + #[unstable(feature = "slice_ptr_get", issue = "74265")] + #[rustc_const_unstable(feature = "slice_ptr_get", issue = "74265")] pub const fn as_mut_ptr(self) -> *mut T { self as *mut T } @@ -1068,7 +1068,7 @@ impl *mut [T] { /// assert_eq!(x.get_unchecked_mut(1), x.as_mut_ptr().add(1)); /// } /// ``` - #[unstable(feature = "slice_ptr_get", issue = "none")] + #[unstable(feature = "slice_ptr_get", issue = "74265")] #[inline] pub unsafe fn get_unchecked_mut(self, index: I) -> *mut I::Output where diff --git a/src/libcore/ptr/non_null.rs b/src/libcore/ptr/non_null.rs index f59da631b46ab..b362a49d604e7 100644 --- a/src/libcore/ptr/non_null.rs +++ b/src/libcore/ptr/non_null.rs @@ -217,8 +217,8 @@ impl NonNull<[T]> { /// assert_eq!(slice.as_non_null_ptr(), NonNull::new(1 as *mut i8).unwrap()); /// ``` #[inline] - #[unstable(feature = "slice_ptr_get", issue = "none")] - #[rustc_const_unstable(feature = "slice_ptr_get", issue = "none")] + #[unstable(feature = "slice_ptr_get", issue = "74265")] + #[rustc_const_unstable(feature = "slice_ptr_get", issue = "74265")] pub const fn as_non_null_ptr(self) -> NonNull { // SAFETY: We know `self` is non-null. unsafe { NonNull::new_unchecked(self.as_ptr().as_mut_ptr()) } @@ -245,7 +245,7 @@ impl NonNull<[T]> { /// assert_eq!(x.get_unchecked_mut(1).as_ptr(), x.as_non_null_ptr().as_ptr().add(1)); /// } /// ``` - #[unstable(feature = "slice_ptr_get", issue = "none")] + #[unstable(feature = "slice_ptr_get", issue = "74265")] #[inline] pub unsafe fn get_unchecked_mut(self, index: I) -> NonNull where From 1e05e09fe9df9919dc1c1c0f36255f4f1098fc24 Mon Sep 17 00:00:00 2001 From: Lzu Tao Date: Fri, 10 Jul 2020 15:59:25 +0000 Subject: [PATCH 82/99] Remove the useless indentation --- src/libstd/thread/mod.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs index d435ca6842518..d354a9b1842c2 100644 --- a/src/libstd/thread/mod.rs +++ b/src/libstd/thread/mod.rs @@ -641,9 +641,8 @@ where #[stable(feature = "rust1", since = "1.0.0")] pub fn current() -> Thread { thread_info::current_thread().expect( - "use of std::thread::current() is not \ - possible after the thread's local \ - data has been destroyed", + "use of std::thread::current() is not possible \ + after the thread's local data has been destroyed", ) } From 0ff820cb62f0b21d422440353b8def10c05ed735 Mon Sep 17 00:00:00 2001 From: Lzu Tao Date: Sun, 12 Jul 2020 10:17:22 +0000 Subject: [PATCH 83/99] Move constants to top file --- src/libstd/sys/windows/path.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/libstd/sys/windows/path.rs b/src/libstd/sys/windows/path.rs index 524f21f889bc2..e70ddce3aa579 100644 --- a/src/libstd/sys/windows/path.rs +++ b/src/libstd/sys/windows/path.rs @@ -2,6 +2,9 @@ use crate::ffi::OsStr; use crate::mem; use crate::path::Prefix; +pub const MAIN_SEP_STR: &str = "\\"; +pub const MAIN_SEP: char = '\\'; + fn os_str_as_u8_slice(s: &OsStr) -> &[u8] { unsafe { mem::transmute(s) } } @@ -90,5 +93,3 @@ pub fn parse_prefix(path: &OsStr) -> Option> { } } -pub const MAIN_SEP_STR: &str = "\\"; -pub const MAIN_SEP: char = '\\'; From 90a7d2470a7ae29c529ae2a3684c47839c57d763 Mon Sep 17 00:00:00 2001 From: Lzu Tao Date: Fri, 10 Jul 2020 15:59:25 +0000 Subject: [PATCH 84/99] Make is_valid_drive_letter function --- src/libstd/sys/windows/path.rs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/libstd/sys/windows/path.rs b/src/libstd/sys/windows/path.rs index e70ddce3aa579..e2b48a22dcdb7 100644 --- a/src/libstd/sys/windows/path.rs +++ b/src/libstd/sys/windows/path.rs @@ -22,6 +22,12 @@ pub fn is_verbatim_sep(b: u8) -> bool { b == b'\\' } +// In most DOS systems, it is not possible to have more than 26 drive letters. +// See . +pub fn is_valid_drive_letter(disk: u8) -> bool { + disk.is_ascii_alphabetic() +} + pub fn parse_prefix(path: &OsStr) -> Option> { use crate::path::Prefix::*; unsafe { @@ -52,7 +58,7 @@ pub fn parse_prefix(path: &OsStr) -> Option> { let idx = path.iter().position(|&b| b == b'\\'); if idx == Some(2) && path[1] == b':' { let c = path[0]; - if c.is_ascii() && (c as char).is_alphabetic() { + if is_valid_drive_letter(c) { // \\?\C:\ path return Some(VerbatimDisk(c.to_ascii_uppercase())); } @@ -77,7 +83,7 @@ pub fn parse_prefix(path: &OsStr) -> Option> { } else if path.get(1) == Some(&b':') { // C: let c = path[0]; - if c.is_ascii() && (c as char).is_alphabetic() { + if is_valid_drive_letter(c) { return Some(Disk(c.to_ascii_uppercase())); } } From 27a966a149f55fe29a25a2fc07e6c8a011ae3dbf Mon Sep 17 00:00:00 2001 From: Lzu Tao Date: Fri, 10 Jul 2020 15:59:25 +0000 Subject: [PATCH 85/99] Make use of slice::strip_prefix and slice pattern --- src/libstd/lib.rs | 1 + src/libstd/sys/windows/path.rs | 51 ++++++++++++++++------------------ 2 files changed, 25 insertions(+), 27 deletions(-) diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 16a4b38a1ae33..5215db7cdb3ce 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -306,6 +306,7 @@ #![feature(shrink_to)] #![feature(slice_concat_ext)] #![feature(slice_internals)] +#![feature(slice_strip)] #![feature(staged_api)] #![feature(std_internals)] #![feature(stdsimd)] diff --git a/src/libstd/sys/windows/path.rs b/src/libstd/sys/windows/path.rs index e2b48a22dcdb7..25ecc79abf0f1 100644 --- a/src/libstd/sys/windows/path.rs +++ b/src/libstd/sys/windows/path.rs @@ -29,23 +29,20 @@ pub fn is_valid_drive_letter(disk: u8) -> bool { } pub fn parse_prefix(path: &OsStr) -> Option> { - use crate::path::Prefix::*; + use Prefix::{DeviceNS, Disk, Verbatim, VerbatimDisk, VerbatimUNC, UNC}; unsafe { // The unsafety here stems from converting between &OsStr and &[u8] // and back. This is safe to do because (1) we only look at ASCII // contents of the encoding and (2) new &OsStr values are produced // only from ASCII-bounded slices of existing &OsStr values. - let mut path = os_str_as_u8_slice(path); + let path = os_str_as_u8_slice(path); - if path.starts_with(br"\\") { - // \\ - path = &path[2..]; - if path.starts_with(br"?\") { - // \\?\ - path = &path[2..]; - if path.starts_with(br"UNC\") { - // \\?\UNC\server\share - path = &path[4..]; + // \\ + if let Some(path) = path.strip_prefix(br"\\") { + // \\?\ + if let Some(path) = path.strip_prefix(br"?\") { + // \\?\UNC\server\share + if let Some(path) = path.strip_prefix(br"UNC\") { let (server, share) = match parse_two_comps(path, is_verbatim_sep) { Some((server, share)) => { (u8_slice_as_os_str(server), u8_slice_as_os_str(share)) @@ -55,22 +52,23 @@ pub fn parse_prefix(path: &OsStr) -> Option> { return Some(VerbatimUNC(server, share)); } else { // \\?\path - let idx = path.iter().position(|&b| b == b'\\'); - if idx == Some(2) && path[1] == b':' { - let c = path[0]; - if is_valid_drive_letter(c) { - // \\?\C:\ path + match path { + // \\?\C:\path + [c, b':', b'\\', ..] if is_valid_drive_letter(*c) => { return Some(VerbatimDisk(c.to_ascii_uppercase())); } + // \\?\cat_pics + _ => { + let idx = path.iter().position(|&b| b == b'\\').unwrap_or(path.len()); + let slice = &path[..idx]; + return Some(Verbatim(u8_slice_as_os_str(slice))); + } } - let slice = &path[..idx.unwrap_or(path.len())]; - return Some(Verbatim(u8_slice_as_os_str(slice))); } - } else if path.starts_with(b".\\") { - // \\.\path - path = &path[2..]; - let pos = path.iter().position(|&b| b == b'\\'); - let slice = &path[..pos.unwrap_or(path.len())]; + } else if let Some(path) = path.strip_prefix(b".\\") { + // \\.\COM42 + let idx = path.iter().position(|&b| b == b'\\').unwrap_or(path.len()); + let slice = &path[..idx]; return Some(DeviceNS(u8_slice_as_os_str(slice))); } match parse_two_comps(path, is_sep_byte) { @@ -78,12 +76,11 @@ pub fn parse_prefix(path: &OsStr) -> Option> { // \\server\share return Some(UNC(u8_slice_as_os_str(server), u8_slice_as_os_str(share))); } - _ => (), + _ => {} } - } else if path.get(1) == Some(&b':') { + } else if let [c, b':', ..] = path { // C: - let c = path[0]; - if is_valid_drive_letter(c) { + if is_valid_drive_letter(*c) { return Some(Disk(c.to_ascii_uppercase())); } } From b1d6798899b7830e869d06e1ddb106a75cb61cc8 Mon Sep 17 00:00:00 2001 From: Lzu Tao Date: Fri, 10 Jul 2020 15:59:25 +0000 Subject: [PATCH 86/99] Rewrite parse_two_comps --- src/libstd/sys/windows/path.rs | 30 ++++++++++++++++++---------- src/libstd/sys/windows/path/tests.rs | 21 +++++++++++++++++++ 2 files changed, 41 insertions(+), 10 deletions(-) create mode 100644 src/libstd/sys/windows/path/tests.rs diff --git a/src/libstd/sys/windows/path.rs b/src/libstd/sys/windows/path.rs index 25ecc79abf0f1..fa22d3bb7d6f4 100644 --- a/src/libstd/sys/windows/path.rs +++ b/src/libstd/sys/windows/path.rs @@ -2,6 +2,9 @@ use crate::ffi::OsStr; use crate::mem; use crate::path::Prefix; +#[cfg(test)] +mod tests; + pub const MAIN_SEP_STR: &str = "\\"; pub const MAIN_SEP: char = '\\'; @@ -43,7 +46,7 @@ pub fn parse_prefix(path: &OsStr) -> Option> { if let Some(path) = path.strip_prefix(br"?\") { // \\?\UNC\server\share if let Some(path) = path.strip_prefix(br"UNC\") { - let (server, share) = match parse_two_comps(path, is_verbatim_sep) { + let (server, share) = match get_first_two_components(path, is_verbatim_sep) { Some((server, share)) => { (u8_slice_as_os_str(server), u8_slice_as_os_str(share)) } @@ -71,7 +74,7 @@ pub fn parse_prefix(path: &OsStr) -> Option> { let slice = &path[..idx]; return Some(DeviceNS(u8_slice_as_os_str(slice))); } - match parse_two_comps(path, is_sep_byte) { + match get_first_two_components(path, is_sep_byte) { Some((server, share)) if !server.is_empty() && !share.is_empty() => { // \\server\share return Some(UNC(u8_slice_as_os_str(server), u8_slice_as_os_str(share))); @@ -86,13 +89,20 @@ pub fn parse_prefix(path: &OsStr) -> Option> { } return None; } - - fn parse_two_comps(mut path: &[u8], f: fn(u8) -> bool) -> Option<(&[u8], &[u8])> { - let first = &path[..path.iter().position(|x| f(*x))?]; - path = &path[(first.len() + 1)..]; - let idx = path.iter().position(|x| f(*x)); - let second = &path[..idx.unwrap_or(path.len())]; - Some((first, second)) - } } +/// Returns the first two path components with predicate `f`. +/// +/// The two components returned will be use by caller +/// to construct `VerbatimUNC` or `UNC` Windows path prefix. +/// +/// Returns [`None`] if there are no separators in path. +fn get_first_two_components(path: &[u8], f: fn(u8) -> bool) -> Option<(&[u8], &[u8])> { + let idx = path.iter().position(|&x| f(x))?; + // Panic safe + // The max `idx+1` is `path.len()` and `path[path.len()..]` is a valid index. + let (first, path) = (&path[..idx], &path[idx + 1..]); + let idx = path.iter().position(|&x| f(x)).unwrap_or(path.len()); + let second = &path[..idx]; + Some((first, second)) +} diff --git a/src/libstd/sys/windows/path/tests.rs b/src/libstd/sys/windows/path/tests.rs new file mode 100644 index 0000000000000..fbac1dc1ca17a --- /dev/null +++ b/src/libstd/sys/windows/path/tests.rs @@ -0,0 +1,21 @@ +use super::*; + +#[test] +fn test_get_first_two_components() { + assert_eq!( + get_first_two_components(br"server\share", is_verbatim_sep), + Some((&b"server"[..], &b"share"[..])), + ); + + assert_eq!( + get_first_two_components(br"server\", is_verbatim_sep), + Some((&b"server"[..], &b""[..])) + ); + + assert_eq!( + get_first_two_components(br"\server\", is_verbatim_sep), + Some((&b""[..], &b"server"[..])) + ); + + assert_eq!(get_first_two_components(br"there are no separators here", is_verbatim_sep), None,); +} From 0281a05f66aada7afc3e5b665b4c48a44abbc517 Mon Sep 17 00:00:00 2001 From: Lzu Tao Date: Fri, 10 Jul 2020 15:59:25 +0000 Subject: [PATCH 87/99] Prefer empty OsStr over unsafe cast from [u8] --- src/libstd/sys/windows/path.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libstd/sys/windows/path.rs b/src/libstd/sys/windows/path.rs index fa22d3bb7d6f4..899a3065038d7 100644 --- a/src/libstd/sys/windows/path.rs +++ b/src/libstd/sys/windows/path.rs @@ -50,7 +50,7 @@ pub fn parse_prefix(path: &OsStr) -> Option> { Some((server, share)) => { (u8_slice_as_os_str(server), u8_slice_as_os_str(share)) } - None => (u8_slice_as_os_str(path), u8_slice_as_os_str(&[])), + None => (u8_slice_as_os_str(path), OsStr::new("")), }; return Some(VerbatimUNC(server, share)); } else { From e31898b02409b8ce5db32761d45c78f9f74dbdc6 Mon Sep 17 00:00:00 2001 From: Lzu Tao Date: Sun, 12 Jul 2020 14:46:00 +0000 Subject: [PATCH 88/99] Reduce unsafe scope --- src/libstd/sys/windows/path.rs | 97 +++++++++++++++++----------------- 1 file changed, 48 insertions(+), 49 deletions(-) diff --git a/src/libstd/sys/windows/path.rs b/src/libstd/sys/windows/path.rs index 899a3065038d7..dda3ed68cfc95 100644 --- a/src/libstd/sys/windows/path.rs +++ b/src/libstd/sys/windows/path.rs @@ -8,6 +8,10 @@ mod tests; pub const MAIN_SEP_STR: &str = "\\"; pub const MAIN_SEP: char = '\\'; +// The unsafety here stems from converting between `&OsStr` and `&[u8]` +// and back. This is safe to do because (1) we only look at ASCII +// contents of the encoding and (2) new &OsStr values are produced +// only from ASCII-bounded slices of existing &OsStr values. fn os_str_as_u8_slice(s: &OsStr) -> &[u8] { unsafe { mem::transmute(s) } } @@ -33,62 +37,57 @@ pub fn is_valid_drive_letter(disk: u8) -> bool { pub fn parse_prefix(path: &OsStr) -> Option> { use Prefix::{DeviceNS, Disk, Verbatim, VerbatimDisk, VerbatimUNC, UNC}; - unsafe { - // The unsafety here stems from converting between &OsStr and &[u8] - // and back. This is safe to do because (1) we only look at ASCII - // contents of the encoding and (2) new &OsStr values are produced - // only from ASCII-bounded slices of existing &OsStr values. - let path = os_str_as_u8_slice(path); - // \\ - if let Some(path) = path.strip_prefix(br"\\") { - // \\?\ - if let Some(path) = path.strip_prefix(br"?\") { - // \\?\UNC\server\share - if let Some(path) = path.strip_prefix(br"UNC\") { - let (server, share) = match get_first_two_components(path, is_verbatim_sep) { - Some((server, share)) => { - (u8_slice_as_os_str(server), u8_slice_as_os_str(share)) - } - None => (u8_slice_as_os_str(path), OsStr::new("")), - }; - return Some(VerbatimUNC(server, share)); - } else { - // \\?\path - match path { - // \\?\C:\path - [c, b':', b'\\', ..] if is_valid_drive_letter(*c) => { - return Some(VerbatimDisk(c.to_ascii_uppercase())); - } - // \\?\cat_pics - _ => { - let idx = path.iter().position(|&b| b == b'\\').unwrap_or(path.len()); - let slice = &path[..idx]; - return Some(Verbatim(u8_slice_as_os_str(slice))); - } + let path = os_str_as_u8_slice(path); + + // \\ + if let Some(path) = path.strip_prefix(br"\\") { + // \\?\ + if let Some(path) = path.strip_prefix(br"?\") { + // \\?\UNC\server\share + if let Some(path) = path.strip_prefix(br"UNC\") { + let (server, share) = match get_first_two_components(path, is_verbatim_sep) { + Some((server, share)) => unsafe { + (u8_slice_as_os_str(server), u8_slice_as_os_str(share)) + }, + None => (unsafe { u8_slice_as_os_str(path) }, OsStr::new("")), + }; + return Some(VerbatimUNC(server, share)); + } else { + // \\?\path + match path { + // \\?\C:\path + [c, b':', b'\\', ..] if is_valid_drive_letter(*c) => { + return Some(VerbatimDisk(c.to_ascii_uppercase())); + } + // \\?\cat_pics + _ => { + let idx = path.iter().position(|&b| b == b'\\').unwrap_or(path.len()); + let slice = &path[..idx]; + return Some(Verbatim(unsafe { u8_slice_as_os_str(slice) })); } } - } else if let Some(path) = path.strip_prefix(b".\\") { - // \\.\COM42 - let idx = path.iter().position(|&b| b == b'\\').unwrap_or(path.len()); - let slice = &path[..idx]; - return Some(DeviceNS(u8_slice_as_os_str(slice))); - } - match get_first_two_components(path, is_sep_byte) { - Some((server, share)) if !server.is_empty() && !share.is_empty() => { - // \\server\share - return Some(UNC(u8_slice_as_os_str(server), u8_slice_as_os_str(share))); - } - _ => {} } - } else if let [c, b':', ..] = path { - // C: - if is_valid_drive_letter(*c) { - return Some(Disk(c.to_ascii_uppercase())); + } else if let Some(path) = path.strip_prefix(b".\\") { + // \\.\COM42 + let idx = path.iter().position(|&b| b == b'\\').unwrap_or(path.len()); + let slice = &path[..idx]; + return Some(DeviceNS(unsafe { u8_slice_as_os_str(slice) })); + } + match get_first_two_components(path, is_sep_byte) { + Some((server, share)) if !server.is_empty() && !share.is_empty() => { + // \\server\share + return Some(unsafe { UNC(u8_slice_as_os_str(server), u8_slice_as_os_str(share)) }); } + _ => {} + } + } else if let [c, b':', ..] = path { + // C: + if is_valid_drive_letter(*c) { + return Some(Disk(c.to_ascii_uppercase())); } - return None; } + None } /// Returns the first two path components with predicate `f`. From 5afbc5201c7bf82cadd69a1a0cea49cfe1e41172 Mon Sep 17 00:00:00 2001 From: David Wood Date: Sun, 12 Jul 2020 16:40:22 +0100 Subject: [PATCH 89/99] typeck: report placeholder type error w/out span This commit fixes a regression introduced in rust-lang/rust#70369 which meant that an error was not being emitted for invalid placeholder types when there wasn't a span available. Signed-off-by: David Wood --- src/librustc_typeck/astconv.rs | 4 +- src/librustc_typeck/collect.rs | 16 ++- src/test/ui/issues/issue-74086.rs | 4 + src/test/ui/issues/issue-74086.stderr | 12 ++ .../ui/typeck/typeck_type_placeholder_item.rs | 2 + .../typeck_type_placeholder_item.stderr | 128 ++++++++++-------- 6 files changed, 103 insertions(+), 63 deletions(-) create mode 100644 src/test/ui/issues/issue-74086.rs create mode 100644 src/test/ui/issues/issue-74086.stderr diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 5d1949626dd84..7581940b6ac69 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -3049,14 +3049,14 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let bare_fn_ty = ty::Binder::bind(tcx.mk_fn_sig(input_tys, output_ty, decl.c_variadic, unsafety, abi)); - if let (false, Some(ident_span)) = (self.allow_ty_infer(), ident_span) { + if !self.allow_ty_infer() { // We always collect the spans for placeholder types when evaluating `fn`s, but we // only want to emit an error complaining about them if infer types (`_`) are not // allowed. `allow_ty_infer` gates this behavior. We check for the presence of // `ident_span` to not emit an error twice when we have `fn foo(_: fn() -> _)`. crate::collect::placeholder_type_error( tcx, - ident_span.shrink_to_hi(), + ident_span.map(|sp| sp.shrink_to_hi()), &generics.params[..], visitor.0, true, diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 15481660a5218..625b72091a6cc 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -129,7 +129,7 @@ struct CollectItemTypesVisitor<'tcx> { /// all already existing generic type parameters to avoid suggesting a name that is already in use. crate fn placeholder_type_error( tcx: TyCtxt<'tcx>, - span: Span, + span: Option, generics: &[hir::GenericParam<'_>], placeholder_types: Vec, suggest: bool, @@ -137,12 +137,15 @@ crate fn placeholder_type_error( if placeholder_types.is_empty() { return; } - let type_name = generics.next_type_param_name(None); + let type_name = generics.next_type_param_name(None); let mut sugg: Vec<_> = placeholder_types.iter().map(|sp| (*sp, (*type_name).to_string())).collect(); + if generics.is_empty() { - sugg.push((span, format!("<{}>", type_name))); + if let Some(span) = span { + sugg.push((span, format!("<{}>", type_name))); + } } else if let Some(arg) = generics.iter().find(|arg| match arg.name { hir::ParamName::Plain(Ident { name: kw::Underscore, .. }) => true, _ => false, @@ -158,6 +161,7 @@ crate fn placeholder_type_error( format!(", {}", type_name), )); } + let mut err = bad_placeholder_type(tcx, placeholder_types); if suggest { err.multipart_suggestion( @@ -186,7 +190,7 @@ fn reject_placeholder_type_signatures_in_item(tcx: TyCtxt<'tcx>, item: &'tcx hir let mut visitor = PlaceholderHirTyCollector::default(); visitor.visit_item(item); - placeholder_type_error(tcx, generics.span, &generics.params[..], visitor.0, suggest); + placeholder_type_error(tcx, Some(generics.span), &generics.params[..], visitor.0, suggest); } impl Visitor<'tcx> for CollectItemTypesVisitor<'tcx> { @@ -722,7 +726,7 @@ fn convert_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::HirId) { // Account for `const C: _;` and `type T = _;`. let mut visitor = PlaceholderHirTyCollector::default(); visitor.visit_trait_item(trait_item); - placeholder_type_error(tcx, DUMMY_SP, &[], visitor.0, false); + placeholder_type_error(tcx, None, &[], visitor.0, false); } hir::TraitItemKind::Type(_, None) => {} @@ -745,7 +749,7 @@ fn convert_impl_item(tcx: TyCtxt<'_>, impl_item_id: hir::HirId) { // Account for `type T = _;` let mut visitor = PlaceholderHirTyCollector::default(); visitor.visit_impl_item(impl_item); - placeholder_type_error(tcx, DUMMY_SP, &[], visitor.0, false); + placeholder_type_error(tcx, None, &[], visitor.0, false); } hir::ImplItemKind::Const(..) => {} } diff --git a/src/test/ui/issues/issue-74086.rs b/src/test/ui/issues/issue-74086.rs new file mode 100644 index 0000000000000..f68a665b2f38d --- /dev/null +++ b/src/test/ui/issues/issue-74086.rs @@ -0,0 +1,4 @@ +fn main() { + static BUG: fn(_) -> u8 = |_| 8; + //~^ ERROR the type placeholder `_` is not allowed within types on item signatures [E0121] +} diff --git a/src/test/ui/issues/issue-74086.stderr b/src/test/ui/issues/issue-74086.stderr new file mode 100644 index 0000000000000..4127f48a093f4 --- /dev/null +++ b/src/test/ui/issues/issue-74086.stderr @@ -0,0 +1,12 @@ +error[E0121]: the type placeholder `_` is not allowed within types on item signatures + --> $DIR/issue-74086.rs:2:20 + | +LL | static BUG: fn(_) -> u8 = |_| 8; + | ^ + | | + | not allowed in type signatures + | help: use type parameters instead: `T` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0121`. diff --git a/src/test/ui/typeck/typeck_type_placeholder_item.rs b/src/test/ui/typeck/typeck_type_placeholder_item.rs index 99a7023089283..133c5231031fd 100644 --- a/src/test/ui/typeck/typeck_type_placeholder_item.rs +++ b/src/test/ui/typeck/typeck_type_placeholder_item.rs @@ -32,6 +32,7 @@ fn test7(x: _) { let _x: usize = x; } fn test8(_f: fn() -> _) { } //~^ ERROR the type placeholder `_` is not allowed within types on item signatures +//~^^ ERROR the type placeholder `_` is not allowed within types on item signatures struct Test9; @@ -98,6 +99,7 @@ pub fn main() { fn fn_test8(_f: fn() -> _) { } //~^ ERROR the type placeholder `_` is not allowed within types on item signatures + //~^^ ERROR the type placeholder `_` is not allowed within types on item signatures struct FnTest9; diff --git a/src/test/ui/typeck/typeck_type_placeholder_item.stderr b/src/test/ui/typeck/typeck_type_placeholder_item.stderr index 6c0653d5fcb7c..a1945f2b9cf4e 100644 --- a/src/test/ui/typeck/typeck_type_placeholder_item.stderr +++ b/src/test/ui/typeck/typeck_type_placeholder_item.stderr @@ -1,35 +1,35 @@ error: expected identifier, found reserved identifier `_` - --> $DIR/typeck_type_placeholder_item.rs:152:18 + --> $DIR/typeck_type_placeholder_item.rs:154:18 | LL | struct BadStruct<_>(_); | ^ expected identifier, found reserved identifier error: expected identifier, found reserved identifier `_` - --> $DIR/typeck_type_placeholder_item.rs:155:16 + --> $DIR/typeck_type_placeholder_item.rs:157:16 | LL | trait BadTrait<_> {} | ^ expected identifier, found reserved identifier error: expected identifier, found reserved identifier `_` - --> $DIR/typeck_type_placeholder_item.rs:165:19 + --> $DIR/typeck_type_placeholder_item.rs:167:19 | LL | struct BadStruct1<_, _>(_); | ^ expected identifier, found reserved identifier error: expected identifier, found reserved identifier `_` - --> $DIR/typeck_type_placeholder_item.rs:165:22 + --> $DIR/typeck_type_placeholder_item.rs:167:22 | LL | struct BadStruct1<_, _>(_); | ^ expected identifier, found reserved identifier error: expected identifier, found reserved identifier `_` - --> $DIR/typeck_type_placeholder_item.rs:170:19 + --> $DIR/typeck_type_placeholder_item.rs:172:19 | LL | struct BadStruct2<_, T>(_, T); | ^ expected identifier, found reserved identifier error: associated constant in `impl` without body - --> $DIR/typeck_type_placeholder_item.rs:201:5 + --> $DIR/typeck_type_placeholder_item.rs:203:5 | LL | const C: _; | ^^^^^^^^^^- @@ -37,7 +37,7 @@ LL | const C: _; | help: provide a definition for the constant: `= ;` error[E0403]: the name `_` is already used for a generic parameter in this item's generic parameters - --> $DIR/typeck_type_placeholder_item.rs:165:22 + --> $DIR/typeck_type_placeholder_item.rs:167:22 | LL | struct BadStruct1<_, _>(_); | - ^ already used @@ -131,6 +131,15 @@ help: use type parameters instead LL | fn test7(x: T) { let _x: usize = x; } | ^^^ ^ +error[E0121]: the type placeholder `_` is not allowed within types on item signatures + --> $DIR/typeck_type_placeholder_item.rs:33:22 + | +LL | fn test8(_f: fn() -> _) { } + | ^ + | | + | not allowed in type signatures + | help: use type parameters instead: `T` + error[E0121]: the type placeholder `_` is not allowed within types on item signatures --> $DIR/typeck_type_placeholder_item.rs:33:22 | @@ -143,7 +152,7 @@ LL | fn test8(_f: fn() -> T) { } | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:46:26 + --> $DIR/typeck_type_placeholder_item.rs:47:26 | LL | fn test11(x: &usize) -> &_ { | -^ @@ -152,7 +161,7 @@ LL | fn test11(x: &usize) -> &_ { | help: replace with the correct return type: `&&usize` error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:51:52 + --> $DIR/typeck_type_placeholder_item.rs:52:52 | LL | unsafe fn test12(x: *const usize) -> *const *const _ { | --------------^ @@ -161,7 +170,7 @@ LL | unsafe fn test12(x: *const usize) -> *const *const _ { | help: replace with the correct return type: `*const *const usize` error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:65:8 + --> $DIR/typeck_type_placeholder_item.rs:66:8 | LL | a: _, | ^ not allowed in type signatures @@ -180,13 +189,13 @@ LL | b: (T, T), | error: missing type for `static` item - --> $DIR/typeck_type_placeholder_item.rs:71:12 + --> $DIR/typeck_type_placeholder_item.rs:72:12 | LL | static A = 42; | ^ help: provide a type for the item: `A: i32` error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:73:15 + --> $DIR/typeck_type_placeholder_item.rs:74:15 | LL | static B: _ = 42; | ^ @@ -195,13 +204,13 @@ LL | static B: _ = 42; | help: replace `_` with the correct type: `i32` error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:75:15 + --> $DIR/typeck_type_placeholder_item.rs:76:15 | LL | static C: Option<_> = Some(42); | ^^^^^^^^^ not allowed in type signatures error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:78:21 + --> $DIR/typeck_type_placeholder_item.rs:79:21 | LL | fn fn_test() -> _ { 5 } | ^ @@ -210,7 +219,7 @@ LL | fn fn_test() -> _ { 5 } | help: replace with the correct return type: `i32` error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:81:23 + --> $DIR/typeck_type_placeholder_item.rs:82:23 | LL | fn fn_test2() -> (_, _) { (5, 5) } | -^--^- @@ -220,7 +229,7 @@ LL | fn fn_test2() -> (_, _) { (5, 5) } | help: replace with the correct return type: `(i32, i32)` error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:84:22 + --> $DIR/typeck_type_placeholder_item.rs:85:22 | LL | static FN_TEST3: _ = "test"; | ^ @@ -229,7 +238,7 @@ LL | static FN_TEST3: _ = "test"; | help: replace `_` with the correct type: `&str` error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:87:22 + --> $DIR/typeck_type_placeholder_item.rs:88:22 | LL | static FN_TEST4: _ = 145; | ^ @@ -238,13 +247,13 @@ LL | static FN_TEST4: _ = 145; | help: replace `_` with the correct type: `i32` error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:90:22 + --> $DIR/typeck_type_placeholder_item.rs:91:22 | LL | static FN_TEST5: (_, _) = (1, 2); | ^^^^^^ not allowed in type signatures error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:93:20 + --> $DIR/typeck_type_placeholder_item.rs:94:20 | LL | fn fn_test6(_: _) { } | ^ not allowed in type signatures @@ -255,7 +264,7 @@ LL | fn fn_test6(_: T) { } | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:96:20 + --> $DIR/typeck_type_placeholder_item.rs:97:20 | LL | fn fn_test7(x: _) { let _x: usize = x; } | ^ not allowed in type signatures @@ -266,7 +275,16 @@ LL | fn fn_test7(x: T) { let _x: usize = x; } | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:99:29 + --> $DIR/typeck_type_placeholder_item.rs:100:29 + | +LL | fn fn_test8(_f: fn() -> _) { } + | ^ + | | + | not allowed in type signatures + | help: use type parameters instead: `T` + +error[E0121]: the type placeholder `_` is not allowed within types on item signatures + --> $DIR/typeck_type_placeholder_item.rs:100:29 | LL | fn fn_test8(_f: fn() -> _) { } | ^ not allowed in type signatures @@ -277,7 +295,7 @@ LL | fn fn_test8(_f: fn() -> T) { } | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:121:12 + --> $DIR/typeck_type_placeholder_item.rs:123:12 | LL | a: _, | ^ not allowed in type signatures @@ -296,13 +314,13 @@ LL | b: (T, T), | error[E0282]: type annotations needed - --> $DIR/typeck_type_placeholder_item.rs:126:18 + --> $DIR/typeck_type_placeholder_item.rs:128:18 | LL | fn fn_test11(_: _) -> (_, _) { panic!() } | ^ cannot infer type error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:126:28 + --> $DIR/typeck_type_placeholder_item.rs:128:28 | LL | fn fn_test11(_: _) -> (_, _) { panic!() } | ^ ^ not allowed in type signatures @@ -310,7 +328,7 @@ LL | fn fn_test11(_: _) -> (_, _) { panic!() } | not allowed in type signatures error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:130:30 + --> $DIR/typeck_type_placeholder_item.rs:132:30 | LL | fn fn_test12(x: i32) -> (_, _) { (x, x) } | -^--^- @@ -320,7 +338,7 @@ LL | fn fn_test12(x: i32) -> (_, _) { (x, x) } | help: replace with the correct return type: `(i32, i32)` error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:133:33 + --> $DIR/typeck_type_placeholder_item.rs:135:33 | LL | fn fn_test13(x: _) -> (i32, _) { (x, x) } | ------^- @@ -329,7 +347,7 @@ LL | fn fn_test13(x: _) -> (i32, _) { (x, x) } | help: replace with the correct return type: `(i32, i32)` error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:152:21 + --> $DIR/typeck_type_placeholder_item.rs:154:21 | LL | struct BadStruct<_>(_); | ^ not allowed in type signatures @@ -340,7 +358,7 @@ LL | struct BadStruct(T); | ^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:157:15 + --> $DIR/typeck_type_placeholder_item.rs:159:15 | LL | impl BadTrait<_> for BadStruct<_> {} | ^ ^ not allowed in type signatures @@ -353,13 +371,13 @@ LL | impl BadTrait for BadStruct {} | ^^^ ^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:160:34 + --> $DIR/typeck_type_placeholder_item.rs:162:34 | LL | fn impl_trait() -> impl BadTrait<_> { | ^ not allowed in type signatures error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:165:25 + --> $DIR/typeck_type_placeholder_item.rs:167:25 | LL | struct BadStruct1<_, _>(_); | ^ not allowed in type signatures @@ -370,7 +388,7 @@ LL | struct BadStruct1(T); | ^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:170:25 + --> $DIR/typeck_type_placeholder_item.rs:172:25 | LL | struct BadStruct2<_, T>(_, T); | ^ not allowed in type signatures @@ -381,13 +399,13 @@ LL | struct BadStruct2(U, T); | ^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:174:14 + --> $DIR/typeck_type_placeholder_item.rs:176:14 | LL | type X = Box<_>; | ^ not allowed in type signatures error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:42:27 + --> $DIR/typeck_type_placeholder_item.rs:43:27 | LL | fn test10(&self, _x : _) { } | ^ not allowed in type signatures @@ -398,7 +416,7 @@ LL | fn test10(&self, _x : T) { } | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:138:31 + --> $DIR/typeck_type_placeholder_item.rs:140:31 | LL | fn method_test1(&self, x: _); | ^ not allowed in type signatures @@ -409,7 +427,7 @@ LL | fn method_test1(&self, x: T); | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:140:31 + --> $DIR/typeck_type_placeholder_item.rs:142:31 | LL | fn method_test2(&self, x: _) -> _; | ^ ^ not allowed in type signatures @@ -422,7 +440,7 @@ LL | fn method_test2(&self, x: T) -> T; | ^^^ ^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:142:31 + --> $DIR/typeck_type_placeholder_item.rs:144:31 | LL | fn method_test3(&self) -> _; | ^ not allowed in type signatures @@ -433,7 +451,7 @@ LL | fn method_test3(&self) -> T; | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:144:26 + --> $DIR/typeck_type_placeholder_item.rs:146:26 | LL | fn assoc_fn_test1(x: _); | ^ not allowed in type signatures @@ -444,7 +462,7 @@ LL | fn assoc_fn_test1(x: T); | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:146:26 + --> $DIR/typeck_type_placeholder_item.rs:148:26 | LL | fn assoc_fn_test2(x: _) -> _; | ^ ^ not allowed in type signatures @@ -457,7 +475,7 @@ LL | fn assoc_fn_test2(x: T) -> T; | ^^^ ^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:148:28 + --> $DIR/typeck_type_placeholder_item.rs:150:28 | LL | fn assoc_fn_test3() -> _; | ^ not allowed in type signatures @@ -468,7 +486,7 @@ LL | fn assoc_fn_test3() -> T; | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:60:37 + --> $DIR/typeck_type_placeholder_item.rs:61:37 | LL | fn clone_from(&mut self, other: _) { *self = Test9; } | ^ not allowed in type signatures @@ -479,7 +497,7 @@ LL | fn clone_from(&mut self, other: T) { *self = Test9; } | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:108:34 + --> $DIR/typeck_type_placeholder_item.rs:110:34 | LL | fn fn_test10(&self, _x : _) { } | ^ not allowed in type signatures @@ -490,7 +508,7 @@ LL | fn fn_test10(&self, _x : T) { } | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:116:41 + --> $DIR/typeck_type_placeholder_item.rs:118:41 | LL | fn clone_from(&mut self, other: _) { *self = FnTest9; } | ^ not allowed in type signatures @@ -501,25 +519,25 @@ LL | fn clone_from(&mut self, other: T) { *self = FnTest9; } | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:180:21 + --> $DIR/typeck_type_placeholder_item.rs:182:21 | LL | type Y = impl Trait<_>; | ^ not allowed in type signatures error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:188:14 + --> $DIR/typeck_type_placeholder_item.rs:190:14 | LL | type B = _; | ^ not allowed in type signatures error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:190:14 + --> $DIR/typeck_type_placeholder_item.rs:192:14 | LL | const C: _; | ^ not allowed in type signatures error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:192:14 + --> $DIR/typeck_type_placeholder_item.rs:194:14 | LL | const D: _ = 42; | ^ @@ -528,7 +546,7 @@ LL | const D: _ = 42; | help: replace `_` with the correct type: `i32` error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:39:24 + --> $DIR/typeck_type_placeholder_item.rs:40:24 | LL | fn test9(&self) -> _ { () } | ^ @@ -537,7 +555,7 @@ LL | fn test9(&self) -> _ { () } | help: replace with the correct return type: `()` error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:57:24 + --> $DIR/typeck_type_placeholder_item.rs:58:24 | LL | fn clone(&self) -> _ { Test9 } | ^ @@ -546,7 +564,7 @@ LL | fn clone(&self) -> _ { Test9 } | help: replace with the correct return type: `Test9` error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:105:31 + --> $DIR/typeck_type_placeholder_item.rs:107:31 | LL | fn fn_test9(&self) -> _ { () } | ^ @@ -555,7 +573,7 @@ LL | fn fn_test9(&self) -> _ { () } | help: replace with the correct return type: `()` error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:113:28 + --> $DIR/typeck_type_placeholder_item.rs:115:28 | LL | fn clone(&self) -> _ { FnTest9 } | ^ @@ -564,25 +582,25 @@ LL | fn clone(&self) -> _ { FnTest9 } | help: replace with the correct return type: `main::FnTest9` error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:197:14 + --> $DIR/typeck_type_placeholder_item.rs:199:14 | LL | type A = _; | ^ not allowed in type signatures error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:199:14 + --> $DIR/typeck_type_placeholder_item.rs:201:14 | LL | type B = _; | ^ not allowed in type signatures error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:201:14 + --> $DIR/typeck_type_placeholder_item.rs:203:14 | LL | const C: _; | ^ not allowed in type signatures error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:204:14 + --> $DIR/typeck_type_placeholder_item.rs:206:14 | LL | const D: _ = 42; | ^ @@ -590,7 +608,7 @@ LL | const D: _ = 42; | not allowed in type signatures | help: replace `_` with the correct type: `i32` -error: aborting due to 64 previous errors +error: aborting due to 66 previous errors Some errors have detailed explanations: E0121, E0282, E0403. For more information about an error, try `rustc --explain E0121`. From 5daedea3dbeb8fb2639d3d142b008135f4fd2b43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 8 Jul 2020 19:39:26 -0700 Subject: [PATCH 90/99] Detect tuple struct incorrectly used as struct pat --- Cargo.lock | 1 + src/librustc_error_codes/error_codes.rs | 1 + src/librustc_error_codes/error_codes/E0769.md | 39 ++++++++ src/librustc_typeck/Cargo.toml | 1 + src/librustc_typeck/check/pat.rs | 91 ++++++++++++++++--- .../missing-fields-in-struct-pattern.rs | 3 +- .../missing-fields-in-struct-pattern.stderr | 17 +--- src/test/ui/type/type-check/issue-41314.rs | 4 +- .../ui/type/type-check/issue-41314.stderr | 17 +--- src/test/ui/union/union-fields-2.stderr | 12 +-- 10 files changed, 137 insertions(+), 49 deletions(-) create mode 100644 src/librustc_error_codes/error_codes/E0769.md diff --git a/Cargo.lock b/Cargo.lock index 2096a3dfff9ea..61a0b5caebec6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3996,6 +3996,7 @@ dependencies = [ "rustc_data_structures", "rustc_errors", "rustc_hir", + "rustc_hir_pretty", "rustc_index", "rustc_infer", "rustc_middle", diff --git a/src/librustc_error_codes/error_codes.rs b/src/librustc_error_codes/error_codes.rs index f687221d78e03..2e1b897216bb2 100644 --- a/src/librustc_error_codes/error_codes.rs +++ b/src/librustc_error_codes/error_codes.rs @@ -450,6 +450,7 @@ E0765: include_str!("./error_codes/E0765.md"), E0766: include_str!("./error_codes/E0766.md"), E0767: include_str!("./error_codes/E0767.md"), E0768: include_str!("./error_codes/E0768.md"), +E0769: include_str!("./error_codes/E0769.md"), ; // E0006, // merged with E0005 // E0008, // cannot bind by-move into a pattern guard diff --git a/src/librustc_error_codes/error_codes/E0769.md b/src/librustc_error_codes/error_codes/E0769.md new file mode 100644 index 0000000000000..d1995be9899b1 --- /dev/null +++ b/src/librustc_error_codes/error_codes/E0769.md @@ -0,0 +1,39 @@ +A tuple struct or tuple variant was used in a pattern as if it were a +struct or struct variant. + +Erroneous code example: + +```compile_fail,E0769 +enum E { + A(i32), +} +let e = E::A(42); +match e { + E::A { number } => println!("{}", x), +} +``` + +To fix this error, you can use the tuple pattern: + +``` +# enum E { +# A(i32), +# } +# let e = E::A(42); +match e { + E::A(number) => println!("{}", number), +} +``` + +Alternatively, you can also use the struct pattern by using the correct +field names and binding them to new identifiers: + +``` +# enum E { +# A(i32), +# } +# let e = E::A(42); +match e { + E::A { 0: number } => println!("{}", number), +} +``` diff --git a/src/librustc_typeck/Cargo.toml b/src/librustc_typeck/Cargo.toml index 9329069c48dd1..93b503c976be4 100644 --- a/src/librustc_typeck/Cargo.toml +++ b/src/librustc_typeck/Cargo.toml @@ -18,6 +18,7 @@ rustc_attr = { path = "../librustc_attr" } rustc_data_structures = { path = "../librustc_data_structures" } rustc_errors = { path = "../librustc_errors" } rustc_hir = { path = "../librustc_hir" } +rustc_hir_pretty = { path = "../librustc_hir_pretty" } rustc_target = { path = "../librustc_target" } rustc_session = { path = "../librustc_session" } smallvec = { version = "1.0", features = ["union", "may_dangle"] } diff --git a/src/librustc_typeck/check/pat.rs b/src/librustc_typeck/check/pat.rs index ea47ae68ce7d3..a654fc3dfc2df 100644 --- a/src/librustc_typeck/check/pat.rs +++ b/src/librustc_typeck/check/pat.rs @@ -1082,20 +1082,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .filter(|ident| !used_fields.contains_key(&ident)) .collect::>(); - if !inexistent_fields.is_empty() && !variant.recovered { - self.error_inexistent_fields( + let inexistent_fields_err = if !inexistent_fields.is_empty() && !variant.recovered { + Some(self.error_inexistent_fields( adt.variant_descr(), &inexistent_fields, &mut unmentioned_fields, variant, - ); - } + )) + } else { + None + }; // Require `..` if struct has non_exhaustive attribute. if variant.is_field_list_non_exhaustive() && !adt.did.is_local() && !etc { self.error_foreign_non_exhaustive_spat(pat, adt.variant_descr(), fields.is_empty()); } + let mut unmentioned_err = None; // Report an error if incorrect number of the fields were specified. if adt.is_union() { if fields.len() != 1 { @@ -1107,7 +1110,25 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { tcx.sess.struct_span_err(pat.span, "`..` cannot be used in union patterns").emit(); } } else if !etc && !unmentioned_fields.is_empty() { - self.error_unmentioned_fields(pat.span, &unmentioned_fields, variant); + unmentioned_err = Some(self.error_unmentioned_fields(pat.span, &unmentioned_fields)); + } + match (inexistent_fields_err, unmentioned_err) { + (Some(mut i), Some(mut u)) => { + if let Some(mut e) = self.error_tuple_variant_as_struct_pat(pat, fields, variant) { + // We don't want to show the inexistent fields error when this was + // `Foo { a, b }` when it should have been `Foo(a, b)`. + i.delay_as_bug(); + u.delay_as_bug(); + e.emit(); + } else { + i.emit(); + u.emit(); + } + } + (None, Some(mut err)) | (Some(mut err), None) => { + err.emit(); + } + (None, None) => {} } no_field_errors } @@ -1154,7 +1175,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { inexistent_fields: &[Ident], unmentioned_fields: &mut Vec, variant: &ty::VariantDef, - ) { + ) -> DiagnosticBuilder<'tcx> { let tcx = self.tcx; let (field_names, t, plural) = if inexistent_fields.len() == 1 { (format!("a field named `{}`", inexistent_fields[0]), "this", "") @@ -1221,15 +1242,62 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { it explicitly.", ); } - err.emit(); + err + } + + fn error_tuple_variant_as_struct_pat( + &self, + pat: &Pat<'_>, + fields: &'tcx [hir::FieldPat<'tcx>], + variant: &ty::VariantDef, + ) -> Option> { + if let (CtorKind::Fn, PatKind::Struct(qpath, ..)) = (variant.ctor_kind, &pat.kind) { + let path = rustc_hir_pretty::to_string(rustc_hir_pretty::NO_ANN, |s| { + s.print_qpath(qpath, false) + }); + let mut err = struct_span_err!( + self.tcx.sess, + pat.span, + E0769, + "tuple variant `{}` written as struct variant", + path + ); + let (sugg, appl) = if fields.len() == variant.fields.len() { + ( + fields + .iter() + .map(|f| match self.tcx.sess.source_map().span_to_snippet(f.pat.span) { + Ok(f) => f, + Err(_) => rustc_hir_pretty::to_string(rustc_hir_pretty::NO_ANN, |s| { + s.print_pat(f.pat) + }), + }) + .collect::>() + .join(", "), + Applicability::MachineApplicable, + ) + } else { + ( + variant.fields.iter().map(|_| "_").collect::>().join(", "), + Applicability::MaybeIncorrect, + ) + }; + err.span_suggestion( + pat.span, + "use the tuple variant pattern syntax instead", + format!("{}({})", path, sugg), + appl, + ); + return Some(err); + } + None } fn error_unmentioned_fields( &self, span: Span, unmentioned_fields: &[Ident], - variant: &ty::VariantDef, - ) { + ) -> DiagnosticBuilder<'tcx> { let field_names = if unmentioned_fields.len() == 1 { format!("field `{}`", unmentioned_fields[0]) } else { @@ -1248,9 +1316,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { field_names ); diag.span_label(span, format!("missing {}", field_names)); - if variant.ctor_kind == CtorKind::Fn { - diag.note("trying to match a tuple variant with a struct variant pattern"); - } if self.tcx.sess.teach(&diag.get_code().unwrap()) { diag.note( "This error indicates that a pattern for a struct fails to specify a \ @@ -1259,7 +1324,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ignore unwanted fields.", ); } - diag.emit(); + diag } fn check_pat_box( diff --git a/src/test/ui/missing/missing-fields-in-struct-pattern.rs b/src/test/ui/missing/missing-fields-in-struct-pattern.rs index 24b6b55db6692..40304a674a633 100644 --- a/src/test/ui/missing/missing-fields-in-struct-pattern.rs +++ b/src/test/ui/missing/missing-fields-in-struct-pattern.rs @@ -2,8 +2,7 @@ struct S(usize, usize, usize, usize); fn main() { if let S { a, b, c, d } = S(1, 2, 3, 4) { - //~^ ERROR struct `S` does not have fields named `a`, `b`, `c`, `d` [E0026] - //~| ERROR pattern does not mention fields `0`, `1`, `2`, `3` [E0027] + //~^ ERROR tuple variant `S` written as struct variant println!("hi"); } } diff --git a/src/test/ui/missing/missing-fields-in-struct-pattern.stderr b/src/test/ui/missing/missing-fields-in-struct-pattern.stderr index f7037468996f4..6583524aad18f 100644 --- a/src/test/ui/missing/missing-fields-in-struct-pattern.stderr +++ b/src/test/ui/missing/missing-fields-in-struct-pattern.stderr @@ -1,18 +1,9 @@ -error[E0026]: struct `S` does not have fields named `a`, `b`, `c`, `d` - --> $DIR/missing-fields-in-struct-pattern.rs:4:16 - | -LL | if let S { a, b, c, d } = S(1, 2, 3, 4) { - | ^ ^ ^ ^ struct `S` does not have these fields - -error[E0027]: pattern does not mention fields `0`, `1`, `2`, `3` +error[E0769]: tuple variant `S` written as struct variant --> $DIR/missing-fields-in-struct-pattern.rs:4:12 | LL | if let S { a, b, c, d } = S(1, 2, 3, 4) { - | ^^^^^^^^^^^^^^^^ missing fields `0`, `1`, `2`, `3` - | - = note: trying to match a tuple variant with a struct variant pattern + | ^^^^^^^^^^^^^^^^ help: use the tuple variant pattern syntax instead: `S(a, b, c, d)` -error: aborting due to 2 previous errors +error: aborting due to previous error -Some errors have detailed explanations: E0026, E0027. -For more information about an error, try `rustc --explain E0026`. +For more information about this error, try `rustc --explain E0769`. diff --git a/src/test/ui/type/type-check/issue-41314.rs b/src/test/ui/type/type-check/issue-41314.rs index 856d4ff6334bc..cbd39f5f9e6ed 100644 --- a/src/test/ui/type/type-check/issue-41314.rs +++ b/src/test/ui/type/type-check/issue-41314.rs @@ -4,7 +4,7 @@ enum X { fn main() { match X::Y(0) { - X::Y { number } => {} //~ ERROR does not have a field named `number` - //~^ ERROR pattern does not mention field `0` + X::Y { number } => {} + //~^ ERROR tuple variant `X::Y` written as struct variant } } diff --git a/src/test/ui/type/type-check/issue-41314.stderr b/src/test/ui/type/type-check/issue-41314.stderr index c2bba98d10a83..bd4d2071c2059 100644 --- a/src/test/ui/type/type-check/issue-41314.stderr +++ b/src/test/ui/type/type-check/issue-41314.stderr @@ -1,18 +1,9 @@ -error[E0026]: variant `X::Y` does not have a field named `number` - --> $DIR/issue-41314.rs:7:16 - | -LL | X::Y { number } => {} - | ^^^^^^ variant `X::Y` does not have this field - -error[E0027]: pattern does not mention field `0` +error[E0769]: tuple variant `X::Y` written as struct variant --> $DIR/issue-41314.rs:7:9 | LL | X::Y { number } => {} - | ^^^^^^^^^^^^^^^ missing field `0` - | - = note: trying to match a tuple variant with a struct variant pattern + | ^^^^^^^^^^^^^^^ help: use the tuple variant pattern syntax instead: `X::Y(number)` -error: aborting due to 2 previous errors +error: aborting due to previous error -Some errors have detailed explanations: E0026, E0027. -For more information about an error, try `rustc --explain E0026`. +For more information about this error, try `rustc --explain E0769`. diff --git a/src/test/ui/union/union-fields-2.stderr b/src/test/ui/union/union-fields-2.stderr index 68cb66d89d218..48654347285d3 100644 --- a/src/test/ui/union/union-fields-2.stderr +++ b/src/test/ui/union/union-fields-2.stderr @@ -48,18 +48,18 @@ error: union patterns should have exactly one field LL | let U { a, b } = u; | ^^^^^^^^^^ -error[E0026]: union `U` does not have a field named `c` - --> $DIR/union-fields-2.rs:18:19 - | -LL | let U { a, b, c } = u; - | ^ union `U` does not have this field - error: union patterns should have exactly one field --> $DIR/union-fields-2.rs:18:9 | LL | let U { a, b, c } = u; | ^^^^^^^^^^^^^ +error[E0026]: union `U` does not have a field named `c` + --> $DIR/union-fields-2.rs:18:19 + | +LL | let U { a, b, c } = u; + | ^ union `U` does not have this field + error: union patterns should have exactly one field --> $DIR/union-fields-2.rs:20:9 | From 0e89f50f6e937349233db1c52af2b33c683782e6 Mon Sep 17 00:00:00 2001 From: Jarek Samic Date: Sun, 12 Jul 2020 14:37:22 -0400 Subject: [PATCH 91/99] Clean up handling of style files in rustdoc Disable all themes other than `light.css` to prevent rule conflicts --- src/librustdoc/config.rs | 5 +- src/librustdoc/html/layout.rs | 25 +++++----- src/librustdoc/html/render.rs | 87 ++++++++++++++++++++++------------ src/librustdoc/html/sources.rs | 2 +- 4 files changed, 76 insertions(+), 43 deletions(-) diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs index 14a6f3c89a3c9..39e33da44964e 100644 --- a/src/librustdoc/config.rs +++ b/src/librustdoc/config.rs @@ -20,6 +20,7 @@ use crate::core::new_handler; use crate::externalfiles::ExternalHtml; use crate::html; use crate::html::markdown::IdMap; +use crate::html::render::StylePath; use crate::html::static_files; use crate::opts; use crate::passes::{self, Condition, DefaultPassOption}; @@ -207,7 +208,7 @@ pub struct RenderOptions { pub sort_modules_alphabetically: bool, /// List of themes to extend the docs with. Original argument name is included to assist in /// displaying errors if it fails a theme check. - pub themes: Vec, + pub themes: Vec, /// If present, CSS file that contains rules to add to the default CSS. pub extension_css: Option, /// A map of crate names to the URL to use instead of querying the crate's `html_root_url`. @@ -410,7 +411,7 @@ impl Options { )) .emit(); } - themes.push(theme_file); + themes.push(StylePath { path: theme_file, disabled: true }); } } diff --git a/src/librustdoc/html/layout.rs b/src/librustdoc/html/layout.rs index ea65b3905272e..cc6b38ebcdb7f 100644 --- a/src/librustdoc/html/layout.rs +++ b/src/librustdoc/html/layout.rs @@ -3,7 +3,7 @@ use std::path::PathBuf; use crate::externalfiles::ExternalHtml; use crate::html::escape::Escape; use crate::html::format::{Buffer, Print}; -use crate::html::render::ensure_trailing_slash; +use crate::html::render::{ensure_trailing_slash, StylePath}; #[derive(Clone)] pub struct Layout { @@ -36,7 +36,7 @@ pub fn render( page: &Page<'_>, sidebar: S, t: T, - themes: &[PathBuf], + style_files: &[StylePath], ) -> String { let static_root_path = page.static_root_path.unwrap_or(page.root_path); format!( @@ -52,10 +52,7 @@ pub fn render( \ \ - {themes}\ - \ - \ + {style_files}\ \ \ {css_extension}\ @@ -172,13 +169,19 @@ pub fn render( after_content = layout.external_html.after_content, sidebar = Buffer::html().to_display(sidebar), krate = layout.krate, - themes = themes + style_files = style_files .iter() - .filter_map(|t| t.file_stem()) - .filter_map(|t| t.to_str()) + .filter_map(|t| { + if let Some(stem) = t.path.file_stem() { Some((stem, t.disabled)) } else { None } + }) + .filter_map(|t| { + if let Some(path) = t.0.to_str() { Some((path, t.1)) } else { None } + }) .map(|t| format!( - r#""#, - Escape(&format!("{}{}{}", static_root_path, t, page.resource_suffix)) + r#""#, + Escape(&format!("{}{}{}", static_root_path, t.0, page.resource_suffix)), + if t.1 { "disabled" } else { "" }, + if t.0 == "light" { "id=\"themeStyle\"" } else { "" } )) .collect::(), suffix = page.resource_suffix, diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 8bba21a2e7ace..be14e686cf146 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -187,8 +187,8 @@ crate struct SharedContext { /// This flag indicates whether listings of modules (in the side bar and documentation itself) /// should be ordered alphabetically or in order of appearance (in the source code). pub sort_modules_alphabetically: bool, - /// Additional themes to be added to the generated docs. - pub themes: Vec, + /// Additional CSS files to be added to the generated docs. + pub style_files: Vec, /// Suffix to be added on resource files (if suffix is "-v2" then "light.css" becomes /// "light-v2.css"). pub resource_suffix: String, @@ -417,6 +417,14 @@ impl Serialize for TypeWithKind { } } +#[derive(Debug, Clone)] +pub struct StylePath { + /// The path to the theme + pub path: PathBuf, + /// What the `disabled` attribute should be set to in the HTML tag + pub disabled: bool, +} + thread_local!(static CACHE_KEY: RefCell> = Default::default()); thread_local!(pub static CURRENT_DEPTH: Cell = Cell::new(0)); @@ -460,7 +468,7 @@ pub fn run( id_map, playground_url, sort_modules_alphabetically, - themes, + themes: style_files, extension_css, extern_html_root_urls, resource_suffix, @@ -530,7 +538,7 @@ pub fn run( layout, created_dirs: Default::default(), sort_modules_alphabetically, - themes, + style_files, resource_suffix, static_root_path, fs: DocFS::new(&errors), @@ -539,6 +547,18 @@ pub fn run( playground, }; + // Add the default themes to the `Vec` of stylepaths + // + // Note that these must be added before `sources::render` is called + // so that the resulting source pages are styled + // + // `light.css` is not disabled because it is the stylesheet that stays loaded + // by the browser as the theme stylesheet. The theme system (hackily) works by + // changing the href to this stylesheet. All other themes are disabled to + // prevent rule conflicts + scx.style_files.push(StylePath { path: PathBuf::from("light.css"), disabled: false }); + scx.style_files.push(StylePath { path: PathBuf::from("dark.css"), disabled: true }); + let dst = output; scx.ensure_dir(&dst)?; krate = sources::render(&dst, &mut scx, krate)?; @@ -615,11 +635,34 @@ fn write_shared( // then we'll run over the "official" styles. let mut themes: FxHashSet = FxHashSet::default(); - for entry in &cx.shared.themes { - let content = try_err!(fs::read(&entry), &entry); - let theme = try_none!(try_none!(entry.file_stem(), &entry).to_str(), &entry); - let extension = try_none!(try_none!(entry.extension(), &entry).to_str(), &entry); - cx.shared.fs.write(cx.path(&format!("{}.{}", theme, extension)), content.as_slice())?; + for entry in &cx.shared.style_files { + let theme = try_none!(try_none!(entry.path.file_stem(), &entry.path).to_str(), &entry.path); + let extension = + try_none!(try_none!(entry.path.extension(), &entry.path).to_str(), &entry.path); + + // Handle the official themes + match theme { + "light" => write_minify( + &cx.shared.fs, + cx.path("light.css"), + static_files::themes::LIGHT, + options.enable_minification, + )?, + "dark" => write_minify( + &cx.shared.fs, + cx.path("dark.css"), + static_files::themes::DARK, + options.enable_minification, + )?, + _ => { + // Handle added third-party themes + let content = try_err!(fs::read(&entry.path), &entry.path); + cx.shared + .fs + .write(cx.path(&format!("{}.{}", theme, extension)), content.as_slice())?; + } + }; + themes.insert(theme.to_owned()); } @@ -633,20 +676,6 @@ fn write_shared( write(cx.path("brush.svg"), static_files::BRUSH_SVG)?; write(cx.path("wheel.svg"), static_files::WHEEL_SVG)?; write(cx.path("down-arrow.svg"), static_files::DOWN_ARROW_SVG)?; - write_minify( - &cx.shared.fs, - cx.path("light.css"), - static_files::themes::LIGHT, - options.enable_minification, - )?; - themes.insert("light".to_owned()); - write_minify( - &cx.shared.fs, - cx.path("dark.css"), - static_files::themes::DARK, - options.enable_minification, - )?; - themes.insert("dark".to_owned()); let mut themes: Vec<&String> = themes.iter().collect(); themes.sort(); @@ -957,7 +986,7 @@ themePicker.onblur = handleThemeButtonsBlur; }) .collect::() ); - let v = layout::render(&cx.shared.layout, &page, "", content, &cx.shared.themes); + let v = layout::render(&cx.shared.layout, &page, "", content, &cx.shared.style_files); cx.shared.fs.write(&dst, v.as_bytes())?; } } @@ -1375,7 +1404,7 @@ impl Context { &page, sidebar, |buf: &mut Buffer| all.print(buf), - &self.shared.themes, + &self.shared.style_files, ); self.shared.fs.write(&final_file, v.as_bytes())?; @@ -1384,9 +1413,9 @@ impl Context { page.description = "Settings of Rustdoc"; page.root_path = "./"; - let mut themes = self.shared.themes.clone(); + let mut style_files = self.shared.style_files.clone(); let sidebar = "

Settings

"; - themes.push(PathBuf::from("settings.css")); + style_files.push(StylePath { path: PathBuf::from("settings.css"), disabled: false }); let v = layout::render( &self.shared.layout, &page, @@ -1395,7 +1424,7 @@ impl Context { self.shared.static_root_path.as_deref().unwrap_or("./"), &self.shared.resource_suffix, ), - &themes, + &style_files, ); self.shared.fs.write(&settings_file, v.as_bytes())?; @@ -1457,7 +1486,7 @@ impl Context { &page, |buf: &mut _| print_sidebar(self, it, buf), |buf: &mut _| print_item(self, it, buf), - &self.shared.themes, + &self.shared.style_files, ) } else { let mut url = self.root_path(); diff --git a/src/librustdoc/html/sources.rs b/src/librustdoc/html/sources.rs index f0900c34a4ba3..03f79b931868b 100644 --- a/src/librustdoc/html/sources.rs +++ b/src/librustdoc/html/sources.rs @@ -123,7 +123,7 @@ impl<'a> SourceCollector<'a> { &page, "", |buf: &mut _| print_src(buf, &contents), - &self.scx.themes, + &self.scx.style_files, ); self.scx.fs.write(&cur, v.as_bytes())?; self.scx.local_sources.insert(p, href); From 8c45cf8e60960698262363cf15aa650437f49a56 Mon Sep 17 00:00:00 2001 From: Jarek Samic Date: Sun, 12 Jul 2020 14:48:13 -0400 Subject: [PATCH 92/99] Add Ayu theme to rustdoc --- src/librustdoc/html/render.rs | 7 + src/librustdoc/html/static/themes/ayu.css | 561 ++++++++++++++++++++++ src/librustdoc/html/static_files.rs | 3 + 3 files changed, 571 insertions(+) create mode 100644 src/librustdoc/html/static/themes/ayu.css diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index be14e686cf146..456eb9fcbc41a 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -558,6 +558,7 @@ pub fn run( // prevent rule conflicts scx.style_files.push(StylePath { path: PathBuf::from("light.css"), disabled: false }); scx.style_files.push(StylePath { path: PathBuf::from("dark.css"), disabled: true }); + scx.style_files.push(StylePath { path: PathBuf::from("ayu.css"), disabled: true }); let dst = output; scx.ensure_dir(&dst)?; @@ -654,6 +655,12 @@ fn write_shared( static_files::themes::DARK, options.enable_minification, )?, + "ayu" => write_minify( + &cx.shared.fs, + cx.path("ayu.css"), + static_files::themes::AYU, + options.enable_minification, + )?, _ => { // Handle added third-party themes let content = try_err!(fs::read(&entry.path), &entry.path); diff --git a/src/librustdoc/html/static/themes/ayu.css b/src/librustdoc/html/static/themes/ayu.css new file mode 100644 index 0000000000000..bc21c28750fd8 --- /dev/null +++ b/src/librustdoc/html/static/themes/ayu.css @@ -0,0 +1,561 @@ +/* +Based off of the Ayu theme +Original by Dempfi (https://github.com/dempfi/ayu) +*/ + +/* General structure and fonts */ + +body { + background-color: #0f1419; + color: #c5c5c5; +} + +h1, h2, h3:not(.impl):not(.method):not(.type):not(.tymethod), h4:not(.method):not(.type):not(.tymethod) { + color: white; +} +h1.fqn { + border-bottom-color: #5c6773; +} +h1.fqn a { + color: #fff; +} +h2, h3:not(.impl):not(.method):not(.type):not(.tymethod) { + border-bottom-color: #5c6773; +} +h4:not(.method):not(.type):not(.tymethod):not(.associatedconstant) { + border: none; +} + +.in-band { + background-color: #0f1419; +} + +.invisible { + background: rgba(0, 0, 0, 0); +} + +code { + color: #ffb454; +} +h3 > code, h4 > code, h5 > code { + color: #e6e1cf; +} +pre > code { + color: #e6e1cf; +} +span code { + color: #e6e1cf; +} +.docblock a > code { + color: #39AFD7 !important; +} +.docblock code, .docblock-short code { + background-color: #191f26; +} +pre { + color: #e6e1cf; + background-color: #191f26; +} + +.sidebar { + background-color: #14191f; +} + +/* Improve the scrollbar display on firefox */ +* { + scrollbar-color: #5c6773 transparent; +} + +.sidebar { + scrollbar-color: #5c6773 transparent; +} + +/* Improve the scrollbar display on webkit-based browsers */ +::-webkit-scrollbar-track { + background-color: transparent; +} +::-webkit-scrollbar-thumb { + background-color: #5c6773; +} +.sidebar::-webkit-scrollbar-track { + background-color: transparent; +} +.sidebar::-webkit-scrollbar-thumb { + background-color: #5c6773; +} + +.sidebar .current { + background-color: transparent; + color: #ffb44c; +} + +.source .sidebar { + background-color: #0f1419; +} + +.sidebar .location { + border-color: #000; + background-color: #0f1419; + color: #fff; +} + +.sidebar-elems .location { + color: #ff7733; +} + +.sidebar-elems .location a { + color: #fff; +} + +.sidebar .version { + border-bottom-color: #DDD; +} + +.sidebar-title { + border-top-color: #5c6773; + border-bottom-color: #5c6773; +} + +.block a:hover { + background: transparent; + color: #ffb44c; +} + +.line-numbers span { color: #5c6773ab; } +.line-numbers .line-highlighted { + background-color: rgba(255, 236, 164, 0.06) !important; + padding-right: 4px; + border-right: 1px solid #ffb44c; +} + +.docblock h1, .docblock h2, .docblock h3, .docblock h4, .docblock h5 { + border-bottom-color: #5c6773; +} + +.docblock table, .docblock table td, .docblock table th { + border-color: #5c6773; +} + +.content .method .where, +.content .fn .where, +.content .where.fmt-newline { + color: #c5c5c5; +} + +.content .highlighted { + color: #000 !important; + background-color: #c6afb3; +} +.content .highlighted a, .content .highlighted span { color: #000 !important; } +.content .highlighted { + background-color: #c6afb3; +} +.search-results a { + color: #0096cf; +} +.search-results a span.desc { + color: #c5c5c5; +} + +.content .stability::before { color: #ccc; } + +.content span.foreigntype, .content a.foreigntype { color: #ef57ff; } +.content span.union, .content a.union { color: #98a01c; } +.content span.constant, .content a.constant, +.content span.static, .content a.static { color: #6380a0; } +.content span.primitive, .content a.primitive { color: #32889b; } +.content span.traitalias, .content a.traitalias { color: #57d399; } +.content span.keyword, .content a.keyword { color: #de5249; } + +.content span.externcrate, .content span.mod, .content a.mod { + color: #acccf9; +} +.content span.struct, .content a.struct { + color: #ffa0a5; +} +.content span.enum, .content a.enum { + color: #99e0c9; +} +.content span.trait, .content a.trait { + color: #39AFD7; +} +.content span.type, .content a.type { + color: #cfbcf5; +} +.content span.fn, .content a.fn, .content span.method, +.content a.method, .content span.tymethod, +.content a.tymethod, .content .fnname { + color: #fdd687; +} +.content span.attr, .content a.attr, .content span.derive, +.content a.derive, .content span.macro, .content a.macro { + color: #a37acc; +} + +pre.rust .comment, pre.rust .doccomment { + color: #788797; + font-style: italic; +} + +nav:not(.sidebar) { + border-bottom-color: #e0e0e0; +} +nav.main .current { + border-top-color: #5c6773; + border-bottom-color: #5c6773; +} +nav.main .separator { + border: 1px solid #5c6773; +} +a { + color: #c5c5c5; +} + +.docblock:not(.type-decl) a:not(.srclink):not(.test-arrow), +.docblock-short a:not(.srclink):not(.test-arrow), .stability a { + color: #39AFD7; +} + +.stab.internal a { + color: #304FFE; +} + +.collapse-toggle { + color: #999; +} + +#crate-search { + color: #c5c5c5; + background-color: #141920; + border-radius: 4px; + box-shadow: none; + border-color: #5c6773; +} + +.search-input { + color: #ffffff; + background-color: #141920; + box-shadow: none; + transition: box-shadow 150ms ease-in-out; + border-radius: 4px; + margin-left: 8px; +} + +#crate-search+.search-input:focus { + box-shadow: 0px 6px 20px 0px black; +} + +.search-focus:disabled { + color: #929292; +} + +.module-item .stab { + color: #000; +} + +.stab.unstable, +.stab.internal, +.stab.deprecated, +.stab.portability { + color: #c5c5c5; + background: #314559 !important; + border-style: none !important; + border-radius: 4px; + padding: 3px 6px 3px 6px; +} + +.stab.portability > code { + color: #e6e1cf; + background-color: transparent; +} + +#help > div { + background: #14191f; + box-shadow: 0px 6px 20px 0px black; + border: none; + border-radius: 4px; +} + +.since { + color: grey; +} + +tr.result span.primitive::after, tr.result span.keyword::after { + color: #788797; +} + +.line-numbers :target { background-color: transparent; } + +/* Code highlighting */ +pre.rust .number, pre.rust .string { color: #b8cc52; } +pre.rust .kw, pre.rust .kw-2, pre.rust .prelude-ty, +pre.rust .bool-val, pre.rust .prelude-val, +pre.rust .op, pre.rust .lifetime { color: #ff7733; } +pre.rust .macro, pre.rust .macro-nonterminal { color: #a37acc; } +pre.rust .question-mark { + color: #ff9011; +} +pre.rust .self { + color: #36a3d9; + font-style: italic; +} +pre.rust .attribute { + color: #e6e1cf; +} +pre.rust .attribute .ident, pre.rust .attribute .op { + color: #e6e1cf; +} + +.example-wrap > pre.line-number { + color: #5c67736e; + border: none; +} + +a.test-arrow { + font-size: 100%; + color: #788797; + border-radius: 4px; + background-color: rgba(255, 255, 255, 0); +} + +a.test-arrow:hover { + background-color: rgba(242, 151, 24, 0.05); + color: #ffb44c; +} + +.toggle-label { + color: #999; +} + +:target > code, :target > .in-band { + background: rgba(255, 236, 164, 0.06); + border-right: 3px solid #ffb44c; +} + +pre.compile_fail { + border-left: 2px solid rgba(255,0,0,.4); +} + +pre.compile_fail:hover, .information:hover + pre.compile_fail { + border-left: 2px solid #f00; +} + +pre.should_panic { + border-left: 2px solid rgba(255,0,0,.4); +} + +pre.should_panic:hover, .information:hover + pre.should_panic { + border-left: 2px solid #f00; +} + +pre.ignore { + border-left: 2px solid rgba(255,142,0,.6); +} + +pre.ignore:hover, .information:hover + pre.ignore { + border-left: 2px solid #ff9200; +} + +.tooltip.compile_fail { + color: rgba(255,0,0,.5); +} + +.information > .compile_fail:hover { + color: #f00; +} + +.tooltip.should_panic { + color: rgba(255,0,0,.5); +} + +.information > .should_panic:hover { + color: #f00; +} + +.tooltip.ignore { + color: rgba(255,142,0,.6); +} + +.information > .ignore:hover { + color: #ff9200; +} + +.search-failed a { + color: #39AFD7; +} + +.tooltip .tooltiptext { + background-color: #314559; + color: #c5c5c5; + border: 1px solid #5c6773; +} + +.tooltip .tooltiptext::after { + border-color: transparent #314559 transparent transparent; +} + +#titles > div.selected { + background-color: #141920 !important; + border-bottom: 1px solid #ffb44c !important; + border-top: none; +} + +#titles > div:not(.selected) { + background-color: transparent !important; + border: none; +} + +#titles > div:hover { + border-bottom: 1px solid rgba(242, 151, 24, 0.3); +} + +#titles > div > div.count { + color: #888; +} + +/* rules that this theme does not need to set, here to satisfy the rule checker */ +/* note that a lot of these are partially set in some way (meaning they are set +individually rather than as a group) */ +/* TODO: these rules should be at the bottom of the file but currently must be +above the `@media (max-width: 700px)` rules due to a bug in the css checker */ +/* see https://github.com/rust-lang/rust/pull/71237#issuecomment-618170143 */ +.content .highlighted.mod, .content .highlighted.externcrate {} +.search-input:focus {} +.content span.attr,.content a.attr,.block a.current.attr,.content span.derive,.content a.derive,.block a.current.derive,.content span.macro,.content a.macro,.block a.current.macro {} +.content .highlighted.trait {} +.content span.struct,.content a.struct,.block a.current.struct {} +#titles>div:hover,#titles>div.selected {} +.content .highlighted.traitalias {} +.content span.type,.content a.type,.block a.current.type {} +.content span.union,.content a.union,.block a.current.union {} +.content .highlighted.foreigntype {} +pre.rust .lifetime {} +.content .highlighted.primitive {} +.content .highlighted.constant,.content .highlighted.static {} +.stab.unstable {} +.content .highlighted.fn,.content .highlighted.method,.content .highlighted.tymethod {} +h2,h3:not(.impl):not(.method):not(.type):not(.tymethod),h4:not(.method):not(.type):not(.tymethod) {} +.content span.enum,.content a.enum,.block a.current.enum {} +.content span.constant,.content a.constant,.block a.current.constant,.content span.static,.content a.static,.block a.current.static {} +.content span.keyword,.content a.keyword,.block a.current.keyword {} +pre.rust .comment {} +.content .highlighted.enum {} +.content .highlighted.struct {} +.content .highlighted.keyword {} +.content span.traitalias,.content a.traitalias,.block a.current.traitalias {} +.content span.fn,.content a.fn,.block a.current.fn,.content span.method,.content a.method,.block a.current.method,.content span.tymethod,.content a.tymethod,.block a.current.tymethod,.content .fnname {} +pre.rust .kw {} +pre.rust .self,pre.rust .bool-val,pre.rust .prelude-val,pre.rust .attribute,pre.rust .attribute .ident {} +.content span.foreigntype,.content a.foreigntype,.block a.current.foreigntype {} +pre.rust .doccomment {} +.stab.deprecated {} +.content .highlighted.attr,.content .highlighted.derive,.content .highlighted.macro {} +.stab.portability {} +.content .highlighted.union {} +.content span.primitive,.content a.primitive,.block a.current.primitive {} +.content span.externcrate,.content span.mod,.content a.mod,.block a.current.mod {} +.content .highlighted.type {} +pre.rust .kw-2,pre.rust .prelude-ty {} +.content span.trait,.content a.trait,.block a.current.trait {} +.stab.internal {} + +@media (max-width: 700px) { + .sidebar-menu { + background-color: #14191f; + border-bottom-color: #5c6773; + border-right-color: #5c6773; + } + + .sidebar-elems { + background-color: #14191f; + border-right-color: #5c6773; + } + + #sidebar-filler { + background-color: #14191f; + border-bottom-color: #5c6773; + } +} + +kbd { + color: #c5c5c5; + background-color: #314559; + border-color: #5c6773; + border-bottom-color: #5c6773; + box-shadow-color: #c6cbd1; +} + +#theme-picker, #settings-menu { + border-color: #5c6773; + background-color: #0f1419; +} + +#theme-picker > img, #settings-menu > img { + filter: invert(100); +} + +#theme-picker:hover, #theme-picker:focus, +#settings-menu:hover, #settings-menu:focus { + border-color: #e0e0e0; +} + +#theme-choices { + border-color: #5c6773; + background-color: #0f1419; +} + +#theme-choices > button:not(:first-child) { + border-top-color: #c5c5c5; +} + +#theme-choices > button:hover, #theme-choices > button:focus { + background-color: rgba(70, 70, 70, 0.33); +} + +@media (max-width: 700px) { + #theme-picker { + background: #0f1419; + } +} + +#all-types { + background-color: #14191f; +} +#all-types:hover { + background-color: rgba(70, 70, 70, 0.33); +} + +.search-results td span.alias { + color: #c5c5c5; +} +.search-results td span.grey { + color: #999; +} + +#sidebar-toggle { + background-color: #14191f; +} +#sidebar-toggle:hover { + background-color: rgba(70, 70, 70, 0.33); +} +#source-sidebar { + background-color: #14191f; +} +#source-sidebar > .title { + color: #fff; + border-bottom-color: #5c6773; +} +div.files > a:hover, div.name:hover { + background-color: #14191f; + color: #ffb44c; +} +div.files > .selected { + background-color: #14191f; + color: #ffb44c; +} +.setting-line > .title { + border-bottom-color: #5c6773; +} +input:checked + .slider { + background-color: #ffb454 !important; +} diff --git a/src/librustdoc/html/static_files.rs b/src/librustdoc/html/static_files.rs index 6790f3bd5d0b1..6bd7e53cdfbe2 100644 --- a/src/librustdoc/html/static_files.rs +++ b/src/librustdoc/html/static_files.rs @@ -64,6 +64,9 @@ pub mod themes { /// The "dark" theme. pub static DARK: &str = include_str!("static/themes/dark.css"); + + /// The "ayu" theme. + pub static AYU: &str = include_str!("static/themes/ayu.css"); } /// Files related to the Fira Sans font. From ed587f83cf721c8ad7d51ba76178e91d732e01c5 Mon Sep 17 00:00:00 2001 From: Adrian Cruceru Date: Sat, 11 Jul 2020 11:33:43 +0000 Subject: [PATCH 93/99] Update llvm-project to latest origin/rustc/10.0-2020-05-05 commit which includes LVI segfault fix --- src/llvm-project | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/llvm-project b/src/llvm-project index d134a53927fa0..86b120e6f302d 160000 --- a/src/llvm-project +++ b/src/llvm-project @@ -1 +1 @@ -Subproject commit d134a53927fa033ae7e0f3e8ee872ff2dc71468d +Subproject commit 86b120e6f302d39cd6973b6391fb299d7bc22122 From f2419b9d6299fb07a1163b47dc273f64e0444a6c Mon Sep 17 00:00:00 2001 From: Takayuki Nakata Date: Tue, 14 Jul 2020 00:11:10 +0900 Subject: [PATCH 94/99] Refactoring to use `constant_context Use `constant_context`, `.is_str()` and `builtin_index()` to simplify. --- clippy_lints/src/repeat_once.rs | 54 +++------------------------------ 1 file changed, 5 insertions(+), 49 deletions(-) diff --git a/clippy_lints/src/repeat_once.rs b/clippy_lints/src/repeat_once.rs index 436374d7c5458..3a0b3b1c2571b 100644 --- a/clippy_lints/src/repeat_once.rs +++ b/clippy_lints/src/repeat_once.rs @@ -1,12 +1,9 @@ -use crate::consts::{miri_to_const, Constant}; +use crate::consts::{constant_context, Constant}; use crate::utils::{in_macro, is_type_diagnostic_item, snippet, span_lint_and_sugg, walk_ptrs_ty}; use if_chain::if_chain; -use rustc_ast::ast::LitKind; use rustc_errors::Applicability; -use rustc_hir::def::{DefKind, Res}; use rustc_hir::{Expr, ExprKind}; use rustc_lint::{LateContext, LateLintPass}; -use rustc_middle::ty::{self, Ty}; use rustc_session::{declare_lint_pass, declare_tool_lint}; declare_clippy_lint! { @@ -44,10 +41,11 @@ impl<'tcx> LateLintPass<'tcx> for RepeatOnce { if_chain! { if let ExprKind::MethodCall(ref path, _, ref args, _) = expr.kind; if path.ident.name == sym!(repeat); - if is_once(cx, &args[1]) && !in_macro(args[0].span); + if let Some(Constant::Int(1)) = constant_context(cx, cx.tables()).expr(&args[1]); + if !in_macro(args[0].span); then { let ty = walk_ptrs_ty(cx.tables().expr_ty(&args[0])); - if is_str(ty){ + if ty.is_str() { span_lint_and_sugg( cx, REPEAT_ONCE, @@ -57,7 +55,7 @@ impl<'tcx> LateLintPass<'tcx> for RepeatOnce { format!("{}.to_string()", snippet(cx, args[0].span, r#""...""#)), Applicability::MachineApplicable, ); - } else if is_slice(ty) { + } else if let Some(_) = ty.builtin_index() { span_lint_and_sugg( cx, REPEAT_ONCE, @@ -82,45 +80,3 @@ impl<'tcx> LateLintPass<'tcx> for RepeatOnce { } } } - -fn is_once<'tcx>(cx: &LateContext<'_>, expr: &'tcx Expr<'_>) -> bool { - match expr.kind { - ExprKind::Lit(ref lit) => { - if let LitKind::Int(ref lit_content, _) = lit.node { - *lit_content == 1 - } else { - false - } - }, - ExprKind::Path(rustc_hir::QPath::Resolved(None, path)) => { - if let Res::Def(DefKind::Const, def_id) = path.res { - let ty = cx.tcx.type_of(def_id); - let con = cx - .tcx - .const_eval_poly(def_id) - .ok() - .map(|val| rustc_middle::ty::Const::from_value(cx.tcx, val, ty)) - .unwrap(); - let con = miri_to_const(con); - con == Some(Constant::Int(1)) - } else { - false - } - }, - _ => false, - } -} - -fn is_str(ty: Ty<'_>) -> bool { - match ty.kind { - ty::Str => true, - _ => false, - } -} - -fn is_slice(ty: Ty<'_>) -> bool { - match ty.kind { - ty::Slice(..) | ty::Array(..) => true, - _ => false, - } -} From d27e7d04a15e29b093fcad97900269f408879c46 Mon Sep 17 00:00:00 2001 From: Lynoure Braakman Date: Mon, 13 Jul 2020 17:41:27 +0200 Subject: [PATCH 95/99] Clarify the description for rfind Changes the example code to illustrate the difference between find and rfind --- src/libcore/str/mod.rs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index 0014501d2c4d0..fdcd56b9dffc0 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -3158,11 +3158,11 @@ impl str { /// Simple patterns: /// /// ``` - /// let s = "Löwe 老虎 LĂ©opard"; + /// let s = "Löwe 老虎 LĂ©opard Gepardi"; /// /// assert_eq!(s.find('L'), Some(0)); /// assert_eq!(s.find('Ă©'), Some(14)); - /// assert_eq!(s.find("LĂ©opard"), Some(13)); + /// assert_eq!(s.find("pard"), Some(17)); /// ``` /// /// More complex patterns using point-free style and closures: @@ -3190,8 +3190,8 @@ impl str { pat.into_searcher(self).next_match().map(|(i, _)| i) } - /// Returns the byte index of the last character of this string slice that - /// matches the pattern. + /// Returns the byte index for the first character of the rightmost match of the pattern in + /// this string slice. /// /// Returns [`None`] if the pattern doesn't match. /// @@ -3207,10 +3207,11 @@ impl str { /// Simple patterns: /// /// ``` - /// let s = "Löwe 老虎 LĂ©opard"; + /// let s = "Löwe 老虎 LĂ©opard Gepardi"; /// /// assert_eq!(s.rfind('L'), Some(13)); /// assert_eq!(s.rfind('Ă©'), Some(14)); + /// assert_eq!(s.rfind("pard"), Some(24)); /// ``` /// /// More complex patterns with closures: From ff796b6d7082d5b5c073797aba17f454eebe3359 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Fri, 19 Jun 2020 11:44:03 +0200 Subject: [PATCH 96/99] Rename collapsable_if fix suggestion to "collapse nested if block" The name "try" is confusing when shown as quick fix by rust-analyzer --- clippy_lints/src/collapsible_if.rs | 4 ++-- tests/ui/collapsible_else_if.stderr | 14 +++++++------- tests/ui/collapsible_if.stderr | 14 +++++++------- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/clippy_lints/src/collapsible_if.rs b/clippy_lints/src/collapsible_if.rs index 8090f4673aae0..42bff564de03d 100644 --- a/clippy_lints/src/collapsible_if.rs +++ b/clippy_lints/src/collapsible_if.rs @@ -115,7 +115,7 @@ fn check_collapsible_maybe_if_let(cx: &EarlyContext<'_>, else_: &ast::Expr) { COLLAPSIBLE_IF, block.span, "this `else { if .. }` block can be collapsed", - "try", + "collapse nested if block", snippet_block_with_applicability(cx, else_.span, "..", Some(block.span), &mut applicability).into_owned(), applicability, ); @@ -142,7 +142,7 @@ fn check_collapsible_no_if_let(cx: &EarlyContext<'_>, expr: &ast::Expr, check: & let rhs = Sugg::ast(cx, check_inner, ".."); diag.span_suggestion( expr.span, - "try", + "collapse nested if block", format!( "if {} {}", lhs.and(&rhs), diff --git a/tests/ui/collapsible_else_if.stderr b/tests/ui/collapsible_else_if.stderr index 28048999e8ec9..3d1c458879e58 100644 --- a/tests/ui/collapsible_else_if.stderr +++ b/tests/ui/collapsible_else_if.stderr @@ -10,7 +10,7 @@ LL | | } | |_____^ | = note: `-D clippy::collapsible-if` implied by `-D warnings` -help: try +help: collapse nested if block | LL | } else if y == "world" { LL | println!("world!") @@ -28,7 +28,7 @@ LL | | } LL | | } | |_____^ | -help: try +help: collapse nested if block | LL | } else if let Some(42) = Some(42) { LL | println!("world!") @@ -48,7 +48,7 @@ LL | | } LL | | } | |_____^ | -help: try +help: collapse nested if block | LL | } else if y == "world" { LL | println!("world") @@ -71,7 +71,7 @@ LL | | } LL | | } | |_____^ | -help: try +help: collapse nested if block | LL | } else if let Some(42) = Some(42) { LL | println!("world") @@ -94,7 +94,7 @@ LL | | } LL | | } | |_____^ | -help: try +help: collapse nested if block | LL | } else if let Some(42) = Some(42) { LL | println!("world") @@ -117,7 +117,7 @@ LL | | } LL | | } | |_____^ | -help: try +help: collapse nested if block | LL | } else if x == "hello" { LL | println!("world") @@ -140,7 +140,7 @@ LL | | } LL | | } | |_____^ | -help: try +help: collapse nested if block | LL | } else if let Some(42) = Some(42) { LL | println!("world") diff --git a/tests/ui/collapsible_if.stderr b/tests/ui/collapsible_if.stderr index 6440ff41be81e..f56dd65b9dd26 100644 --- a/tests/ui/collapsible_if.stderr +++ b/tests/ui/collapsible_if.stderr @@ -9,7 +9,7 @@ LL | | } | |_____^ | = note: `-D clippy::collapsible-if` implied by `-D warnings` -help: try +help: collapse nested if block | LL | if x == "hello" && y == "world" { LL | println!("Hello world!"); @@ -26,7 +26,7 @@ LL | | } LL | | } | |_____^ | -help: try +help: collapse nested if block | LL | if (x == "hello" || x == "world") && (y == "world" || y == "hello") { LL | println!("Hello world!"); @@ -43,7 +43,7 @@ LL | | } LL | | } | |_____^ | -help: try +help: collapse nested if block | LL | if x == "hello" && x == "world" && (y == "world" || y == "hello") { LL | println!("Hello world!"); @@ -60,7 +60,7 @@ LL | | } LL | | } | |_____^ | -help: try +help: collapse nested if block | LL | if (x == "hello" || x == "world") && y == "world" && y == "hello" { LL | println!("Hello world!"); @@ -77,7 +77,7 @@ LL | | } LL | | } | |_____^ | -help: try +help: collapse nested if block | LL | if x == "hello" && x == "world" && y == "world" && y == "hello" { LL | println!("Hello world!"); @@ -94,7 +94,7 @@ LL | | } LL | | } | |_____^ | -help: try +help: collapse nested if block | LL | if 42 == 1337 && 'a' != 'A' { LL | println!("world!") @@ -111,7 +111,7 @@ LL | | } LL | | } | |_____^ | -help: try +help: collapse nested if block | LL | if x == "hello" && y == "world" { // Collapsible LL | println!("Hello world!"); From b4091032abbadf586ea8c77bc547ec2ac403ef0a Mon Sep 17 00:00:00 2001 From: Takayuki Nakata Date: Tue, 14 Jul 2020 08:08:13 +0900 Subject: [PATCH 97/99] Use `.is_some()` not `Some(_)` --- clippy_lints/src/repeat_once.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clippy_lints/src/repeat_once.rs b/clippy_lints/src/repeat_once.rs index 3a0b3b1c2571b..a3af369e41e5a 100644 --- a/clippy_lints/src/repeat_once.rs +++ b/clippy_lints/src/repeat_once.rs @@ -55,7 +55,7 @@ impl<'tcx> LateLintPass<'tcx> for RepeatOnce { format!("{}.to_string()", snippet(cx, args[0].span, r#""...""#)), Applicability::MachineApplicable, ); - } else if let Some(_) = ty.builtin_index() { + } else if ty.builtin_index().is_some() { span_lint_and_sugg( cx, REPEAT_ONCE, From c492ca40a288d8a85353ba112c4d38fe87ef453e Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 14 Jul 2020 10:31:54 +1000 Subject: [PATCH 98/99] Use `ArrayVec` in `SparseBitSet`. Instead of `SmallVec`, because the maximum size is known. --- Cargo.lock | 12 +++++++++--- src/librustc_index/Cargo.toml | 2 +- src/librustc_index/bit_set.rs | 11 +++++------ 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 905f523aa53d6..9431a5004403f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -94,6 +94,12 @@ dependencies = [ "nodrop", ] +[[package]] +name = "arrayvec" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cff77d8686867eceff3105329d4698d96c2391c176d5d03adc90c7389162b5b8" + [[package]] name = "atty" version = "0.2.14" @@ -164,7 +170,7 @@ version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5d6d530bdd2d52966a6d03b7a964add7ae1a288d25214066fd4b600f0f796400" dependencies = [ - "arrayvec", + "arrayvec 0.4.7", "constant_time_eq", ] @@ -714,7 +720,7 @@ version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fedcd6772e37f3da2a9af9bf12ebe046c0dfe657992377b4df982a2b54cd37a9" dependencies = [ - "arrayvec", + "arrayvec 0.4.7", "cfg-if", "crossbeam-utils 0.6.5", "lazy_static", @@ -3494,8 +3500,8 @@ dependencies = [ name = "rustc_index" version = "0.0.0" dependencies = [ + "arrayvec 0.5.1", "rustc_serialize", - "smallvec 1.4.0", ] [[package]] diff --git a/src/librustc_index/Cargo.toml b/src/librustc_index/Cargo.toml index f0422b1af1b97..00b23760182a2 100644 --- a/src/librustc_index/Cargo.toml +++ b/src/librustc_index/Cargo.toml @@ -11,4 +11,4 @@ doctest = false [dependencies] rustc_serialize = { path = "../librustc_serialize" } -smallvec = { version = "1.0", features = ["union", "may_dangle"] } +arrayvec = "0.5.1" diff --git a/src/librustc_index/bit_set.rs b/src/librustc_index/bit_set.rs index cb8b30830c5de..3e1d4b68c6fa1 100644 --- a/src/librustc_index/bit_set.rs +++ b/src/librustc_index/bit_set.rs @@ -1,5 +1,5 @@ use crate::vec::{Idx, IndexVec}; -use smallvec::SmallVec; +use arrayvec::ArrayVec; use std::fmt; use std::iter; use std::marker::PhantomData; @@ -355,20 +355,19 @@ where const SPARSE_MAX: usize = 8; /// A fixed-size bitset type with a sparse representation and a maximum of -/// `SPARSE_MAX` elements. The elements are stored as a sorted `SmallVec` with -/// no duplicates; although `SmallVec` can spill its elements to the heap, that -/// never happens within this type because of the `SPARSE_MAX` limit. +/// `SPARSE_MAX` elements. The elements are stored as a sorted `ArrayVec` with +/// no duplicates. /// /// This type is used by `HybridBitSet`; do not use directly. #[derive(Clone, Debug)] pub struct SparseBitSet { domain_size: usize, - elems: SmallVec<[T; SPARSE_MAX]>, + elems: ArrayVec<[T; SPARSE_MAX]>, } impl SparseBitSet { fn new_empty(domain_size: usize) -> Self { - SparseBitSet { domain_size, elems: SmallVec::new() } + SparseBitSet { domain_size, elems: ArrayVec::new() } } fn len(&self) -> usize { From 0e9a20f311c7816b8ac4e92f487ce95b813ce6f6 Mon Sep 17 00:00:00 2001 From: Yoshua Wuyts Date: Tue, 14 Jul 2020 11:59:11 +0200 Subject: [PATCH 99/99] Remove unnecessary type hints from the Wake impl --- src/liballoc/task.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/liballoc/task.rs b/src/liballoc/task.rs index 0d1cc99df47c5..252e04a410548 100644 --- a/src/liballoc/task.rs +++ b/src/liballoc/task.rs @@ -69,14 +69,13 @@ fn raw_waker(waker: Arc) -> RawWaker { // Wake by value, moving the Arc into the Wake::wake function unsafe fn wake(waker: *const ()) { - let waker: Arc = unsafe { Arc::from_raw(waker as *const W) }; + let waker = unsafe { Arc::from_raw(waker as *const W) }; ::wake(waker); } // Wake by reference, wrap the waker in ManuallyDrop to avoid dropping it unsafe fn wake_by_ref(waker: *const ()) { - let waker: ManuallyDrop> = - unsafe { ManuallyDrop::new(Arc::from_raw(waker as *const W)) }; + let waker = unsafe { ManuallyDrop::new(Arc::from_raw(waker as *const W)) }; ::wake_by_ref(&waker); }