Auto merge of #4575 - Manishearth:suggestions, r=oli-obk

Make more tests rustfixable

Fixes https://github.com/rust-lang/rust-clippy/issues/3630

changelog: Improve suggestions for many lints in preparation for `cargo fix --clippy`

r? @phansch @yaahc
This commit is contained in:
bors 2019-09-25 21:54:14 +00:00
commit 1366629262
84 changed files with 1471 additions and 823 deletions

View file

@ -1,5 +1,6 @@
use crate::utils::SpanlessEq;
use crate::utils::{get_item_name, higher, match_type, paths, snippet, snippet_opt, span_lint_and_then, walk_ptrs_ty};
use crate::utils::{get_item_name, higher, match_type, paths, snippet, snippet_opt};
use crate::utils::{snippet_with_applicability, span_lint_and_then, walk_ptrs_ty};
use if_chain::if_chain;
use rustc::hir::intravisit::{walk_expr, NestedVisitorMap, Visitor};
use rustc::hir::*;
@ -64,6 +65,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for HashMapPass {
} else {
true
}
// XXXManishearth we can also check for if/else blocks containing `None`.
};
let mut visitor = InsertVisitor {
@ -145,10 +147,11 @@ impl<'a, 'tcx, 'b> Visitor<'tcx> for InsertVisitor<'a, 'tcx, 'b> {
span_lint_and_then(self.cx, MAP_ENTRY, self.span,
&format!("usage of `contains_key` followed by `insert` on a `{}`", self.ty), |db| {
if self.sole_expr {
let help = format!("{}.entry({}).or_insert({})",
snippet(self.cx, self.map.span, "map"),
snippet(self.cx, params[1].span, ".."),
snippet(self.cx, params[2].span, ".."));
let mut app = Applicability::MachineApplicable;
let help = format!("{}.entry({}).or_insert({});",
snippet_with_applicability(self.cx, self.map.span, "map", &mut app),
snippet_with_applicability(self.cx, params[1].span, "..", &mut app),
snippet_with_applicability(self.cx, params[2].span, "..", &mut app));
db.span_suggestion(
self.span,
@ -158,15 +161,13 @@ impl<'a, 'tcx, 'b> Visitor<'tcx> for InsertVisitor<'a, 'tcx, 'b> {
);
}
else {
let help = format!("{}.entry({})",
let help = format!("consider using `{}.entry({})`",
snippet(self.cx, self.map.span, "map"),
snippet(self.cx, params[1].span, ".."));
db.span_suggestion(
db.span_label(
self.span,
"consider using",
help,
Applicability::MachineApplicable, // snippet
&help,
);
}
});

View file

@ -118,7 +118,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for EqOp {
left.span,
"use the left value directly",
lsnip,
Applicability::MachineApplicable, // snippet
Applicability::MaybeIncorrect, // FIXME #2597
);
})
} else if !lcpy
@ -136,7 +136,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for EqOp {
right.span,
"use the right value directly",
rsnip,
Applicability::MachineApplicable, // snippet
Applicability::MaybeIncorrect, // FIXME #2597
);
},
)

View file

