mirror of
https://github.com/rust-lang/rust-clippy
synced 2025-02-17 14:38:46 +00:00
Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
3c22b2314c
39 changed files with 1008 additions and 729 deletions
|
@ -63,8 +63,7 @@ matrix:
|
||||||
- env: INTEGRATION=chronotope/chrono
|
- env: INTEGRATION=chronotope/chrono
|
||||||
- env: INTEGRATION=serde-rs/serde
|
- env: INTEGRATION=serde-rs/serde
|
||||||
- env: INTEGRATION=Geal/nom
|
- env: INTEGRATION=Geal/nom
|
||||||
# uncomment once https://github.com/rust-lang/rust/issues/55376 is fixed
|
- env: INTEGRATION=hyperium/hyper
|
||||||
# - env: INTEGRATION=hyperium/hyper
|
|
||||||
allow_failures:
|
allow_failures:
|
||||||
- os: windows
|
- os: windows
|
||||||
env: BASE_TEST=true
|
env: BASE_TEST=true
|
||||||
|
|
|
@ -48,7 +48,7 @@ rustc_tools_util = { version = "0.1.0", path = "rustc_tools_util"}
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
clippy_dev = { version = "0.0.1", path = "clippy_dev" }
|
clippy_dev = { version = "0.0.1", path = "clippy_dev" }
|
||||||
cargo_metadata = "0.6"
|
cargo_metadata = "0.6"
|
||||||
compiletest_rs = "0.3.7"
|
compiletest_rs = "0.3.16"
|
||||||
lazy_static = "1.0"
|
lazy_static = "1.0"
|
||||||
serde_derive = "1.0"
|
serde_derive = "1.0"
|
||||||
clippy-mini-macro-test = { version = "0.2", path = "mini-macro" }
|
clippy-mini-macro-test = { version = "0.2", path = "mini-macro" }
|
||||||
|
|
|
@ -24,21 +24,20 @@ cd clippy_lints && cargo test && cd ..
|
||||||
cd rustc_tools_util && cargo test && cd ..
|
cd rustc_tools_util && cargo test && cd ..
|
||||||
# check that the lint lists are up-to-date
|
# check that the lint lists are up-to-date
|
||||||
./util/update_lints.py -c
|
./util/update_lints.py -c
|
||||||
mkdir -p ~/rust/cargo/bin
|
|
||||||
cp target/debug/cargo-clippy ~/rust/cargo/bin/cargo-clippy
|
CLIPPY="`pwd`/target/debug/cargo-clippy clippy"
|
||||||
cp target/debug/clippy-driver ~/rust/cargo/bin/clippy-driver
|
|
||||||
rm ~/.cargo/bin/cargo-clippy
|
|
||||||
# run clippy on its own codebase...
|
# run clippy on its own codebase...
|
||||||
PATH=$PATH:~/rust/cargo/bin cargo clippy --all-targets --all-features -- -D clippy::all -D clippy::internal
|
${CLIPPY} --all-targets --all-features -- -D clippy::all -D clippy::internal
|
||||||
# ... and some test directories
|
# ... and some test directories
|
||||||
cd clippy_workspace_tests && PATH=$PATH:~/rust/cargo/bin cargo clippy -- -D clippy::all && cd ..
|
for dir in clippy_workspace_tests clippy_workspace_tests/src clippy_workspace_tests/subcrate clippy_workspace_tests/subcrate/src clippy_dev rustc_tools_util
|
||||||
cd clippy_workspace_tests/src && PATH=$PATH:~/rust/cargo/bin cargo clippy -- -D clippy::all && cd ../..
|
do
|
||||||
cd clippy_workspace_tests/subcrate && PATH=$PATH:~/rust/cargo/bin cargo clippy -- -D clippy::all && cd ../..
|
cd ${dir}
|
||||||
cd clippy_workspace_tests/subcrate/src && PATH=$PATH:~/rust/cargo/bin cargo clippy -- -D clippy::all && cd ../../..
|
${CLIPPY} -- -D clippy::all
|
||||||
cd clippy_dev && PATH=$PATH:~/rust/cargo/bin cargo clippy -- -D clippy::all && cd ..
|
cd -
|
||||||
cd rustc_tools_util/ && PATH=$PATH:~/rust/cargo/bin cargo clippy -- -D clippy::all && cd ..
|
done
|
||||||
|
|
||||||
|
|
||||||
# test --manifest-path
|
# test --manifest-path
|
||||||
PATH=$PATH:~/rust/cargo/bin cargo clippy --manifest-path=clippy_workspace_tests/Cargo.toml -- -D clippy::all
|
${CLIPPY} --manifest-path=clippy_workspace_tests/Cargo.toml -- -D clippy::all
|
||||||
cd clippy_workspace_tests/subcrate && PATH=$PATH:~/rust/cargo/bin cargo clippy --manifest-path=../Cargo.toml -- -D clippy::all && cd ../..
|
cd clippy_workspace_tests/subcrate && ${CLIPPY} --manifest-path=../Cargo.toml -- -D clippy::all && cd ../..
|
||||||
set +x
|
set +x
|
||||||
|
|
|
@ -28,9 +28,6 @@ function check() {
|
||||||
}
|
}
|
||||||
|
|
||||||
case ${INTEGRATION} in
|
case ${INTEGRATION} in
|
||||||
rust-lang/cargo)
|
|
||||||
check
|
|
||||||
;;
|
|
||||||
*)
|
*)
|
||||||
check
|
check
|
||||||
;;
|
;;
|
||||||
|
|
|
@ -12,7 +12,7 @@ use crate::rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||||
use crate::rustc::{declare_tool_lint, lint_array};
|
use crate::rustc::{declare_tool_lint, lint_array};
|
||||||
use crate::rustc::hir::*;
|
use crate::rustc::hir::*;
|
||||||
use crate::syntax::ast::NodeId;
|
use crate::syntax::ast::NodeId;
|
||||||
use crate::utils::{in_macro, match_def_path, match_trait_method, same_tys, snippet, span_lint_and_then};
|
use crate::utils::{in_macro, match_def_path, match_trait_method, same_tys, snippet, snippet_with_macro_callsite, span_lint_and_then};
|
||||||
use crate::utils::{opt_def_id, paths, resolve_node};
|
use crate::utils::{opt_def_id, paths, resolve_node};
|
||||||
use crate::rustc_errors::Applicability;
|
use crate::rustc_errors::Applicability;
|
||||||
|
|
||||||
|
@ -72,7 +72,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for IdentityConversion {
|
||||||
let a = cx.tables.expr_ty(e);
|
let a = cx.tables.expr_ty(e);
|
||||||
let b = cx.tables.expr_ty(&args[0]);
|
let b = cx.tables.expr_ty(&args[0]);
|
||||||
if same_tys(cx, a, b) {
|
if same_tys(cx, a, b) {
|
||||||
let sugg = snippet(cx, args[0].span, "<expr>").into_owned();
|
let sugg = snippet_with_macro_callsite(cx, args[0].span, "<expr>").to_string();
|
||||||
|
|
||||||
span_lint_and_then(cx, IDENTITY_CONVERSION, e.span, "identical conversion", |db| {
|
span_lint_and_then(cx, IDENTITY_CONVERSION, e.span, "identical conversion", |db| {
|
||||||
db.span_suggestion_with_applicability(
|
db.span_suggestion_with_applicability(
|
||||||
e.span,
|
e.span,
|
||||||
|
|
|
@ -48,6 +48,7 @@ use toml;
|
||||||
|
|
||||||
// Currently, categories "style", "correctness", "complexity" and "perf" are enabled by default,
|
// Currently, categories "style", "correctness", "complexity" and "perf" are enabled by default,
|
||||||
// as said in the README.md of this repository. If this changes, please update README.md.
|
// as said in the README.md of this repository. If this changes, please update README.md.
|
||||||
|
#[macro_export]
|
||||||
macro_rules! declare_clippy_lint {
|
macro_rules! declare_clippy_lint {
|
||||||
{ pub $name:tt, style, $description:tt } => {
|
{ pub $name:tt, style, $description:tt } => {
|
||||||
declare_tool_lint! { pub clippy::$name, Warn, $description, report_in_external_macro: true }
|
declare_tool_lint! { pub clippy::$name, Warn, $description, report_in_external_macro: true }
|
||||||
|
|
|
@ -19,7 +19,8 @@ use crate::syntax::ast::LitKind;
|
||||||
use crate::syntax::source_map::Span;
|
use crate::syntax::source_map::Span;
|
||||||
use crate::utils::paths;
|
use crate::utils::paths;
|
||||||
use crate::utils::{expr_block, is_allowed, is_expn_of, match_qpath, match_type, multispan_sugg,
|
use crate::utils::{expr_block, is_allowed, is_expn_of, match_qpath, match_type, multispan_sugg,
|
||||||
remove_blocks, snippet, span_lint_and_sugg, span_lint_and_then, span_note_and_lint, walk_ptrs_ty};
|
remove_blocks, snippet, span_lint_and_sugg, span_lint_and_then,
|
||||||
|
span_note_and_lint, walk_ptrs_ty};
|
||||||
use crate::utils::sugg::Sugg;
|
use crate::utils::sugg::Sugg;
|
||||||
use crate::consts::{constant, Constant};
|
use crate::consts::{constant, Constant};
|
||||||
use crate::rustc_errors::Applicability;
|
use crate::rustc_errors::Applicability;
|
||||||
|
|
|
@ -21,7 +21,7 @@ use crate::utils::sugg;
|
||||||
use crate::utils::{
|
use crate::utils::{
|
||||||
get_arg_name, get_trait_def_id, implements_trait, in_macro, is_copy, is_expn_of, is_self, is_self_ty,
|
get_arg_name, get_trait_def_id, implements_trait, in_macro, is_copy, is_expn_of, is_self, is_self_ty,
|
||||||
iter_input_pats, last_path_segment, match_def_path, match_path, match_qpath, match_trait_method, match_type,
|
iter_input_pats, last_path_segment, match_def_path, match_path, match_qpath, match_trait_method, match_type,
|
||||||
match_var, method_chain_args, remove_blocks, return_ty, same_tys, single_segment_path, snippet, span_lint,
|
match_var, method_chain_args, remove_blocks, return_ty, same_tys, single_segment_path, snippet, snippet_with_macro_callsite, span_lint,
|
||||||
span_lint_and_sugg, span_lint_and_then, span_note_and_lint, walk_ptrs_ty, walk_ptrs_ty_depth, SpanlessEq,
|
span_lint_and_sugg, span_lint_and_then, span_note_and_lint, walk_ptrs_ty, walk_ptrs_ty_depth, SpanlessEq,
|
||||||
};
|
};
|
||||||
use if_chain::if_chain;
|
use if_chain::if_chain;
|
||||||
|
@ -568,7 +568,14 @@ declare_clippy_lint! {
|
||||||
/// **Why is this bad?** Using the Index trait (`[]`) is more clear and more
|
/// **Why is this bad?** Using the Index trait (`[]`) is more clear and more
|
||||||
/// concise.
|
/// concise.
|
||||||
///
|
///
|
||||||
/// **Known problems:** None.
|
/// **Known problems:** Not a replacement for error handling: Using either
|
||||||
|
/// `.unwrap()` or the Index trait (`[]`) carries the risk of causing a `panic`
|
||||||
|
/// if the value being accessed is `None`. If the use of `.get().unwrap()` is a
|
||||||
|
/// temporary placeholder for dealing with the `Option` type, then this does
|
||||||
|
/// not mitigate the need for error handling. If there is a chance that `.get()`
|
||||||
|
/// will be `None` in your program, then it is advisable that the `None` case
|
||||||
|
/// is handled in a future refactor instead of using `.unwrap()` or the Index
|
||||||
|
/// trait.
|
||||||
///
|
///
|
||||||
/// **Example:**
|
/// **Example:**
|
||||||
/// ```rust
|
/// ```rust
|
||||||
|
@ -1062,9 +1069,9 @@ fn lint_or_fun_call(cx: &LateContext<'_, '_>, expr: &hir::Expr, method_span: Spa
|
||||||
}
|
}
|
||||||
|
|
||||||
let sugg: Cow<'_, _> = match (fn_has_arguments, !or_has_args) {
|
let sugg: Cow<'_, _> = match (fn_has_arguments, !or_has_args) {
|
||||||
(true, _) => format!("|_| {}", snippet(cx, arg.span, "..")).into(),
|
(true, _) => format!("|_| {}", snippet_with_macro_callsite(cx, arg.span, "..")).into(),
|
||||||
(false, false) => format!("|| {}", snippet(cx, arg.span, "..")).into(),
|
(false, false) => format!("|| {}", snippet_with_macro_callsite(cx, arg.span, "..")).into(),
|
||||||
(false, true) => snippet(cx, fun_span, ".."),
|
(false, true) => snippet_with_macro_callsite(cx, fun_span, ".."),
|
||||||
};
|
};
|
||||||
let span_replace_word = method_span.with_hi(span.hi());
|
let span_replace_word = method_span.with_hi(span.hi());
|
||||||
span_lint_and_sugg(
|
span_lint_and_sugg(
|
||||||
|
|
|
@ -17,7 +17,7 @@ use crate::rustc::{declare_tool_lint, lint_array};
|
||||||
use crate::rustc::hir::*;
|
use crate::rustc::hir::*;
|
||||||
use crate::syntax::ast::LitKind;
|
use crate::syntax::ast::LitKind;
|
||||||
use crate::syntax::source_map::Spanned;
|
use crate::syntax::source_map::Spanned;
|
||||||
use crate::utils::{snippet, span_lint, span_lint_and_sugg};
|
use crate::utils::{in_macro, snippet, span_lint, span_lint_and_sugg};
|
||||||
use crate::utils::sugg::Sugg;
|
use crate::utils::sugg::Sugg;
|
||||||
|
|
||||||
/// **What it does:** Checks for expressions of the form `if c { true } else {
|
/// **What it does:** Checks for expressions of the form `if c { true } else {
|
||||||
|
@ -133,6 +133,9 @@ impl LintPass for BoolComparison {
|
||||||
|
|
||||||
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for BoolComparison {
|
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for BoolComparison {
|
||||||
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr) {
|
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr) {
|
||||||
|
if in_macro(e.span) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
use self::Expression::*;
|
use self::Expression::*;
|
||||||
if let ExprKind::Binary(Spanned { node: BinOpKind::Eq, .. }, ref left_side, ref right_side) = e.node {
|
if let ExprKind::Binary(Spanned { node: BinOpKind::Eq, .. }, ref left_side, ref right_side) = e.node {
|
||||||
match (fetch_bool_expr(left_side), fetch_bool_expr(right_side)) {
|
match (fetch_bool_expr(left_side), fetch_bool_expr(right_side)) {
|
||||||
|
|
|
@ -12,7 +12,7 @@ use crate::rustc::hir::{def_id, Body, FnDecl};
|
||||||
use crate::rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
use crate::rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||||
use crate::rustc::mir::{
|
use crate::rustc::mir::{
|
||||||
self, traversal,
|
self, traversal,
|
||||||
visit::{PlaceContext, Visitor},
|
visit::{MutatingUseContext, NonUseContext, PlaceContext, Visitor},
|
||||||
TerminatorKind,
|
TerminatorKind,
|
||||||
};
|
};
|
||||||
use crate::rustc::ty;
|
use crate::rustc::ty;
|
||||||
|
@ -279,7 +279,7 @@ impl<'tcx> mir::visit::Visitor<'tcx> for LocalUseVisitor {
|
||||||
|
|
||||||
fn visit_local(&mut self, local: &mir::Local, ctx: PlaceContext<'tcx>, _: mir::Location) {
|
fn visit_local(&mut self, local: &mir::Local, ctx: PlaceContext<'tcx>, _: mir::Location) {
|
||||||
match ctx {
|
match ctx {
|
||||||
PlaceContext::Drop | PlaceContext::StorageDead => return,
|
PlaceContext::MutatingUse(MutatingUseContext::Drop) | PlaceContext::NonUse(NonUseContext::StorageDead) => return,
|
||||||
_ => {},
|
_ => {},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
// option. This file may not be copied, modified, or distributed
|
// option. This file may not be copied, modified, or distributed
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
|
|
||||||
use crate::rustc::hir::*;
|
use crate::rustc::hir::*;
|
||||||
use crate::rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
use crate::rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||||
use crate::rustc::{declare_tool_lint, lint_array};
|
use crate::rustc::{declare_tool_lint, lint_array};
|
||||||
|
@ -92,7 +91,14 @@ impl LintPass for StringAdd {
|
||||||
|
|
||||||
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for StringAdd {
|
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for StringAdd {
|
||||||
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr) {
|
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr) {
|
||||||
if let ExprKind::Binary(Spanned { node: BinOpKind::Add, .. }, ref left, _) = e.node {
|
if let ExprKind::Binary(
|
||||||
|
Spanned {
|
||||||
|
node: BinOpKind::Add, ..
|
||||||
|
},
|
||||||
|
ref left,
|
||||||
|
_,
|
||||||
|
) = e.node
|
||||||
|
{
|
||||||
if is_string(cx, left) {
|
if is_string(cx, left) {
|
||||||
if !is_allowed(cx, STRING_ADD_ASSIGN, e.id) {
|
if !is_allowed(cx, STRING_ADD_ASSIGN, e.id) {
|
||||||
let parent = get_parent_expr(cx, e);
|
let parent = get_parent_expr(cx, e);
|
||||||
|
@ -132,13 +138,15 @@ fn is_string(cx: &LateContext<'_, '_>, e: &Expr) -> bool {
|
||||||
|
|
||||||
fn is_add(cx: &LateContext<'_, '_>, src: &Expr, target: &Expr) -> bool {
|
fn is_add(cx: &LateContext<'_, '_>, src: &Expr, target: &Expr) -> bool {
|
||||||
match src.node {
|
match src.node {
|
||||||
ExprKind::Binary(Spanned { node: BinOpKind::Add, .. }, ref left, _) => SpanlessEq::new(cx).eq_expr(target, left),
|
ExprKind::Binary(
|
||||||
|
Spanned {
|
||||||
|
node: BinOpKind::Add, ..
|
||||||
|
},
|
||||||
|
ref left,
|
||||||
|
_,
|
||||||
|
) => SpanlessEq::new(cx).eq_expr(target, left),
|
||||||
ExprKind::Block(ref block, _) => {
|
ExprKind::Block(ref block, _) => {
|
||||||
block.stmts.is_empty()
|
block.stmts.is_empty() && block.expr.as_ref().map_or(false, |expr| is_add(cx, expr, target))
|
||||||
&& block
|
|
||||||
.expr
|
|
||||||
.as_ref()
|
|
||||||
.map_or(false, |expr| is_add(cx, expr, target))
|
|
||||||
},
|
},
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
|
@ -155,14 +163,33 @@ impl LintPass for StringLitAsBytes {
|
||||||
|
|
||||||
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for StringLitAsBytes {
|
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for StringLitAsBytes {
|
||||||
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr) {
|
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr) {
|
||||||
use crate::syntax::ast::LitKind;
|
use crate::syntax::ast::{LitKind, StrStyle};
|
||||||
use crate::utils::{in_macro, snippet};
|
use crate::utils::{in_macro, snippet};
|
||||||
|
|
||||||
if let ExprKind::MethodCall(ref path, _, ref args) = e.node {
|
if let ExprKind::MethodCall(ref path, _, ref args) = e.node {
|
||||||
if path.ident.name == "as_bytes" {
|
if path.ident.name == "as_bytes" {
|
||||||
if let ExprKind::Lit(ref lit) = args[0].node {
|
if let ExprKind::Lit(ref lit) = args[0].node {
|
||||||
if let LitKind::Str(ref lit_content, _) = lit.node {
|
if let LitKind::Str(ref lit_content, style) = lit.node {
|
||||||
if lit_content.as_str().chars().all(|c| c.is_ascii()) && !in_macro(args[0].span) {
|
let callsite = snippet(cx, args[0].span.source_callsite(), r#""foo""#);
|
||||||
|
let expanded = if let StrStyle::Raw(n) = style {
|
||||||
|
let term = (0..n).map(|_| '#').collect::<String>();
|
||||||
|
format!("r{0}\"{1}\"{0}", term, lit_content.as_str())
|
||||||
|
} else {
|
||||||
|
format!("\"{}\"", lit_content.as_str())
|
||||||
|
};
|
||||||
|
if callsite.starts_with("include_str!") {
|
||||||
|
span_lint_and_sugg(
|
||||||
|
cx,
|
||||||
|
STRING_LIT_AS_BYTES,
|
||||||
|
e.span,
|
||||||
|
"calling `as_bytes()` on `include_str!(..)`",
|
||||||
|
"consider using `include_bytes!(..)` instead",
|
||||||
|
snippet(cx, args[0].span, r#""foo""#).replacen("include_str", "include_bytes", 1),
|
||||||
|
);
|
||||||
|
} else if callsite == expanded
|
||||||
|
&& lit_content.as_str().chars().all(|c| c.is_ascii())
|
||||||
|
&& !in_macro(args[0].span)
|
||||||
|
{
|
||||||
span_lint_and_sugg(
|
span_lint_and_sugg(
|
||||||
cx,
|
cx,
|
||||||
STRING_LIT_AS_BYTES,
|
STRING_LIT_AS_BYTES,
|
||||||
|
|
|
@ -36,7 +36,7 @@ use crate::syntax_pos::symbol::keywords::SelfType;
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
/// could be
|
/// could be
|
||||||
/// ```
|
/// ```rust
|
||||||
/// struct Foo {}
|
/// struct Foo {}
|
||||||
/// impl Foo {
|
/// impl Foo {
|
||||||
/// fn new() -> Self {
|
/// fn new() -> Self {
|
||||||
|
|
|
@ -9,12 +9,13 @@
|
||||||
|
|
||||||
|
|
||||||
use crate::utils::{
|
use crate::utils::{
|
||||||
match_qpath, match_type, paths, span_help_and_lint, span_lint, span_lint_and_sugg, walk_ptrs_ty,
|
match_def_path, match_type, paths, span_help_and_lint, span_lint, span_lint_and_sugg, walk_ptrs_ty,
|
||||||
};
|
};
|
||||||
use if_chain::if_chain;
|
use if_chain::if_chain;
|
||||||
use crate::rustc::hir;
|
use crate::rustc::hir;
|
||||||
use crate::rustc::hir::intravisit::{walk_expr, NestedVisitorMap, Visitor};
|
use crate::rustc::hir::intravisit::{walk_expr, NestedVisitorMap, Visitor};
|
||||||
use crate::rustc::hir::*;
|
use crate::rustc::hir::*;
|
||||||
|
use crate::rustc::hir::def::Def;
|
||||||
use crate::rustc::lint::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintArray, LintPass};
|
use crate::rustc::lint::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintArray, LintPass};
|
||||||
use crate::rustc::{declare_tool_lint, lint_array};
|
use crate::rustc::{declare_tool_lint, lint_array};
|
||||||
use crate::rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
use crate::rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||||
|
@ -160,15 +161,21 @@ impl LintPass for LintWithoutLintPass {
|
||||||
|
|
||||||
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for LintWithoutLintPass {
|
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for LintWithoutLintPass {
|
||||||
fn check_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx Item) {
|
fn check_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx Item) {
|
||||||
if let hir::ItemKind::Static(ref ty, MutImmutable, body_id) = item.node {
|
if let hir::ItemKind::Static(ref ty, MutImmutable, _) = item.node {
|
||||||
if is_lint_ref_type(ty) {
|
if is_lint_ref_type(cx, ty) {
|
||||||
self.declared_lints.insert(item.name, item.span);
|
self.declared_lints.insert(item.name, item.span);
|
||||||
} else if is_lint_array_type(ty) && item.name == "ARRAY" {
|
}
|
||||||
if let VisibilityKind::Inherited = item.vis.node {
|
} else if let hir::ItemKind::Impl(.., Some(ref trait_ref), _, ref impl_item_refs) = item.node {
|
||||||
|
if_chain! {
|
||||||
|
if let hir::TraitRef{path, ..} = trait_ref;
|
||||||
|
if let Def::Trait(def_id) = path.def;
|
||||||
|
if match_def_path(cx.tcx, def_id, &paths::LINT_PASS);
|
||||||
|
then {
|
||||||
let mut collector = LintCollector {
|
let mut collector = LintCollector {
|
||||||
output: &mut self.registered_lints,
|
output: &mut self.registered_lints,
|
||||||
cx,
|
cx,
|
||||||
};
|
};
|
||||||
|
let body_id = cx.tcx.hir.body_owned_by(impl_item_refs[0].id.node_id);
|
||||||
collector.visit_expr(&cx.tcx.hir.body(body_id).value);
|
collector.visit_expr(&cx.tcx.hir.body(body_id).value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -203,28 +210,22 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for LintWithoutLintPass {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_lint_ref_type(ty: &Ty) -> bool {
|
fn is_lint_ref_type<'tcx>(cx: &LateContext<'_, 'tcx>, ty: &Ty) -> bool {
|
||||||
if let TyKind::Rptr(
|
if let TyKind::Rptr(
|
||||||
_,
|
_,
|
||||||
MutTy {
|
MutTy {
|
||||||
ty: ref inner,
|
ty: ref inner,
|
||||||
mutbl: MutImmutable,
|
mutbl: MutImmutable,
|
||||||
},
|
},
|
||||||
) = ty.node
|
) = ty.node {
|
||||||
{
|
|
||||||
if let TyKind::Path(ref path) = inner.node {
|
if let TyKind::Path(ref path) = inner.node {
|
||||||
return match_qpath(path, &paths::LINT);
|
if let Def::Struct(def_id) = cx.tables.qpath_def(path, inner.hir_id) {
|
||||||
|
return match_def_path(cx.tcx, def_id, &paths::LINT);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
fn is_lint_array_type(ty: &Ty) -> bool {
|
false
|
||||||
if let TyKind::Path(ref path) = ty.node {
|
|
||||||
match_qpath(path, &paths::LINT_ARRAY)
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct LintCollector<'a, 'tcx: 'a> {
|
struct LintCollector<'a, 'tcx: 'a> {
|
||||||
|
|
|
@ -362,6 +362,12 @@ pub fn snippet<'a, 'b, T: LintContext<'b>>(cx: &T, span: Span, default: &'a str)
|
||||||
snippet_opt(cx, span).map_or_else(|| Cow::Borrowed(default), From::from)
|
snippet_opt(cx, span).map_or_else(|| Cow::Borrowed(default), From::from)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Same as `snippet`, but should only be used when it's clear that the input span is
|
||||||
|
/// not a macro argument.
|
||||||
|
pub fn snippet_with_macro_callsite<'a, 'b, T: LintContext<'b>>(cx: &T, span: Span, default: &'a str) -> Cow<'a, str> {
|
||||||
|
snippet(cx, span.source_callsite(), default)
|
||||||
|
}
|
||||||
|
|
||||||
/// Convert a span to a code snippet. Returns `None` if not available.
|
/// Convert a span to a code snippet. Returns `None` if not available.
|
||||||
pub fn snippet_opt<'a, T: LintContext<'a>>(cx: &T, span: Span) -> Option<String> {
|
pub fn snippet_opt<'a, T: LintContext<'a>>(cx: &T, span: Span) -> Option<String> {
|
||||||
cx.sess().source_map().span_to_snippet(span).ok()
|
cx.sess().source_map().span_to_snippet(span).ok()
|
||||||
|
@ -386,7 +392,7 @@ pub fn snippet_block<'a, 'b, T: LintContext<'b>>(cx: &T, span: Span, default: &'
|
||||||
pub fn last_line_of_span<'a, T: LintContext<'a>>(cx: &T, span: Span) -> Span {
|
pub fn last_line_of_span<'a, T: LintContext<'a>>(cx: &T, span: Span) -> Span {
|
||||||
let file_map_and_line = cx.sess().source_map().lookup_line(span.lo()).unwrap();
|
let file_map_and_line = cx.sess().source_map().lookup_line(span.lo()).unwrap();
|
||||||
let line_no = file_map_and_line.line;
|
let line_no = file_map_and_line.line;
|
||||||
let line_start = &file_map_and_line.fm.lines[line_no];
|
let line_start = &file_map_and_line.sf.lines[line_no];
|
||||||
Span::new(*line_start, span.hi(), span.ctxt())
|
Span::new(*line_start, span.hi(), span.ctxt())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -400,7 +406,10 @@ pub fn expr_block<'a, 'b, T: LintContext<'b>>(
|
||||||
) -> Cow<'a, str> {
|
) -> Cow<'a, str> {
|
||||||
let code = snippet_block(cx, expr.span, default);
|
let code = snippet_block(cx, expr.span, default);
|
||||||
let string = option.unwrap_or_default();
|
let string = option.unwrap_or_default();
|
||||||
if let ExprKind::Block(_, _) = expr.node {
|
if in_macro(expr.span) {
|
||||||
|
Cow::Owned(format!("{{ {} }}", snippet_with_macro_callsite(cx, expr.span, default)))
|
||||||
|
}
|
||||||
|
else if let ExprKind::Block(_, _) = expr.node {
|
||||||
Cow::Owned(format!("{}{}", code, string))
|
Cow::Owned(format!("{}{}", code, string))
|
||||||
} else if string.is_empty() {
|
} else if string.is_empty() {
|
||||||
Cow::Owned(format!("{{ {} }}", code))
|
Cow::Owned(format!("{{ {} }}", code))
|
||||||
|
|
|
@ -56,7 +56,7 @@ pub const ITERATOR: [&str; 4] = ["core", "iter", "iterator", "Iterator"];
|
||||||
pub const LATE_CONTEXT: [&str; 4] = ["rustc", "lint", "context", "LateContext"];
|
pub const LATE_CONTEXT: [&str; 4] = ["rustc", "lint", "context", "LateContext"];
|
||||||
pub const LINKED_LIST: [&str; 4] = ["alloc", "collections", "linked_list", "LinkedList"];
|
pub const LINKED_LIST: [&str; 4] = ["alloc", "collections", "linked_list", "LinkedList"];
|
||||||
pub const LINT: [&str; 3] = ["rustc", "lint", "Lint"];
|
pub const LINT: [&str; 3] = ["rustc", "lint", "Lint"];
|
||||||
pub const LINT_ARRAY: [&str; 3] = ["rustc", "lint", "LintArray"];
|
pub const LINT_PASS: [&str; 3] = ["rustc", "lint", "LintPass"];
|
||||||
pub const MEM_DISCRIMINANT: [&str; 3] = ["core", "mem", "discriminant"];
|
pub const MEM_DISCRIMINANT: [&str; 3] = ["core", "mem", "discriminant"];
|
||||||
pub const MEM_FORGET: [&str; 3] = ["core", "mem", "forget"];
|
pub const MEM_FORGET: [&str; 3] = ["core", "mem", "forget"];
|
||||||
pub const MEM_REPLACE: [&str; 3] = ["core", "mem", "replace"];
|
pub const MEM_REPLACE: [&str; 3] = ["core", "mem", "replace"];
|
||||||
|
|
|
@ -548,7 +548,7 @@ impl<'a, 'b, 'c, T: LintContext<'c>> DiagnosticBuilderExt<'c, T> for rustc_error
|
||||||
let hi = cx.sess().source_map().next_point(remove_span).hi();
|
let hi = cx.sess().source_map().next_point(remove_span).hi();
|
||||||
let fmpos = cx.sess().source_map().lookup_byte_offset(hi);
|
let fmpos = cx.sess().source_map().lookup_byte_offset(hi);
|
||||||
|
|
||||||
if let Some(ref src) = fmpos.fm.src {
|
if let Some(ref src) = fmpos.sf.src {
|
||||||
let non_whitespace_offset = src[fmpos.pos.to_usize()..].find(|c| c != ' ' && c != '\t' && c != '\n');
|
let non_whitespace_offset = src[fmpos.pos.to_usize()..].find(|c| c != ' ' && c != '\t' && c != '\n');
|
||||||
|
|
||||||
if let Some(non_whitespace_offset) = non_whitespace_offset {
|
if let Some(non_whitespace_offset) = non_whitespace_offset {
|
||||||
|
|
|
@ -75,7 +75,10 @@ fn config(mode: &str, dir: PathBuf) -> compiletest::Config {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_mode(mode: &str, dir: PathBuf) {
|
fn run_mode(mode: &str, dir: PathBuf) {
|
||||||
compiletest::run_tests(&config(mode, dir));
|
let cfg = config(mode, dir);
|
||||||
|
// clean rmeta data, otherwise "cargo check; cargo test" fails (#2896)
|
||||||
|
cfg.clean_rmeta();
|
||||||
|
compiletest::run_tests(&cfg);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_ui_toml_tests(config: &compiletest::Config, mut tests: Vec<test::TestDescAndFn>) -> Result<bool, io::Error> {
|
fn run_ui_toml_tests(config: &compiletest::Config, mut tests: Vec<test::TestDescAndFn>) -> Result<bool, io::Error> {
|
||||||
|
|
122
tests/ui/explicit_counter_loop.rs
Normal file
122
tests/ui/explicit_counter_loop.rs
Normal file
|
@ -0,0 +1,122 @@
|
||||||
|
// Copyright 2014-2018 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
#![warn(clippy::explicit_counter_loop)]
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let mut vec = vec![1, 2, 3, 4];
|
||||||
|
let mut _index = 0;
|
||||||
|
for _v in &vec {
|
||||||
|
_index += 1
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut _index = 1;
|
||||||
|
_index = 0;
|
||||||
|
for _v in &vec {
|
||||||
|
_index += 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mod issue_1219 {
|
||||||
|
pub fn test() {
|
||||||
|
// should not trigger the lint because variable is used after the loop #473
|
||||||
|
let vec = vec![1,2,3];
|
||||||
|
let mut index = 0;
|
||||||
|
for _v in &vec { index += 1 }
|
||||||
|
println!("index: {}", index);
|
||||||
|
|
||||||
|
// should not trigger the lint because the count is conditional #1219
|
||||||
|
let text = "banana";
|
||||||
|
let mut count = 0;
|
||||||
|
for ch in text.chars() {
|
||||||
|
if ch == 'a' {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
count += 1;
|
||||||
|
println!("{}", count);
|
||||||
|
}
|
||||||
|
|
||||||
|
// should not trigger the lint because the count is conditional
|
||||||
|
let text = "banana";
|
||||||
|
let mut count = 0;
|
||||||
|
for ch in text.chars() {
|
||||||
|
if ch == 'a' {
|
||||||
|
count += 1;
|
||||||
|
}
|
||||||
|
println!("{}", count);
|
||||||
|
}
|
||||||
|
|
||||||
|
// should trigger the lint because the count is not conditional
|
||||||
|
let text = "banana";
|
||||||
|
let mut count = 0;
|
||||||
|
for ch in text.chars() {
|
||||||
|
count += 1;
|
||||||
|
if ch == 'a' {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
println!("{}", count);
|
||||||
|
}
|
||||||
|
|
||||||
|
// should trigger the lint because the count is not conditional
|
||||||
|
let text = "banana";
|
||||||
|
let mut count = 0;
|
||||||
|
for ch in text.chars() {
|
||||||
|
count += 1;
|
||||||
|
for i in 0..2 {
|
||||||
|
let _ = 123;
|
||||||
|
}
|
||||||
|
println!("{}", count);
|
||||||
|
}
|
||||||
|
|
||||||
|
// should not trigger the lint because the count is incremented multiple times
|
||||||
|
let text = "banana";
|
||||||
|
let mut count = 0;
|
||||||
|
for ch in text.chars() {
|
||||||
|
count += 1;
|
||||||
|
for i in 0..2 {
|
||||||
|
count += 1;
|
||||||
|
}
|
||||||
|
println!("{}", count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mod issue_3308 {
|
||||||
|
pub fn test() {
|
||||||
|
// should not trigger the lint because the count is incremented multiple times
|
||||||
|
let mut skips = 0;
|
||||||
|
let erasures = vec![];
|
||||||
|
for i in 0..10 {
|
||||||
|
while erasures.contains(&(i + skips)) {
|
||||||
|
skips += 1;
|
||||||
|
}
|
||||||
|
println!("{}", skips);
|
||||||
|
}
|
||||||
|
|
||||||
|
// should not trigger the lint because the count is incremented multiple times
|
||||||
|
let mut skips = 0;
|
||||||
|
for i in 0..10 {
|
||||||
|
let mut j = 0;
|
||||||
|
while j < 5 {
|
||||||
|
skips += 1;
|
||||||
|
j += 1;
|
||||||
|
}
|
||||||
|
println!("{}", skips);
|
||||||
|
}
|
||||||
|
|
||||||
|
// should not trigger the lint because the count is incremented multiple times
|
||||||
|
let mut skips = 0;
|
||||||
|
for i in 0..10 {
|
||||||
|
for j in 0..5 {
|
||||||
|
skips += 1;
|
||||||
|
}
|
||||||
|
println!("{}", skips);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
28
tests/ui/explicit_counter_loop.stderr
Normal file
28
tests/ui/explicit_counter_loop.stderr
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
error: the variable `_index` is used as a loop counter. Consider using `for (_index, item) in &vec.enumerate()` or similar iterators
|
||||||
|
--> $DIR/explicit_counter_loop.rs:15:15
|
||||||
|
|
|
||||||
|
15 | for _v in &vec {
|
||||||
|
| ^^^^
|
||||||
|
|
|
||||||
|
= note: `-D clippy::explicit-counter-loop` implied by `-D warnings`
|
||||||
|
|
||||||
|
error: the variable `_index` is used as a loop counter. Consider using `for (_index, item) in &vec.enumerate()` or similar iterators
|
||||||
|
--> $DIR/explicit_counter_loop.rs:21:15
|
||||||
|
|
|
||||||
|
21 | for _v in &vec {
|
||||||
|
| ^^^^
|
||||||
|
|
||||||
|
error: the variable `count` is used as a loop counter. Consider using `for (count, item) in text.chars().enumerate()` or similar iterators
|
||||||
|
--> $DIR/explicit_counter_loop.rs:58:19
|
||||||
|
|
|
||||||
|
58 | for ch in text.chars() {
|
||||||
|
| ^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: the variable `count` is used as a loop counter. Consider using `for (count, item) in text.chars().enumerate()` or similar iterators
|
||||||
|
--> $DIR/explicit_counter_loop.rs:69:19
|
||||||
|
|
|
||||||
|
69 | for ch in text.chars() {
|
||||||
|
| ^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to 4 previous errors
|
||||||
|
|
|
@ -7,10 +7,6 @@
|
||||||
// option. This file may not be copied, modified, or distributed
|
// option. This file may not be copied, modified, or distributed
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
use std::collections::*;
|
use std::collections::*;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
|
@ -18,60 +14,6 @@ static STATIC: [usize; 4] = [0, 1, 8, 16];
|
||||||
const CONST: [usize; 4] = [0, 1, 8, 16];
|
const CONST: [usize; 4] = [0, 1, 8, 16];
|
||||||
|
|
||||||
#[warn(clippy::all)]
|
#[warn(clippy::all)]
|
||||||
fn for_loop_over_option_and_result() {
|
|
||||||
let option = Some(1);
|
|
||||||
let result = option.ok_or("x not found");
|
|
||||||
let v = vec![0, 1, 2];
|
|
||||||
|
|
||||||
// check FOR_LOOP_OVER_OPTION lint
|
|
||||||
for x in option {
|
|
||||||
println!("{}", x);
|
|
||||||
}
|
|
||||||
|
|
||||||
// check FOR_LOOP_OVER_RESULT lint
|
|
||||||
for x in result {
|
|
||||||
println!("{}", x);
|
|
||||||
}
|
|
||||||
|
|
||||||
for x in option.ok_or("x not found") {
|
|
||||||
println!("{}", x);
|
|
||||||
}
|
|
||||||
|
|
||||||
// make sure LOOP_OVER_NEXT lint takes clippy::precedence when next() is the last call
|
|
||||||
// in the chain
|
|
||||||
for x in v.iter().next() {
|
|
||||||
println!("{}", x);
|
|
||||||
}
|
|
||||||
|
|
||||||
// make sure we lint when next() is not the last call in the chain
|
|
||||||
for x in v.iter().next().and(Some(0)) {
|
|
||||||
println!("{}", x);
|
|
||||||
}
|
|
||||||
|
|
||||||
for x in v.iter().next().ok_or("x not found") {
|
|
||||||
println!("{}", x);
|
|
||||||
}
|
|
||||||
|
|
||||||
// check for false positives
|
|
||||||
|
|
||||||
// for loop false positive
|
|
||||||
for x in v {
|
|
||||||
println!("{}", x);
|
|
||||||
}
|
|
||||||
|
|
||||||
// while let false positive for Option
|
|
||||||
while let Some(x) = option {
|
|
||||||
println!("{}", x);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// while let false positive for Result
|
|
||||||
while let Ok(x) = result {
|
|
||||||
println!("{}", x);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Unrelated(Vec<u8>);
|
struct Unrelated(Vec<u8>);
|
||||||
impl Unrelated {
|
impl Unrelated {
|
||||||
fn next(&self) -> std::slice::Iter<u8> {
|
fn next(&self) -> std::slice::Iter<u8> {
|
||||||
|
@ -84,7 +26,7 @@ impl Unrelated {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[warn(clippy::needless_range_loop, clippy::explicit_iter_loop, clippy::explicit_into_iter_loop, clippy::iter_next_loop, clippy::reverse_range_loop,
|
#[warn(clippy::needless_range_loop, clippy::explicit_iter_loop, clippy::explicit_into_iter_loop, clippy::iter_next_loop, clippy::reverse_range_loop,
|
||||||
clippy::explicit_counter_loop, clippy::for_kv_map)]
|
clippy::for_kv_map)]
|
||||||
#[warn(clippy::unused_collect)]
|
#[warn(clippy::unused_collect)]
|
||||||
#[allow(clippy::linkedlist, clippy::shadow_unrelated, clippy::unnecessary_mut_passed, clippy::cyclomatic_complexity, clippy::similar_names)]
|
#[allow(clippy::linkedlist, clippy::shadow_unrelated, clippy::unnecessary_mut_passed, clippy::cyclomatic_complexity, clippy::similar_names)]
|
||||||
#[allow(clippy::many_single_char_names, unused_variables)]
|
#[allow(clippy::many_single_char_names, unused_variables)]
|
||||||
|
@ -275,16 +217,6 @@ fn main() {
|
||||||
let _y = vec.iter().cloned().map(|x| out.push(x)).collect::<Vec<_>>(); // this is fine
|
let _y = vec.iter().cloned().map(|x| out.push(x)).collect::<Vec<_>>(); // this is fine
|
||||||
|
|
||||||
// Loop with explicit counter variable
|
// Loop with explicit counter variable
|
||||||
let mut _index = 0;
|
|
||||||
for _v in &vec {
|
|
||||||
_index += 1
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut _index = 1;
|
|
||||||
_index = 0;
|
|
||||||
for _v in &vec {
|
|
||||||
_index += 1
|
|
||||||
}
|
|
||||||
|
|
||||||
// Potential false positives
|
// Potential false positives
|
||||||
let mut _index = 0;
|
let mut _index = 0;
|
||||||
|
@ -389,8 +321,6 @@ fn main() {
|
||||||
}
|
}
|
||||||
println!("index: {}", index);
|
println!("index: {}", index);
|
||||||
|
|
||||||
for_loop_over_option_and_result();
|
|
||||||
|
|
||||||
let m: HashMap<u64, u64> = HashMap::new();
|
let m: HashMap<u64, u64> = HashMap::new();
|
||||||
for (_, v) in &m {
|
for (_, v) in &m {
|
||||||
let _v = v;
|
let _v = v;
|
||||||
|
@ -594,103 +524,3 @@ mod issue_2496 {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mod issue_1219 {
|
|
||||||
#[warn(clippy::explicit_counter_loop)]
|
|
||||||
pub fn test() {
|
|
||||||
// should not trigger the lint because variable is used after the loop #473
|
|
||||||
let vec = vec![1,2,3];
|
|
||||||
let mut index = 0;
|
|
||||||
for _v in &vec { index += 1 }
|
|
||||||
println!("index: {}", index);
|
|
||||||
|
|
||||||
// should not trigger the lint because the count is conditional #1219
|
|
||||||
let text = "banana";
|
|
||||||
let mut count = 0;
|
|
||||||
for ch in text.chars() {
|
|
||||||
if ch == 'a' {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
count += 1;
|
|
||||||
println!("{}", count);
|
|
||||||
}
|
|
||||||
|
|
||||||
// should not trigger the lint because the count is conditional
|
|
||||||
let text = "banana";
|
|
||||||
let mut count = 0;
|
|
||||||
for ch in text.chars() {
|
|
||||||
if ch == 'a' {
|
|
||||||
count += 1;
|
|
||||||
}
|
|
||||||
println!("{}", count);
|
|
||||||
}
|
|
||||||
|
|
||||||
// should trigger the lint because the count is not conditional
|
|
||||||
let text = "banana";
|
|
||||||
let mut count = 0;
|
|
||||||
for ch in text.chars() {
|
|
||||||
count += 1;
|
|
||||||
if ch == 'a' {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
println!("{}", count);
|
|
||||||
}
|
|
||||||
|
|
||||||
// should trigger the lint because the count is not conditional
|
|
||||||
let text = "banana";
|
|
||||||
let mut count = 0;
|
|
||||||
for ch in text.chars() {
|
|
||||||
count += 1;
|
|
||||||
for i in 0..2 {
|
|
||||||
let _ = 123;
|
|
||||||
}
|
|
||||||
println!("{}", count);
|
|
||||||
}
|
|
||||||
|
|
||||||
// should not trigger the lint because the count is incremented multiple times
|
|
||||||
let text = "banana";
|
|
||||||
let mut count = 0;
|
|
||||||
for ch in text.chars() {
|
|
||||||
count += 1;
|
|
||||||
for i in 0..2 {
|
|
||||||
count += 1;
|
|
||||||
}
|
|
||||||
println!("{}", count);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mod issue_3308 {
|
|
||||||
#[warn(clippy::explicit_counter_loop)]
|
|
||||||
pub fn test() {
|
|
||||||
// should not trigger the lint because the count is incremented multiple times
|
|
||||||
let mut skips = 0;
|
|
||||||
let erasures = vec![];
|
|
||||||
for i in 0..10 {
|
|
||||||
while erasures.contains(&(i + skips)) {
|
|
||||||
skips += 1;
|
|
||||||
}
|
|
||||||
println!("{}", skips);
|
|
||||||
}
|
|
||||||
|
|
||||||
// should not trigger the lint because the count is incremented multiple times
|
|
||||||
let mut skips = 0;
|
|
||||||
for i in 0..10 {
|
|
||||||
let mut j = 0;
|
|
||||||
while j < 5 {
|
|
||||||
skips += 1;
|
|
||||||
j += 1;
|
|
||||||
}
|
|
||||||
println!("{}", skips);
|
|
||||||
}
|
|
||||||
|
|
||||||
// should not trigger the lint because the count is incremented multiple times
|
|
||||||
let mut skips = 0;
|
|
||||||
for i in 0..10 {
|
|
||||||
for j in 0..5 {
|
|
||||||
skips += 1;
|
|
||||||
}
|
|
||||||
println!("{}", skips);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,515 +1,421 @@
|
||||||
error: for loop over `option`, which is an `Option`. This is more readably written as an `if let` statement.
|
|
||||||
--> $DIR/for_loop.rs:27:14
|
|
||||||
|
|
|
||||||
27 | for x in option {
|
|
||||||
| ^^^^^^
|
|
||||||
|
|
|
||||||
= note: `-D clippy::for-loop-over-option` implied by `-D warnings`
|
|
||||||
= help: consider replacing `for x in option` with `if let Some(x) = option`
|
|
||||||
|
|
||||||
error: for loop over `result`, which is a `Result`. This is more readably written as an `if let` statement.
|
|
||||||
--> $DIR/for_loop.rs:32:14
|
|
||||||
|
|
|
||||||
32 | for x in result {
|
|
||||||
| ^^^^^^
|
|
||||||
|
|
|
||||||
= note: `-D clippy::for-loop-over-result` implied by `-D warnings`
|
|
||||||
= help: consider replacing `for x in result` with `if let Ok(x) = result`
|
|
||||||
|
|
||||||
error: for loop over `option.ok_or("x not found")`, which is a `Result`. This is more readably written as an `if let` statement.
|
|
||||||
--> $DIR/for_loop.rs:36:14
|
|
||||||
|
|
|
||||||
36 | for x in option.ok_or("x not found") {
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= help: consider replacing `for x in option.ok_or("x not found")` with `if let Ok(x) = option.ok_or("x not found")`
|
|
||||||
|
|
||||||
error: you are iterating over `Iterator::next()` which is an Option; this will compile but is probably not what you want
|
|
||||||
--> $DIR/for_loop.rs:42:14
|
|
||||||
|
|
|
||||||
42 | for x in v.iter().next() {
|
|
||||||
| ^^^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= note: `-D clippy::iter-next-loop` implied by `-D warnings`
|
|
||||||
|
|
||||||
error: for loop over `v.iter().next().and(Some(0))`, which is an `Option`. This is more readably written as an `if let` statement.
|
|
||||||
--> $DIR/for_loop.rs:47:14
|
|
||||||
|
|
|
||||||
47 | for x in v.iter().next().and(Some(0)) {
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= help: consider replacing `for x in v.iter().next().and(Some(0))` with `if let Some(x) = v.iter().next().and(Some(0))`
|
|
||||||
|
|
||||||
error: for loop over `v.iter().next().ok_or("x not found")`, which is a `Result`. This is more readably written as an `if let` statement.
|
|
||||||
--> $DIR/for_loop.rs:51:14
|
|
||||||
|
|
|
||||||
51 | for x in v.iter().next().ok_or("x not found") {
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= help: consider replacing `for x in v.iter().next().ok_or("x not found")` with `if let Ok(x) = v.iter().next().ok_or("x not found")`
|
|
||||||
|
|
||||||
error: this loop never actually loops
|
|
||||||
--> $DIR/for_loop.rs:63:5
|
|
||||||
|
|
|
||||||
63 | / while let Some(x) = option {
|
|
||||||
64 | | println!("{}", x);
|
|
||||||
65 | | break;
|
|
||||||
66 | | }
|
|
||||||
| |_____^
|
|
||||||
|
|
|
||||||
= note: `-D clippy::never-loop` implied by `-D warnings`
|
|
||||||
|
|
||||||
error: this loop never actually loops
|
|
||||||
--> $DIR/for_loop.rs:69:5
|
|
||||||
|
|
|
||||||
69 | / while let Ok(x) = result {
|
|
||||||
70 | | println!("{}", x);
|
|
||||||
71 | | break;
|
|
||||||
72 | | }
|
|
||||||
| |_____^
|
|
||||||
|
|
||||||
error: the loop variable `i` is only used to index `vec`.
|
error: the loop variable `i` is only used to index `vec`.
|
||||||
--> $DIR/for_loop.rs:96:14
|
--> $DIR/for_loop.rs:38:14
|
||||||
|
|
|
|
||||||
96 | for i in 0..vec.len() {
|
38 | for i in 0..vec.len() {
|
||||||
| ^^^^^^^^^^^^
|
| ^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
= note: `-D clippy::needless-range-loop` implied by `-D warnings`
|
= note: `-D clippy::needless-range-loop` implied by `-D warnings`
|
||||||
help: consider using an iterator
|
help: consider using an iterator
|
||||||
|
|
|
|
||||||
96 | for <item> in &vec {
|
38 | for <item> in &vec {
|
||||||
| ^^^^^^ ^^^^
|
| ^^^^^^ ^^^^
|
||||||
|
|
||||||
error: the loop variable `i` is only used to index `vec`.
|
error: the loop variable `i` is only used to index `vec`.
|
||||||
--> $DIR/for_loop.rs:105:14
|
--> $DIR/for_loop.rs:47:14
|
||||||
|
|
|
|
||||||
105 | for i in 0..vec.len() {
|
47 | for i in 0..vec.len() {
|
||||||
| ^^^^^^^^^^^^
|
| ^^^^^^^^^^^^
|
||||||
help: consider using an iterator
|
help: consider using an iterator
|
||||||
|
|
|
|
||||||
105 | for <item> in &vec {
|
47 | for <item> in &vec {
|
||||||
| ^^^^^^ ^^^^
|
| ^^^^^^ ^^^^
|
||||||
|
|
||||||
error: the loop variable `j` is only used to index `STATIC`.
|
error: the loop variable `j` is only used to index `STATIC`.
|
||||||
--> $DIR/for_loop.rs:110:14
|
--> $DIR/for_loop.rs:52:14
|
||||||
|
|
|
|
||||||
110 | for j in 0..4 {
|
52 | for j in 0..4 {
|
||||||
| ^^^^
|
| ^^^^
|
||||||
help: consider using an iterator
|
help: consider using an iterator
|
||||||
|
|
|
|
||||||
110 | for <item> in &STATIC {
|
52 | for <item> in &STATIC {
|
||||||
| ^^^^^^ ^^^^^^^
|
| ^^^^^^ ^^^^^^^
|
||||||
|
|
||||||
error: the loop variable `j` is only used to index `CONST`.
|
error: the loop variable `j` is only used to index `CONST`.
|
||||||
--> $DIR/for_loop.rs:114:14
|
--> $DIR/for_loop.rs:56:14
|
||||||
|
|
|
|
||||||
114 | for j in 0..4 {
|
56 | for j in 0..4 {
|
||||||
| ^^^^
|
| ^^^^
|
||||||
help: consider using an iterator
|
help: consider using an iterator
|
||||||
|
|
|
|
||||||
114 | for <item> in &CONST {
|
56 | for <item> in &CONST {
|
||||||
| ^^^^^^ ^^^^^^
|
| ^^^^^^ ^^^^^^
|
||||||
|
|
||||||
error: the loop variable `i` is used to index `vec`
|
error: the loop variable `i` is used to index `vec`
|
||||||
--> $DIR/for_loop.rs:118:14
|
--> $DIR/for_loop.rs:60:14
|
||||||
|
|
|
|
||||||
118 | for i in 0..vec.len() {
|
60 | for i in 0..vec.len() {
|
||||||
| ^^^^^^^^^^^^
|
| ^^^^^^^^^^^^
|
||||||
help: consider using an iterator
|
help: consider using an iterator
|
||||||
|
|
|
|
||||||
118 | for (i, <item>) in vec.iter().enumerate() {
|
60 | for (i, <item>) in vec.iter().enumerate() {
|
||||||
| ^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: the loop variable `i` is only used to index `vec2`.
|
error: the loop variable `i` is only used to index `vec2`.
|
||||||
--> $DIR/for_loop.rs:126:14
|
--> $DIR/for_loop.rs:68:14
|
||||||
|
|
|
|
||||||
126 | for i in 0..vec.len() {
|
68 | for i in 0..vec.len() {
|
||||||
| ^^^^^^^^^^^^
|
| ^^^^^^^^^^^^
|
||||||
help: consider using an iterator
|
help: consider using an iterator
|
||||||
|
|
|
|
||||||
126 | for <item> in vec2.iter().take(vec.len()) {
|
68 | for <item> in vec2.iter().take(vec.len()) {
|
||||||
| ^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: the loop variable `i` is only used to index `vec`.
|
error: the loop variable `i` is only used to index `vec`.
|
||||||
--> $DIR/for_loop.rs:130:14
|
--> $DIR/for_loop.rs:72:14
|
||||||
|
|
|
|
||||||
130 | for i in 5..vec.len() {
|
72 | for i in 5..vec.len() {
|
||||||
| ^^^^^^^^^^^^
|
| ^^^^^^^^^^^^
|
||||||
help: consider using an iterator
|
help: consider using an iterator
|
||||||
|
|
|
|
||||||
130 | for <item> in vec.iter().skip(5) {
|
72 | for <item> in vec.iter().skip(5) {
|
||||||
| ^^^^^^ ^^^^^^^^^^^^^^^^^^
|
| ^^^^^^ ^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: the loop variable `i` is only used to index `vec`.
|
error: the loop variable `i` is only used to index `vec`.
|
||||||
--> $DIR/for_loop.rs:134:14
|
--> $DIR/for_loop.rs:76:14
|
||||||
|
|
|
|
||||||
134 | for i in 0..MAX_LEN {
|
76 | for i in 0..MAX_LEN {
|
||||||
| ^^^^^^^^^^
|
| ^^^^^^^^^^
|
||||||
help: consider using an iterator
|
help: consider using an iterator
|
||||||
|
|
|
|
||||||
134 | for <item> in vec.iter().take(MAX_LEN) {
|
76 | for <item> in vec.iter().take(MAX_LEN) {
|
||||||
| ^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: the loop variable `i` is only used to index `vec`.
|
error: the loop variable `i` is only used to index `vec`.
|
||||||
--> $DIR/for_loop.rs:138:14
|
--> $DIR/for_loop.rs:80:14
|
||||||
|
|
|
|
||||||
138 | for i in 0..=MAX_LEN {
|
80 | for i in 0..=MAX_LEN {
|
||||||
| ^^^^^^^^^^^
|
| ^^^^^^^^^^^
|
||||||
help: consider using an iterator
|
help: consider using an iterator
|
||||||
|
|
|
|
||||||
138 | for <item> in vec.iter().take(MAX_LEN + 1) {
|
80 | for <item> in vec.iter().take(MAX_LEN + 1) {
|
||||||
| ^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: the loop variable `i` is only used to index `vec`.
|
error: the loop variable `i` is only used to index `vec`.
|
||||||
--> $DIR/for_loop.rs:142:14
|
--> $DIR/for_loop.rs:84:14
|
||||||
|
|
|
|
||||||
142 | for i in 5..10 {
|
84 | for i in 5..10 {
|
||||||
| ^^^^^
|
| ^^^^^
|
||||||
help: consider using an iterator
|
help: consider using an iterator
|
||||||
|
|
|
|
||||||
142 | for <item> in vec.iter().take(10).skip(5) {
|
84 | for <item> in vec.iter().take(10).skip(5) {
|
||||||
| ^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: the loop variable `i` is only used to index `vec`.
|
error: the loop variable `i` is only used to index `vec`.
|
||||||
--> $DIR/for_loop.rs:146:14
|
--> $DIR/for_loop.rs:88:14
|
||||||
|
|
|
|
||||||
146 | for i in 5..=10 {
|
88 | for i in 5..=10 {
|
||||||
| ^^^^^^
|
| ^^^^^^
|
||||||
help: consider using an iterator
|
help: consider using an iterator
|
||||||
|
|
|
|
||||||
146 | for <item> in vec.iter().take(10 + 1).skip(5) {
|
88 | for <item> in vec.iter().take(10 + 1).skip(5) {
|
||||||
| ^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: the loop variable `i` is used to index `vec`
|
error: the loop variable `i` is used to index `vec`
|
||||||
--> $DIR/for_loop.rs:150:14
|
--> $DIR/for_loop.rs:92:14
|
||||||
|
|
|
|
||||||
150 | for i in 5..vec.len() {
|
92 | for i in 5..vec.len() {
|
||||||
| ^^^^^^^^^^^^
|
| ^^^^^^^^^^^^
|
||||||
help: consider using an iterator
|
help: consider using an iterator
|
||||||
|
|
|
|
||||||
150 | for (i, <item>) in vec.iter().enumerate().skip(5) {
|
92 | for (i, <item>) in vec.iter().enumerate().skip(5) {
|
||||||
| ^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: the loop variable `i` is used to index `vec`
|
error: the loop variable `i` is used to index `vec`
|
||||||
--> $DIR/for_loop.rs:154:14
|
--> $DIR/for_loop.rs:96:14
|
||||||
|
|
|
|
||||||
154 | for i in 5..10 {
|
96 | for i in 5..10 {
|
||||||
| ^^^^^
|
| ^^^^^
|
||||||
help: consider using an iterator
|
help: consider using an iterator
|
||||||
|
|
|
|
||||||
154 | for (i, <item>) in vec.iter().enumerate().take(10).skip(5) {
|
96 | for (i, <item>) in vec.iter().enumerate().take(10).skip(5) {
|
||||||
| ^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: this range is empty so this for loop will never run
|
error: this range is empty so this for loop will never run
|
||||||
--> $DIR/for_loop.rs:158:14
|
--> $DIR/for_loop.rs:100:14
|
||||||
|
|
|
|
||||||
158 | for i in 10..0 {
|
100 | for i in 10..0 {
|
||||||
| ^^^^^
|
| ^^^^^
|
||||||
|
|
|
|
||||||
= note: `-D clippy::reverse-range-loop` implied by `-D warnings`
|
= note: `-D clippy::reverse-range-loop` implied by `-D warnings`
|
||||||
help: consider using the following if you are attempting to iterate over this range in reverse
|
help: consider using the following if you are attempting to iterate over this range in reverse
|
||||||
|
|
|
|
||||||
158 | for i in (0..10).rev() {
|
100 | for i in (0..10).rev() {
|
||||||
| ^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: this range is empty so this for loop will never run
|
error: this range is empty so this for loop will never run
|
||||||
--> $DIR/for_loop.rs:162:14
|
--> $DIR/for_loop.rs:104:14
|
||||||
|
|
|
|
||||||
162 | for i in 10..=0 {
|
104 | for i in 10..=0 {
|
||||||
| ^^^^^^
|
| ^^^^^^
|
||||||
help: consider using the following if you are attempting to iterate over this range in reverse
|
help: consider using the following if you are attempting to iterate over this range in reverse
|
||||||
|
|
|
|
||||||
162 | for i in (0...10).rev() {
|
104 | for i in (0...10).rev() {
|
||||||
| ^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: this range is empty so this for loop will never run
|
error: this range is empty so this for loop will never run
|
||||||
--> $DIR/for_loop.rs:166:14
|
--> $DIR/for_loop.rs:108:14
|
||||||
|
|
|
|
||||||
166 | for i in MAX_LEN..0 {
|
108 | for i in MAX_LEN..0 {
|
||||||
| ^^^^^^^^^^
|
| ^^^^^^^^^^
|
||||||
help: consider using the following if you are attempting to iterate over this range in reverse
|
help: consider using the following if you are attempting to iterate over this range in reverse
|
||||||
|
|
|
|
||||||
166 | for i in (0..MAX_LEN).rev() {
|
108 | for i in (0..MAX_LEN).rev() {
|
||||||
| ^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: this range is empty so this for loop will never run
|
error: this range is empty so this for loop will never run
|
||||||
--> $DIR/for_loop.rs:170:14
|
--> $DIR/for_loop.rs:112:14
|
||||||
|
|
|
|
||||||
170 | for i in 5..5 {
|
112 | for i in 5..5 {
|
||||||
| ^^^^
|
| ^^^^
|
||||||
|
|
||||||
error: this range is empty so this for loop will never run
|
error: this range is empty so this for loop will never run
|
||||||
--> $DIR/for_loop.rs:195:14
|
--> $DIR/for_loop.rs:137:14
|
||||||
|
|
|
|
||||||
195 | for i in 10..5 + 4 {
|
137 | for i in 10..5 + 4 {
|
||||||
| ^^^^^^^^^
|
| ^^^^^^^^^
|
||||||
help: consider using the following if you are attempting to iterate over this range in reverse
|
help: consider using the following if you are attempting to iterate over this range in reverse
|
||||||
|
|
|
|
||||||
195 | for i in (5 + 4..10).rev() {
|
137 | for i in (5 + 4..10).rev() {
|
||||||
| ^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: this range is empty so this for loop will never run
|
error: this range is empty so this for loop will never run
|
||||||
--> $DIR/for_loop.rs:199:14
|
--> $DIR/for_loop.rs:141:14
|
||||||
|
|
|
|
||||||
199 | for i in (5 + 2)..(3 - 1) {
|
141 | for i in (5 + 2)..(3 - 1) {
|
||||||
| ^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^
|
||||||
help: consider using the following if you are attempting to iterate over this range in reverse
|
help: consider using the following if you are attempting to iterate over this range in reverse
|
||||||
|
|
|
|
||||||
199 | for i in ((3 - 1)..(5 + 2)).rev() {
|
141 | for i in ((3 - 1)..(5 + 2)).rev() {
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: this range is empty so this for loop will never run
|
error: this range is empty so this for loop will never run
|
||||||
--> $DIR/for_loop.rs:203:14
|
--> $DIR/for_loop.rs:145:14
|
||||||
|
|
|
|
||||||
203 | for i in (5 + 2)..(8 - 1) {
|
145 | for i in (5 + 2)..(8 - 1) {
|
||||||
| ^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: it is more concise to loop over references to containers instead of using explicit iteration methods
|
error: it is more concise to loop over references to containers instead of using explicit iteration methods
|
||||||
--> $DIR/for_loop.rs:225:15
|
--> $DIR/for_loop.rs:167:15
|
||||||
|
|
|
|
||||||
225 | for _v in vec.iter() {}
|
167 | for _v in vec.iter() {}
|
||||||
| ^^^^^^^^^^ help: to write this more concisely, try: `&vec`
|
| ^^^^^^^^^^ help: to write this more concisely, try: `&vec`
|
||||||
|
|
|
|
||||||
= note: `-D clippy::explicit-iter-loop` implied by `-D warnings`
|
= note: `-D clippy::explicit-iter-loop` implied by `-D warnings`
|
||||||
|
|
||||||
error: it is more concise to loop over references to containers instead of using explicit iteration methods
|
error: it is more concise to loop over references to containers instead of using explicit iteration methods
|
||||||
--> $DIR/for_loop.rs:227:15
|
--> $DIR/for_loop.rs:169:15
|
||||||
|
|
|
|
||||||
227 | for _v in vec.iter_mut() {}
|
169 | for _v in vec.iter_mut() {}
|
||||||
| ^^^^^^^^^^^^^^ help: to write this more concisely, try: `&mut vec`
|
| ^^^^^^^^^^^^^^ help: to write this more concisely, try: `&mut vec`
|
||||||
|
|
||||||
error: it is more concise to loop over containers instead of using explicit iteration methods`
|
error: it is more concise to loop over containers instead of using explicit iteration methods`
|
||||||
--> $DIR/for_loop.rs:230:15
|
--> $DIR/for_loop.rs:172:15
|
||||||
|
|
|
|
||||||
230 | for _v in out_vec.into_iter() {}
|
172 | for _v in out_vec.into_iter() {}
|
||||||
| ^^^^^^^^^^^^^^^^^^^ help: to write this more concisely, try: `out_vec`
|
| ^^^^^^^^^^^^^^^^^^^ help: to write this more concisely, try: `out_vec`
|
||||||
|
|
|
|
||||||
= note: `-D clippy::explicit-into-iter-loop` implied by `-D warnings`
|
= note: `-D clippy::explicit-into-iter-loop` implied by `-D warnings`
|
||||||
|
|
||||||
error: it is more concise to loop over references to containers instead of using explicit iteration methods
|
error: it is more concise to loop over references to containers instead of using explicit iteration methods
|
||||||
--> $DIR/for_loop.rs:233:15
|
--> $DIR/for_loop.rs:175:15
|
||||||
|
|
|
|
||||||
233 | for _v in array.into_iter() {}
|
175 | for _v in array.into_iter() {}
|
||||||
| ^^^^^^^^^^^^^^^^^ help: to write this more concisely, try: `&array`
|
| ^^^^^^^^^^^^^^^^^ help: to write this more concisely, try: `&array`
|
||||||
|
|
||||||
error: it is more concise to loop over references to containers instead of using explicit iteration methods
|
error: it is more concise to loop over references to containers instead of using explicit iteration methods
|
||||||
--> $DIR/for_loop.rs:238:15
|
--> $DIR/for_loop.rs:180:15
|
||||||
|
|
|
|
||||||
238 | for _v in [1, 2, 3].iter() {}
|
180 | for _v in [1, 2, 3].iter() {}
|
||||||
| ^^^^^^^^^^^^^^^^ help: to write this more concisely, try: `&[1, 2, 3]`
|
| ^^^^^^^^^^^^^^^^ help: to write this more concisely, try: `&[1, 2, 3]`
|
||||||
|
|
||||||
error: it is more concise to loop over references to containers instead of using explicit iteration methods
|
error: it is more concise to loop over references to containers instead of using explicit iteration methods
|
||||||
--> $DIR/for_loop.rs:242:15
|
--> $DIR/for_loop.rs:184:15
|
||||||
|
|
|
|
||||||
242 | for _v in [0; 32].iter() {}
|
184 | for _v in [0; 32].iter() {}
|
||||||
| ^^^^^^^^^^^^^^ help: to write this more concisely, try: `&[0; 32]`
|
| ^^^^^^^^^^^^^^ help: to write this more concisely, try: `&[0; 32]`
|
||||||
|
|
||||||
error: it is more concise to loop over references to containers instead of using explicit iteration methods
|
error: it is more concise to loop over references to containers instead of using explicit iteration methods
|
||||||
--> $DIR/for_loop.rs:247:15
|
--> $DIR/for_loop.rs:189:15
|
||||||
|
|
|
|
||||||
247 | for _v in ll.iter() {}
|
189 | for _v in ll.iter() {}
|
||||||
| ^^^^^^^^^ help: to write this more concisely, try: `&ll`
|
| ^^^^^^^^^ help: to write this more concisely, try: `&ll`
|
||||||
|
|
||||||
error: it is more concise to loop over references to containers instead of using explicit iteration methods
|
error: it is more concise to loop over references to containers instead of using explicit iteration methods
|
||||||
--> $DIR/for_loop.rs:250:15
|
--> $DIR/for_loop.rs:192:15
|
||||||
|
|
|
|
||||||
250 | for _v in vd.iter() {}
|
192 | for _v in vd.iter() {}
|
||||||
| ^^^^^^^^^ help: to write this more concisely, try: `&vd`
|
| ^^^^^^^^^ help: to write this more concisely, try: `&vd`
|
||||||
|
|
||||||
error: it is more concise to loop over references to containers instead of using explicit iteration methods
|
error: it is more concise to loop over references to containers instead of using explicit iteration methods
|
||||||
--> $DIR/for_loop.rs:253:15
|
--> $DIR/for_loop.rs:195:15
|
||||||
|
|
|
|
||||||
253 | for _v in bh.iter() {}
|
195 | for _v in bh.iter() {}
|
||||||
| ^^^^^^^^^ help: to write this more concisely, try: `&bh`
|
| ^^^^^^^^^ help: to write this more concisely, try: `&bh`
|
||||||
|
|
||||||
error: it is more concise to loop over references to containers instead of using explicit iteration methods
|
error: it is more concise to loop over references to containers instead of using explicit iteration methods
|
||||||
--> $DIR/for_loop.rs:256:15
|
--> $DIR/for_loop.rs:198:15
|
||||||
|
|
|
|
||||||
256 | for _v in hm.iter() {}
|
198 | for _v in hm.iter() {}
|
||||||
| ^^^^^^^^^ help: to write this more concisely, try: `&hm`
|
| ^^^^^^^^^ help: to write this more concisely, try: `&hm`
|
||||||
|
|
||||||
error: it is more concise to loop over references to containers instead of using explicit iteration methods
|
error: it is more concise to loop over references to containers instead of using explicit iteration methods
|
||||||
--> $DIR/for_loop.rs:259:15
|
--> $DIR/for_loop.rs:201:15
|
||||||
|
|
|
|
||||||
259 | for _v in bt.iter() {}
|
201 | for _v in bt.iter() {}
|
||||||
| ^^^^^^^^^ help: to write this more concisely, try: `&bt`
|
| ^^^^^^^^^ help: to write this more concisely, try: `&bt`
|
||||||
|
|
||||||
error: it is more concise to loop over references to containers instead of using explicit iteration methods
|
error: it is more concise to loop over references to containers instead of using explicit iteration methods
|
||||||
--> $DIR/for_loop.rs:262:15
|
--> $DIR/for_loop.rs:204:15
|
||||||
|
|
|
|
||||||
262 | for _v in hs.iter() {}
|
204 | for _v in hs.iter() {}
|
||||||
| ^^^^^^^^^ help: to write this more concisely, try: `&hs`
|
| ^^^^^^^^^ help: to write this more concisely, try: `&hs`
|
||||||
|
|
||||||
error: it is more concise to loop over references to containers instead of using explicit iteration methods
|
error: it is more concise to loop over references to containers instead of using explicit iteration methods
|
||||||
--> $DIR/for_loop.rs:265:15
|
--> $DIR/for_loop.rs:207:15
|
||||||
|
|
|
|
||||||
265 | for _v in bs.iter() {}
|
207 | for _v in bs.iter() {}
|
||||||
| ^^^^^^^^^ help: to write this more concisely, try: `&bs`
|
| ^^^^^^^^^ help: to write this more concisely, try: `&bs`
|
||||||
|
|
||||||
error: you are iterating over `Iterator::next()` which is an Option; this will compile but is probably not what you want
|
error: you are iterating over `Iterator::next()` which is an Option; this will compile but is probably not what you want
|
||||||
--> $DIR/for_loop.rs:267:15
|
--> $DIR/for_loop.rs:209:15
|
||||||
|
|
|
|
||||||
267 | for _v in vec.iter().next() {}
|
209 | for _v in vec.iter().next() {}
|
||||||
| ^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: `-D clippy::iter-next-loop` implied by `-D warnings`
|
||||||
|
|
||||||
error: you are collect()ing an iterator and throwing away the result. Consider using an explicit for loop to exhaust the iterator
|
error: you are collect()ing an iterator and throwing away the result. Consider using an explicit for loop to exhaust the iterator
|
||||||
--> $DIR/for_loop.rs:274:5
|
--> $DIR/for_loop.rs:216:5
|
||||||
|
|
|
|
||||||
274 | vec.iter().cloned().map(|x| out.push(x)).collect::<Vec<_>>();
|
216 | vec.iter().cloned().map(|x| out.push(x)).collect::<Vec<_>>();
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
= note: `-D clippy::unused-collect` implied by `-D warnings`
|
= note: `-D clippy::unused-collect` implied by `-D warnings`
|
||||||
|
|
||||||
error: the variable `_index` is used as a loop counter. Consider using `for (_index, item) in &vec.enumerate()` or similar iterators
|
|
||||||
--> $DIR/for_loop.rs:279:15
|
|
||||||
|
|
|
||||||
279 | for _v in &vec {
|
|
||||||
| ^^^^
|
|
||||||
|
|
|
||||||
= note: `-D clippy::explicit-counter-loop` implied by `-D warnings`
|
|
||||||
|
|
||||||
error: the variable `_index` is used as a loop counter. Consider using `for (_index, item) in &vec.enumerate()` or similar iterators
|
|
||||||
--> $DIR/for_loop.rs:285:15
|
|
||||||
|
|
|
||||||
285 | for _v in &vec {
|
|
||||||
| ^^^^
|
|
||||||
|
|
||||||
error: you seem to want to iterate on a map's values
|
error: you seem to want to iterate on a map's values
|
||||||
--> $DIR/for_loop.rs:395:19
|
--> $DIR/for_loop.rs:325:19
|
||||||
|
|
|
|
||||||
395 | for (_, v) in &m {
|
325 | for (_, v) in &m {
|
||||||
| ^^
|
| ^^
|
||||||
|
|
|
|
||||||
= note: `-D clippy::for-kv-map` implied by `-D warnings`
|
= note: `-D clippy::for-kv-map` implied by `-D warnings`
|
||||||
help: use the corresponding method
|
help: use the corresponding method
|
||||||
|
|
|
|
||||||
395 | for v in m.values() {
|
325 | for v in m.values() {
|
||||||
| ^ ^^^^^^^^^^
|
| ^ ^^^^^^^^^^
|
||||||
|
|
||||||
error: you seem to want to iterate on a map's values
|
error: you seem to want to iterate on a map's values
|
||||||
--> $DIR/for_loop.rs:400:19
|
--> $DIR/for_loop.rs:330:19
|
||||||
|
|
|
|
||||||
400 | for (_, v) in &*m {
|
330 | for (_, v) in &*m {
|
||||||
| ^^^
|
| ^^^
|
||||||
help: use the corresponding method
|
help: use the corresponding method
|
||||||
|
|
|
|
||||||
400 | for v in (*m).values() {
|
330 | for v in (*m).values() {
|
||||||
| ^ ^^^^^^^^^^^^^
|
| ^ ^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: you seem to want to iterate on a map's values
|
error: you seem to want to iterate on a map's values
|
||||||
--> $DIR/for_loop.rs:408:19
|
--> $DIR/for_loop.rs:338:19
|
||||||
|
|
|
|
||||||
408 | for (_, v) in &mut m {
|
338 | for (_, v) in &mut m {
|
||||||
| ^^^^^^
|
| ^^^^^^
|
||||||
help: use the corresponding method
|
help: use the corresponding method
|
||||||
|
|
|
|
||||||
408 | for v in m.values_mut() {
|
338 | for v in m.values_mut() {
|
||||||
| ^ ^^^^^^^^^^^^^^
|
| ^ ^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: you seem to want to iterate on a map's values
|
error: you seem to want to iterate on a map's values
|
||||||
--> $DIR/for_loop.rs:413:19
|
--> $DIR/for_loop.rs:343:19
|
||||||
|
|
|
|
||||||
413 | for (_, v) in &mut *m {
|
343 | for (_, v) in &mut *m {
|
||||||
| ^^^^^^^
|
| ^^^^^^^
|
||||||
help: use the corresponding method
|
help: use the corresponding method
|
||||||
|
|
|
|
||||||
413 | for v in (*m).values_mut() {
|
343 | for v in (*m).values_mut() {
|
||||||
| ^ ^^^^^^^^^^^^^^^^^
|
| ^ ^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: you seem to want to iterate on a map's keys
|
error: you seem to want to iterate on a map's keys
|
||||||
--> $DIR/for_loop.rs:419:24
|
--> $DIR/for_loop.rs:349:24
|
||||||
|
|
|
|
||||||
419 | for (k, _value) in rm {
|
349 | for (k, _value) in rm {
|
||||||
| ^^
|
| ^^
|
||||||
help: use the corresponding method
|
help: use the corresponding method
|
||||||
|
|
|
|
||||||
419 | for k in rm.keys() {
|
349 | for k in rm.keys() {
|
||||||
| ^ ^^^^^^^^^
|
| ^ ^^^^^^^^^
|
||||||
|
|
||||||
error: it looks like you're manually copying between slices
|
error: it looks like you're manually copying between slices
|
||||||
--> $DIR/for_loop.rs:472:14
|
--> $DIR/for_loop.rs:402:14
|
||||||
|
|
|
|
||||||
472 | for i in 0..src.len() {
|
402 | for i in 0..src.len() {
|
||||||
| ^^^^^^^^^^^^ help: try replacing the loop by: `dst[..src.len()].clone_from_slice(&src[..])`
|
| ^^^^^^^^^^^^ help: try replacing the loop by: `dst[..src.len()].clone_from_slice(&src[..])`
|
||||||
|
|
|
|
||||||
= note: `-D clippy::manual-memcpy` implied by `-D warnings`
|
= note: `-D clippy::manual-memcpy` implied by `-D warnings`
|
||||||
|
|
||||||
error: it looks like you're manually copying between slices
|
error: it looks like you're manually copying between slices
|
||||||
--> $DIR/for_loop.rs:477:14
|
--> $DIR/for_loop.rs:407:14
|
||||||
|
|
|
|
||||||
477 | for i in 0..src.len() {
|
407 | for i in 0..src.len() {
|
||||||
| ^^^^^^^^^^^^ help: try replacing the loop by: `dst[10..(src.len() + 10)].clone_from_slice(&src[..])`
|
| ^^^^^^^^^^^^ help: try replacing the loop by: `dst[10..(src.len() + 10)].clone_from_slice(&src[..])`
|
||||||
|
|
||||||
error: it looks like you're manually copying between slices
|
error: it looks like you're manually copying between slices
|
||||||
--> $DIR/for_loop.rs:482:14
|
--> $DIR/for_loop.rs:412:14
|
||||||
|
|
|
|
||||||
482 | for i in 0..src.len() {
|
412 | for i in 0..src.len() {
|
||||||
| ^^^^^^^^^^^^ help: try replacing the loop by: `dst[..src.len()].clone_from_slice(&src[10..])`
|
| ^^^^^^^^^^^^ help: try replacing the loop by: `dst[..src.len()].clone_from_slice(&src[10..])`
|
||||||
|
|
||||||
error: it looks like you're manually copying between slices
|
error: it looks like you're manually copying between slices
|
||||||
--> $DIR/for_loop.rs:487:14
|
--> $DIR/for_loop.rs:417:14
|
||||||
|
|
|
|
||||||
487 | for i in 11..src.len() {
|
417 | for i in 11..src.len() {
|
||||||
| ^^^^^^^^^^^^^ help: try replacing the loop by: `dst[11..src.len()].clone_from_slice(&src[(11 - 10)..(src.len() - 10)])`
|
| ^^^^^^^^^^^^^ help: try replacing the loop by: `dst[11..src.len()].clone_from_slice(&src[(11 - 10)..(src.len() - 10)])`
|
||||||
|
|
||||||
error: it looks like you're manually copying between slices
|
error: it looks like you're manually copying between slices
|
||||||
--> $DIR/for_loop.rs:492:14
|
--> $DIR/for_loop.rs:422:14
|
||||||
|
|
|
|
||||||
492 | for i in 0..dst.len() {
|
422 | for i in 0..dst.len() {
|
||||||
| ^^^^^^^^^^^^ help: try replacing the loop by: `dst.clone_from_slice(&src[..dst.len()])`
|
| ^^^^^^^^^^^^ help: try replacing the loop by: `dst.clone_from_slice(&src[..dst.len()])`
|
||||||
|
|
||||||
error: it looks like you're manually copying between slices
|
error: it looks like you're manually copying between slices
|
||||||
--> $DIR/for_loop.rs:505:14
|
--> $DIR/for_loop.rs:435:14
|
||||||
|
|
|
|
||||||
505 | for i in 10..256 {
|
435 | for i in 10..256 {
|
||||||
| ^^^^^^^
|
| ^^^^^^^
|
||||||
help: try replacing the loop by
|
help: try replacing the loop by
|
||||||
|
|
|
|
||||||
505 | for i in dst[10..256].clone_from_slice(&src[(10 - 5)..(256 - 5)])
|
435 | for i in dst[10..256].clone_from_slice(&src[(10 - 5)..(256 - 5)])
|
||||||
506 | dst2[(10 + 500)..(256 + 500)].clone_from_slice(&src[10..256]) {
|
436 | dst2[(10 + 500)..(256 + 500)].clone_from_slice(&src[10..256]) {
|
||||||
|
|
|
|
||||||
|
|
||||||
error: it looks like you're manually copying between slices
|
error: it looks like you're manually copying between slices
|
||||||
--> $DIR/for_loop.rs:517:14
|
--> $DIR/for_loop.rs:447:14
|
||||||
|
|
|
|
||||||
517 | for i in 10..LOOP_OFFSET {
|
447 | for i in 10..LOOP_OFFSET {
|
||||||
| ^^^^^^^^^^^^^^^ help: try replacing the loop by: `dst[(10 + LOOP_OFFSET)..(LOOP_OFFSET + LOOP_OFFSET)].clone_from_slice(&src[(10 - some_var)..(LOOP_OFFSET - some_var)])`
|
| ^^^^^^^^^^^^^^^ help: try replacing the loop by: `dst[(10 + LOOP_OFFSET)..(LOOP_OFFSET + LOOP_OFFSET)].clone_from_slice(&src[(10 - some_var)..(LOOP_OFFSET - some_var)])`
|
||||||
|
|
||||||
error: it looks like you're manually copying between slices
|
error: it looks like you're manually copying between slices
|
||||||
--> $DIR/for_loop.rs:530:14
|
--> $DIR/for_loop.rs:460:14
|
||||||
|
|
|
|
||||||
530 | for i in 0..src_vec.len() {
|
460 | for i in 0..src_vec.len() {
|
||||||
| ^^^^^^^^^^^^^^^^ help: try replacing the loop by: `dst_vec[..src_vec.len()].clone_from_slice(&src_vec[..])`
|
| ^^^^^^^^^^^^^^^^ help: try replacing the loop by: `dst_vec[..src_vec.len()].clone_from_slice(&src_vec[..])`
|
||||||
|
|
||||||
error: it looks like you're manually copying between slices
|
error: it looks like you're manually copying between slices
|
||||||
--> $DIR/for_loop.rs:559:14
|
--> $DIR/for_loop.rs:489:14
|
||||||
|
|
|
|
||||||
559 | for i in from..from + src.len() {
|
489 | for i in from..from + src.len() {
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^ help: try replacing the loop by: `dst[from..from + src.len()].clone_from_slice(&src[0..(from + src.len() - from)])`
|
| ^^^^^^^^^^^^^^^^^^^^^^ help: try replacing the loop by: `dst[from..from + src.len()].clone_from_slice(&src[0..(from + src.len() - from)])`
|
||||||
|
|
||||||
error: it looks like you're manually copying between slices
|
error: it looks like you're manually copying between slices
|
||||||
--> $DIR/for_loop.rs:563:14
|
--> $DIR/for_loop.rs:493:14
|
||||||
|
|
|
|
||||||
563 | for i in from..from + 3 {
|
493 | for i in from..from + 3 {
|
||||||
| ^^^^^^^^^^^^^^ help: try replacing the loop by: `dst[from..from + 3].clone_from_slice(&src[0..(from + 3 - from)])`
|
| ^^^^^^^^^^^^^^ help: try replacing the loop by: `dst[from..from + 3].clone_from_slice(&src[0..(from + 3 - from)])`
|
||||||
|
|
||||||
error: it looks like you're manually copying between slices
|
error: it looks like you're manually copying between slices
|
||||||
--> $DIR/for_loop.rs:570:14
|
--> $DIR/for_loop.rs:500:14
|
||||||
|
|
|
|
||||||
570 | for i in 0..src.len() {
|
500 | for i in 0..src.len() {
|
||||||
| ^^^^^^^^^^^^ help: try replacing the loop by: `dst[..src.len()].clone_from_slice(&src[..])`
|
| ^^^^^^^^^^^^ help: try replacing the loop by: `dst[..src.len()].clone_from_slice(&src[..])`
|
||||||
|
|
||||||
error: the variable `count` is used as a loop counter. Consider using `for (count, item) in text.chars().enumerate()` or similar iterators
|
error: aborting due to 51 previous errors
|
||||||
--> $DIR/for_loop.rs:631:19
|
|
||||||
|
|
|
||||||
631 | for ch in text.chars() {
|
|
||||||
| ^^^^^^^^^^^^
|
|
||||||
|
|
||||||
error: the variable `count` is used as a loop counter. Consider using `for (count, item) in text.chars().enumerate()` or similar iterators
|
|
||||||
--> $DIR/for_loop.rs:642:19
|
|
||||||
|
|
|
||||||
642 | for ch in text.chars() {
|
|
||||||
| ^^^^^^^^^^^^
|
|
||||||
|
|
||||||
error: aborting due to 63 previous errors
|
|
||||||
|
|
||||||
|
|
68
tests/ui/for_loop_over_option_result.rs
Normal file
68
tests/ui/for_loop_over_option_result.rs
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
// Copyright 2014-2018 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
#![warn(clippy::for_loop_over_option, clippy::for_loop_over_result)]
|
||||||
|
|
||||||
|
/// Tests for_loop_over_result and for_loop_over_option
|
||||||
|
|
||||||
|
fn for_loop_over_option_and_result() {
|
||||||
|
let option = Some(1);
|
||||||
|
let result = option.ok_or("x not found");
|
||||||
|
let v = vec![0, 1, 2];
|
||||||
|
|
||||||
|
// check FOR_LOOP_OVER_OPTION lint
|
||||||
|
for x in option {
|
||||||
|
println!("{}", x);
|
||||||
|
}
|
||||||
|
|
||||||
|
// check FOR_LOOP_OVER_RESULT lint
|
||||||
|
for x in result {
|
||||||
|
println!("{}", x);
|
||||||
|
}
|
||||||
|
|
||||||
|
for x in option.ok_or("x not found") {
|
||||||
|
println!("{}", x);
|
||||||
|
}
|
||||||
|
|
||||||
|
// make sure LOOP_OVER_NEXT lint takes clippy::precedence when next() is the last call
|
||||||
|
// in the chain
|
||||||
|
for x in v.iter().next() {
|
||||||
|
println!("{}", x);
|
||||||
|
}
|
||||||
|
|
||||||
|
// make sure we lint when next() is not the last call in the chain
|
||||||
|
for x in v.iter().next().and(Some(0)) {
|
||||||
|
println!("{}", x);
|
||||||
|
}
|
||||||
|
|
||||||
|
for x in v.iter().next().ok_or("x not found") {
|
||||||
|
println!("{}", x);
|
||||||
|
}
|
||||||
|
|
||||||
|
// check for false positives
|
||||||
|
|
||||||
|
// for loop false positive
|
||||||
|
for x in v {
|
||||||
|
println!("{}", x);
|
||||||
|
}
|
||||||
|
|
||||||
|
// while let false positive for Option
|
||||||
|
while let Some(x) = option {
|
||||||
|
println!("{}", x);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// while let false positive for Result
|
||||||
|
while let Ok(x) = result {
|
||||||
|
println!("{}", x);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
72
tests/ui/for_loop_over_option_result.stderr
Normal file
72
tests/ui/for_loop_over_option_result.stderr
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
error: for loop over `option`, which is an `Option`. This is more readably written as an `if let` statement.
|
||||||
|
--> $DIR/for_loop_over_option_result.rs:20:14
|
||||||
|
|
|
||||||
|
20 | for x in option {
|
||||||
|
| ^^^^^^
|
||||||
|
|
|
||||||
|
= note: `-D clippy::for-loop-over-option` implied by `-D warnings`
|
||||||
|
= help: consider replacing `for x in option` with `if let Some(x) = option`
|
||||||
|
|
||||||
|
error: for loop over `result`, which is a `Result`. This is more readably written as an `if let` statement.
|
||||||
|
--> $DIR/for_loop_over_option_result.rs:25:14
|
||||||
|
|
|
||||||
|
25 | for x in result {
|
||||||
|
| ^^^^^^
|
||||||
|
|
|
||||||
|
= note: `-D clippy::for-loop-over-result` implied by `-D warnings`
|
||||||
|
= help: consider replacing `for x in result` with `if let Ok(x) = result`
|
||||||
|
|
||||||
|
error: for loop over `option.ok_or("x not found")`, which is a `Result`. This is more readably written as an `if let` statement.
|
||||||
|
--> $DIR/for_loop_over_option_result.rs:29:14
|
||||||
|
|
|
||||||
|
29 | for x in option.ok_or("x not found") {
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= help: consider replacing `for x in option.ok_or("x not found")` with `if let Ok(x) = option.ok_or("x not found")`
|
||||||
|
|
||||||
|
error: you are iterating over `Iterator::next()` which is an Option; this will compile but is probably not what you want
|
||||||
|
--> $DIR/for_loop_over_option_result.rs:35:14
|
||||||
|
|
|
||||||
|
35 | for x in v.iter().next() {
|
||||||
|
| ^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: #[deny(clippy::iter_next_loop)] on by default
|
||||||
|
|
||||||
|
error: for loop over `v.iter().next().and(Some(0))`, which is an `Option`. This is more readably written as an `if let` statement.
|
||||||
|
--> $DIR/for_loop_over_option_result.rs:40:14
|
||||||
|
|
|
||||||
|
40 | for x in v.iter().next().and(Some(0)) {
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= help: consider replacing `for x in v.iter().next().and(Some(0))` with `if let Some(x) = v.iter().next().and(Some(0))`
|
||||||
|
|
||||||
|
error: for loop over `v.iter().next().ok_or("x not found")`, which is a `Result`. This is more readably written as an `if let` statement.
|
||||||
|
--> $DIR/for_loop_over_option_result.rs:44:14
|
||||||
|
|
|
||||||
|
44 | for x in v.iter().next().ok_or("x not found") {
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= help: consider replacing `for x in v.iter().next().ok_or("x not found")` with `if let Ok(x) = v.iter().next().ok_or("x not found")`
|
||||||
|
|
||||||
|
error: this loop never actually loops
|
||||||
|
--> $DIR/for_loop_over_option_result.rs:56:5
|
||||||
|
|
|
||||||
|
56 | / while let Some(x) = option {
|
||||||
|
57 | | println!("{}", x);
|
||||||
|
58 | | break;
|
||||||
|
59 | | }
|
||||||
|
| |_____^
|
||||||
|
|
|
||||||
|
= note: #[deny(clippy::never_loop)] on by default
|
||||||
|
|
||||||
|
error: this loop never actually loops
|
||||||
|
--> $DIR/for_loop_over_option_result.rs:62:5
|
||||||
|
|
|
||||||
|
62 | / while let Ok(x) = result {
|
||||||
|
63 | | println!("{}", x);
|
||||||
|
64 | | break;
|
||||||
|
65 | | }
|
||||||
|
| |_____^
|
||||||
|
|
||||||
|
error: aborting due to 8 previous errors
|
||||||
|
|
|
@ -53,4 +53,5 @@ fn main() {
|
||||||
let _ = String::from(format!("A: {:04}", 123));
|
let _ = String::from(format!("A: {:04}", 123));
|
||||||
let _ = "".lines().into_iter();
|
let _ = "".lines().into_iter();
|
||||||
let _ = vec![1, 2, 3].into_iter().into_iter();
|
let _ = vec![1, 2, 3].into_iter().into_iter();
|
||||||
|
let _: String = format!("Hello {}", "world").into();
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,5 +58,11 @@ error: identical conversion
|
||||||
55 | let _ = vec![1, 2, 3].into_iter().into_iter();
|
55 | let _ = vec![1, 2, 3].into_iter().into_iter();
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `vec![1, 2, 3].into_iter()`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `vec![1, 2, 3].into_iter()`
|
||||||
|
|
||||||
error: aborting due to 9 previous errors
|
error: identical conversion
|
||||||
|
--> $DIR/identity_conversion.rs:56:21
|
||||||
|
|
|
||||||
|
56 | let _: String = format!("Hello {}", "world").into();
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into()`: `format!("Hello {}", "world")`
|
||||||
|
|
||||||
|
error: aborting due to 10 previous errors
|
||||||
|
|
||||||
|
|
32
tests/ui/lint_without_lint_pass.rs
Normal file
32
tests/ui/lint_without_lint_pass.rs
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
#![deny(clippy::internal)]
|
||||||
|
|
||||||
|
#![feature(rustc_private)]
|
||||||
|
|
||||||
|
#[macro_use]
|
||||||
|
extern crate rustc;
|
||||||
|
use rustc::lint;
|
||||||
|
|
||||||
|
#[macro_use]
|
||||||
|
extern crate clippy_lints;
|
||||||
|
|
||||||
|
declare_clippy_lint! {
|
||||||
|
pub TEST_LINT,
|
||||||
|
correctness,
|
||||||
|
""
|
||||||
|
}
|
||||||
|
|
||||||
|
declare_clippy_lint! {
|
||||||
|
pub TEST_LINT_REGISTERED,
|
||||||
|
correctness,
|
||||||
|
""
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Pass;
|
||||||
|
impl lint::LintPass for Pass {
|
||||||
|
fn get_lints(&self) -> lint::LintArray {
|
||||||
|
lint_array!(TEST_LINT_REGISTERED)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
}
|
20
tests/ui/lint_without_lint_pass.stderr
Normal file
20
tests/ui/lint_without_lint_pass.stderr
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
error: the lint `TEST_LINT` is not added to any `LintPass`
|
||||||
|
--> $DIR/lint_without_lint_pass.rs:12:1
|
||||||
|
|
|
||||||
|
12 | / declare_clippy_lint! {
|
||||||
|
13 | | pub TEST_LINT,
|
||||||
|
14 | | correctness,
|
||||||
|
15 | | ""
|
||||||
|
16 | | }
|
||||||
|
| |_^
|
||||||
|
|
|
||||||
|
note: lint level defined here
|
||||||
|
--> $DIR/lint_without_lint_pass.rs:1:9
|
||||||
|
|
|
||||||
|
1 | #![deny(clippy::internal)]
|
||||||
|
| ^^^^^^^^^^^^^^^^
|
||||||
|
= note: #[deny(clippy::lint_without_lint_pass)] implied by #[deny(clippy::internal)]
|
||||||
|
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
|
@ -33,7 +33,7 @@ error: you seem to be trying to use match for destructuring a single pattern. Co
|
||||||
51 | | &(v, 1) => println!("{}", v),
|
51 | | &(v, 1) => println!("{}", v),
|
||||||
52 | | _ => println!("none"),
|
52 | | _ => println!("none"),
|
||||||
53 | | }
|
53 | | }
|
||||||
| |_____^ help: try this: `if let &(v, 1) = tup { $ crate :: io :: _print ( format_args_nl ! ( $ ( $ arg ) * ) ) ; } else { $ crate :: io :: _print ( format_args_nl ! ( $ ( $ arg ) * ) ) ; }`
|
| |_____^ help: try this: `if let &(v, 1) = tup { println!("{}", v) } else { println!("none") }`
|
||||||
|
|
||||||
error: you don't need to add `&` to all patterns
|
error: you don't need to add `&` to all patterns
|
||||||
--> $DIR/matches.rs:50:5
|
--> $DIR/matches.rs:50:5
|
||||||
|
|
|
@ -297,7 +297,7 @@ error: use of `unwrap_or` followed by a function call
|
||||||
--> $DIR/methods.rs:339:14
|
--> $DIR/methods.rs:339:14
|
||||||
|
|
|
|
||||||
339 | with_vec.unwrap_or(vec![]);
|
339 | with_vec.unwrap_or(vec![]);
|
||||||
| ^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(|| < [ _ ] > :: into_vec ( box [ $ ( $ x ) , * ] ))`
|
| ^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(|| vec![])`
|
||||||
|
|
||||||
error: use of `unwrap_or` followed by a function call
|
error: use of `unwrap_or` followed by a function call
|
||||||
--> $DIR/methods.rs:344:21
|
--> $DIR/methods.rs:344:21
|
||||||
|
|
|
@ -8,10 +8,32 @@
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#![warn(clippy::needless_bool)]
|
#![warn(clippy::needless_bool)]
|
||||||
|
|
||||||
|
use std::cell::Cell;
|
||||||
|
|
||||||
|
macro_rules! bool_comparison_trigger {
|
||||||
|
($($i:ident: $def:expr, $stb:expr );+ $(;)*) => (
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct Trigger {
|
||||||
|
$($i: (Cell<bool>, bool, bool)),+
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
impl Trigger {
|
||||||
|
pub fn trigger(&self, key: &str) -> bool {
|
||||||
|
$(
|
||||||
|
if let stringify!($i) = key {
|
||||||
|
return self.$i.1 && self.$i.2 == $def;
|
||||||
|
}
|
||||||
|
)+
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
#[allow(clippy::if_same_then_else)]
|
#[allow(clippy::if_same_then_else)]
|
||||||
fn main() {
|
fn main() {
|
||||||
let x = true;
|
let x = true;
|
||||||
|
@ -28,6 +50,9 @@ fn main() {
|
||||||
bool_ret5(x, x);
|
bool_ret5(x, x);
|
||||||
bool_ret4(x);
|
bool_ret4(x);
|
||||||
bool_ret6(x, x);
|
bool_ret6(x, x);
|
||||||
|
needless_bool(x);
|
||||||
|
needless_bool2(x);
|
||||||
|
needless_bool3(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::if_same_then_else, clippy::needless_return)]
|
#[allow(clippy::if_same_then_else, clippy::needless_return)]
|
||||||
|
@ -59,3 +84,23 @@ fn bool_ret4(x: bool) -> bool {
|
||||||
fn bool_ret6(x: bool, y: bool) -> bool {
|
fn bool_ret6(x: bool, y: bool) -> bool {
|
||||||
if x && y { return false } else { return true };
|
if x && y { return false } else { return true };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn needless_bool(x: bool) {
|
||||||
|
if x == true { };
|
||||||
|
}
|
||||||
|
|
||||||
|
fn needless_bool2(x: bool) {
|
||||||
|
if x == false { };
|
||||||
|
}
|
||||||
|
|
||||||
|
fn needless_bool3(x: bool) {
|
||||||
|
|
||||||
|
bool_comparison_trigger! {
|
||||||
|
test_one: false, false;
|
||||||
|
test_three: false, false;
|
||||||
|
test_two: true, true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if x == true { };
|
||||||
|
if x == false { };
|
||||||
|
}
|
||||||
|
|
|
@ -1,70 +1,96 @@
|
||||||
error: this if-then-else expression will always return true
|
error: this if-then-else expression will always return true
|
||||||
--> $DIR/needless_bool.rs:19:5
|
--> $DIR/needless_bool.rs:41:5
|
||||||
|
|
|
|
||||||
19 | if x { true } else { true };
|
41 | if x { true } else { true };
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
= note: `-D clippy::needless-bool` implied by `-D warnings`
|
= note: `-D clippy::needless-bool` implied by `-D warnings`
|
||||||
|
|
||||||
error: this if-then-else expression will always return false
|
error: this if-then-else expression will always return false
|
||||||
--> $DIR/needless_bool.rs:20:5
|
--> $DIR/needless_bool.rs:42:5
|
||||||
|
|
|
|
||||||
20 | if x { false } else { false };
|
42 | if x { false } else { false };
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: this if-then-else expression returns a bool literal
|
error: this if-then-else expression returns a bool literal
|
||||||
--> $DIR/needless_bool.rs:21:5
|
--> $DIR/needless_bool.rs:43:5
|
||||||
|
|
|
|
||||||
21 | if x { true } else { false };
|
43 | if x { true } else { false };
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can reduce it to: `x`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can reduce it to: `x`
|
||||||
|
|
||||||
error: this if-then-else expression returns a bool literal
|
error: this if-then-else expression returns a bool literal
|
||||||
--> $DIR/needless_bool.rs:22:5
|
--> $DIR/needless_bool.rs:44:5
|
||||||
|
|
|
|
||||||
22 | if x { false } else { true };
|
44 | if x { false } else { true };
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can reduce it to: `!x`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can reduce it to: `!x`
|
||||||
|
|
||||||
error: this if-then-else expression returns a bool literal
|
|
||||||
--> $DIR/needless_bool.rs:23:5
|
|
||||||
|
|
|
||||||
23 | if x && y { false } else { true };
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can reduce it to: `!(x && y)`
|
|
||||||
|
|
||||||
error: this if-then-else expression will always return true
|
|
||||||
--> $DIR/needless_bool.rs:35:5
|
|
||||||
|
|
|
||||||
35 | if x { return true } else { return true };
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
error: this if-then-else expression will always return false
|
|
||||||
--> $DIR/needless_bool.rs:40:5
|
|
||||||
|
|
|
||||||
40 | if x { return false } else { return false };
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
error: this if-then-else expression returns a bool literal
|
error: this if-then-else expression returns a bool literal
|
||||||
--> $DIR/needless_bool.rs:45:5
|
--> $DIR/needless_bool.rs:45:5
|
||||||
|
|
|
|
||||||
45 | if x { return true } else { return false };
|
45 | if x && y { false } else { true };
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can reduce it to: `!(x && y)`
|
||||||
|
|
||||||
|
error: this if-then-else expression will always return true
|
||||||
|
--> $DIR/needless_bool.rs:60:5
|
||||||
|
|
|
||||||
|
60 | if x { return true } else { return true };
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: this if-then-else expression will always return false
|
||||||
|
--> $DIR/needless_bool.rs:65:5
|
||||||
|
|
|
||||||
|
65 | if x { return false } else { return false };
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: this if-then-else expression returns a bool literal
|
||||||
|
--> $DIR/needless_bool.rs:70:5
|
||||||
|
|
|
||||||
|
70 | if x { return true } else { return false };
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can reduce it to: `return x`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can reduce it to: `return x`
|
||||||
|
|
||||||
error: this if-then-else expression returns a bool literal
|
error: this if-then-else expression returns a bool literal
|
||||||
--> $DIR/needless_bool.rs:50:5
|
--> $DIR/needless_bool.rs:75:5
|
||||||
|
|
|
|
||||||
50 | if x && y { return true } else { return false };
|
75 | if x && y { return true } else { return false };
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can reduce it to: `return x && y`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can reduce it to: `return x && y`
|
||||||
|
|
||||||
error: this if-then-else expression returns a bool literal
|
error: this if-then-else expression returns a bool literal
|
||||||
--> $DIR/needless_bool.rs:55:5
|
--> $DIR/needless_bool.rs:80:5
|
||||||
|
|
|
|
||||||
55 | if x { return false } else { return true };
|
80 | if x { return false } else { return true };
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can reduce it to: `return !x`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can reduce it to: `return !x`
|
||||||
|
|
||||||
error: this if-then-else expression returns a bool literal
|
error: this if-then-else expression returns a bool literal
|
||||||
--> $DIR/needless_bool.rs:60:5
|
--> $DIR/needless_bool.rs:85:5
|
||||||
|
|
|
|
||||||
60 | if x && y { return false } else { return true };
|
85 | if x && y { return false } else { return true };
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can reduce it to: `return !(x && y)`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can reduce it to: `return !(x && y)`
|
||||||
|
|
||||||
error: aborting due to 11 previous errors
|
error: equality checks against true are unnecessary
|
||||||
|
--> $DIR/needless_bool.rs:89:7
|
||||||
|
|
|
||||||
|
89 | if x == true { };
|
||||||
|
| ^^^^^^^^^^ help: try simplifying it as shown: `x`
|
||||||
|
|
|
||||||
|
= note: `-D clippy::bool-comparison` implied by `-D warnings`
|
||||||
|
|
||||||
|
error: equality checks against false can be replaced by a negation
|
||||||
|
--> $DIR/needless_bool.rs:93:7
|
||||||
|
|
|
||||||
|
93 | if x == false { };
|
||||||
|
| ^^^^^^^^^^^ help: try simplifying it as shown: `!x`
|
||||||
|
|
||||||
|
error: equality checks against true are unnecessary
|
||||||
|
--> $DIR/needless_bool.rs:104:8
|
||||||
|
|
|
||||||
|
104 | if x == true { };
|
||||||
|
| ^^^^^^^^^ help: try simplifying it as shown: `x`
|
||||||
|
|
||||||
|
error: equality checks against false can be replaced by a negation
|
||||||
|
--> $DIR/needless_bool.rs:105:8
|
||||||
|
|
|
||||||
|
105 | if x == false { };
|
||||||
|
| ^^^^^^^^^^ help: try simplifying it as shown: `!x`
|
||||||
|
|
||||||
|
error: aborting due to 15 previous errors
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
#![feature(box_syntax)]
|
#![feature(box_syntax)]
|
||||||
|
|
||||||
|
|
||||||
#![warn(clippy::no_effect, clippy::unnecessary_operation)]
|
#![warn(clippy::no_effect)]
|
||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
#![allow(path_statements)]
|
#![allow(path_statements)]
|
||||||
#![allow(clippy::deref_addrof)]
|
#![allow(clippy::deref_addrof)]
|
||||||
|
@ -105,33 +105,4 @@ fn main() {
|
||||||
DropTuple(0);
|
DropTuple(0);
|
||||||
DropEnum::Tuple(0);
|
DropEnum::Tuple(0);
|
||||||
DropEnum::Struct { field: 0 };
|
DropEnum::Struct { field: 0 };
|
||||||
|
|
||||||
Tuple(get_number());
|
|
||||||
Struct { field: get_number() };
|
|
||||||
Struct { ..get_struct() };
|
|
||||||
Enum::Tuple(get_number());
|
|
||||||
Enum::Struct { field: get_number() };
|
|
||||||
5 + get_number();
|
|
||||||
*&get_number();
|
|
||||||
&get_number();
|
|
||||||
(5, 6, get_number());
|
|
||||||
box get_number();
|
|
||||||
get_number()..;
|
|
||||||
..get_number();
|
|
||||||
5..get_number();
|
|
||||||
[42, get_number()];
|
|
||||||
[42, 55][get_number() as usize];
|
|
||||||
(42, get_number()).1;
|
|
||||||
[get_number(); 55];
|
|
||||||
[42; 55][get_number() as usize];
|
|
||||||
{get_number()};
|
|
||||||
FooString { s: 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() };
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -150,127 +150,5 @@ error: statement with no effect
|
||||||
98 | FooString { s: s };
|
98 | FooString { s: s };
|
||||||
| ^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: statement can be reduced
|
error: aborting due to 25 previous errors
|
||||||
--> $DIR/no_effect.rs:109:5
|
|
||||||
|
|
|
||||||
109 | Tuple(get_number());
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^ help: replace it with: `get_number();`
|
|
||||||
|
|
|
||||||
= note: `-D clippy::unnecessary-operation` implied by `-D warnings`
|
|
||||||
|
|
||||||
error: statement can be reduced
|
|
||||||
--> $DIR/no_effect.rs:110:5
|
|
||||||
|
|
|
||||||
110 | Struct { field: get_number() };
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `get_number();`
|
|
||||||
|
|
||||||
error: statement can be reduced
|
|
||||||
--> $DIR/no_effect.rs:111:5
|
|
||||||
|
|
|
||||||
111 | Struct { ..get_struct() };
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `get_struct();`
|
|
||||||
|
|
||||||
error: statement can be reduced
|
|
||||||
--> $DIR/no_effect.rs:112:5
|
|
||||||
|
|
|
||||||
112 | Enum::Tuple(get_number());
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `get_number();`
|
|
||||||
|
|
||||||
error: statement can be reduced
|
|
||||||
--> $DIR/no_effect.rs:113:5
|
|
||||||
|
|
|
||||||
113 | Enum::Struct { field: get_number() };
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `get_number();`
|
|
||||||
|
|
||||||
error: statement can be reduced
|
|
||||||
--> $DIR/no_effect.rs:114:5
|
|
||||||
|
|
|
||||||
114 | 5 + get_number();
|
|
||||||
| ^^^^^^^^^^^^^^^^^ help: replace it with: `5;get_number();`
|
|
||||||
|
|
||||||
error: statement can be reduced
|
|
||||||
--> $DIR/no_effect.rs:115:5
|
|
||||||
|
|
|
||||||
115 | *&get_number();
|
|
||||||
| ^^^^^^^^^^^^^^^ help: replace it with: `get_number();`
|
|
||||||
|
|
||||||
error: statement can be reduced
|
|
||||||
--> $DIR/no_effect.rs:116:5
|
|
||||||
|
|
|
||||||
116 | &get_number();
|
|
||||||
| ^^^^^^^^^^^^^^ help: replace it with: `get_number();`
|
|
||||||
|
|
||||||
error: statement can be reduced
|
|
||||||
--> $DIR/no_effect.rs:117:5
|
|
||||||
|
|
|
||||||
117 | (5, 6, get_number());
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `5;6;get_number();`
|
|
||||||
|
|
||||||
error: statement can be reduced
|
|
||||||
--> $DIR/no_effect.rs:118:5
|
|
||||||
|
|
|
||||||
118 | box get_number();
|
|
||||||
| ^^^^^^^^^^^^^^^^^ help: replace it with: `get_number();`
|
|
||||||
|
|
||||||
error: statement can be reduced
|
|
||||||
--> $DIR/no_effect.rs:119:5
|
|
||||||
|
|
|
||||||
119 | get_number()..;
|
|
||||||
| ^^^^^^^^^^^^^^^ help: replace it with: `get_number();`
|
|
||||||
|
|
||||||
error: statement can be reduced
|
|
||||||
--> $DIR/no_effect.rs:120:5
|
|
||||||
|
|
|
||||||
120 | ..get_number();
|
|
||||||
| ^^^^^^^^^^^^^^^ help: replace it with: `get_number();`
|
|
||||||
|
|
||||||
error: statement can be reduced
|
|
||||||
--> $DIR/no_effect.rs:121:5
|
|
||||||
|
|
|
||||||
121 | 5..get_number();
|
|
||||||
| ^^^^^^^^^^^^^^^^ help: replace it with: `5;get_number();`
|
|
||||||
|
|
||||||
error: statement can be reduced
|
|
||||||
--> $DIR/no_effect.rs:122:5
|
|
||||||
|
|
|
||||||
122 | [42, get_number()];
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^ help: replace it with: `42;get_number();`
|
|
||||||
|
|
||||||
error: statement can be reduced
|
|
||||||
--> $DIR/no_effect.rs:123:5
|
|
||||||
|
|
|
||||||
123 | [42, 55][get_number() as usize];
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `[42, 55];get_number() as usize;`
|
|
||||||
|
|
||||||
error: statement can be reduced
|
|
||||||
--> $DIR/no_effect.rs:124:5
|
|
||||||
|
|
|
||||||
124 | (42, get_number()).1;
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `42;get_number();`
|
|
||||||
|
|
||||||
error: statement can be reduced
|
|
||||||
--> $DIR/no_effect.rs:125:5
|
|
||||||
|
|
|
||||||
125 | [get_number(); 55];
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^ help: replace it with: `get_number();`
|
|
||||||
|
|
||||||
error: statement can be reduced
|
|
||||||
--> $DIR/no_effect.rs:126:5
|
|
||||||
|
|
|
||||||
126 | [42; 55][get_number() as usize];
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `[42; 55];get_number() as usize;`
|
|
||||||
|
|
||||||
error: statement can be reduced
|
|
||||||
--> $DIR/no_effect.rs:127:5
|
|
||||||
|
|
|
||||||
127 | {get_number()};
|
|
||||||
| ^^^^^^^^^^^^^^^ help: replace it with: `get_number();`
|
|
||||||
|
|
||||||
error: statement can be reduced
|
|
||||||
--> $DIR/no_effect.rs:128:5
|
|
||||||
|
|
|
||||||
128 | FooString { s: String::from("blah"), };
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `String::from("blah");`
|
|
||||||
|
|
||||||
error: aborting due to 45 previous errors
|
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,15 @@ fn single_match(){
|
||||||
_ => ()
|
_ => ()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let x = Some(1u8);
|
||||||
|
match x {
|
||||||
|
// Note the missing block braces.
|
||||||
|
// We suggest `if let Some(y) = x { .. }` because the macro
|
||||||
|
// is expanded before we can do anything.
|
||||||
|
Some(y) => println!("{:?}", y),
|
||||||
|
_ => ()
|
||||||
|
}
|
||||||
|
|
||||||
let z = (1u8,1u8);
|
let z = (1u8,1u8);
|
||||||
match z {
|
match z {
|
||||||
(2...3, 7...9) => dummy(),
|
(2...3, 7...9) => dummy(),
|
||||||
|
|
|
@ -12,38 +12,50 @@ error: you seem to be trying to use match for destructuring a single pattern. Co
|
||||||
error: you seem to be trying to use match for destructuring a single pattern. Consider using `if let`
|
error: you seem to be trying to use match for destructuring a single pattern. Consider using `if let`
|
||||||
--> $DIR/single_match.rs:27:5
|
--> $DIR/single_match.rs:27:5
|
||||||
|
|
|
|
||||||
27 | / match z {
|
27 | / match x {
|
||||||
28 | | (2...3, 7...9) => dummy(),
|
28 | | // Note the missing block braces.
|
||||||
29 | | _ => {}
|
29 | | // We suggest `if let Some(y) = x { .. }` because the macro
|
||||||
30 | | };
|
30 | | // is expanded before we can do anything.
|
||||||
|
31 | | Some(y) => println!("{:?}", y),
|
||||||
|
32 | | _ => ()
|
||||||
|
33 | | }
|
||||||
|
| |_____^ help: try this: `if let Some(y) = x { println!("{:?}", y) }`
|
||||||
|
|
||||||
|
error: you seem to be trying to use match for destructuring a single pattern. Consider using `if let`
|
||||||
|
--> $DIR/single_match.rs:36:5
|
||||||
|
|
|
||||||
|
36 | / match z {
|
||||||
|
37 | | (2...3, 7...9) => dummy(),
|
||||||
|
38 | | _ => {}
|
||||||
|
39 | | };
|
||||||
| |_____^ help: try this: `if let (2...3, 7...9) = z { dummy() }`
|
| |_____^ help: try this: `if let (2...3, 7...9) = z { dummy() }`
|
||||||
|
|
||||||
error: you seem to be trying to use match for destructuring a single pattern. Consider using `if let`
|
error: you seem to be trying to use match for destructuring a single pattern. Consider using `if let`
|
||||||
--> $DIR/single_match.rs:53:5
|
--> $DIR/single_match.rs:62:5
|
||||||
|
|
|
|
||||||
53 | / match x {
|
62 | / match x {
|
||||||
54 | | Some(y) => dummy(),
|
63 | | Some(y) => dummy(),
|
||||||
55 | | None => ()
|
64 | | None => ()
|
||||||
56 | | };
|
65 | | };
|
||||||
| |_____^ help: try this: `if let Some(y) = x { dummy() }`
|
| |_____^ help: try this: `if let Some(y) = x { dummy() }`
|
||||||
|
|
||||||
error: you seem to be trying to use match for destructuring a single pattern. Consider using `if let`
|
error: you seem to be trying to use match for destructuring a single pattern. Consider using `if let`
|
||||||
--> $DIR/single_match.rs:58:5
|
--> $DIR/single_match.rs:67:5
|
||||||
|
|
|
|
||||||
58 | / match y {
|
67 | / match y {
|
||||||
59 | | Ok(y) => dummy(),
|
68 | | Ok(y) => dummy(),
|
||||||
60 | | Err(..) => ()
|
69 | | Err(..) => ()
|
||||||
61 | | };
|
70 | | };
|
||||||
| |_____^ help: try this: `if let Ok(y) = y { dummy() }`
|
| |_____^ help: try this: `if let Ok(y) = y { dummy() }`
|
||||||
|
|
||||||
error: you seem to be trying to use match for destructuring a single pattern. Consider using `if let`
|
error: you seem to be trying to use match for destructuring a single pattern. Consider using `if let`
|
||||||
--> $DIR/single_match.rs:65:5
|
--> $DIR/single_match.rs:74:5
|
||||||
|
|
|
|
||||||
65 | / match c {
|
74 | / match c {
|
||||||
66 | | Cow::Borrowed(..) => dummy(),
|
75 | | Cow::Borrowed(..) => dummy(),
|
||||||
67 | | Cow::Owned(..) => (),
|
76 | | Cow::Owned(..) => (),
|
||||||
68 | | };
|
77 | | };
|
||||||
| |_____^ help: try this: `if let Cow::Borrowed(..) = c { dummy() }`
|
| |_____^ help: try this: `if let Cow::Borrowed(..) = c { dummy() }`
|
||||||
|
|
||||||
error: aborting due to 5 previous errors
|
error: aborting due to 6 previous errors
|
||||||
|
|
||||||
|
|
|
@ -10,10 +10,10 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#[warn(clippy::string_add)]
|
#[warn(clippy::string_add)]
|
||||||
#[allow(clippy::string_add_assign)]
|
#[allow(clippy::string_add_assign)]
|
||||||
fn add_only() { // ignores assignment distinction
|
fn add_only() {
|
||||||
|
// ignores assignment distinction
|
||||||
let mut x = "".to_owned();
|
let mut x = "".to_owned();
|
||||||
|
|
||||||
for _ in 1..3 {
|
for _ in 1..3 {
|
||||||
|
@ -59,12 +59,17 @@ fn both() {
|
||||||
fn str_lit_as_bytes() {
|
fn str_lit_as_bytes() {
|
||||||
let bs = "hello there".as_bytes();
|
let bs = "hello there".as_bytes();
|
||||||
|
|
||||||
|
let bs = r###"raw string with three ### in it and some " ""###.as_bytes();
|
||||||
|
|
||||||
// no warning, because this cannot be written as a byte string literal:
|
// no warning, because this cannot be written as a byte string literal:
|
||||||
let ubs = "☃".as_bytes();
|
let ubs = "☃".as_bytes();
|
||||||
|
|
||||||
let strify = stringify!(foobar).as_bytes();
|
let strify = stringify!(foobar).as_bytes();
|
||||||
|
|
||||||
|
let includestr = include_str!("entry.rs").as_bytes();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::assign_op_pattern)]
|
||||||
fn main() {
|
fn main() {
|
||||||
add_only();
|
add_only();
|
||||||
add_assign_only();
|
add_assign_only();
|
||||||
|
@ -72,6 +77,6 @@ fn main() {
|
||||||
|
|
||||||
// the add is only caught for `String`
|
// the add is only caught for `String`
|
||||||
let mut x = 1;
|
let mut x = 1;
|
||||||
; x = x + 1;
|
x = x + 1;
|
||||||
assert_eq!(2, x);
|
assert_eq!(2, x);
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,16 +61,16 @@ error: calling `as_bytes()` on a string literal
|
||||||
= note: `-D clippy::string-lit-as-bytes` implied by `-D warnings`
|
= note: `-D clippy::string-lit-as-bytes` implied by `-D warnings`
|
||||||
|
|
||||||
error: calling `as_bytes()` on a string literal
|
error: calling `as_bytes()` on a string literal
|
||||||
--> $DIR/strings.rs:65:18
|
--> $DIR/strings.rs:62:14
|
||||||
|
|
|
|
||||||
65 | let strify = stringify!(foobar).as_bytes();
|
62 | let bs = r###"raw string with three ### in it and some " ""###.as_bytes();
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using a byte string literal instead: `bstringify!(foobar)`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using a byte string literal instead: `br###"raw string with three ### in it and some " ""###`
|
||||||
|
|
||||||
error: manual implementation of an assign operation
|
error: calling `as_bytes()` on `include_str!(..)`
|
||||||
--> $DIR/strings.rs:75:7
|
--> $DIR/strings.rs:69:22
|
||||||
|
|
|
|
||||||
75 | ; x = x + 1;
|
69 | let includestr = include_str!("entry.rs").as_bytes();
|
||||||
| ^^^^^^^^^ help: replace it with: `x += 1`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `include_bytes!(..)` instead: `include_bytes!("entry.rs")`
|
||||||
|
|
||||||
error: aborting due to 11 previous errors
|
error: aborting due to 11 previous errors
|
||||||
|
|
||||||
|
|
76
tests/ui/unnecessary_operation.rs
Normal file
76
tests/ui/unnecessary_operation.rs
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
// Copyright 2014-2018 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
#![feature(box_syntax)]
|
||||||
|
#![allow(clippy::deref_addrof)]
|
||||||
|
#![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_struct() -> Struct { Struct { field: 0 } }
|
||||||
|
fn get_drop_struct() -> DropStruct { DropStruct { field: 0 } }
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
Tuple(get_number());
|
||||||
|
Struct { field: get_number() };
|
||||||
|
Struct { ..get_struct() };
|
||||||
|
Enum::Tuple(get_number());
|
||||||
|
Enum::Struct { field: get_number() };
|
||||||
|
5 + get_number();
|
||||||
|
*&get_number();
|
||||||
|
&get_number();
|
||||||
|
(5, 6, get_number());
|
||||||
|
box get_number();
|
||||||
|
get_number()..;
|
||||||
|
..get_number();
|
||||||
|
5..get_number();
|
||||||
|
[42, get_number()];
|
||||||
|
[42, 55][get_number() as usize];
|
||||||
|
(42, get_number()).1;
|
||||||
|
[get_number(); 55];
|
||||||
|
[42; 55][get_number() as usize];
|
||||||
|
{get_number()};
|
||||||
|
FooString { s: 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() };
|
||||||
|
}
|
124
tests/ui/unnecessary_operation.stderr
Normal file
124
tests/ui/unnecessary_operation.stderr
Normal file
|
@ -0,0 +1,124 @@
|
||||||
|
error: statement can be reduced
|
||||||
|
--> $DIR/unnecessary_operation.rs:48:5
|
||||||
|
|
|
||||||
|
48 | Tuple(get_number());
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^ help: replace it with: `get_number();`
|
||||||
|
|
|
||||||
|
= note: `-D clippy::unnecessary-operation` implied by `-D warnings`
|
||||||
|
|
||||||
|
error: statement can be reduced
|
||||||
|
--> $DIR/unnecessary_operation.rs:49:5
|
||||||
|
|
|
||||||
|
49 | Struct { field: get_number() };
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `get_number();`
|
||||||
|
|
||||||
|
error: statement can be reduced
|
||||||
|
--> $DIR/unnecessary_operation.rs:50:5
|
||||||
|
|
|
||||||
|
50 | Struct { ..get_struct() };
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `get_struct();`
|
||||||
|
|
||||||
|
error: statement can be reduced
|
||||||
|
--> $DIR/unnecessary_operation.rs:51:5
|
||||||
|
|
|
||||||
|
51 | Enum::Tuple(get_number());
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `get_number();`
|
||||||
|
|
||||||
|
error: statement can be reduced
|
||||||
|
--> $DIR/unnecessary_operation.rs:52:5
|
||||||
|
|
|
||||||
|
52 | Enum::Struct { field: get_number() };
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `get_number();`
|
||||||
|
|
||||||
|
error: statement can be reduced
|
||||||
|
--> $DIR/unnecessary_operation.rs:53:5
|
||||||
|
|
|
||||||
|
53 | 5 + get_number();
|
||||||
|
| ^^^^^^^^^^^^^^^^^ help: replace it with: `5;get_number();`
|
||||||
|
|
||||||
|
error: statement can be reduced
|
||||||
|
--> $DIR/unnecessary_operation.rs:54:5
|
||||||
|
|
|
||||||
|
54 | *&get_number();
|
||||||
|
| ^^^^^^^^^^^^^^^ help: replace it with: `get_number();`
|
||||||
|
|
||||||
|
error: statement can be reduced
|
||||||
|
--> $DIR/unnecessary_operation.rs:55:5
|
||||||
|
|
|
||||||
|
55 | &get_number();
|
||||||
|
| ^^^^^^^^^^^^^^ help: replace it with: `get_number();`
|
||||||
|
|
||||||
|
error: statement can be reduced
|
||||||
|
--> $DIR/unnecessary_operation.rs:56:5
|
||||||
|
|
|
||||||
|
56 | (5, 6, get_number());
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `5;6;get_number();`
|
||||||
|
|
||||||
|
error: statement can be reduced
|
||||||
|
--> $DIR/unnecessary_operation.rs:57:5
|
||||||
|
|
|
||||||
|
57 | box get_number();
|
||||||
|
| ^^^^^^^^^^^^^^^^^ help: replace it with: `get_number();`
|
||||||
|
|
||||||
|
error: statement can be reduced
|
||||||
|
--> $DIR/unnecessary_operation.rs:58:5
|
||||||
|
|
|
||||||
|
58 | get_number()..;
|
||||||
|
| ^^^^^^^^^^^^^^^ help: replace it with: `get_number();`
|
||||||
|
|
||||||
|
error: statement can be reduced
|
||||||
|
--> $DIR/unnecessary_operation.rs:59:5
|
||||||
|
|
|
||||||
|
59 | ..get_number();
|
||||||
|
| ^^^^^^^^^^^^^^^ help: replace it with: `get_number();`
|
||||||
|
|
||||||
|
error: statement can be reduced
|
||||||
|
--> $DIR/unnecessary_operation.rs:60:5
|
||||||
|
|
|
||||||
|
60 | 5..get_number();
|
||||||
|
| ^^^^^^^^^^^^^^^^ help: replace it with: `5;get_number();`
|
||||||
|
|
||||||
|
error: statement can be reduced
|
||||||
|
--> $DIR/unnecessary_operation.rs:61:5
|
||||||
|
|
|
||||||
|
61 | [42, get_number()];
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^ help: replace it with: `42;get_number();`
|
||||||
|
|
||||||
|
error: statement can be reduced
|
||||||
|
--> $DIR/unnecessary_operation.rs:62:5
|
||||||
|
|
|
||||||
|
62 | [42, 55][get_number() as usize];
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `[42, 55];get_number() as usize;`
|
||||||
|
|
||||||
|
error: statement can be reduced
|
||||||
|
--> $DIR/unnecessary_operation.rs:63:5
|
||||||
|
|
|
||||||
|
63 | (42, get_number()).1;
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `42;get_number();`
|
||||||
|
|
||||||
|
error: statement can be reduced
|
||||||
|
--> $DIR/unnecessary_operation.rs:64:5
|
||||||
|
|
|
||||||
|
64 | [get_number(); 55];
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^ help: replace it with: `get_number();`
|
||||||
|
|
||||||
|
error: statement can be reduced
|
||||||
|
--> $DIR/unnecessary_operation.rs:65:5
|
||||||
|
|
|
||||||
|
65 | [42; 55][get_number() as usize];
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `[42; 55];get_number() as usize;`
|
||||||
|
|
||||||
|
error: statement can be reduced
|
||||||
|
--> $DIR/unnecessary_operation.rs:66:5
|
||||||
|
|
|
||||||
|
66 | {get_number()};
|
||||||
|
| ^^^^^^^^^^^^^^^ help: replace it with: `get_number();`
|
||||||
|
|
||||||
|
error: statement can be reduced
|
||||||
|
--> $DIR/unnecessary_operation.rs:67:5
|
||||||
|
|
|
||||||
|
67 | FooString { s: String::from("blah"), };
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `String::from("blah");`
|
||||||
|
|
||||||
|
error: aborting due to 20 previous errors
|
||||||
|
|
Loading…
Add table
Reference in a new issue