@ -2427,12 +2427,17 @@ fn check_needless_collect<'a, 'tcx>(expr: &'tcx Expr, cx: &LateContext<'a, 'tcx>
let contains_arg = snippet(cx, args[1].span, "??");
let span = shorten_needless_collect_span(expr);
span_lint_and_then(cx, NEEDLESS_COLLECT, span, NEEDLESS_COLLECT_MSG, |db| {
let (arg, pred) = if contains_arg.starts_with('&') {
("x", &contains_arg[1..])
} else {
("&x", &*contains_arg)
};
db.span_suggestion(
span,
"replace with",
format!(
".any(|&x| x == {})",
if contains_arg.starts_with('&') { &contains_arg[1..] } else { &contains_arg }
".any(|{}| x == {})",
arg, pred
),
Applicability::MachineApplicable,
);

View file

@ -217,15 +217,15 @@ fn lint_map_unit_fn(cx: &LateContext<'_, '_>, stmt: &hir::Stmt, expr: &hir::Expr
if is_unit_function(cx, fn_arg) {
let msg = suggestion_msg("function", map_type);
let suggestion = format!(
"if let {0}({1}) = {2} {{ {3}(...) }}",
"if let {0}({binding}) = {1} {{ {2}({binding}) }}",
variant,
let_binding_name(cx, var_arg),
snippet(cx, var_arg.span, "_"),
snippet(cx, fn_arg.span, "_")
snippet(cx, fn_arg.span, "_"),
binding = let_binding_name(cx, var_arg)
);
span_lint_and_then(cx, lint, expr.span, &msg, |db| {
db.span_suggestion(stmt.span, "try this", suggestion, Applicability::Unspecified);
db.span_suggestion(stmt.span, "try this", suggestion, Applicability::MachineApplicable);
});
} else if let Some((binding, closure_expr)) = unit_closure(cx, fn_arg) {
let msg = suggestion_msg("closure", map_type);
@ -250,9 +250,9 @@ fn lint_map_unit_fn(cx: &LateContext<'_, '_>, stmt: &hir::Stmt, expr: &hir::Expr
"if let {0}({1}) = {2} {{ ... }}",
variant,
snippet(cx, binding.pat.span, "_"),
snippet(cx, var_arg.span, "_")
snippet(cx, var_arg.span, "_"),
);
db.span_suggestion(stmt.span, "try this", suggestion, Applicability::Unspecified);
db.span_suggestion(stmt.span, "try this", suggestion, Applicability::HasPlaceholders);
}
});
}

View file

@ -1,5 +1,6 @@
use crate::utils::{
constants, snippet, snippet_opt, span_help_and_lint, span_lint, span_lint_and_sugg, span_lint_and_then,
constants, snippet_opt, snippet_with_applicability, span_help_and_lint, span_lint, span_lint_and_sugg,
span_lint_and_then,
};
use if_chain::if_chain;
use rustc::lint::{in_external_macro, EarlyContext, EarlyLintPass, LintArray, LintContext, LintPass};
@ -414,13 +415,10 @@ impl EarlyLintPass for MiscEarlyLints {
"Try not to call a closure in the expression where it is declared.",
|db| {
if decl.inputs.is_empty() {
let hint = snippet(cx, block.span, "..").into_owned();
db.span_suggestion(
expr.span,
"Try doing something like: ",
hint,
Applicability::MachineApplicable, // snippet
);
let mut app = Applicability::MachineApplicable;
let hint =
snippet_with_applicability(cx, block.span, "..", &mut app).into_owned();
db.span_suggestion(expr.span, "Try doing something like: ", hint, app);
}
},
);

View file

@ -2,9 +2,9 @@
//!
//! This lint is **warn** by default
use crate::utils::{snippet, span_lint_and_then};
use crate::utils::{snippet_with_applicability, span_lint_and_then};
use if_chain::if_chain;
use rustc::hir::{BindingAnnotation, MutImmutable, Pat, PatKind};
use rustc::hir::{BindingAnnotation, MutImmutable, Node, Pat, PatKind};
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
use rustc::{declare_lint_pass, declare_tool_lint};
use rustc_errors::Applicability;
@ -65,16 +65,25 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessBorrowedRef {
// Check sub_pat got a `ref` keyword (excluding `ref mut`).
if let PatKind::Binding(BindingAnnotation::Ref, .., spanned_name, _) = sub_pat.node;
let parent_id = cx.tcx.hir().get_parent_node(pat.hir_id);
if let Some(parent_node) = cx.tcx.hir().find(parent_id);
then {
// do not recurse within patterns, as they may have other references
// XXXManishearth we can relax this constraint if we only check patterns
// with a single ref pattern inside them
if let Node::Pat(_) = parent_node {
return;
}
let mut applicability = Applicability::MachineApplicable;
span_lint_and_then(cx, NEEDLESS_BORROWED_REFERENCE, pat.span,
"this pattern takes a reference on something that is being de-referenced",
|db| {
let hint = snippet(cx, spanned_name.span, "..").into_owned();
let hint = snippet_with_applicability(cx, spanned_name.span, "..", &mut applicability).into_owned();
db.span_suggestion(
pat.span,
"try removing the `&ref` part and just keep",
hint,
Applicability::MachineApplicable, // snippet
applicability,
);
});
}

View file

@ -10,7 +10,6 @@ use rustc::lint::{LateContext, LateLintPass, Lint, LintArray, LintPass};
use rustc::ty::adjustment::Adjust;
use rustc::ty::{Ty, TypeFlags};
use rustc::{declare_lint_pass, declare_tool_lint};
use rustc_errors::Applicability;
use rustc_typeck::hir_ty_to_ty;
use syntax_pos::{InnerSpan, Span, DUMMY_SP};
@ -125,16 +124,11 @@ fn verify_ty_bound<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, ty: Ty<'tcx>, source: S
match source {
Source::Item { .. } => {
let const_kw_span = span.from_inner(InnerSpan::new(0, 5));
db.span_suggestion(
const_kw_span,
"make this a static item",
"static".to_string(),
Applicability::MachineApplicable,
);
db.span_label(const_kw_span, "make this a static item (maybe with lazy_static)");
},
Source::Assoc { ty: ty_span, .. } => {
if ty.flags.contains(TypeFlags::HAS_FREE_LOCAL_NAMES) {
db.span_help(ty_span, &format!("consider requiring `{}` to be `Copy`", ty));
db.span_label(ty_span, &format!("consider requiring `{}` to be `Copy`", ty));
}
},
Source::Expr { .. } => {

View file

@ -49,14 +49,22 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for RedundantPatternMatching {
if let ExprKind::Match(ref op, ref arms, ref match_source) = expr.node {
match match_source {
MatchSource::Normal => find_sugg_for_match(cx, expr, op, arms),
MatchSource::IfLetDesugar { .. } => find_sugg_for_if_let(cx, expr, op, arms),
MatchSource::IfLetDesugar { contains_else_clause } => {
find_sugg_for_if_let(cx, expr, op, arms, *contains_else_clause)
},
_ => return,
}
}
}
}
fn find_sugg_for_if_let<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr, op: &P<Expr>, arms: &HirVec<Arm>) {
fn find_sugg_for_if_let<'a, 'tcx>(
cx: &LateContext<'a, 'tcx>,
expr: &'tcx Expr,
op: &P<Expr>,
arms: &HirVec<Arm>,
has_else: bool,
) {
let good_method = match arms[0].pat.node {
PatKind::TupleStruct(ref path, ref patterns, _) if patterns.len() == 1 => {
if let PatKind::Wild = patterns[0].node {
@ -79,6 +87,8 @@ fn find_sugg_for_if_let<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr,
_ => return,
};
let maybe_semi = if has_else { "" } else { ";" };
span_lint_and_then(
cx,
REDUNDANT_PATTERN_MATCHING,
@ -89,7 +99,7 @@ fn find_sugg_for_if_let<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr,
db.span_suggestion(
span,
"try this",
format!("{}.{}", snippet(cx, op.span, "_"), good_method),
format!("{}.{}{}", snippet(cx, op.span, "_"), good_method, maybe_semi),
Applicability::MaybeIncorrect, // snippet
);
},

View file

@ -0,0 +1,15 @@
// run-rustfix
#![allow(unused, clippy::needless_pass_by_value)]
#![warn(clippy::map_entry)]
use std::collections::{BTreeMap, HashMap};
use std::hash::Hash;
fn foo() {}
fn insert_if_absent0<K: Eq + Hash, V>(m: &mut HashMap<K, V>, k: K, v: V) {
m.entry(k).or_insert(v);
}
fn main() {}

17
tests/ui/entry_fixable.rs Normal file
View file

@ -0,0 +1,17 @@
// run-rustfix
#![allow(unused, clippy::needless_pass_by_value)]
#![warn(clippy::map_entry)]
use std::collections::{BTreeMap, HashMap};
use std::hash::Hash;
fn foo() {}
fn insert_if_absent0<K: Eq + Hash, V>(m: &mut HashMap<K, V>, k: K, v: V) {
if !m.contains_key(&k) {
m.insert(k, v);
}
}
fn main() {}

View file

@ -0,0 +1,12 @@
error: usage of `contains_key` followed by `insert` on a `HashMap`
--> $DIR/entry_fixable.rs:12:5
|
LL | / if !m.contains_key(&k) {
LL | | m.insert(k, v);
LL | | }
| |_____^ help: consider using: `m.entry(k).or_insert(v);`
|
= note: `-D clippy::map-entry` implied by `-D warnings`
error: aborting due to previous error

View file

@ -6,19 +6,6 @@ use std::hash::Hash;
fn foo() {}
fn insert_if_absent0<K: Eq + Hash, V>(m: &mut HashMap<K, V>, k: K, v: V) {
if !m.contains_key(&k) {
m.insert(k, v);
}
}
fn insert_if_absent1<K: Eq + Hash, V>(m: &mut HashMap<K, V>, k: K, v: V) {
if !m.contains_key(&k) {
foo();
m.insert(k, v);
}
}
fn insert_if_absent2<K: Eq + Hash, V>(m: &mut HashMap<K, V>, k: K, v: V) {
if !m.contains_key(&k) {
m.insert(k, v)
@ -62,6 +49,7 @@ fn insert_in_btreemap<K: Ord, V>(m: &mut BTreeMap<K, V>, k: K, v: V) {
};
}
// should not trigger
fn insert_other_if_absent<K: Eq + Hash, V>(m: &mut HashMap<K, V>, k: K, o: K, v: V) {
if !m.contains_key(&k) {
m.insert(o, v);

View file

@ -1,44 +1,27 @@
error: usage of `contains_key` followed by `insert` on a `HashMap`
--> $DIR/entry.rs:10:5
--> $DIR/entry_unfixable.rs:10:5
|
LL | / if !m.contains_key(&k) {
LL | | m.insert(k, v);
LL | | }
| |_____^ help: consider using: `m.entry(k).or_insert(v)`
LL | | m.insert(k, v)
LL | | } else {
LL | | None
LL | | };
| |_____^ consider using `m.entry(k)`
|
= note: `-D clippy::map-entry` implied by `-D warnings`
error: usage of `contains_key` followed by `insert` on a `HashMap`
--> $DIR/entry.rs:16:5
|
LL | / if !m.contains_key(&k) {
LL | | foo();
LL | | m.insert(k, v);
LL | | }
| |_____^ help: consider using: `m.entry(k)`
error: usage of `contains_key` followed by `insert` on a `HashMap`
--> $DIR/entry.rs:23:5
|
LL | / if !m.contains_key(&k) {
LL | | m.insert(k, v)
LL | | } else {
LL | | None
LL | | };
| |_____^ help: consider using: `m.entry(k)`
error: usage of `contains_key` followed by `insert` on a `HashMap`
--> $DIR/entry.rs:31:5
--> $DIR/entry_unfixable.rs:18:5
|
LL | / if m.contains_key(&k) {
LL | | None
LL | | } else {
LL | | m.insert(k, v)
LL | | };
| |_____^ help: consider using: `m.entry(k)`
| |_____^ consider using `m.entry(k)`
error: usage of `contains_key` followed by `insert` on a `HashMap`
--> $DIR/entry.rs:39:5
--> $DIR/entry_unfixable.rs:26:5
|
LL | / if !m.contains_key(&k) {
LL | | foo();
@ -46,10 +29,10 @@ LL | | m.insert(k, v)
LL | | } else {
LL | | None
LL | | };
| |_____^ help: consider using: `m.entry(k)`
| |_____^ consider using `m.entry(k)`
error: usage of `contains_key` followed by `insert` on a `HashMap`
--> $DIR/entry.rs:48:5
--> $DIR/entry_unfixable.rs:35:5
|
LL | / if m.contains_key(&k) {
LL | | None
@ -57,10 +40,10 @@ LL | | } else {
LL | | foo();
LL | | m.insert(k, v)
LL | | };
| |_____^ help: consider using: `m.entry(k)`
| |_____^ consider using `m.entry(k)`
error: usage of `contains_key` followed by `insert` on a `BTreeMap`
--> $DIR/entry.rs:57:5
--> $DIR/entry_unfixable.rs:44:5
|
LL | / if !m.contains_key(&k) {
LL | | foo();
@ -68,7 +51,7 @@ LL | | m.insert(k, v)
LL | | } else {
LL | | None
LL | | };
| |_____^ help: consider using: `m.entry(k)`
| |_____^ consider using `m.entry(k)`
error: aborting due to 7 previous errors
error: aborting due to 5 previous errors

View file

@ -1,3 +1,5 @@
// does not test any rustfixable lints
#[rustfmt::skip]
#[warn(clippy::eq_op)]
#[allow(clippy::identity_op, clippy::double_parens, clippy::many_single_char_names)]

View file

@ -1,5 +1,5 @@
error: equal expressions as operands to `==`
--> $DIR/eq_op.rs:9:5
--> $DIR/eq_op.rs:11:5
|
LL | 1 == 1;
| ^^^^^^
@ -7,157 +7,157 @@ LL | 1 == 1;
= note: `-D clippy::eq-op` implied by `-D warnings`
error: equal expressions as operands to `==`
--> $DIR/eq_op.rs:10:5
--> $DIR/eq_op.rs:12:5
|
LL | "no" == "no";
| ^^^^^^^^^^^^
error: equal expressions as operands to `!=`
--> $DIR/eq_op.rs:12:5
--> $DIR/eq_op.rs:14:5
|
LL | false != false;
| ^^^^^^^^^^^^^^
error: equal expressions as operands to `<`
--> $DIR/eq_op.rs:13:5
--> $DIR/eq_op.rs:15:5
|
LL | 1.5 < 1.5;
| ^^^^^^^^^
error: equal expressions as operands to `>=`
--> $DIR/eq_op.rs:14:5
--> $DIR/eq_op.rs:16:5
|
LL | 1u64 >= 1u64;
| ^^^^^^^^^^^^
error: equal expressions as operands to `&`
--> $DIR/eq_op.rs:17:5
--> $DIR/eq_op.rs:19:5
|
LL | (1 as u64) & (1 as u64);
| ^^^^^^^^^^^^^^^^^^^^^^^
error: equal expressions as operands to `^`
--> $DIR/eq_op.rs:18:5
--> $DIR/eq_op.rs:20:5
|
LL | 1 ^ ((((((1))))));
| ^^^^^^^^^^^^^^^^^
error: equal expressions as operands to `<`
--> $DIR/eq_op.rs:21:5
--> $DIR/eq_op.rs:23:5
|
LL | (-(2) < -(2));
| ^^^^^^^^^^^^^
error: equal expressions as operands to `==`
--> $DIR/eq_op.rs:22:5
--> $DIR/eq_op.rs:24:5
|
LL | ((1 + 1) & (1 + 1) == (1 + 1) & (1 + 1));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: equal expressions as operands to `&`
--> $DIR/eq_op.rs:22:6
--> $DIR/eq_op.rs:24:6
|
LL | ((1 + 1) & (1 + 1) == (1 + 1) & (1 + 1));
| ^^^^^^^^^^^^^^^^^
error: equal expressions as operands to `&`
--> $DIR/eq_op.rs:22:27
--> $DIR/eq_op.rs:24:27
|
LL | ((1 + 1) & (1 + 1) == (1 + 1) & (1 + 1));
| ^^^^^^^^^^^^^^^^^
error: equal expressions as operands to `==`
--> $DIR/eq_op.rs:23:5
--> $DIR/eq_op.rs:25:5
|
LL | (1 * 2) + (3 * 4) == 1 * 2 + 3 * 4;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: equal expressions as operands to `!=`
--> $DIR/eq_op.rs:26:5
--> $DIR/eq_op.rs:28:5
|
LL | ([1] != [1]);
| ^^^^^^^^^^^^
error: equal expressions as operands to `!=`
--> $DIR/eq_op.rs:27:5
--> $DIR/eq_op.rs:29:5
|
LL | ((1, 2) != (1, 2));
| ^^^^^^^^^^^^^^^^^^
error: equal expressions as operands to `==`
--> $DIR/eq_op.rs:31:5
--> $DIR/eq_op.rs:33:5
|
LL | 1 + 1 == 2;
| ^^^^^^^^^^
error: equal expressions as operands to `==`
--> $DIR/eq_op.rs:32:5
--> $DIR/eq_op.rs:34:5
|
LL | 1 - 1 == 0;
| ^^^^^^^^^^
error: equal expressions as operands to `-`
--> $DIR/eq_op.rs:32:5
--> $DIR/eq_op.rs:34:5
|
LL | 1 - 1 == 0;
| ^^^^^
error: equal expressions as operands to `-`
--> $DIR/eq_op.rs:34:5
--> $DIR/eq_op.rs:36:5
|
LL | 1 - 1;
| ^^^^^
error: equal expressions as operands to `/`
--> $DIR/eq_op.rs:35:5
--> $DIR/eq_op.rs:37:5
|
LL | 1 / 1;
| ^^^^^
error: equal expressions as operands to `&&`
--> $DIR/eq_op.rs:36:5
--> $DIR/eq_op.rs:38:5
|
LL | true && true;
| ^^^^^^^^^^^^
error: equal expressions as operands to `||`
--> $DIR/eq_op.rs:38:5
--> $DIR/eq_op.rs:40:5
|
LL | true || true;
| ^^^^^^^^^^^^
error: equal expressions as operands to `&&`
--> $DIR/eq_op.rs:44:5
--> $DIR/eq_op.rs:46:5
|
LL | a == b && b == a;
| ^^^^^^^^^^^^^^^^
error: equal expressions as operands to `&&`
--> $DIR/eq_op.rs:45:5
--> $DIR/eq_op.rs:47:5
|
LL | a != b && b != a;
| ^^^^^^^^^^^^^^^^
error: equal expressions as operands to `&&`
--> $DIR/eq_op.rs:46:5
--> $DIR/eq_op.rs:48:5
|
LL | a < b && b > a;
| ^^^^^^^^^^^^^^
error: equal expressions as operands to `&&`
--> $DIR/eq_op.rs:47:5
--> $DIR/eq_op.rs:49:5
|
LL | a <= b && b >= a;
| ^^^^^^^^^^^^^^^^
error: equal expressions as operands to `==`
--> $DIR/eq_op.rs:50:5
--> $DIR/eq_op.rs:52:5
|
LL | a == a;
| ^^^^^^
error: equal expressions as operands to `/`
--> $DIR/eq_op.rs:60:20
--> $DIR/eq_op.rs:62:20
|
LL | const D: u32 = A / A;
| ^^^^^

View file

@ -1,3 +1,5 @@
// does not test any rustfixable lints
#![warn(clippy::float_cmp_const)]
#![allow(clippy::float_cmp)]
#![allow(unused, clippy::no_effect, clippy::unnecessary_operation)]

View file

@ -1,84 +1,84 @@
error: strict comparison of f32 or f64 constant
--> $DIR/float_cmp_const.rs:18:5
--> $DIR/float_cmp_const.rs:20:5
|
LL | 1f32 == ONE;
| ^^^^^^^^^^^ help: consider comparing them within some error: `(1f32 - ONE).abs() < error`
|
= note: `-D clippy::float-cmp-const` implied by `-D warnings`
note: std::f32::EPSILON and std::f64::EPSILON are available.
--> $DIR/float_cmp_const.rs:18:5
--> $DIR/float_cmp_const.rs:20:5
|
LL | 1f32 == ONE;
| ^^^^^^^^^^^
error: strict comparison of f32 or f64 constant
--> $DIR/float_cmp_const.rs:19:5
--> $DIR/float_cmp_const.rs:21:5
|
LL | TWO == ONE;
| ^^^^^^^^^^ help: consider comparing them within some error: `(TWO - ONE).abs() < error`
|
note: std::f32::EPSILON and std::f64::EPSILON are available.
--> $DIR/float_cmp_const.rs:19:5
--> $DIR/float_cmp_const.rs:21:5
|
LL | TWO == ONE;
| ^^^^^^^^^^
error: strict comparison of f32 or f64 constant
--> $DIR/float_cmp_const.rs:20:5
--> $DIR/float_cmp_const.rs:22:5
|
LL | TWO != ONE;
| ^^^^^^^^^^ help: consider comparing them within some error: `(TWO - ONE).abs() > error`
|
note: std::f32::EPSILON and std::f64::EPSILON are available.
--> $DIR/float_cmp_const.rs:20:5
--> $DIR/float_cmp_const.rs:22:5
|
LL | TWO != ONE;
| ^^^^^^^^^^
error: strict comparison of f32 or f64 constant
--> $DIR/float_cmp_const.rs:21:5
--> $DIR/float_cmp_const.rs:23:5
|
LL | ONE + ONE == TWO;
| ^^^^^^^^^^^^^^^^ help: consider comparing them within some error: `(ONE + ONE - TWO).abs() < error`
|
note: std::f32::EPSILON and std::f64::EPSILON are available.
--> $DIR/float_cmp_const.rs:21:5
--> $DIR/float_cmp_const.rs:23:5
|
LL | ONE + ONE == TWO;
| ^^^^^^^^^^^^^^^^
error: strict comparison of f32 or f64 constant
--> $DIR/float_cmp_const.rs:23:5
--> $DIR/float_cmp_const.rs:25:5
|
LL | x as f32 == ONE;
| ^^^^^^^^^^^^^^^ help: consider comparing them within some error: `(x as f32 - ONE).abs() < error`
|
note: std::f32::EPSILON and std::f64::EPSILON are available.
--> $DIR/float_cmp_const.rs:23:5
--> $DIR/float_cmp_const.rs:25:5
|
LL | x as f32 == ONE;
| ^^^^^^^^^^^^^^^
error: strict comparison of f32 or f64 constant
--> $DIR/float_cmp_const.rs:26:5
--> $DIR/float_cmp_const.rs:28:5
|
LL | v == ONE;
| ^^^^^^^^ help: consider comparing them within some error: `(v - ONE).abs() < error`
|
note: std::f32::EPSILON and std::f64::EPSILON are available.
--> $DIR/float_cmp_const.rs:26:5
--> $DIR/float_cmp_const.rs:28:5
|
LL | v == ONE;
| ^^^^^^^^
error: strict comparison of f32 or f64 constant
--> $DIR/float_cmp_const.rs:27:5
--> $DIR/float_cmp_const.rs:29:5
|
LL | v != ONE;
| ^^^^^^^^ help: consider comparing them within some error: `(v - ONE).abs() > error`
|
note: std::f32::EPSILON and std::f64::EPSILON are available.
--> $DIR/float_cmp_const.rs:27:5
--> $DIR/float_cmp_const.rs:29:5
|
LL | v != ONE;
| ^^^^^^^^

View file

@ -0,0 +1,22 @@
// run-rustfix
#![allow(unused)]
use std::collections::HashSet;
use std::collections::VecDeque;
fn main() {
let v = [1, 2, 3, 4, 5];
let v2: Vec<isize> = v.to_vec();
let v3: HashSet<isize> = v.iter().cloned().collect();
let v4: VecDeque<isize> = v.iter().cloned().collect();
// Handle macro expansion in suggestion
let _: Vec<isize> = vec![1, 2, 3].to_vec();
// Issue #3704
unsafe {
let _: Vec<u8> = std::ffi::CStr::from_ptr(std::ptr::null())
.to_bytes().to_vec();
}
}

View file

@ -0,0 +1,25 @@
// run-rustfix
#![allow(unused)]
use std::collections::HashSet;
use std::collections::VecDeque;
fn main() {
let v = [1, 2, 3, 4, 5];
let v2: Vec<isize> = v.iter().cloned().collect();
let v3: HashSet<isize> = v.iter().cloned().collect();
let v4: VecDeque<isize> = v.iter().cloned().collect();
// Handle macro expansion in suggestion
let _: Vec<isize> = vec![1, 2, 3].iter().cloned().collect();
// Issue #3704
unsafe {
let _: Vec<u8> = std::ffi::CStr::from_ptr(std::ptr::null())
.to_bytes()
.iter()
.cloned()
.collect();
}
}

View file

@ -0,0 +1,26 @@
error: called `iter().cloned().collect()` on a slice to create a `Vec`. Calling `to_vec()` is both faster and more readable
--> $DIR/iter_cloned_collect.rs:10:27
|
LL | let v2: Vec<isize> = v.iter().cloned().collect();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `.to_vec()`
|
= note: `-D clippy::iter-cloned-collect` implied by `-D warnings`
error: called `iter().cloned().collect()` on a slice to create a `Vec`. Calling `to_vec()` is both faster and more readable
--> $DIR/iter_cloned_collect.rs:15:38
|
LL | let _: Vec<isize> = vec![1, 2, 3].iter().cloned().collect();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `.to_vec()`
error: called `iter().cloned().collect()` on a slice to create a `Vec`. Calling `to_vec()` is both faster and more readable
--> $DIR/iter_cloned_collect.rs:20:24
|
LL | .to_bytes()
| ________________________^
LL | | .iter()
LL | | .cloned()
LL | | .collect();
| |______________________^ help: try: `.to_vec()`
error: aborting due to 3 previous errors

View file

@ -1,4 +1,5 @@
#![warn(clippy::large_digit_groups)]
// does not test any rustfixable lints
#![warn(clippy::mixed_case_hex_literals)]
#![warn(clippy::zero_prefixed_literal)]
#![allow(clippy::unseparated_literal_suffix)]
@ -28,8 +29,6 @@ fn main() {
let ok16 = 0xFE_BAFE_ABAB_ABCD;
let ok17 = 0x123_4567_8901_usize;
let fail13 = 0x1_23456_78901_usize;
let fail19 = 12_3456_21;
let fail22 = 3__4___23;
let fail23 = 3__16___23;

View file

@ -1,5 +1,5 @@
error: inconsistent casing in hexadecimal literal
--> $DIR/literals.rs:13:17
--> $DIR/literals.rs:14:17
|
LL | let fail1 = 0xabCD;
| ^^^^^^
@ -7,19 +7,19 @@ LL | let fail1 = 0xabCD;
= note: `-D clippy::mixed-case-hex-literals` implied by `-D warnings`
error: inconsistent casing in hexadecimal literal
--> $DIR/literals.rs:14:17
--> $DIR/literals.rs:15:17
|
LL | let fail2 = 0xabCD_u32;
| ^^^^^^^^^^
error: inconsistent casing in hexadecimal literal
--> $DIR/literals.rs:15:17
--> $DIR/literals.rs:16:17
|
LL | let fail2 = 0xabCD_isize;
| ^^^^^^^^^^^^
error: this is a decimal constant
--> $DIR/literals.rs:16:27
--> $DIR/literals.rs:17:27
|
LL | let fail_multi_zero = 000_123usize;
| ^^^^^^^^^^^^
@ -35,7 +35,7 @@ LL | let fail_multi_zero = 0o123usize;
| ^^^^^^^^^^
error: this is a decimal constant
--> $DIR/literals.rs:20:17
--> $DIR/literals.rs:21:17
|
LL | let fail8 = 0123;
| ^^^^
@ -48,16 +48,8 @@ help: if you mean to use an octal constant, use `0o`
LL | let fail8 = 0o123;
| ^^^^^
error: digit groups should be smaller
--> $DIR/literals.rs:31:18
|
LL | let fail13 = 0x1_23456_78901_usize;
| ^^^^^^^^^^^^^^^^^^^^^ help: consider: `0x0123_4567_8901_usize`
|
= note: `-D clippy::large-digit-groups` implied by `-D warnings`
error: digits grouped inconsistently by underscores
--> $DIR/literals.rs:33:18
--> $DIR/literals.rs:32:18
|
LL | let fail19 = 12_3456_21;
| ^^^^^^^^^^ help: consider: `12_345_621`
@ -65,16 +57,16 @@ LL | let fail19 = 12_3456_21;
= note: `-D clippy::inconsistent-digit-grouping` implied by `-D warnings`
error: digits grouped inconsistently by underscores
--> $DIR/literals.rs:34:18
--> $DIR/literals.rs:33:18
|
LL | let fail22 = 3__4___23;
| ^^^^^^^^^ help: consider: `3_423`
error: digits grouped inconsistently by underscores
--> $DIR/literals.rs:35:18
--> $DIR/literals.rs:34:18
|
LL | let fail23 = 3__16___23;
| ^^^^^^^^^^ help: consider: `31_623`
error: aborting due to 9 previous errors
error: aborting due to 8 previous errors

View file

@ -0,0 +1,8 @@
// run-rustfix
#![warn(clippy::all, clippy::pedantic)]
#![allow(clippy::missing_docs_in_private_items)]
fn main() {
let _: Vec<_> = vec![5_i8; 6].into_iter().flat_map(|x| 0..x).collect();
}

View file

@ -1,3 +1,5 @@
// run-rustfix
#![warn(clippy::all, clippy::pedantic)]
#![allow(clippy::missing_docs_in_private_items)]

View file

@ -1,5 +1,5 @@
error: called `map(..).flatten()` on an `Iterator`. This is more succinctly expressed by calling `.flat_map(..)`
--> $DIR/map_flatten.rs:5:21
--> $DIR/map_flatten.rs:7: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)`

View file

@ -0,0 +1,45 @@
// run-rustfix
#![deny(clippy::mem_discriminant_non_enum)]
use std::mem;
enum Foo {
One(usize),
Two(u8),
}
fn main() {
// bad
mem::discriminant(&Some(2));
mem::discriminant(&None::<u8>);
mem::discriminant(&Foo::One(5));
mem::discriminant(&Foo::Two(5));
let ro = &Some(3);
let rro = &ro;
mem::discriminant(ro);
mem::discriminant(*rro);
mem::discriminant(*rro);
macro_rules! mem_discriminant_but_in_a_macro {
($param:expr) => {
mem::discriminant($param)
};
}
mem_discriminant_but_in_a_macro!(*rro);
let rrrrro = &&&rro;
mem::discriminant(****rrrrro);
mem::discriminant(****rrrrro);
// ok
mem::discriminant(&Some(2));
mem::discriminant(&None::<u8>);
mem::discriminant(&Foo::One(5));
mem::discriminant(&Foo::Two(5));
mem::discriminant(ro);
mem::discriminant(*rro);
mem::discriminant(****rrrrro);
}

View file

@ -1,3 +1,5 @@
// run-rustfix
#![deny(clippy::mem_discriminant_non_enum)]
use std::mem;
@ -7,16 +9,12 @@ enum Foo {
Two(u8),
}
struct A(Foo);
fn main() {
// bad
mem::discriminant(&"hello");
mem::discriminant(&&Some(2));
mem::discriminant(&&None::<u8>);
mem::discriminant(&&Foo::One(5));
mem::discriminant(&&Foo::Two(5));
mem::discriminant(&A(Foo::One(0)));
let ro = &Some(3);
let rro = &ro;

View file

@ -1,25 +1,19 @@
error: calling `mem::discriminant` on non-enum type `&str`
--> $DIR/mem_discriminant.rs:14:5
|
LL | mem::discriminant(&"hello");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: lint level defined here
--> $DIR/mem_discriminant.rs:1:9
|
LL | #![deny(clippy::mem_discriminant_non_enum)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: calling `mem::discriminant` on non-enum type `&std::option::Option<i32>`
--> $DIR/mem_discriminant.rs:15:5
--> $DIR/mem_discriminant.rs:14:5
|
LL | mem::discriminant(&&Some(2));
| ^^^^^^^^^^^^^^^^^^---------^
| |
| help: try dereferencing: `&Some(2)`
|
note: lint level defined here
--> $DIR/mem_discriminant.rs:3:9
|
LL | #![deny(clippy::mem_discriminant_non_enum)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: calling `mem::discriminant` on non-enum type `&std::option::Option<u8>`
--> $DIR/mem_discriminant.rs:16:5
--> $DIR/mem_discriminant.rs:15:5
|
LL | mem::discriminant(&&None::<u8>);
| ^^^^^^^^^^^^^^^^^^------------^
@ -27,7 +21,7 @@ LL | mem::discriminant(&&None::<u8>);
| help: try dereferencing: `&None::<u8>`
error: calling `mem::discriminant` on non-enum type `&Foo`
--> $DIR/mem_discriminant.rs:17:5
--> $DIR/mem_discriminant.rs:16:5
|
LL | mem::discriminant(&&Foo::One(5));
| ^^^^^^^^^^^^^^^^^^-------------^
@ -35,21 +29,15 @@ LL | mem::discriminant(&&Foo::One(5));
| help: try dereferencing: `&Foo::One(5)`
error: calling `mem::discriminant` on non-enum type `&Foo`
--> $DIR/mem_discriminant.rs:18:5
--> $DIR/mem_discriminant.rs:17:5
|
LL | mem::discriminant(&&Foo::Two(5));
| ^^^^^^^^^^^^^^^^^^-------------^
| |
| help: try dereferencing: `&Foo::Two(5)`
error: calling `mem::discriminant` on non-enum type `A`
--> $DIR/mem_discriminant.rs:19:5
|
LL | mem::discriminant(&A(Foo::One(0)));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: calling `mem::discriminant` on non-enum type `&std::option::Option<i32>`
--> $DIR/mem_discriminant.rs:23:5
--> $DIR/mem_discriminant.rs:21:5
|
LL | mem::discriminant(&ro);
| ^^^^^^^^^^^^^^^^^^---^
@ -57,7 +45,7 @@ LL | mem::discriminant(&ro);
| help: try dereferencing: `ro`
error: calling `mem::discriminant` on non-enum type `&std::option::Option<i32>`
--> $DIR/mem_discriminant.rs:24:5
--> $DIR/mem_discriminant.rs:22:5
|
LL | mem::discriminant(rro);
| ^^^^^^^^^^^^^^^^^^---^
@ -65,7 +53,7 @@ LL | mem::discriminant(rro);
| help: try dereferencing: `*rro`
error: calling `mem::discriminant` on non-enum type `&&std::option::Option<i32>`
--> $DIR/mem_discriminant.rs:25:5
--> $DIR/mem_discriminant.rs:23:5
|
LL | mem::discriminant(&rro);
| ^^^^^^^^^^^^^^^^^^----^
@ -73,7 +61,7 @@ LL | mem::discriminant(&rro);
| help: try dereferencing: `*rro`
error: calling `mem::discriminant` on non-enum type `&&std::option::Option<i32>`
--> $DIR/mem_discriminant.rs:29:13
--> $DIR/mem_discriminant.rs:27:13
|
LL | mem::discriminant($param)
| ^^^^^^^^^^^^^^^^^^^^^^^^^
@ -85,7 +73,7 @@ LL | mem_discriminant_but_in_a_macro!(&rro);
| in this macro invocation
error: calling `mem::discriminant` on non-enum type `&&&&&std::option::Option<i32>`
--> $DIR/mem_discriminant.rs:36:5
--> $DIR/mem_discriminant.rs:34:5
|
LL | mem::discriminant(&rrrrro);
| ^^^^^^^^^^^^^^^^^^-------^
@ -93,12 +81,12 @@ LL | mem::discriminant(&rrrrro);
| help: try dereferencing: `****rrrrro`
error: calling `mem::discriminant` on non-enum type `&&&std::option::Option<i32>`
--> $DIR/mem_discriminant.rs:37:5
--> $DIR/mem_discriminant.rs:35:5
|
LL | mem::discriminant(*rrrrro);
| ^^^^^^^^^^^^^^^^^^-------^
| |
| help: try dereferencing: `****rrrrro`
error: aborting due to 12 previous errors
error: aborting due to 10 previous errors

View file

@ -0,0 +1,16 @@
#![deny(clippy::mem_discriminant_non_enum)]
use std::mem;
enum Foo {
One(usize),
Two(u8),
}
struct A(Foo);
fn main() {
// bad
mem::discriminant(&"hello");
mem::discriminant(&A(Foo::One(0)));
}

View file

@ -0,0 +1,20 @@
error: calling `mem::discriminant` on non-enum type `&str`
--> $DIR/mem_discriminant_unfixable.rs:14:5
|
LL | mem::discriminant(&"hello");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: lint level defined here
--> $DIR/mem_discriminant_unfixable.rs:1:9
|
LL | #![deny(clippy::mem_discriminant_non_enum)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: calling `mem::discriminant` on non-enum type `A`
--> $DIR/mem_discriminant_unfixable.rs:15:5
|
LL | mem::discriminant(&A(Foo::One(0)));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 2 previous errors

View file

@ -0,0 +1,62 @@
// run-rustfix
#![allow(clippy::needless_borrowed_reference)]
#[allow(clippy::trivially_copy_pass_by_ref)]
fn x(y: &i32) -> i32 {
*y
}
#[warn(clippy::all, clippy::needless_borrow)]
#[allow(unused_variables)]
fn main() {
let a = 5;
let b = x(&a);
let c = x(&a);
let s = &String::from("hi");
let s_ident = f(&s); // should not error, because `&String` implements Copy, but `String` does not
let g_val = g(&Vec::new()); // should not error, because `&Vec<T>` derefs to `&[T]`
let vec = Vec::new();
let vec_val = g(&vec); // should not error, because `&Vec<T>` derefs to `&[T]`
h(&"foo"); // should not error, because the `&&str` is required, due to `&Trait`
if let Some(cake) = Some(&5) {}
let garbl = match 42 {
44 => &a,
45 => {
println!("foo");
&&a // FIXME: this should lint, too
},
46 => &a,
_ => panic!(),
};
}
fn f<T: Copy>(y: &T) -> T {
*y
}
fn g(y: &[u8]) -> u8 {
y[0]
}
trait Trait {}
impl<'a> Trait for &'a str {}
fn h(_: &dyn Trait) {}
#[warn(clippy::needless_borrow)]
#[allow(dead_code)]
fn issue_1432() {
let mut v = Vec::<String>::new();
let _ = v.iter_mut().filter(|&ref a| a.is_empty());
let _ = v.iter().filter(|&a| a.is_empty());
let _ = v.iter().filter(|&a| a.is_empty());
}
#[allow(dead_code)]
#[warn(clippy::needless_borrow)]
#[derive(Debug)]
enum Foo<'a> {
Str(&'a str),
}

View file

@ -1,4 +1,6 @@
use std::borrow::Cow;
// run-rustfix
#![allow(clippy::needless_borrowed_reference)]
#[allow(clippy::trivially_copy_pass_by_ref)]
fn x(y: &i32) -> i32 {

View file

@ -1,5 +1,5 @@
error: this expression borrows a reference that is immediately dereferenced by the compiler
--> $DIR/needless_borrow.rs:13:15
--> $DIR/needless_borrow.rs:15:15
|
LL | let c = x(&&a);
| ^^^ help: change this to: `&a`
@ -7,36 +7,22 @@ LL | let c = x(&&a);
= note: `-D clippy::needless-borrow` implied by `-D warnings`
error: this pattern creates a reference to a reference
--> $DIR/needless_borrow.rs:20:17
--> $DIR/needless_borrow.rs:22:17
|
LL | if let Some(ref cake) = Some(&5) {}
| ^^^^^^^^ help: change this to: `cake`
error: this expression borrows a reference that is immediately dereferenced by the compiler
--> $DIR/needless_borrow.rs:27:15
--> $DIR/needless_borrow.rs:29:15
|
LL | 46 => &&a,
| ^^^ help: change this to: `&a`
error: this pattern takes a reference on something that is being de-referenced
--> $DIR/needless_borrow.rs:49:34
|
LL | let _ = v.iter_mut().filter(|&ref a| a.is_empty());
| ^^^^^^ help: try removing the `&ref` part and just keep: `a`
|
= note: `-D clippy::needless-borrowed-reference` implied by `-D warnings`
error: this pattern takes a reference on something that is being de-referenced
--> $DIR/needless_borrow.rs:50:30
|
LL | let _ = v.iter().filter(|&ref a| a.is_empty());
| ^^^^^^ help: try removing the `&ref` part and just keep: `a`
error: this pattern creates a reference to a reference
--> $DIR/needless_borrow.rs:50:31
--> $DIR/needless_borrow.rs:52:31
|
LL | let _ = v.iter().filter(|&ref a| a.is_empty());
| ^^^^^ help: change this to: `a`
error: aborting due to 6 previous errors
error: aborting due to 4 previous errors

View file

@ -0,0 +1,45 @@
// run-rustfix
#[warn(clippy::needless_borrowed_reference)]
#[allow(unused_variables)]
fn main() {
let mut v = Vec::<String>::new();
let _ = v.iter_mut().filter(|a| a.is_empty());
// ^ should be linted
let var = 3;
let thingy = Some(&var);
if let Some(&ref v) = thingy {
// ^ should be linted
}
let mut var2 = 5;
let thingy2 = Some(&mut var2);
if let Some(&mut ref mut v) = thingy2 {
// ^ should **not** be linted
// v is borrowed as mutable.
*v = 10;
}
if let Some(&mut ref v) = thingy2 {
// ^ should **not** be linted
// here, v is borrowed as immutable.
// can't do that:
//*v = 15;
}
}
#[allow(dead_code)]
enum Animal {
Cat(u64),
Dog(u64),
}
#[allow(unused_variables)]
#[allow(dead_code)]
fn foo(a: &Animal, b: &Animal) {
match (a, b) {
(&Animal::Cat(v), &ref k) | (&ref k, &Animal::Cat(v)) => (), // lifetime mismatch error if there is no '&ref'
// ^ and ^ should **not** be linted
(&Animal::Dog(ref a), &Animal::Dog(_)) => (), // ^ should **not** be linted
}
}

View file

@ -1,3 +1,5 @@
// run-rustfix
#[warn(clippy::needless_borrowed_reference)]
#[allow(unused_variables)]
fn main() {

View file

@ -1,28 +1,10 @@
error: this pattern takes a reference on something that is being de-referenced
--> $DIR/needless_borrowed_ref.rs:5:34
--> $DIR/needless_borrowed_ref.rs:7:34
|
LL | let _ = v.iter_mut().filter(|&ref a| a.is_empty());
| ^^^^^^ help: try removing the `&ref` part and just keep: `a`
|
= note: `-D clippy::needless-borrowed-reference` implied by `-D warnings`
error: this pattern takes a reference on something that is being de-referenced
--> $DIR/needless_borrowed_ref.rs:10:17
|
LL | if let Some(&ref v) = thingy {
| ^^^^^^ help: try removing the `&ref` part and just keep: `v`
error: this pattern takes a reference on something that is being de-referenced
--> $DIR/needless_borrowed_ref.rs:39:27
|
LL | (&Animal::Cat(v), &ref k) | (&ref k, &Animal::Cat(v)) => (), // lifetime mismatch error if there is no '&ref'
| ^^^^^^ help: try removing the `&ref` part and just keep: `k`
error: this pattern takes a reference on something that is being de-referenced
--> $DIR/needless_borrowed_ref.rs:39:38
|
LL | (&Animal::Cat(v), &ref k) | (&ref k, &Animal::Cat(v)) => (), // lifetime mismatch error if there is no '&ref'
| ^^^^^^ help: try removing the `&ref` part and just keep: `k`
error: aborting due to 4 previous errors
error: aborting due to previous error

View file

@ -0,0 +1,21 @@
// run-rustfix
#![allow(unused, clippy::suspicious_map)]
use std::collections::{BTreeSet, HashMap, HashSet};
#[warn(clippy::needless_collect)]
#[allow(unused_variables, clippy::iter_cloned_collect)]
fn main() {
let sample = [1; 5];
let len = sample.iter().count();
if sample.iter().next().is_none() {
// Empty
}
sample.iter().cloned().any(|x| x == 1);
sample.iter().map(|x| (x, x)).count();
// Notice the `HashSet`--this should not be linted
sample.iter().collect::<HashSet<_>>().len();
// Neither should this
sample.iter().collect::<BTreeSet<_>>().len();
}

View file

@ -1,3 +1,7 @@
// run-rustfix
#![allow(unused, clippy::suspicious_map)]
use std::collections::{BTreeSet, HashMap, HashSet};
#[warn(clippy::needless_collect)]

View file

@ -1,5 +1,5 @@
error: avoid using `collect()` when not needed
--> $DIR/needless_collect.rs:7:28
--> $DIR/needless_collect.rs:11:28
|
LL | let len = sample.iter().collect::<Vec<_>>().len();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `.count()`
@ -7,19 +7,19 @@ LL | let len = sample.iter().collect::<Vec<_>>().len();
= note: `-D clippy::needless-collect` implied by `-D warnings`
error: avoid using `collect()` when not needed
--> $DIR/needless_collect.rs:8:21
--> $DIR/needless_collect.rs:12:21
|
LL | if sample.iter().collect::<Vec<_>>().is_empty() {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `.next().is_none()`
error: avoid using `collect()` when not needed
--> $DIR/needless_collect.rs:11:27
--> $DIR/needless_collect.rs:15:27
|
LL | sample.iter().cloned().collect::<Vec<_>>().contains(&1);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `.any(|&x| x == 1)`
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `.any(|x| x == 1)`
error: avoid using `collect()` when not needed
--> $DIR/needless_collect.rs:12:34
--> $DIR/needless_collect.rs:16:34
|
LL | sample.iter().map(|x| (x, x)).collect::<HashMap<_, _>>().len();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `.count()`

View file

@ -0,0 +1,78 @@
// run-rustfix
#![allow(unused, clippy::needless_bool, clippy::match_bool)]
#![allow(clippy::if_same_then_else, clippy::single_match)]
#![warn(clippy::needless_return)]
macro_rules! the_answer {
() => {
42
};
}
fn test_end_of_fn() -> bool {
if true {
// no error!
return true;
}
true
}
fn test_no_semicolon() -> bool {
true
}
fn test_if_block() -> bool {
if true {
true
} else {
false
}
}
fn test_match(x: bool) -> bool {
match x {
true => false,
false => {
true
},
}
}
fn test_closure() {
let _ = || {
true
};
let _ = || true;
}
fn test_macro_call() -> i32 {
return the_answer!();
}
fn test_void_fun() {
}
fn test_void_if_fun(b: bool) {
if b {
} else {
}
}
fn test_void_match(x: u32) {
match x {
0 => (),
_ => {},
}
}
fn main() {
let _ = test_end_of_fn();
let _ = test_no_semicolon();
let _ = test_if_block();
let _ = test_match(true);
test_closure();
}

View file

@ -1,3 +1,7 @@
// run-rustfix
#![allow(unused, clippy::needless_bool, clippy::match_bool)]
#![allow(clippy::if_same_then_else, clippy::single_match)]
#![warn(clippy::needless_return)]
macro_rules! the_answer {

View file

@ -1,5 +1,5 @@
error: unneeded return statement
--> $DIR/needless_return.rs:14:5
--> $DIR/needless_return.rs:18:5
|
LL | return true;
| ^^^^^^^^^^^^ help: remove `return`: `true`
@ -7,67 +7,67 @@ LL | return true;
= note: `-D clippy::needless-return` implied by `-D warnings`
error: unneeded return statement
--> $DIR/needless_return.rs:18:5
--> $DIR/needless_return.rs:22:5
|
LL | return true;
| ^^^^^^^^^^^^ help: remove `return`: `true`
error: unneeded return statement
--> $DIR/needless_return.rs:23:9
--> $DIR/needless_return.rs:27:9
|
LL | return true;
| ^^^^^^^^^^^^ help: remove `return`: `true`
error: unneeded return statement
--> $DIR/needless_return.rs:25:9
--> $DIR/needless_return.rs:29:9
|
LL | return false;
| ^^^^^^^^^^^^^ help: remove `return`: `false`
error: unneeded return statement
--> $DIR/needless_return.rs:31:17
--> $DIR/needless_return.rs:35:17
|
LL | true => return false,
| ^^^^^^^^^^^^ help: remove `return`: `false`
error: unneeded return statement
--> $DIR/needless_return.rs:33:13
--> $DIR/needless_return.rs:37:13
|
LL | return true;
| ^^^^^^^^^^^^ help: remove `return`: `true`
error: unneeded return statement
--> $DIR/needless_return.rs:40:9
--> $DIR/needless_return.rs:44:9
|
LL | return true;
| ^^^^^^^^^^^^ help: remove `return`: `true`
error: unneeded return statement
--> $DIR/needless_return.rs:42:16
--> $DIR/needless_return.rs:46:16
|
LL | let _ = || return true;
| ^^^^^^^^^^^ help: remove `return`: `true`
error: unneeded return statement
--> $DIR/needless_return.rs:50:5
--> $DIR/needless_return.rs:54:5
|
LL | return;
| ^^^^^^^ help: remove `return`
error: unneeded return statement
--> $DIR/needless_return.rs:55:9
--> $DIR/needless_return.rs:59:9
|
LL | return;
| ^^^^^^^ help: remove `return`
error: unneeded return statement
--> $DIR/needless_return.rs:57:9
--> $DIR/needless_return.rs:61:9
|
LL | return;
| ^^^^^^^ help: remove `return`
error: unneeded return statement
--> $DIR/needless_return.rs:64:14
--> $DIR/needless_return.rs:68:14
|
LL | _ => return,
| ^^^^^^ help: replace `return` with an empty block: `{}`

View file

@ -4,7 +4,7 @@ error: a const item should never be interior mutable
LL | const ATOMIC: AtomicUsize = AtomicUsize::new(5); //~ ERROR interior mutable
| -----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
| help: make this a static item: `static`
| make this a static item (maybe with lazy_static)
|
= note: `#[deny(clippy::declare_interior_mutable_const)]` on by default
@ -14,7 +14,7 @@ error: a const item should never be interior mutable
LL | const CELL: Cell<usize> = Cell::new(6); //~ ERROR interior mutable
| -----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
| help: make this a static item: `static`
| make this a static item (maybe with lazy_static)
error: a const item should never be interior mutable
--> $DIR/non_copy_const.rs:11:1
@ -22,7 +22,7 @@ error: a const item should never be interior mutable
LL | const ATOMIC_TUPLE: ([AtomicUsize; 1], Vec<AtomicUsize>, u8) = ([ATOMIC], Vec::new(), 7);
| -----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
| help: make this a static item: `static`
| make this a static item (maybe with lazy_static)
error: a const item should never be interior mutable
--> $DIR/non_copy_const.rs:16:9
@ -43,37 +43,25 @@ error: a const item should never be interior mutable
--> $DIR/non_copy_const.rs:44:5
|
LL | const INPUT: T;
| ^^^^^^^^^^^^^^^
|
help: consider requiring `T` to be `Copy`
--> $DIR/non_copy_const.rs:44:18
|
LL | const INPUT: T;
| ^
| ^^^^^^^^^^^^^-^
| |
| consider requiring `T` to be `Copy`
error: a const item should never be interior mutable
--> $DIR/non_copy_const.rs:47:5
|
LL | const ASSOC: Self::NonCopyType;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: consider requiring `<Self as Trait<T>>::NonCopyType` to be `Copy`
--> $DIR/non_copy_const.rs:47:18
|
LL | const ASSOC: Self::NonCopyType;
| ^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^-----------------^
| |
| consider requiring `<Self as Trait<T>>::NonCopyType` to be `Copy`
error: a const item should never be interior mutable
--> $DIR/non_copy_const.rs:51:5
|
LL | const AN_INPUT: T = Self::INPUT;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: consider requiring `T` to be `Copy`
--> $DIR/non_copy_const.rs:51:21
|
LL | const AN_INPUT: T = Self::INPUT;
| ^
| ^^^^^^^^^^^^^^^^-^^^^^^^^^^^^^^^
| |
| consider requiring `T` to be `Copy`
error: a const item should never be interior mutable
--> $DIR/non_copy_const.rs:16:9
@ -88,13 +76,9 @@ error: a const item should never be interior mutable
--> $DIR/non_copy_const.rs:60:5
|
LL | const SELF_2: Self;
| ^^^^^^^^^^^^^^^^^^^
|
help: consider requiring `Self` to be `Copy`
--> $DIR/non_copy_const.rs:60:19
|
LL | const SELF_2: Self;
| ^^^^
| ^^^^^^^^^^^^^^----^
| |
| consider requiring `Self` to be `Copy`
error: a const item should never be interior mutable
--> $DIR/non_copy_const.rs:81:5
@ -106,25 +90,17 @@ error: a const item should never be interior mutable
--> $DIR/non_copy_const.rs:84:5
|
LL | const U_SELF: U = U::SELF_2;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: consider requiring `U` to be `Copy`
--> $DIR/non_copy_const.rs:84:19
|
LL | const U_SELF: U = U::SELF_2;
| ^
| ^^^^^^^^^^^^^^-^^^^^^^^^^^^^
| |
| consider requiring `U` to be `Copy`
error: a const item should never be interior mutable
--> $DIR/non_copy_const.rs:87:5
|
LL | const T_ASSOC: T::NonCopyType = T::ASSOC;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: consider requiring `<T as Trait<u32>>::NonCopyType` to be `Copy`
--> $DIR/non_copy_const.rs:87:20
|
LL | const T_ASSOC: T::NonCopyType = T::ASSOC;
| ^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^--------------^^^^^^^^^^^^
| |
| consider requiring `<T as Trait<u32>>::NonCopyType` to be `Copy`
error: a const item with interior mutability should not be borrowed
--> $DIR/non_copy_const.rs:94:5

View file

@ -0,0 +1,78 @@
// run-rustfix
#![warn(clippy::option_map_unit_fn)]
#![allow(unused)]
fn do_nothing<T>(_: T) {}
fn diverge<T>(_: T) -> ! {
panic!()
}
fn plus_one(value: usize) -> usize {
value + 1
}
struct HasOption {
field: Option<usize>,
}
impl HasOption {
fn do_option_nothing(self: &Self, value: usize) {}
fn do_option_plus_one(self: &Self, value: usize) -> usize {
value + 1
}
}
#[rustfmt::skip]
fn option_map_unit_fn() {
let x = HasOption { field: Some(10) };
x.field.map(plus_one);
let _ : Option<()> = x.field.map(do_nothing);
if let Some(x_field) = x.field { do_nothing(x_field) }
if let Some(x_field) = x.field { do_nothing(x_field) }
if let Some(x_field) = x.field { diverge(x_field) }
let captured = 10;
if let Some(value) = x.field { do_nothing(value + captured) };
let _ : Option<()> = x.field.map(|value| do_nothing(value + captured));
if let Some(value) = x.field { x.do_option_nothing(value + captured) }
if let Some(value) = x.field { x.do_option_plus_one(value + captured); }
if let Some(value) = x.field { do_nothing(value + captured) }
if let Some(value) = x.field { do_nothing(value + captured) }
if let Some(value) = x.field { do_nothing(value + captured); }
if let Some(value) = x.field { do_nothing(value + captured); }
if let Some(value) = x.field { diverge(value + captured) }
if let Some(value) = x.field { diverge(value + captured) }
if let Some(value) = x.field { diverge(value + captured); }
if let Some(value) = x.field { diverge(value + captured); }
x.field.map(|value| plus_one(value + captured));
x.field.map(|value| { plus_one(value + captured) });
if let Some(value) = x.field { let y = plus_one(value + captured); }
if let Some(value) = x.field { plus_one(value + captured); }
if let Some(value) = x.field { plus_one(value + captured); }
if let Some(ref value) = x.field { do_nothing(value + captured) }}
fn main() {}

View file

@ -1,3 +1,5 @@
// run-rustfix
#![warn(clippy::option_map_unit_fn)]
#![allow(unused)]
@ -71,29 +73,6 @@ fn option_map_unit_fn() {
x.field.map(|value| { { plus_one(value + captured); } });
x.field.map(|ref value| { do_nothing(value + captured) });
x.field.map(|value| { do_nothing(value); do_nothing(value) });
x.field.map(|value| if value > 0 { do_nothing(value); do_nothing(value) });
// Suggestion for the let block should be `{ ... }` as it's too difficult to build a
// proper suggestion for these cases
x.field.map(|value| {
do_nothing(value);
do_nothing(value)
});
x.field.map(|value| { do_nothing(value); do_nothing(value); });
// The following should suggest `if let Some(_X) ...` as it's difficult to generate a proper let variable name for them
Some(42).map(diverge);
"12".parse::<i32>().ok().map(diverge);
Some(plus_one(1)).map(do_nothing);
// Should suggest `if let Some(_y) ...` to not override the existing foo variable
let y = Some(42);
y.map(do_nothing);
}
x.field.map(|ref value| { do_nothing(value + captured) });}
fn main() {}

View file

@ -1,31 +1,31 @@
error: called `map(f)` on an Option value where `f` is a unit function
--> $DIR/option_map_unit_fn.rs:32:5
--> $DIR/option_map_unit_fn_fixable.rs:34:5
|
LL | x.field.map(do_nothing);
| ^^^^^^^^^^^^^^^^^^^^^^^-
| |
| help: try this: `if let Some(x_field) = x.field { do_nothing(...) }`
| help: try this: `if let Some(x_field) = x.field { do_nothing(x_field) }`
|
= note: `-D clippy::option-map-unit-fn` implied by `-D warnings`
error: called `map(f)` on an Option value where `f` is a unit function
--> $DIR/option_map_unit_fn.rs:34:5
--> $DIR/option_map_unit_fn_fixable.rs:36:5
|
LL | x.field.map(do_nothing);
| ^^^^^^^^^^^^^^^^^^^^^^^-
| |
| help: try this: `if let Some(x_field) = x.field { do_nothing(...) }`
| help: try this: `if let Some(x_field) = x.field { do_nothing(x_field) }`
error: called `map(f)` on an Option value where `f` is a unit function
--> $DIR/option_map_unit_fn.rs:36:5
--> $DIR/option_map_unit_fn_fixable.rs:38:5
|
LL | x.field.map(diverge);
| ^^^^^^^^^^^^^^^^^^^^-
| |
| help: try this: `if let Some(x_field) = x.field { diverge(...) }`
| help: try this: `if let Some(x_field) = x.field { diverge(x_field) }`
error: called `map(f)` on an Option value where `f` is a unit closure
--> $DIR/option_map_unit_fn.rs:42:5
--> $DIR/option_map_unit_fn_fixable.rs:44:5
|
LL | x.field.map(|value| x.do_option_nothing(value + captured));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
@ -33,7 +33,7 @@ LL | x.field.map(|value| x.do_option_nothing(value + captured));
| help: try this: `if let Some(value) = x.field { x.do_option_nothing(value + captured) }`
error: called `map(f)` on an Option value where `f` is a unit closure
--> $DIR/option_map_unit_fn.rs:44:5
--> $DIR/option_map_unit_fn_fixable.rs:46:5
|
LL | x.field.map(|value| { x.do_option_plus_one(value + captured); });
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
@ -41,7 +41,7 @@ LL | x.field.map(|value| { x.do_option_plus_one(value + captured); });
| help: try this: `if let Some(value) = x.field { x.do_option_plus_one(value + captured); }`
error: called `map(f)` on an Option value where `f` is a unit closure
--> $DIR/option_map_unit_fn.rs:47:5
--> $DIR/option_map_unit_fn_fixable.rs:49:5
|
LL | x.field.map(|value| do_nothing(value + captured));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
@ -49,7 +49,7 @@ LL | x.field.map(|value| do_nothing(value + captured));
| help: try this: `if let Some(value) = x.field { do_nothing(value + captured) }`
error: called `map(f)` on an Option value where `f` is a unit closure
--> $DIR/option_map_unit_fn.rs:49:5
--> $DIR/option_map_unit_fn_fixable.rs:51:5
|
LL | x.field.map(|value| { do_nothing(value + captured) });
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
@ -57,7 +57,7 @@ LL | x.field.map(|value| { do_nothing(value + captured) });
| help: try this: `if let Some(value) = x.field { do_nothing(value + captured) }`
error: called `map(f)` on an Option value where `f` is a unit closure
--> $DIR/option_map_unit_fn.rs:51:5
--> $DIR/option_map_unit_fn_fixable.rs:53:5
|
LL | x.field.map(|value| { do_nothing(value + captured); });
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
@ -65,7 +65,7 @@ LL | x.field.map(|value| { do_nothing(value + captured); });
| help: try this: `if let Some(value) = x.field { do_nothing(value + captured); }`
error: called `map(f)` on an Option value where `f` is a unit closure
--> $DIR/option_map_unit_fn.rs:53:5
--> $DIR/option_map_unit_fn_fixable.rs:55:5
|
LL | x.field.map(|value| { { do_nothing(value + captured); } });
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
@ -73,7 +73,7 @@ LL | x.field.map(|value| { { do_nothing(value + captured); } });
| help: try this: `if let Some(value) = x.field { do_nothing(value + captured); }`
error: called `map(f)` on an Option value where `f` is a unit closure
--> $DIR/option_map_unit_fn.rs:56:5
--> $DIR/option_map_unit_fn_fixable.rs:58:5
|
LL | x.field.map(|value| diverge(value + captured));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
@ -81,7 +81,7 @@ LL | x.field.map(|value| diverge(value + captured));
| help: try this: `if let Some(value) = x.field { diverge(value + captured) }`
error: called `map(f)` on an Option value where `f` is a unit closure
--> $DIR/option_map_unit_fn.rs:58:5
--> $DIR/option_map_unit_fn_fixable.rs:60:5
|
LL | x.field.map(|value| { diverge(value + captured) });
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
@ -89,7 +89,7 @@ LL | x.field.map(|value| { diverge(value + captured) });
| help: try this: `if let Some(value) = x.field { diverge(value + captured) }`
error: called `map(f)` on an Option value where `f` is a unit closure
--> $DIR/option_map_unit_fn.rs:60:5
--> $DIR/option_map_unit_fn_fixable.rs:62:5
|
LL | x.field.map(|value| { diverge(value + captured); });
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
@ -97,7 +97,7 @@ LL | x.field.map(|value| { diverge(value + captured); });
| help: try this: `if let Some(value) = x.field { diverge(value + captured); }`
error: called `map(f)` on an Option value where `f` is a unit closure
--> $DIR/option_map_unit_fn.rs:62:5
--> $DIR/option_map_unit_fn_fixable.rs:64:5
|
LL | x.field.map(|value| { { diverge(value + captured); } });
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
@ -105,7 +105,7 @@ LL | x.field.map(|value| { { diverge(value + captured); } });
| help: try this: `if let Some(value) = x.field { diverge(value + captured); }`
error: called `map(f)` on an Option value where `f` is a unit closure
--> $DIR/option_map_unit_fn.rs:67:5
--> $DIR/option_map_unit_fn_fixable.rs:69:5
|
LL | x.field.map(|value| { let y = plus_one(value + captured); });
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
@ -113,7 +113,7 @@ LL | x.field.map(|value| { let y = plus_one(value + captured); });
| help: try this: `if let Some(value) = x.field { let y = plus_one(value + captured); }`
error: called `map(f)` on an Option value where `f` is a unit closure
--> $DIR/option_map_unit_fn.rs:69:5
--> $DIR/option_map_unit_fn_fixable.rs:71:5
|
LL | x.field.map(|value| { plus_one(value + captured); });
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
@ -121,7 +121,7 @@ LL | x.field.map(|value| { plus_one(value + captured); });
| help: try this: `if let Some(value) = x.field { plus_one(value + captured); }`
error: called `map(f)` on an Option value where `f` is a unit closure
--> $DIR/option_map_unit_fn.rs:71:5
--> $DIR/option_map_unit_fn_fixable.rs:73:5
|
LL | x.field.map(|value| { { plus_one(value + captured); } });
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
@ -129,82 +129,12 @@ LL | x.field.map(|value| { { plus_one(value + captured); } });
| help: try this: `if let Some(value) = x.field { plus_one(value + captured); }`
error: called `map(f)` on an Option value where `f` is a unit closure
--> $DIR/option_map_unit_fn.rs:74:5
--> $DIR/option_map_unit_fn_fixable.rs:76:5
|
LL | x.field.map(|ref value| { do_nothing(value + captured) });
LL | x.field.map(|ref value| { do_nothing(value + captured) });}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
| |
| help: try this: `if let Some(ref value) = x.field { do_nothing(value + captured) }`
error: called `map(f)` on an Option value where `f` is a unit closure
--> $DIR/option_map_unit_fn.rs:77:5
|
LL | x.field.map(|value| { do_nothing(value); do_nothing(value) });
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
| |
| help: try this: `if let Some(value) = x.field { ... }`
error: called `map(f)` on an Option value where `f` is a unit closure
--> $DIR/option_map_unit_fn.rs:79:5
|
LL | x.field.map(|value| if value > 0 { do_nothing(value); do_nothing(value) });
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
| |
| help: try this: `if let Some(value) = x.field { ... }`
error: called `map(f)` on an Option value where `f` is a unit closure
--> $DIR/option_map_unit_fn.rs:83:5
|
LL | x.field.map(|value| {
| _____^
| |_____|
| ||
LL | || do_nothing(value);
LL | || do_nothing(value)
LL | || });
| ||______^- help: try this: `if let Some(value) = x.field { ... }`
| |_______|
|
error: called `map(f)` on an Option value where `f` is a unit closure
--> $DIR/option_map_unit_fn.rs:87:5
|
LL | x.field.map(|value| { do_nothing(value); do_nothing(value); });
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
| |
| help: try this: `if let Some(value) = x.field { ... }`
error: called `map(f)` on an Option value where `f` is a unit function
--> $DIR/option_map_unit_fn.rs:90:5
|
LL | Some(42).map(diverge);
| ^^^^^^^^^^^^^^^^^^^^^-
| |
| help: try this: `if let Some(_) = Some(42) { diverge(...) }`
error: called `map(f)` on an Option value where `f` is a unit function
--> $DIR/option_map_unit_fn.rs:91:5
|
LL | "12".parse::<i32>().ok().map(diverge);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
| |
| help: try this: `if let Some(_) = "12".parse::<i32>().ok() { diverge(...) }`
error: called `map(f)` on an Option value where `f` is a unit function
--> $DIR/option_map_unit_fn.rs:92:5
|
LL | Some(plus_one(1)).map(do_nothing);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
| |
| help: try this: `if let Some(_) = Some(plus_one(1)) { do_nothing(...) }`
error: called `map(f)` on an Option value where `f` is a unit function
--> $DIR/option_map_unit_fn.rs:96:5
|
LL | y.map(do_nothing);
| ^^^^^^^^^^^^^^^^^-
| |
| help: try this: `if let Some(_y) = y { do_nothing(...) }`
error: aborting due to 25 previous errors
error: aborting due to 17 previous errors

View file

@ -0,0 +1,39 @@
#![warn(clippy::option_map_unit_fn)]
#![allow(unused)]
fn do_nothing<T>(_: T) {}
fn diverge<T>(_: T) -> ! {
panic!()
}
fn plus_one(value: usize) -> usize {
value + 1
}
#[rustfmt::skip]
fn option_map_unit_fn() {
x.field.map(|value| { do_nothing(value); do_nothing(value) });
x.field.map(|value| if value > 0 { do_nothing(value); do_nothing(value) });
// Suggestion for the let block should be `{ ... }` as it's too difficult to build a
// proper suggestion for these cases
x.field.map(|value| {
do_nothing(value);
do_nothing(value)
});
x.field.map(|value| { do_nothing(value); do_nothing(value); });
// The following should suggest `if let Some(_X) ...` as it's difficult to generate a proper let variable name for them
Some(42).map(diverge);
"12".parse::<i32>().ok().map(diverge);
Some(plus_one(1)).map(do_nothing);
// Should suggest `if let Some(_y) ...` to not override the existing foo variable
let y = Some(42);
y.map(do_nothing);
}
fn main() {}

View file

@ -0,0 +1,27 @@
error[E0425]: cannot find value `x` in this scope
--> $DIR/option_map_unit_fn_unfixable.rs:17:5
|
LL | x.field.map(|value| { do_nothing(value); do_nothing(value) });
| ^ not found in this scope
error[E0425]: cannot find value `x` in this scope
--> $DIR/option_map_unit_fn_unfixable.rs:19:5
|
LL | x.field.map(|value| if value > 0 { do_nothing(value); do_nothing(value) });
| ^ not found in this scope
error[E0425]: cannot find value `x` in this scope
--> $DIR/option_map_unit_fn_unfixable.rs:23:5
|
LL | x.field.map(|value| {
| ^ not found in this scope
error[E0425]: cannot find value `x` in this scope
--> $DIR/option_map_unit_fn_unfixable.rs:27:5
|
LL | x.field.map(|value| { do_nothing(value); do_nothing(value); });
| ^ not found in this scope
error: aborting due to 4 previous errors
For more information about this error, try `rustc --explain E0425`.

View file

@ -1,8 +1,8 @@
// non rustfixable, see redundant_closure_call_fixable.rs
#![warn(clippy::redundant_closure_call)]
fn main() {
let a = (|| 42)();
let mut i = 1;
let mut k = (|m| m + 1)(i);

View file

@ -12,12 +12,6 @@ error: Closure called just once immediately after it was declared
LL | i = closure(3);
| ^^^^^^^^^^^^^^
error: Try not to call a closure in the expression where it is declared.
--> $DIR/redundant_closure_call.rs:4:13
|
LL | let a = (|| 42)();
| ^^^^^^^^^ help: Try doing something like: : `42`
error: Try not to call a closure in the expression where it is declared.
--> $DIR/redundant_closure_call.rs:7:17
|
@ -30,5 +24,5 @@ error: Try not to call a closure in the expression where it is declared.
LL | k = (|a, b| a * b)(1, 5);
| ^^^^^^^^^^^^^^^^^^^^
error: aborting due to 5 previous errors
error: aborting due to 4 previous errors

View file

@ -0,0 +1,8 @@
// run-rustfix
#![warn(clippy::redundant_closure_call)]
#![allow(unused)]
fn main() {
let a = 42;
}

View file

@ -0,0 +1,8 @@
// run-rustfix
#![warn(clippy::redundant_closure_call)]
#![allow(unused)]
fn main() {
let a = (|| 42)();
}

View file

@ -0,0 +1,10 @@
error: Try not to call a closure in the expression where it is declared.
--> $DIR/redundant_closure_call_fixable.rs:7:13
|
LL | let a = (|| 42)();
| ^^^^^^^^^ help: Try doing something like: : `42`
|
= note: `-D clippy::redundant-closure-call` implied by `-D warnings`
error: aborting due to previous error

View file

@ -0,0 +1,60 @@
// run-rustfix
#![warn(clippy::all)]
#![warn(clippy::redundant_pattern_matching)]
#![allow(clippy::unit_arg, clippy::let_unit_value, unused_must_use)]
fn main() {
Ok::<i32, i32>(42).is_ok();
Err::<i32, i32>(42).is_err();
None::<()>.is_none();
Some(42).is_some();
if Ok::<i32, i32>(42).is_ok() {}
if Err::<i32, i32>(42).is_err() {}
if None::<i32>.is_none() {}
if Some(42).is_some() {}
if let Ok(x) = Ok::<i32, i32>(42) {
println!("{}", x);
}
Ok::<i32, i32>(42).is_ok();
Ok::<i32, i32>(42).is_err();
Err::<i32, i32>(42).is_err();
Err::<i32, i32>(42).is_ok();
Some(42).is_some();
None::<()>.is_none();
let _ = None::<()>.is_none();
let _ = Ok::<usize, ()>(4).is_ok();
let _ = does_something();
let _ = returns_unit();
let opt = Some(false);
let x = opt.is_some();
takes_bool(x);
}
fn takes_bool(_: bool) {}
fn does_something() -> bool {
Ok::<i32, i32>(4).is_ok()
}
fn returns_unit() {
Ok::<i32, i32>(4).is_ok();
}

View file

@ -1,6 +1,8 @@
// run-rustfix
#![warn(clippy::all)]
#![warn(clippy::redundant_pattern_matching)]
#![allow(clippy::unit_arg, clippy::let_unit_value)]
#![allow(clippy::unit_arg, clippy::let_unit_value, unused_must_use)]
fn main() {
if let Ok(_) = Ok::<i32, i32>(42) {}
@ -66,12 +68,9 @@ fn main() {
let opt = Some(false);
let x = if let Some(_) = opt { true } else { false };
takes_bool(x);
let y = if let Some(_) = opt {};
takes_unit(y);
}
fn takes_bool(x: bool) {}
fn takes_unit(x: ()) {}
fn takes_bool(_: bool) {}
fn does_something() -> bool {
if let Ok(_) = Ok::<i32, i32>(4) {

View file

@ -1,31 +1,31 @@
error: redundant pattern matching, consider using `is_ok()`
--> $DIR/redundant_pattern_matching.rs:6:12
--> $DIR/redundant_pattern_matching.rs:8:12
|
LL | if let Ok(_) = Ok::<i32, i32>(42) {}
| -------^^^^^------------------------ help: try this: `Ok::<i32, i32>(42).is_ok()`
| -------^^^^^------------------------ help: try this: `Ok::<i32, i32>(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.rs:8:12
|
LL | if let Err(_) = Err::<i32, i32>(42) {}
| -------^^^^^^------------------------- help: try this: `Err::<i32, i32>(42).is_err()`
error: redundant pattern matching, consider using `is_none()`
--> $DIR/redundant_pattern_matching.rs:10:12
|
LL | if let None = None::<()> {}
| -------^^^^---------------- help: try this: `None::<()>.is_none()`
LL | if let Err(_) = Err::<i32, i32>(42) {}
| -------^^^^^^------------------------- help: try this: `Err::<i32, i32>(42).is_err();`
error: redundant pattern matching, consider using `is_some()`
error: redundant pattern matching, consider using `is_none()`
--> $DIR/redundant_pattern_matching.rs:12:12
|
LL | if let None = None::<()> {}
| -------^^^^---------------- help: try this: `None::<()>.is_none();`
error: redundant pattern matching, consider using `is_some()`
--> $DIR/redundant_pattern_matching.rs:14:12
|
LL | if let Some(_) = Some(42) {}
| -------^^^^^^^-------------- help: try this: `Some(42).is_some()`
| -------^^^^^^^-------------- help: try this: `Some(42).is_some();`
error: redundant pattern matching, consider using `is_ok()`
--> $DIR/redundant_pattern_matching.rs:26:5
--> $DIR/redundant_pattern_matching.rs:28:5
|
LL | / match Ok::<i32, i32>(42) {
LL | | Ok(_) => true,
@ -34,7 +34,7 @@ LL | | };
| |_____^ help: try this: `Ok::<i32, i32>(42).is_ok()`
error: redundant pattern matching, consider using `is_err()`
--> $DIR/redundant_pattern_matching.rs:31:5
--> $DIR/redundant_pattern_matching.rs:33:5
|
LL | / match Ok::<i32, i32>(42) {
LL | | Ok(_) => false,
@ -43,7 +43,7 @@ LL | | };
| |_____^ help: try this: `Ok::<i32, i32>(42).is_err()`
error: redundant pattern matching, consider using `is_err()`
--> $DIR/redundant_pattern_matching.rs:36:5
--> $DIR/redundant_pattern_matching.rs:38:5
|
LL | / match Err::<i32, i32>(42) {
LL | | Ok(_) => false,
@ -52,7 +52,7 @@ LL | | };
| |_____^ help: try this: `Err::<i32, i32>(42).is_err()`
error: redundant pattern matching, consider using `is_ok()`
--> $DIR/redundant_pattern_matching.rs:41:5
--> $DIR/redundant_pattern_matching.rs:43:5
|
LL | / match Err::<i32, i32>(42) {
LL | | Ok(_) => true,
@ -61,7 +61,7 @@ LL | | };
| |_____^ help: try this: `Err::<i32, i32>(42).is_ok()`
error: redundant pattern matching, consider using `is_some()`
--> $DIR/redundant_pattern_matching.rs:46:5
--> $DIR/redundant_pattern_matching.rs:48:5
|
LL | / match Some(42) {
LL | | Some(_) => true,
@ -70,7 +70,7 @@ LL | | };
| |_____^ help: try this: `Some(42).is_some()`
error: redundant pattern matching, consider using `is_none()`
--> $DIR/redundant_pattern_matching.rs:51:5
--> $DIR/redundant_pattern_matching.rs:53:5
|
LL | / match None::<()> {
LL | | Some(_) => false,
@ -79,7 +79,7 @@ LL | | };
| |_____^ help: try this: `None::<()>.is_none()`
error: redundant pattern matching, consider using `is_none()`
--> $DIR/redundant_pattern_matching.rs:56:13
--> $DIR/redundant_pattern_matching.rs:58:13
|
LL | let _ = match None::<()> {
| _____________^
@ -89,25 +89,19 @@ LL | | };
| |_____^ help: try this: `None::<()>.is_none()`
error: redundant pattern matching, consider using `is_ok()`
--> $DIR/redundant_pattern_matching.rs:61:20
--> $DIR/redundant_pattern_matching.rs:63:20
|
LL | let _ = if let Ok(_) = Ok::<usize, ()>(4) { true } else { false };
| -------^^^^^--------------------------------------------- help: try this: `Ok::<usize, ()>(4).is_ok()`
error: redundant pattern matching, consider using `is_some()`
--> $DIR/redundant_pattern_matching.rs:67:20
--> $DIR/redundant_pattern_matching.rs:69:20
|
LL | let x = if let Some(_) = opt { true } else { false };
| -------^^^^^^^------------------------------ help: try this: `opt.is_some()`
error: redundant pattern matching, consider using `is_some()`
--> $DIR/redundant_pattern_matching.rs:69:20
|
LL | let y = if let Some(_) = opt {};
| -------^^^^^^^--------- help: try this: `opt.is_some()`
error: redundant pattern matching, consider using `is_ok()`
--> $DIR/redundant_pattern_matching.rs:77:12
--> $DIR/redundant_pattern_matching.rs:76:12
|
LL | if let Ok(_) = Ok::<i32, i32>(4) {
| _____- ^^^^^
@ -118,7 +112,7 @@ LL | | }
| |_____- help: try this: `Ok::<i32, i32>(4).is_ok()`
error: redundant pattern matching, consider using `is_ok()`
--> $DIR/redundant_pattern_matching.rs:85:12
--> $DIR/redundant_pattern_matching.rs:84:12
|
LL | if let Ok(_) = Ok::<i32, i32>(4) {
| _____- ^^^^^
@ -128,5 +122,5 @@ LL | | false
LL | | };
| |_____- help: try this: `Ok::<i32, i32>(4).is_ok()`
error: aborting due to 16 previous errors
error: aborting due to 15 previous errors

View file

@ -0,0 +1,56 @@
// run-rustfix
#![allow(unused)]
#[derive(Debug)]
struct Foo {}
const VAR_ONE: &str = "Test constant #1"; // ERROR Consider removing 'static.
const VAR_TWO: &str = "Test constant #2"; // This line should not raise a warning.
const VAR_THREE: &[&str] = &["one", "two"]; // ERROR Consider removing 'static
const VAR_FOUR: (&str, (&str, &str), &str) = ("on", ("th", "th"), "on"); // ERROR Consider removing 'static
const VAR_SIX: &u8 = &5;
const VAR_HEIGHT: &Foo = &Foo {};
const VAR_SLICE: &[u8] = b"Test constant #1"; // ERROR Consider removing 'static.
const VAR_TUPLE: &(u8, u8) = &(1, 2); // ERROR Consider removing 'static.
const VAR_ARRAY: &[u8; 1] = b"T"; // ERROR Consider removing 'static.
static STATIC_VAR_ONE: &str = "Test static #1"; // ERROR Consider removing 'static.
static STATIC_VAR_TWO: &str = "Test static #2"; // This line should not raise a warning.
static STATIC_VAR_THREE: &[&str] = &["one", "two"]; // ERROR Consider removing 'static
static STATIC_VAR_SIX: &u8 = &5;
static STATIC_VAR_HEIGHT: &Foo = &Foo {};
static STATIC_VAR_SLICE: &[u8] = b"Test static #3"; // ERROR Consider removing 'static.
static STATIC_VAR_TUPLE: &(u8, u8) = &(1, 2); // ERROR Consider removing 'static.
static STATIC_VAR_ARRAY: &[u8; 1] = b"T"; // ERROR Consider removing 'static.
fn main() {
let false_positive: &'static str = "test";
}
trait Bar {
const TRAIT_VAR: &'static str;
}
impl Foo {
const IMPL_VAR: &'static str = "var";
}
impl Bar for Foo {
const TRAIT_VAR: &'static str = "foo";
}

View file

@ -1,3 +1,7 @@
// run-rustfix
#![allow(unused)]
#[derive(Debug)]
struct Foo {}
@ -9,12 +13,8 @@ const VAR_THREE: &[&'static str] = &["one", "two"]; // ERROR Consider removing '
const VAR_FOUR: (&str, (&str, &'static str), &'static str) = ("on", ("th", "th"), "on"); // ERROR Consider removing 'static
const VAR_FIVE: &'static [&[&'static str]] = &[&["test"], &["other one"]]; // ERROR Consider removing 'static
const VAR_SIX: &'static u8 = &5;
const VAR_SEVEN: &[&(&str, &'static [&'static str])] = &[&("one", &["other one"])];
const VAR_HEIGHT: &'static Foo = &Foo {};
const VAR_SLICE: &'static [u8] = b"Test constant #1"; // ERROR Consider removing 'static.
@ -29,14 +29,8 @@ static STATIC_VAR_TWO: &str = "Test static #2"; // This line should not raise a
static STATIC_VAR_THREE: &[&'static str] = &["one", "two"]; // ERROR Consider removing 'static
static STATIC_VAR_FOUR: (&str, (&str, &'static str), &'static str) = ("on", ("th", "th"), "on"); // ERROR Consider removing 'static
static STATIC_VAR_FIVE: &'static [&[&'static str]] = &[&["test"], &["other one"]]; // ERROR Consider removing 'static
static STATIC_VAR_SIX: &'static u8 = &5;
static STATIC_VAR_SEVEN: &[&(&str, &'static [&'static str])] = &[&("one", &["other one"])];
static STATIC_VAR_HEIGHT: &'static Foo = &Foo {};
static STATIC_VAR_SLICE: &'static [u8] = b"Test static #3"; // ERROR Consider removing 'static.
@ -47,15 +41,6 @@ static STATIC_VAR_ARRAY: &'static [u8; 1] = b"T"; // ERROR Consider removing 'st
fn main() {
let false_positive: &'static str = "test";
println!("{}", VAR_ONE);
println!("{}", VAR_TWO);
println!("{:?}", VAR_THREE);
println!("{:?}", VAR_FOUR);
println!("{:?}", VAR_FIVE);
println!("{:?}", VAR_SIX);
println!("{:?}", VAR_SEVEN);
println!("{:?}", VAR_HEIGHT);
println!("{}", false_positive);
}
trait Bar {

View file

@ -1,5 +1,5 @@
error: Constants have by default a `'static` lifetime
--> $DIR/redundant_static_lifetimes.rs:4:17
--> $DIR/redundant_static_lifetimes.rs:8:17
|
LL | const VAR_ONE: &'static str = "Test constant #1"; // ERROR Consider removing 'static.
| -^^^^^^^---- help: consider removing `'static`: `&str`
@ -7,53 +7,29 @@ LL | const VAR_ONE: &'static str = "Test constant #1"; // ERROR Consider removin
= note: `-D clippy::redundant-static-lifetimes` implied by `-D warnings`
error: Constants have by default a `'static` lifetime
--> $DIR/redundant_static_lifetimes.rs:8:21
--> $DIR/redundant_static_lifetimes.rs:12:21
|
LL | const VAR_THREE: &[&'static str] = &["one", "two"]; // ERROR Consider removing 'static
| -^^^^^^^---- help: consider removing `'static`: `&str`
error: Constants have by default a `'static` lifetime
--> $DIR/redundant_static_lifetimes.rs:10:32
--> $DIR/redundant_static_lifetimes.rs:14:32
|
LL | const VAR_FOUR: (&str, (&str, &'static str), &'static str) = ("on", ("th", "th"), "on"); // ERROR Consider removing 'static
| -^^^^^^^---- help: consider removing `'static`: `&str`
error: Constants have by default a `'static` lifetime
--> $DIR/redundant_static_lifetimes.rs:10:47
--> $DIR/redundant_static_lifetimes.rs:14:47
|
LL | const VAR_FOUR: (&str, (&str, &'static str), &'static str) = ("on", ("th", "th"), "on"); // ERROR Consider removing 'static
| -^^^^^^^---- help: consider removing `'static`: `&str`
error: Constants have by default a `'static` lifetime
--> $DIR/redundant_static_lifetimes.rs:12:18
|
LL | const VAR_FIVE: &'static [&[&'static str]] = &[&["test"], &["other one"]]; // ERROR Consider removing 'static
| -^^^^^^^------------------ help: consider removing `'static`: `&[&[&'static str]]`
error: Constants have by default a `'static` lifetime
--> $DIR/redundant_static_lifetimes.rs:12:30
|
LL | const VAR_FIVE: &'static [&[&'static str]] = &[&["test"], &["other one"]]; // ERROR Consider removing 'static
| -^^^^^^^---- help: consider removing `'static`: `&str`
error: Constants have by default a `'static` lifetime
--> $DIR/redundant_static_lifetimes.rs:14:17
--> $DIR/redundant_static_lifetimes.rs:16:17
|
LL | const VAR_SIX: &'static u8 = &5;
| -^^^^^^^--- help: consider removing `'static`: `&u8`
error: Constants have by default a `'static` lifetime
--> $DIR/redundant_static_lifetimes.rs:16:29
|
LL | const VAR_SEVEN: &[&(&str, &'static [&'static str])] = &[&("one", &["other one"])];
| -^^^^^^^--------------- help: consider removing `'static`: `&[&'static str]`
error: Constants have by default a `'static` lifetime
--> $DIR/redundant_static_lifetimes.rs:16:39
|
LL | const VAR_SEVEN: &[&(&str, &'static [&'static str])] = &[&("one", &["other one"])];
| -^^^^^^^---- help: consider removing `'static`: `&str`
error: Constants have by default a `'static` lifetime
--> $DIR/redundant_static_lifetimes.rs:18:20
|
@ -91,70 +67,34 @@ LL | static STATIC_VAR_THREE: &[&'static str] = &["one", "two"]; // ERROR Consid
| -^^^^^^^---- help: consider removing `'static`: `&str`
error: Statics have by default a `'static` lifetime
--> $DIR/redundant_static_lifetimes.rs:32:40
|
LL | static STATIC_VAR_FOUR: (&str, (&str, &'static str), &'static str) = ("on", ("th", "th"), "on"); // ERROR Consider removing 'static
| -^^^^^^^---- help: consider removing `'static`: `&str`
error: Statics have by default a `'static` lifetime
--> $DIR/redundant_static_lifetimes.rs:32:55
|
LL | static STATIC_VAR_FOUR: (&str, (&str, &'static str), &'static str) = ("on", ("th", "th"), "on"); // ERROR Consider removing 'static
| -^^^^^^^---- help: consider removing `'static`: `&str`
error: Statics have by default a `'static` lifetime
--> $DIR/redundant_static_lifetimes.rs:34:26
|
LL | static STATIC_VAR_FIVE: &'static [&[&'static str]] = &[&["test"], &["other one"]]; // ERROR Consider removing 'static
| -^^^^^^^------------------ help: consider removing `'static`: `&[&[&'static str]]`
error: Statics have by default a `'static` lifetime
--> $DIR/redundant_static_lifetimes.rs:34:38
|
LL | static STATIC_VAR_FIVE: &'static [&[&'static str]] = &[&["test"], &["other one"]]; // ERROR Consider removing 'static
| -^^^^^^^---- help: consider removing `'static`: `&str`
error: Statics have by default a `'static` lifetime
--> $DIR/redundant_static_lifetimes.rs:36:25
--> $DIR/redundant_static_lifetimes.rs:32:25
|
LL | static STATIC_VAR_SIX: &'static u8 = &5;
| -^^^^^^^--- help: consider removing `'static`: `&u8`
error: Statics have by default a `'static` lifetime
--> $DIR/redundant_static_lifetimes.rs:38:37
|
LL | static STATIC_VAR_SEVEN: &[&(&str, &'static [&'static str])] = &[&("one", &["other one"])];
| -^^^^^^^--------------- help: consider removing `'static`: `&[&'static str]`
error: Statics have by default a `'static` lifetime
--> $DIR/redundant_static_lifetimes.rs:38:47
|
LL | static STATIC_VAR_SEVEN: &[&(&str, &'static [&'static str])] = &[&("one", &["other one"])];
| -^^^^^^^---- help: consider removing `'static`: `&str`
error: Statics have by default a `'static` lifetime
--> $DIR/redundant_static_lifetimes.rs:40:28
--> $DIR/redundant_static_lifetimes.rs:34:28
|
LL | static STATIC_VAR_HEIGHT: &'static Foo = &Foo {};
| -^^^^^^^---- help: consider removing `'static`: `&Foo`
error: Statics have by default a `'static` lifetime
--> $DIR/redundant_static_lifetimes.rs:42:27
--> $DIR/redundant_static_lifetimes.rs:36:27
|
LL | static STATIC_VAR_SLICE: &'static [u8] = b"Test static #3"; // ERROR Consider removing 'static.
| -^^^^^^^----- help: consider removing `'static`: `&[u8]`
error: Statics have by default a `'static` lifetime
--> $DIR/redundant_static_lifetimes.rs:44:27
--> $DIR/redundant_static_lifetimes.rs:38:27
|
LL | static STATIC_VAR_TUPLE: &'static (u8, u8) = &(1, 2); // ERROR Consider removing 'static.
| -^^^^^^^--------- help: consider removing `'static`: `&(u8, u8)`
error: Statics have by default a `'static` lifetime
--> $DIR/redundant_static_lifetimes.rs:46:27
--> $DIR/redundant_static_lifetimes.rs:40:27
|
LL | static STATIC_VAR_ARRAY: &'static [u8; 1] = b"T"; // ERROR Consider removing 'static.
| -^^^^^^^-------- help: consider removing `'static`: `&[u8; 1]`
error: aborting due to 26 previous errors
error: aborting due to 16 previous errors

View file

@ -0,0 +1,13 @@
// these are rustfixable, but run-rustfix tests cannot handle them
const VAR_FIVE: &'static [&[&'static str]] = &[&["test"], &["other one"]]; // ERROR Consider removing 'static
const VAR_SEVEN: &[&(&str, &'static [&'static str])] = &[&("one", &["other one"])];
static STATIC_VAR_FOUR: (&str, (&str, &'static str), &'static str) = ("on", ("th", "th"), "on"); // ERROR Consider removing 'static
static STATIC_VAR_FIVE: &'static [&[&'static str]] = &[&["test"], &["other one"]]; // ERROR Consider removing 'static
static STATIC_VAR_SEVEN: &[&(&str, &'static [&'static str])] = &[&("one", &["other one"])];
fn main() {}

View file

@ -0,0 +1,64 @@
error: Constants have by default a `'static` lifetime
--> $DIR/redundant_static_lifetimes_multiple.rs:3:18
|
LL | const VAR_FIVE: &'static [&[&'static str]] = &[&["test"], &["other one"]]; // ERROR Consider removing 'static
| -^^^^^^^------------------ help: consider removing `'static`: `&[&[&'static str]]`
|
= note: `-D clippy::redundant-static-lifetimes` implied by `-D warnings`
error: Constants have by default a `'static` lifetime
--> $DIR/redundant_static_lifetimes_multiple.rs:3:30
|
LL | const VAR_FIVE: &'static [&[&'static str]] = &[&["test"], &["other one"]]; // ERROR Consider removing 'static
| -^^^^^^^---- help: consider removing `'static`: `&str`
error: Constants have by default a `'static` lifetime
--> $DIR/redundant_static_lifetimes_multiple.rs:5:29
|
LL | const VAR_SEVEN: &[&(&str, &'static [&'static str])] = &[&("one", &["other one"])];
| -^^^^^^^--------------- help: consider removing `'static`: `&[&'static str]`
error: Constants have by default a `'static` lifetime
--> $DIR/redundant_static_lifetimes_multiple.rs:5:39
|
LL | const VAR_SEVEN: &[&(&str, &'static [&'static str])] = &[&("one", &["other one"])];
| -^^^^^^^---- help: consider removing `'static`: `&str`
error: Statics have by default a `'static` lifetime
--> $DIR/redundant_static_lifetimes_multiple.rs:7:40
|
LL | static STATIC_VAR_FOUR: (&str, (&str, &'static str), &'static str) = ("on", ("th", "th"), "on"); // ERROR Consider removing 'static
| -^^^^^^^---- help: consider removing `'static`: `&str`
error: Statics have by default a `'static` lifetime
--> $DIR/redundant_static_lifetimes_multiple.rs:7:55
|
LL | static STATIC_VAR_FOUR: (&str, (&str, &'static str), &'static str) = ("on", ("th", "th"), "on"); // ERROR Consider removing 'static
| -^^^^^^^---- help: consider removing `'static`: `&str`
error: Statics have by default a `'static` lifetime
--> $DIR/redundant_static_lifetimes_multiple.rs:9:26
|
LL | static STATIC_VAR_FIVE: &'static [&[&'static str]] = &[&["test"], &["other one"]]; // ERROR Consider removing 'static
| -^^^^^^^------------------ help: consider removing `'static`: `&[&[&'static str]]`
error: Statics have by default a `'static` lifetime
--> $DIR/redundant_static_lifetimes_multiple.rs:9:38
|
LL | static STATIC_VAR_FIVE: &'static [&[&'static str]] = &[&["test"], &["other one"]]; // ERROR Consider removing 'static
| -^^^^^^^---- help: consider removing `'static`: `&str`
error: Statics have by default a `'static` lifetime
--> $DIR/redundant_static_lifetimes_multiple.rs:11:37
|
LL | static STATIC_VAR_SEVEN: &[&(&str, &'static [&'static str])] = &[&("one", &["other one"])];
| -^^^^^^^--------------- help: consider removing `'static`: `&[&'static str]`
error: Statics have by default a `'static` lifetime
--> $DIR/redundant_static_lifetimes_multiple.rs:11:47
|
LL | static STATIC_VAR_SEVEN: &[&(&str, &'static [&'static str])] = &[&("one", &["other one"])];
| -^^^^^^^---- help: consider removing `'static`: `&str`
error: aborting due to 10 previous errors

View file

@ -0,0 +1,4 @@
// run-rustfix
#[clippy::cognitive_complexity = "1"]
fn main() {}

View file

@ -1,2 +1,4 @@
// run-rustfix
#[clippy::cyclomatic_complexity = "1"]
fn main() {}

View file

@ -1,5 +1,5 @@
error: Usage of deprecated attribute
--> $DIR/renamed_builtin_attr.rs:1:11
--> $DIR/renamed_builtin_attr.rs:3:11
|
LL | #[clippy::cyclomatic_complexity = "1"]
| ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `cognitive_complexity`

View file

@ -0,0 +1,81 @@
// run-rustfix
#![feature(never_type)]
#![warn(clippy::result_map_unit_fn)]
#![allow(unused)]
fn do_nothing<T>(_: T) {}
fn diverge<T>(_: T) -> ! {
panic!()
}
fn plus_one(value: usize) -> usize {
value + 1
}
struct HasResult {
field: Result<usize, usize>,
}
impl HasResult {
fn do_result_nothing(self: &Self, value: usize) {}
fn do_result_plus_one(self: &Self, value: usize) -> usize {
value + 1
}
}
#[rustfmt::skip]
fn result_map_unit_fn() {
let x = HasResult { field: Ok(10) };
x.field.map(plus_one);
let _: Result<(), usize> = x.field.map(do_nothing);
if let Ok(x_field) = x.field { do_nothing(x_field) }
if let Ok(x_field) = x.field { do_nothing(x_field) }
if let Ok(x_field) = x.field { diverge(x_field) }
let captured = 10;
if let Ok(value) = x.field { do_nothing(value + captured) };
let _: Result<(), usize> = x.field.map(|value| do_nothing(value + captured));
if let Ok(value) = x.field { x.do_result_nothing(value + captured) }
if let Ok(value) = x.field { x.do_result_plus_one(value + captured); }
if let Ok(value) = x.field { do_nothing(value + captured) }
if let Ok(value) = x.field { do_nothing(value + captured) }
if let Ok(value) = x.field { do_nothing(value + captured); }
if let Ok(value) = x.field { do_nothing(value + captured); }
if let Ok(value) = x.field { diverge(value + captured) }
if let Ok(value) = x.field { diverge(value + captured) }
if let Ok(value) = x.field { diverge(value + captured); }
if let Ok(value) = x.field { diverge(value + captured); }
x.field.map(|value| plus_one(value + captured));
x.field.map(|value| { plus_one(value + captured) });
if let Ok(value) = x.field { let y = plus_one(value + captured); }
if let Ok(value) = x.field { plus_one(value + captured); }
if let Ok(value) = x.field { plus_one(value + captured); }
if let Ok(ref value) = x.field { do_nothing(value + captured) }
}
fn main() {}

View file

@ -1,3 +1,5 @@
// run-rustfix
#![feature(never_type)]
#![warn(clippy::result_map_unit_fn)]
#![allow(unused)]
@ -74,29 +76,6 @@ fn result_map_unit_fn() {
x.field.map(|ref value| { do_nothing(value + captured) });
x.field.map(|value| { do_nothing(value); do_nothing(value) });
x.field.map(|value| if value > 0 { do_nothing(value); do_nothing(value) });
// Suggestion for the let block should be `{ ... }` as it's too difficult to build a
// proper suggestion for these cases
x.field.map(|value| {
do_nothing(value);
do_nothing(value)
});
x.field.map(|value| { do_nothing(value); do_nothing(value); });
// The following should suggest `if let Ok(_X) ...` as it's difficult to generate a proper let variable name for them
let res: Result<!, usize> = Ok(42).map(diverge);
"12".parse::<i32>().map(diverge);
let res: Result<(), usize> = Ok(plus_one(1)).map(do_nothing);
// Should suggest `if let Ok(_y) ...` to not override the existing foo variable
let y: Result<usize, usize> = Ok(42);
y.map(do_nothing);
}
fn main() {}

View file

@ -1,31 +1,31 @@
error: called `map(f)` on an Result value where `f` is a unit function
--> $DIR/result_map_unit_fn.rs:34:5
--> $DIR/result_map_unit_fn_fixable.rs:36:5
|
LL | x.field.map(do_nothing);
| ^^^^^^^^^^^^^^^^^^^^^^^-
| |
| help: try this: `if let Ok(x_field) = x.field { do_nothing(...) }`
| help: try this: `if let Ok(x_field) = x.field { do_nothing(x_field) }`
|
= note: `-D clippy::result-map-unit-fn` implied by `-D warnings`
error: called `map(f)` on an Result value where `f` is a unit function
--> $DIR/result_map_unit_fn.rs:36:5
--> $DIR/result_map_unit_fn_fixable.rs:38:5
|
LL | x.field.map(do_nothing);
| ^^^^^^^^^^^^^^^^^^^^^^^-
| |
| help: try this: `if let Ok(x_field) = x.field { do_nothing(...) }`
| help: try this: `if let Ok(x_field) = x.field { do_nothing(x_field) }`
error: called `map(f)` on an Result value where `f` is a unit function
--> $DIR/result_map_unit_fn.rs:38:5
--> $DIR/result_map_unit_fn_fixable.rs:40:5
|
LL | x.field.map(diverge);
| ^^^^^^^^^^^^^^^^^^^^-
| |
| help: try this: `if let Ok(x_field) = x.field { diverge(...) }`
| help: try this: `if let Ok(x_field) = x.field { diverge(x_field) }`
error: called `map(f)` on an Result value where `f` is a unit closure
--> $DIR/result_map_unit_fn.rs:44:5
--> $DIR/result_map_unit_fn_fixable.rs:46:5
|
LL | x.field.map(|value| x.do_result_nothing(value + captured));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
@ -33,7 +33,7 @@ LL | x.field.map(|value| x.do_result_nothing(value + captured));
| help: try this: `if let Ok(value) = x.field { x.do_result_nothing(value + captured) }`
error: called `map(f)` on an Result value where `f` is a unit closure
--> $DIR/result_map_unit_fn.rs:46:5
--> $DIR/result_map_unit_fn_fixable.rs:48:5
|
LL | x.field.map(|value| { x.do_result_plus_one(value + captured); });
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
@ -41,7 +41,7 @@ LL | x.field.map(|value| { x.do_result_plus_one(value + captured); });
| help: try this: `if let Ok(value) = x.field { x.do_result_plus_one(value + captured); }`
error: called `map(f)` on an Result value where `f` is a unit closure
--> $DIR/result_map_unit_fn.rs:49:5
--> $DIR/result_map_unit_fn_fixable.rs:51:5
|
LL | x.field.map(|value| do_nothing(value + captured));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
@ -49,7 +49,7 @@ LL | x.field.map(|value| do_nothing(value + captured));
| help: try this: `if let Ok(value) = x.field { do_nothing(value + captured) }`
error: called `map(f)` on an Result value where `f` is a unit closure
--> $DIR/result_map_unit_fn.rs:51:5
--> $DIR/result_map_unit_fn_fixable.rs:53:5
|
LL | x.field.map(|value| { do_nothing(value + captured) });
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
@ -57,7 +57,7 @@ LL | x.field.map(|value| { do_nothing(value + captured) });
| help: try this: `if let Ok(value) = x.field { do_nothing(value + captured) }`
error: called `map(f)` on an Result value where `f` is a unit closure
--> $DIR/result_map_unit_fn.rs:53:5
--> $DIR/result_map_unit_fn_fixable.rs:55:5
|
LL | x.field.map(|value| { do_nothing(value + captured); });
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
@ -65,7 +65,7 @@ LL | x.field.map(|value| { do_nothing(value + captured); });
| help: try this: `if let Ok(value) = x.field { do_nothing(value + captured); }`
error: called `map(f)` on an Result value where `f` is a unit closure
--> $DIR/result_map_unit_fn.rs:55:5
--> $DIR/result_map_unit_fn_fixable.rs:57:5
|
LL | x.field.map(|value| { { do_nothing(value + captured); } });
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
@ -73,7 +73,7 @@ LL | x.field.map(|value| { { do_nothing(value + captured); } });
| help: try this: `if let Ok(value) = x.field { do_nothing(value + captured); }`
error: called `map(f)` on an Result value where `f` is a unit closure
--> $DIR/result_map_unit_fn.rs:58:5
--> $DIR/result_map_unit_fn_fixable.rs:60:5
|
LL | x.field.map(|value| diverge(value + captured));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
@ -81,7 +81,7 @@ LL | x.field.map(|value| diverge(value + captured));
| help: try this: `if let Ok(value) = x.field { diverge(value + captured) }`
error: called `map(f)` on an Result value where `f` is a unit closure
--> $DIR/result_map_unit_fn.rs:60:5
--> $DIR/result_map_unit_fn_fixable.rs:62:5
|
LL | x.field.map(|value| { diverge(value + captured) });
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
@ -89,7 +89,7 @@ LL | x.field.map(|value| { diverge(value + captured) });
| help: try this: `if let Ok(value) = x.field { diverge(value + captured) }`
error: called `map(f)` on an Result value where `f` is a unit closure
--> $DIR/result_map_unit_fn.rs:62:5
--> $DIR/result_map_unit_fn_fixable.rs:64:5
|
LL | x.field.map(|value| { diverge(value + captured); });
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
@ -97,7 +97,7 @@ LL | x.field.map(|value| { diverge(value + captured); });
| help: try this: `if let Ok(value) = x.field { diverge(value + captured); }`
error: called `map(f)` on an Result value where `f` is a unit closure
--> $DIR/result_map_unit_fn.rs:64:5
--> $DIR/result_map_unit_fn_fixable.rs:66:5
|
LL | x.field.map(|value| { { diverge(value + captured); } });
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
@ -105,7 +105,7 @@ LL | x.field.map(|value| { { diverge(value + captured); } });
| help: try this: `if let Ok(value) = x.field { diverge(value + captured); }`
error: called `map(f)` on an Result value where `f` is a unit closure
--> $DIR/result_map_unit_fn.rs:69:5
--> $DIR/result_map_unit_fn_fixable.rs:71:5
|
LL | x.field.map(|value| { let y = plus_one(value + captured); });
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
@ -113,7 +113,7 @@ LL | x.field.map(|value| { let y = plus_one(value + captured); });
| help: try this: `if let Ok(value) = x.field { let y = plus_one(value + captured); }`
error: called `map(f)` on an Result value where `f` is a unit closure
--> $DIR/result_map_unit_fn.rs:71:5
--> $DIR/result_map_unit_fn_fixable.rs:73:5
|
LL | x.field.map(|value| { plus_one(value + captured); });
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
@ -121,7 +121,7 @@ LL | x.field.map(|value| { plus_one(value + captured); });
| help: try this: `if let Ok(value) = x.field { plus_one(value + captured); }`
error: called `map(f)` on an Result value where `f` is a unit closure
--> $DIR/result_map_unit_fn.rs:73:5
--> $DIR/result_map_unit_fn_fixable.rs:75:5
|
LL | x.field.map(|value| { { plus_one(value + captured); } });
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
@ -129,66 +129,12 @@ LL | x.field.map(|value| { { plus_one(value + captured); } });
| help: try this: `if let Ok(value) = x.field { plus_one(value + captured); }`
error: called `map(f)` on an Result value where `f` is a unit closure
--> $DIR/result_map_unit_fn.rs:76:5
--> $DIR/result_map_unit_fn_fixable.rs:78:5
|
LL | x.field.map(|ref value| { do_nothing(value + captured) });
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
| |
| help: try this: `if let Ok(ref value) = x.field { do_nothing(value + captured) }`
error: called `map(f)` on an Result value where `f` is a unit closure
--> $DIR/result_map_unit_fn.rs:79:5
|
LL | x.field.map(|value| { do_nothing(value); do_nothing(value) });
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
| |
| help: try this: `if let Ok(value) = x.field { ... }`
error: called `map(f)` on an Result value where `f` is a unit closure
--> $DIR/result_map_unit_fn.rs:81:5
|
LL | x.field.map(|value| if value > 0 { do_nothing(value); do_nothing(value) });
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
| |
| help: try this: `if let Ok(value) = x.field { ... }`
error: called `map(f)` on an Result value where `f` is a unit closure
--> $DIR/result_map_unit_fn.rs:85:5
|
LL | x.field.map(|value| {
| _____^
| |_____|
| ||
LL | || do_nothing(value);
LL | || do_nothing(value)
LL | || });
| ||______^- help: try this: `if let Ok(value) = x.field { ... }`
| |_______|
|
error: called `map(f)` on an Result value where `f` is a unit closure
--> $DIR/result_map_unit_fn.rs:89:5
|
LL | x.field.map(|value| { do_nothing(value); do_nothing(value); });
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
| |
| help: try this: `if let Ok(value) = x.field { ... }`
error: called `map(f)` on an Result value where `f` is a unit function
--> $DIR/result_map_unit_fn.rs:93:5
|
LL | "12".parse::<i32>().map(diverge);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
| |
| help: try this: `if let Ok(_) = "12".parse::<i32>() { diverge(...) }`
error: called `map(f)` on an Result value where `f` is a unit function
--> $DIR/result_map_unit_fn.rs:99:5
|
LL | y.map(do_nothing);
| ^^^^^^^^^^^^^^^^^-
| |
| help: try this: `if let Ok(_y) = y { do_nothing(...) }`
error: aborting due to 23 previous errors
error: aborting due to 17 previous errors

View file

@ -0,0 +1,40 @@
#![feature(never_type)]
#![warn(clippy::result_map_unit_fn)]
#![allow(unused)]
fn do_nothing<T>(_: T) {}
fn diverge<T>(_: T) -> ! {
panic!()
}
fn plus_one(value: usize) -> usize {
value + 1
}
#[rustfmt::skip]
fn result_map_unit_fn() {
x.field.map(|value| { do_nothing(value); do_nothing(value) });
x.field.map(|value| if value > 0 { do_nothing(value); do_nothing(value) });
// Suggestion for the let block should be `{ ... }` as it's too difficult to build a
// proper suggestion for these cases
x.field.map(|value| {
do_nothing(value);
do_nothing(value)
});
x.field.map(|value| { do_nothing(value); do_nothing(value); });
// The following should suggest `if let Ok(_X) ...` as it's difficult to generate a proper let variable name for them
let res: Result<!, usize> = Ok(42).map(diverge);
"12".parse::<i32>().map(diverge);
let res: Result<(), usize> = Ok(plus_one(1)).map(do_nothing);
// Should suggest `if let Ok(_y) ...` to not override the existing foo variable
let y: Result<usize, usize> = Ok(42);
y.map(do_nothing);
}
fn main() {}

View file

@ -0,0 +1,27 @@
error[E0425]: cannot find value `x` in this scope
--> $DIR/result_map_unit_fn_unfixable.rs:17:5
|
LL | x.field.map(|value| { do_nothing(value); do_nothing(value) });
| ^ not found in this scope
error[E0425]: cannot find value `x` in this scope
--> $DIR/result_map_unit_fn_unfixable.rs:19:5
|
LL | x.field.map(|value| if value > 0 { do_nothing(value); do_nothing(value) });
| ^ not found in this scope
error[E0425]: cannot find value `x` in this scope
--> $DIR/result_map_unit_fn_unfixable.rs:23:5
|
LL | x.field.map(|value| {
| ^ not found in this scope
error[E0425]: cannot find value `x` in this scope
--> $DIR/result_map_unit_fn_unfixable.rs:27:5
|
LL | x.field.map(|value| { do_nothing(value); do_nothing(value); });
| ^ not found in this scope
error: aborting due to 4 previous errors
For more information about this error, try `rustc --explain E0425`.

19
tests/ui/string_add.rs Normal file
View file

@ -0,0 +1,19 @@
#[warn(clippy::string_add)]
#[allow(clippy::string_add_assign, unused)]
fn main() {
// ignores assignment distinction
let mut x = "".to_owned();
for _ in 1..3 {
x = x + ".";
}
let y = "".to_owned();
let z = y + "...";
assert_eq!(&x, &z);
let mut x = 1;
x = x + 1;
assert_eq!(2, x);
}

View file

@ -0,0 +1,30 @@
error: manual implementation of an assign operation
--> $DIR/string_add.rs:8:9
|
LL | x = x + ".";
| ^^^^^^^^^^^ help: replace it with: `x += "."`
|
= note: `-D clippy::assign-op-pattern` implied by `-D warnings`
error: you added something to a string. Consider using `String::push_str()` instead
--> $DIR/string_add.rs:8:13
|
LL | x = x + ".";
| ^^^^^^^
|
= note: `-D clippy::string-add` implied by `-D warnings`
error: you added something to a string. Consider using `String::push_str()` instead
--> $DIR/string_add.rs:12:13
|
LL | let z = y + "...";
| ^^^^^^^^^
error: manual implementation of an assign operation
--> $DIR/string_add.rs:17:5
|
LL | x = x + 1;
| ^^^^^^^^^ help: replace it with: `x += 1`
error: aborting due to 4 previous errors

View file

@ -0,0 +1,21 @@
// run-rustfix
#[allow(clippy::string_add, unused)]
#[warn(clippy::string_add_assign)]
fn main() {
// ignores assignment distinction
let mut x = "".to_owned();
for _ in 1..3 {
x += ".";
}
let y = "".to_owned();
let z = y + "...";
assert_eq!(&x, &z);
let mut x = 1;
x += 1;
assert_eq!(2, x);
}

View file

@ -0,0 +1,21 @@
// run-rustfix
#[allow(clippy::string_add, unused)]
#[warn(clippy::string_add_assign)]
fn main() {
// ignores assignment distinction
let mut x = "".to_owned();
for _ in 1..3 {
x = x + ".";
}
let y = "".to_owned();
let z = y + "...";
assert_eq!(&x, &z);
let mut x = 1;
x = x + 1;
assert_eq!(2, x);
}

View file

@ -0,0 +1,24 @@
error: you assigned the result of adding something to this string. Consider using `String::push_str()` instead
--> $DIR/string_add_assign.rs:10:9
|
LL | x = x + ".";
| ^^^^^^^^^^^
|
= note: `-D clippy::string-add-assign` implied by `-D warnings`
error: manual implementation of an assign operation
--> $DIR/string_add_assign.rs:10:9
|
LL | x = x + ".";
| ^^^^^^^^^^^ help: replace it with: `x += "."`
|
= note: `-D clippy::assign-op-pattern` implied by `-D warnings`
error: manual implementation of an assign operation
--> $DIR/string_add_assign.rs:19:5
|
LL | x = x + 1;
| ^^^^^^^^^ help: replace it with: `x += 1`
error: aborting due to 3 previous errors

View file

@ -14,7 +14,7 @@ fn str_lit_as_bytes() {
let strify = stringify!(foobar).as_bytes();
let includestr = include_bytes!("entry.rs");
let includestr = include_bytes!("entry_unfixable.rs");
}
fn main() {}

View file

@ -14,7 +14,7 @@ fn str_lit_as_bytes() {
let strify = stringify!(foobar).as_bytes();
let includestr = include_str!("entry.rs").as_bytes();
let includestr = include_str!("entry_unfixable.rs").as_bytes();
}
fn main() {}

View file

@ -15,8 +15,8 @@ LL | let bs = r###"raw string with 3# plus " ""###.as_bytes();
error: calling `as_bytes()` on `include_str!(..)`
--> $DIR/string_lit_as_bytes.rs:17:22
|
LL | let includestr = include_str!("entry.rs").as_bytes();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `include_bytes!(..)` instead: `include_bytes!("entry.rs")`
LL | let includestr = include_str!("entry_unfixable.rs").as_bytes();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `include_bytes!(..)` instead: `include_bytes!("entry_unfixable.rs")`
error: aborting due to 3 previous errors

View file

@ -1,55 +0,0 @@
#[warn(clippy::string_add)]
#[allow(clippy::string_add_assign)]
fn add_only() {
// ignores assignment distinction
let mut x = "".to_owned();
for _ in 1..3 {
x = x + ".";
}
let y = "".to_owned();
let z = y + "...";
assert_eq!(&x, &z);
}
#[warn(clippy::string_add_assign)]
fn add_assign_only() {
let mut x = "".to_owned();
for _ in 1..3 {
x = x + ".";
}
let y = "".to_owned();
let z = y + "...";
assert_eq!(&x, &z);
}
#[warn(clippy::string_add, clippy::string_add_assign)]
fn both() {
let mut x = "".to_owned();
for _ in 1..3 {
x = x + ".";
}
let y = "".to_owned();
let z = y + "...";
assert_eq!(&x, &z);
}
#[allow(clippy::assign_op_pattern)]
fn main() {
add_only();
add_assign_only();
both();
// the add is only caught for `String`
let mut x = 1;
x = x + 1;
assert_eq!(2, x);
}

View file

@ -1,56 +0,0 @@
error: manual implementation of an assign operation
--> $DIR/strings.rs:8:9
|
LL | x = x + ".";
| ^^^^^^^^^^^ help: replace it with: `x += "."`
|
= note: `-D clippy::assign-op-pattern` implied by `-D warnings`
error: you added something to a string. Consider using `String::push_str()` instead
--> $DIR/strings.rs:8:13
|
LL | x = x + ".";
| ^^^^^^^
|
= note: `-D clippy::string-add` implied by `-D warnings`
error: you added something to a string. Consider using `String::push_str()` instead
--> $DIR/strings.rs:12:13
|
LL | let z = y + "...";
| ^^^^^^^^^
error: you assigned the result of adding something to this string. Consider using `String::push_str()` instead
--> $DIR/strings.rs:22:9
|
LL | x = x + ".";
| ^^^^^^^^^^^
|
= note: `-D clippy::string-add-assign` implied by `-D warnings`
error: manual implementation of an assign operation
--> $DIR/strings.rs:22:9
|
LL | x = x + ".";
| ^^^^^^^^^^^ help: replace it with: `x += "."`
error: you assigned the result of adding something to this string. Consider using `String::push_str()` instead
--> $DIR/strings.rs:36:9
|
LL | x = x + ".";
| ^^^^^^^^^^^
error: manual implementation of an assign operation
--> $DIR/strings.rs:36:9
|
LL | x = x + ".";
| ^^^^^^^^^^^ help: replace it with: `x += "."`
error: you added something to a string. Consider using `String::push_str()` instead
--> $DIR/strings.rs:40:13
|
LL | let z = y + "...";
| ^^^^^^^^^
error: aborting due to 8 previous errors

View file

@ -1,9 +1,9 @@
// does not test any rustfixable lints
#![warn(clippy::clone_on_ref_ptr)]
#![allow(unused)]
use std::cell::RefCell;
use std::collections::HashSet;
use std::collections::VecDeque;
use std::rc::{self, Rc};
use std::sync::{self, Arc};
@ -66,25 +66,6 @@ fn clone_on_double_ref() {
println!("{:p} {:p}", *y, z);
}
fn iter_clone_collect() {
let v = [1, 2, 3, 4, 5];
let v2: Vec<isize> = v.iter().cloned().collect();
let v3: HashSet<isize> = v.iter().cloned().collect();
let v4: VecDeque<isize> = v.iter().cloned().collect();
// Handle macro expansion in suggestion
let _: Vec<isize> = vec![1, 2, 3].iter().cloned().collect();
// Issue #3704
unsafe {
let _: Vec<u8> = std::ffi::CStr::from_ptr(std::ptr::null())
.to_bytes()
.iter()
.cloned()
.collect();
}
}
mod many_derefs {
struct A;
struct B;

View file

@ -78,35 +78,11 @@ help: or try being explicit about what type to clone
LL | let z: &Vec<_> = &std::vec::Vec<i32>::clone(y);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: called `iter().cloned().collect()` on a slice to create a `Vec`. Calling `to_vec()` is both faster and more readable
--> $DIR/unnecessary_clone.rs:71:27
|
LL | let v2: Vec<isize> = v.iter().cloned().collect();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `.to_vec()`
|
= note: `-D clippy::iter-cloned-collect` implied by `-D warnings`
error: called `iter().cloned().collect()` on a slice to create a `Vec`. Calling `to_vec()` is both faster and more readable
--> $DIR/unnecessary_clone.rs:76:38
|
LL | let _: Vec<isize> = vec![1, 2, 3].iter().cloned().collect();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `.to_vec()`
error: called `iter().cloned().collect()` on a slice to create a `Vec`. Calling `to_vec()` is both faster and more readable
--> $DIR/unnecessary_clone.rs:81:24
|
LL | .to_bytes()
| ________________________^
LL | | .iter()
LL | | .cloned()
LL | | .collect();
| |______________________^ help: try: `.to_vec()`
error: using `clone` on a `Copy` type
--> $DIR/unnecessary_clone.rs:119:20
--> $DIR/unnecessary_clone.rs:100:20
|
LL | let _: E = a.clone();
| ^^^^^^^^^ help: try dereferencing it: `*****a`
error: aborting due to 15 previous errors
error: aborting due to 12 previous errors

View file

@ -0,0 +1,79 @@
// run-rustfix
#![feature(box_syntax)]
#![allow(clippy::deref_addrof, dead_code, unused, clippy::no_effect)]
#![warn(clippy::unnecessary_operation)]
struct Tuple(i32);
struct Struct {
field: i32,
}
enum Enum {
Tuple(i32),
Struct { field: i32 },
}
struct DropStruct {
field: i32,
}
impl Drop for DropStruct {
fn drop(&mut self) {}
}
struct DropTuple(i32);
impl Drop for DropTuple {
fn drop(&mut self) {}
}
enum DropEnum {
Tuple(i32),
Struct { field: i32 },
}
impl Drop for DropEnum {
fn drop(&mut self) {}
}
struct FooString {
s: String,
}
fn get_number() -> i32 {
0
}
fn get_usize() -> usize {
0
}
fn get_struct() -> Struct {
Struct { field: 0 }
}
fn get_drop_struct() -> DropStruct {
DropStruct { field: 0 }
}
fn main() {
get_number();
get_number();
get_struct();
get_number();
get_number();
5;get_number();
get_number();
get_number();
5;6;get_number();
get_number();
get_number();
get_number();
5;get_number();
42;get_number();
[42, 55];get_usize();
42;get_number();
get_number();
[42; 55];get_usize();
get_number();
String::from("blah");
// Do not warn
DropTuple(get_number());
DropStruct { field: get_number() };
DropStruct { field: get_number() };
DropStruct { ..get_drop_struct() };
DropEnum::Tuple(get_number());
DropEnum::Struct { field: get_number() };
}

View file

@ -1,5 +1,7 @@
// run-rustfix
#![feature(box_syntax)]
#![allow(clippy::deref_addrof)]
#![allow(clippy::deref_addrof, dead_code, unused, clippy::no_effect)]
#![warn(clippy::unnecessary_operation)]
struct Tuple(i32);
@ -34,6 +36,10 @@ struct FooString {
fn get_number() -> i32 {
0
}
fn get_usize() -> usize {
0
}
fn get_struct() -> Struct {
Struct { field: 0 }
}
@ -56,10 +62,10 @@ fn main() {
..get_number();
5..get_number();
[42, get_number()];
[42, 55][get_number() as usize];
[42, 55][get_usize()];
(42, get_number()).1;
[get_number(); 55];
[42; 55][get_number() as usize];
[42; 55][get_usize()];
{
get_number()
};

View file

@ -1,5 +1,5 @@
error: statement can be reduced
--> $DIR/unnecessary_operation.rs:45:5
--> $DIR/unnecessary_operation.rs:51:5
|
LL | Tuple(get_number());
| ^^^^^^^^^^^^^^^^^^^^ help: replace it with: `get_number();`
@ -7,109 +7,109 @@ LL | Tuple(get_number());
= note: `-D clippy::unnecessary-operation` implied by `-D warnings`
error: statement can be reduced
--> $DIR/unnecessary_operation.rs:46:5
--> $DIR/unnecessary_operation.rs:52:5
|
LL | Struct { field: get_number() };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `get_number();`
error: statement can be reduced
--> $DIR/unnecessary_operation.rs:47:5
--> $DIR/unnecessary_operation.rs:53:5
|
LL | Struct { ..get_struct() };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `get_struct();`
error: statement can be reduced
--> $DIR/unnecessary_operation.rs:48:5
--> $DIR/unnecessary_operation.rs:54:5
|
LL | Enum::Tuple(get_number());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `get_number();`
error: statement can be reduced
--> $DIR/unnecessary_operation.rs:49:5
--> $DIR/unnecessary_operation.rs:55:5
|
LL | Enum::Struct { field: get_number() };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `get_number();`
error: statement can be reduced
--> $DIR/unnecessary_operation.rs:50:5
--> $DIR/unnecessary_operation.rs:56:5
|
LL | 5 + get_number();
| ^^^^^^^^^^^^^^^^^ help: replace it with: `5;get_number();`
error: statement can be reduced
--> $DIR/unnecessary_operation.rs:51:5
--> $DIR/unnecessary_operation.rs:57:5
|
LL | *&get_number();
| ^^^^^^^^^^^^^^^ help: replace it with: `get_number();`
error: statement can be reduced
--> $DIR/unnecessary_operation.rs:52:5
--> $DIR/unnecessary_operation.rs:58:5
|
LL | &get_number();
| ^^^^^^^^^^^^^^ help: replace it with: `get_number();`
error: statement can be reduced
--> $DIR/unnecessary_operation.rs:53:5
--> $DIR/unnecessary_operation.rs:59:5
|
LL | (5, 6, get_number());
| ^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `5;6;get_number();`
error: statement can be reduced
--> $DIR/unnecessary_operation.rs:54:5
--> $DIR/unnecessary_operation.rs:60:5
|
LL | box get_number();
| ^^^^^^^^^^^^^^^^^ help: replace it with: `get_number();`
error: statement can be reduced
--> $DIR/unnecessary_operation.rs:55:5
--> $DIR/unnecessary_operation.rs:61:5
|
LL | get_number()..;
| ^^^^^^^^^^^^^^^ help: replace it with: `get_number();`
error: statement can be reduced
--> $DIR/unnecessary_operation.rs:56:5
--> $DIR/unnecessary_operation.rs:62:5
|
LL | ..get_number();
| ^^^^^^^^^^^^^^^ help: replace it with: `get_number();`
error: statement can be reduced
--> $DIR/unnecessary_operation.rs:57:5
--> $DIR/unnecessary_operation.rs:63:5
|
LL | 5..get_number();
| ^^^^^^^^^^^^^^^^ help: replace it with: `5;get_number();`
error: statement can be reduced
--> $DIR/unnecessary_operation.rs:58:5
--> $DIR/unnecessary_operation.rs:64:5
|
LL | [42, get_number()];
| ^^^^^^^^^^^^^^^^^^^ help: replace it with: `42;get_number();`
error: statement can be reduced
--> $DIR/unnecessary_operation.rs:59:5
--> $DIR/unnecessary_operation.rs:65:5
|
LL | [42, 55][get_number() as usize];
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `[42, 55];get_number() as usize;`
LL | [42, 55][get_usize()];
| ^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `[42, 55];get_usize();`
error: statement can be reduced
--> $DIR/unnecessary_operation.rs:60:5
--> $DIR/unnecessary_operation.rs:66:5
|
LL | (42, get_number()).1;
| ^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `42;get_number();`
error: statement can be reduced
--> $DIR/unnecessary_operation.rs:61:5
--> $DIR/unnecessary_operation.rs:67:5
|
LL | [get_number(); 55];
| ^^^^^^^^^^^^^^^^^^^ help: replace it with: `get_number();`
error: statement can be reduced
--> $DIR/unnecessary_operation.rs:62:5
--> $DIR/unnecessary_operation.rs:68:5
|
LL | [42; 55][get_number() as usize];
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `[42; 55];get_number() as usize;`
LL | [42; 55][get_usize()];
| ^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `[42; 55];get_usize();`
error: statement can be reduced
--> $DIR/unnecessary_operation.rs:63:5
--> $DIR/unnecessary_operation.rs:69:5
|
LL | / {
LL | | get_number()
@ -117,7 +117,7 @@ LL | | };
| |______^ help: replace it with: `get_number();`
error: statement can be reduced
--> $DIR/unnecessary_operation.rs:66:5
--> $DIR/unnecessary_operation.rs:72:5
|
LL | / FooString {
LL | | s: String::from("blah"),