Auto merge of #10933 - y21:issue2262-followup, r=Centri3
[`useless_vec`]: lint on `vec![_]` invocations that adjust to a slice Fixes #2262 (well, actually my PR over at #10901 did do most of the stuff, but this PR implements the one last other case mentioned in the comments that my PR didn't fix) Before this change, it would lint `(&vec![1]).iter().sum::<i32>()`, but not `vec![1].iter().sum::<i32>()`. This PR handles this case. This also refactors a few things that I wanted to do in my other PR but forgot about. changelog: [`useless_vec`]: lint on `vec![_]` invocations that adjust to a slice
This commit is contained in:
commit
da56c3502a
16 changed files with 124 additions and 117 deletions
|
|
@ -8,7 +8,6 @@ use clippy_utils::ty::is_copy;
|
|||
use clippy_utils::visitors::for_each_local_use_after_expr;
|
||||
use clippy_utils::{get_parent_expr, higher, is_trait_method};
|
||||
use if_chain::if_chain;
|
||||
use rustc_ast::BindingAnnotation;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::{BorrowKind, Expr, ExprKind, Mutability, Node, PatKind};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
|
|
@ -54,11 +53,7 @@ declare_clippy_lint! {
|
|||
impl_lint_pass!(UselessVec => [USELESS_VEC]);
|
||||
|
||||
fn adjusts_to_slice(cx: &LateContext<'_>, e: &Expr<'_>) -> bool {
|
||||
if let ty::Ref(_, ty, _) = cx.typeck_results().expr_ty_adjusted(e).kind() {
|
||||
ty.is_slice()
|
||||
} else {
|
||||
false
|
||||
}
|
||||
matches!(cx.typeck_results().expr_ty_adjusted(e).kind(), ty::Ref(_, ty, _) if ty.is_slice())
|
||||
}
|
||||
|
||||
/// Checks if the given expression is a method call to a `Vec` method
|
||||
|
|
@ -76,13 +71,21 @@ fn is_allowed_vec_method(cx: &LateContext<'_>, e: &Expr<'_>) -> bool {
|
|||
|
||||
impl<'tcx> LateLintPass<'tcx> for UselessVec {
|
||||
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
|
||||
// search for `&vec![_]` expressions where the adjusted type is `&[_]`
|
||||
// search for `&vec![_]` or `vec![_]` expressions where the adjusted type is `&[_]`
|
||||
if_chain! {
|
||||
if adjusts_to_slice(cx, expr);
|
||||
if let ExprKind::AddrOf(BorrowKind::Ref, mutability, addressee) = expr.kind;
|
||||
if let Some(vec_args) = higher::VecArgs::hir(cx, addressee);
|
||||
if let Some(vec_args) = higher::VecArgs::hir(cx, expr.peel_borrows());
|
||||
then {
|
||||
self.check_vec_macro(cx, &vec_args, mutability, expr.span, SuggestSlice::Yes);
|
||||
let (suggest_slice, span) = if let ExprKind::AddrOf(BorrowKind::Ref, mutability, _) = expr.kind {
|
||||
// `expr` is `&vec![_]`, so suggest `&[_]` (or `&mut[_]` resp.)
|
||||
(SuggestedType::SliceRef(mutability), expr.span)
|
||||
} else {
|
||||
// `expr` is the `vec![_]` expansion, so suggest `[_]`
|
||||
// and also use the span of the actual `vec![_]` expression
|
||||
(SuggestedType::Array, expr.span.ctxt().outer_expn_data().call_site)
|
||||
};
|
||||
|
||||
self.check_vec_macro(cx, &vec_args, span, suggest_slice);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -93,7 +96,7 @@ impl<'tcx> LateLintPass<'tcx> for UselessVec {
|
|||
// for now ignore locals with type annotations.
|
||||
// this is to avoid compile errors when doing the suggestion here: let _: Vec<_> = vec![..];
|
||||
&& local.ty.is_none()
|
||||
&& let PatKind::Binding(BindingAnnotation(_, mutbl), id, ..) = local.pat.kind
|
||||
&& let PatKind::Binding(_, id, ..) = local.pat.kind
|
||||
&& is_copy(cx, vec_type(cx.typeck_results().expr_ty_adjusted(expr)))
|
||||
{
|
||||
let only_slice_uses = for_each_local_use_after_expr(cx, id, expr.hir_id, |expr| {
|
||||
|
|
@ -113,9 +116,8 @@ impl<'tcx> LateLintPass<'tcx> for UselessVec {
|
|||
self.check_vec_macro(
|
||||
cx,
|
||||
&vec_args,
|
||||
mutbl,
|
||||
expr.span.ctxt().outer_expn_data().call_site,
|
||||
SuggestSlice::No
|
||||
SuggestedType::Array
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -128,7 +130,7 @@ impl<'tcx> LateLintPass<'tcx> for UselessVec {
|
|||
then {
|
||||
// report the error around the `vec!` not inside `<std macros>:`
|
||||
let span = arg.span.ctxt().outer_expn_data().call_site;
|
||||
self.check_vec_macro(cx, &vec_args, Mutability::Not, span, SuggestSlice::No);
|
||||
self.check_vec_macro(cx, &vec_args, span, SuggestedType::Array);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -137,11 +139,11 @@ impl<'tcx> LateLintPass<'tcx> for UselessVec {
|
|||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
enum SuggestSlice {
|
||||
enum SuggestedType {
|
||||
/// Suggest using a slice `&[..]` / `&mut [..]`
|
||||
Yes,
|
||||
SliceRef(Mutability),
|
||||
/// Suggest using an array: `[..]`
|
||||
No,
|
||||
Array,
|
||||
}
|
||||
|
||||
impl UselessVec {
|
||||
|
|
@ -149,17 +151,11 @@ impl UselessVec {
|
|||
&mut self,
|
||||
cx: &LateContext<'tcx>,
|
||||
vec_args: &higher::VecArgs<'tcx>,
|
||||
mutability: Mutability,
|
||||
span: Span,
|
||||
suggest_slice: SuggestSlice,
|
||||
suggest_slice: SuggestedType,
|
||||
) {
|
||||
let mut applicability = Applicability::MachineApplicable;
|
||||
|
||||
let (borrow_prefix_mut, borrow_prefix) = match suggest_slice {
|
||||
SuggestSlice::Yes => ("&mut ", "&"),
|
||||
SuggestSlice::No => ("", ""),
|
||||
};
|
||||
|
||||
let snippet = match *vec_args {
|
||||
higher::VecArgs::Repeat(elem, len) => {
|
||||
if let Some(Constant::Int(len_constant)) = constant(cx, cx.typeck_results(), len) {
|
||||
|
|
@ -168,21 +164,13 @@ impl UselessVec {
|
|||
return;
|
||||
}
|
||||
|
||||
match mutability {
|
||||
Mutability::Mut => {
|
||||
format!(
|
||||
"{borrow_prefix_mut}[{}; {}]",
|
||||
snippet_with_applicability(cx, elem.span, "elem", &mut applicability),
|
||||
snippet_with_applicability(cx, len.span, "len", &mut applicability)
|
||||
)
|
||||
},
|
||||
Mutability::Not => {
|
||||
format!(
|
||||
"{borrow_prefix}[{}; {}]",
|
||||
snippet_with_applicability(cx, elem.span, "elem", &mut applicability),
|
||||
snippet_with_applicability(cx, len.span, "len", &mut applicability)
|
||||
)
|
||||
},
|
||||
let elem = snippet_with_applicability(cx, elem.span, "elem", &mut applicability);
|
||||
let len = snippet_with_applicability(cx, len.span, "len", &mut applicability);
|
||||
|
||||
match suggest_slice {
|
||||
SuggestedType::SliceRef(Mutability::Mut) => format!("&mut [{elem}; {len}]"),
|
||||
SuggestedType::SliceRef(Mutability::Not) => format!("&[{elem}; {len}]"),
|
||||
SuggestedType::Array => format!("[{elem}; {len}]"),
|
||||
}
|
||||
} else {
|
||||
return;
|
||||
|
|
@ -194,25 +182,24 @@ impl UselessVec {
|
|||
return;
|
||||
}
|
||||
let span = args[0].span.to(last.span);
|
||||
let args = snippet_with_applicability(cx, span, "..", &mut applicability);
|
||||
|
||||
match mutability {
|
||||
Mutability::Mut => {
|
||||
format!(
|
||||
"{borrow_prefix_mut}[{}]",
|
||||
snippet_with_applicability(cx, span, "..", &mut applicability)
|
||||
)
|
||||
match suggest_slice {
|
||||
SuggestedType::SliceRef(Mutability::Mut) => {
|
||||
format!("&mut [{args}]")
|
||||
},
|
||||
Mutability::Not => {
|
||||
format!(
|
||||
"{borrow_prefix}[{}]",
|
||||
snippet_with_applicability(cx, span, "..", &mut applicability)
|
||||
)
|
||||
SuggestedType::SliceRef(Mutability::Not) => {
|
||||
format!("&[{args}]")
|
||||
},
|
||||
SuggestedType::Array => {
|
||||
format!("[{args}]")
|
||||
},
|
||||
}
|
||||
} else {
|
||||
match mutability {
|
||||
Mutability::Mut => format!("{borrow_prefix_mut}[]"),
|
||||
Mutability::Not => format!("{borrow_prefix}[]"),
|
||||
match suggest_slice {
|
||||
SuggestedType::SliceRef(Mutability::Mut) => "&mut []".to_owned(),
|
||||
SuggestedType::SliceRef(Mutability::Not) => "&[]".to_owned(),
|
||||
SuggestedType::Array => "[]".to_owned(),
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -226,8 +213,8 @@ impl UselessVec {
|
|||
&format!(
|
||||
"you can use {} directly",
|
||||
match suggest_slice {
|
||||
SuggestSlice::Yes => "a slice",
|
||||
SuggestSlice::No => "an array",
|
||||
SuggestedType::SliceRef(_) => "a slice",
|
||||
SuggestedType::Array => "an array",
|
||||
}
|
||||
),
|
||||
snippet,
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#![warn(clippy::cloned_instead_of_copied)]
|
||||
#![allow(unused)]
|
||||
#![allow(clippy::useless_vec)]
|
||||
|
||||
fn main() {
|
||||
// yay
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#![warn(clippy::cloned_instead_of_copied)]
|
||||
#![allow(unused)]
|
||||
#![allow(clippy::useless_vec)]
|
||||
|
||||
fn main() {
|
||||
// yay
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
error: used `cloned` where `copied` could be used instead
|
||||
--> $DIR/cloned_instead_of_copied.rs:8:24
|
||||
--> $DIR/cloned_instead_of_copied.rs:9:24
|
||||
|
|
||||
LL | let _ = [1].iter().cloned();
|
||||
| ^^^^^^ help: try: `copied`
|
||||
|
|
@ -7,43 +7,43 @@ LL | let _ = [1].iter().cloned();
|
|||
= note: `-D clippy::cloned-instead-of-copied` implied by `-D warnings`
|
||||
|
||||
error: used `cloned` where `copied` could be used instead
|
||||
--> $DIR/cloned_instead_of_copied.rs:9:31
|
||||
--> $DIR/cloned_instead_of_copied.rs:10:31
|
||||
|
|
||||
LL | let _ = vec!["hi"].iter().cloned();
|
||||
| ^^^^^^ help: try: `copied`
|
||||
|
||||
error: used `cloned` where `copied` could be used instead
|
||||
--> $DIR/cloned_instead_of_copied.rs:10:22
|
||||
--> $DIR/cloned_instead_of_copied.rs:11:22
|
||||
|
|
||||
LL | let _ = Some(&1).cloned();
|
||||
| ^^^^^^ help: try: `copied`
|
||||
|
||||
error: used `cloned` where `copied` could be used instead
|
||||
--> $DIR/cloned_instead_of_copied.rs:11:34
|
||||
--> $DIR/cloned_instead_of_copied.rs:12:34
|
||||
|
|
||||
LL | let _ = Box::new([1].iter()).cloned();
|
||||
| ^^^^^^ help: try: `copied`
|
||||
|
||||
error: used `cloned` where `copied` could be used instead
|
||||
--> $DIR/cloned_instead_of_copied.rs:12:32
|
||||
--> $DIR/cloned_instead_of_copied.rs:13:32
|
||||
|
|
||||
LL | let _ = Box::new(Some(&1)).cloned();
|
||||
| ^^^^^^ help: try: `copied`
|
||||
|
||||
error: used `cloned` where `copied` could be used instead
|
||||
--> $DIR/cloned_instead_of_copied.rs:28:22
|
||||
--> $DIR/cloned_instead_of_copied.rs:29:22
|
||||
|
|
||||
LL | let _ = Some(&1).cloned(); // Option::copied needs 1.35
|
||||
| ^^^^^^ help: try: `copied`
|
||||
|
||||
error: used `cloned` where `copied` could be used instead
|
||||
--> $DIR/cloned_instead_of_copied.rs:33:24
|
||||
--> $DIR/cloned_instead_of_copied.rs:34:24
|
||||
|
|
||||
LL | let _ = [1].iter().cloned(); // Iterator::copied needs 1.36
|
||||
| ^^^^^^ help: try: `copied`
|
||||
|
||||
error: used `cloned` where `copied` could be used instead
|
||||
--> $DIR/cloned_instead_of_copied.rs:34:22
|
||||
--> $DIR/cloned_instead_of_copied.rs:35:22
|
||||
|
|
||||
LL | let _ = Some(&1).cloned();
|
||||
| ^^^^^^ help: try: `copied`
|
||||
|
|
|
|||
|
|
@ -7,7 +7,8 @@
|
|||
clippy::no_effect,
|
||||
clippy::option_map_unit_fn,
|
||||
clippy::redundant_closure_call,
|
||||
clippy::uninlined_format_args
|
||||
clippy::uninlined_format_args,
|
||||
clippy::useless_vec
|
||||
)]
|
||||
|
||||
use std::path::{Path, PathBuf};
|
||||
|
|
|
|||
|
|
@ -7,7 +7,8 @@
|
|||
clippy::no_effect,
|
||||
clippy::option_map_unit_fn,
|
||||
clippy::redundant_closure_call,
|
||||
clippy::uninlined_format_args
|
||||
clippy::uninlined_format_args,
|
||||
clippy::useless_vec
|
||||
)]
|
||||
|
||||
use std::path::{Path, PathBuf};
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
error: redundant closure
|
||||
--> $DIR/eta.rs:28:27
|
||||
--> $DIR/eta.rs:29:27
|
||||
|
|
||||
LL | let a = Some(1u8).map(|a| foo(a));
|
||||
| ^^^^^^^^^^ help: replace the closure with the function itself: `foo`
|
||||
|
|
@ -7,31 +7,31 @@ LL | let a = Some(1u8).map(|a| foo(a));
|
|||
= note: `-D clippy::redundant-closure` implied by `-D warnings`
|
||||
|
||||
error: redundant closure
|
||||
--> $DIR/eta.rs:32:40
|
||||
--> $DIR/eta.rs:33:40
|
||||
|
|
||||
LL | let _: Option<Vec<u8>> = true.then(|| vec![]); // special case vec!
|
||||
| ^^^^^^^^^ help: replace the closure with `Vec::new`: `std::vec::Vec::new`
|
||||
|
||||
error: redundant closure
|
||||
--> $DIR/eta.rs:33:35
|
||||
--> $DIR/eta.rs:34:35
|
||||
|
|
||||
LL | let d = Some(1u8).map(|a| foo((|b| foo2(b))(a))); //is adjusted?
|
||||
| ^^^^^^^^^^^^^ help: replace the closure with the function itself: `foo2`
|
||||
|
||||
error: redundant closure
|
||||
--> $DIR/eta.rs:34:26
|
||||
--> $DIR/eta.rs:35:26
|
||||
|
|
||||
LL | all(&[1, 2, 3], &&2, |x, y| below(x, y)); //is adjusted
|
||||
| ^^^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `below`
|
||||
|
||||
error: redundant closure
|
||||
--> $DIR/eta.rs:41:27
|
||||
--> $DIR/eta.rs:42:27
|
||||
|
|
||||
LL | let e = Some(1u8).map(|a| generic(a));
|
||||
| ^^^^^^^^^^^^^^ help: replace the closure with the function itself: `generic`
|
||||
|
||||
error: redundant closure
|
||||
--> $DIR/eta.rs:93:51
|
||||
--> $DIR/eta.rs:94:51
|
||||
|
|
||||
LL | let e = Some(TestStruct { some_ref: &i }).map(|a| a.foo());
|
||||
| ^^^^^^^^^^^ help: replace the closure with the method itself: `TestStruct::foo`
|
||||
|
|
@ -39,121 +39,121 @@ LL | let e = Some(TestStruct { some_ref: &i }).map(|a| a.foo());
|
|||
= note: `-D clippy::redundant-closure-for-method-calls` implied by `-D warnings`
|
||||
|
||||
error: redundant closure
|
||||
--> $DIR/eta.rs:94:51
|
||||
--> $DIR/eta.rs:95:51
|
||||
|
|
||||
LL | let e = Some(TestStruct { some_ref: &i }).map(|a| a.trait_foo());
|
||||
| ^^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `TestTrait::trait_foo`
|
||||
|
||||
error: redundant closure
|
||||
--> $DIR/eta.rs:96:42
|
||||
--> $DIR/eta.rs:97:42
|
||||
|
|
||||
LL | let e = Some(&mut vec![1, 2, 3]).map(|v| v.clear());
|
||||
| ^^^^^^^^^^^^^ help: replace the closure with the method itself: `std::vec::Vec::clear`
|
||||
|
||||
error: redundant closure
|
||||
--> $DIR/eta.rs:100:29
|
||||
--> $DIR/eta.rs:101:29
|
||||
|
|
||||
LL | let e = Some("str").map(|s| s.to_string());
|
||||
| ^^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `std::string::ToString::to_string`
|
||||
|
||||
error: redundant closure
|
||||
--> $DIR/eta.rs:101:27
|
||||
--> $DIR/eta.rs:102:27
|
||||
|
|
||||
LL | let e = Some('a').map(|s| s.to_uppercase());
|
||||
| ^^^^^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `char::to_uppercase`
|
||||
|
||||
error: redundant closure
|
||||
--> $DIR/eta.rs:103:65
|
||||
--> $DIR/eta.rs:104:65
|
||||
|
|
||||
LL | let e: std::vec::Vec<char> = vec!['a', 'b', 'c'].iter().map(|c| c.to_ascii_uppercase()).collect();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `char::to_ascii_uppercase`
|
||||
|
||||
error: redundant closure
|
||||
--> $DIR/eta.rs:166:22
|
||||
--> $DIR/eta.rs:167:22
|
||||
|
|
||||
LL | requires_fn_once(|| x());
|
||||
| ^^^^^^ help: replace the closure with the function itself: `x`
|
||||
|
||||
error: redundant closure
|
||||
--> $DIR/eta.rs:173:27
|
||||
--> $DIR/eta.rs:174:27
|
||||
|
|
||||
LL | let a = Some(1u8).map(|a| foo_ptr(a));
|
||||
| ^^^^^^^^^^^^^^ help: replace the closure with the function itself: `foo_ptr`
|
||||
|
||||
error: redundant closure
|
||||
--> $DIR/eta.rs:178:27
|
||||
--> $DIR/eta.rs:179:27
|
||||
|
|
||||
LL | let a = Some(1u8).map(|a| closure(a));
|
||||
| ^^^^^^^^^^^^^^ help: replace the closure with the function itself: `closure`
|
||||
|
||||
error: redundant closure
|
||||
--> $DIR/eta.rs:210:28
|
||||
--> $DIR/eta.rs:211:28
|
||||
|
|
||||
LL | x.into_iter().for_each(|x| add_to_res(x));
|
||||
| ^^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `&mut add_to_res`
|
||||
|
||||
error: redundant closure
|
||||
--> $DIR/eta.rs:211:28
|
||||
--> $DIR/eta.rs:212:28
|
||||
|
|
||||
LL | y.into_iter().for_each(|x| add_to_res(x));
|
||||
| ^^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `&mut add_to_res`
|
||||
|
||||
error: redundant closure
|
||||
--> $DIR/eta.rs:212:28
|
||||
--> $DIR/eta.rs:213:28
|
||||
|
|
||||
LL | z.into_iter().for_each(|x| add_to_res(x));
|
||||
| ^^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `add_to_res`
|
||||
|
||||
error: redundant closure
|
||||
--> $DIR/eta.rs:219:21
|
||||
--> $DIR/eta.rs:220:21
|
||||
|
|
||||
LL | Some(1).map(|n| closure(n));
|
||||
| ^^^^^^^^^^^^^^ help: replace the closure with the function itself: `&mut closure`
|
||||
|
||||
error: redundant closure
|
||||
--> $DIR/eta.rs:223:21
|
||||
--> $DIR/eta.rs:224:21
|
||||
|
|
||||
LL | Some(1).map(|n| in_loop(n));
|
||||
| ^^^^^^^^^^^^^^ help: replace the closure with the function itself: `in_loop`
|
||||
|
||||
error: redundant closure
|
||||
--> $DIR/eta.rs:316:18
|
||||
--> $DIR/eta.rs:317:18
|
||||
|
|
||||
LL | takes_fn_mut(|| f());
|
||||
| ^^^^^^ help: replace the closure with the function itself: `&mut f`
|
||||
|
||||
error: redundant closure
|
||||
--> $DIR/eta.rs:319:19
|
||||
--> $DIR/eta.rs:320:19
|
||||
|
|
||||
LL | takes_fn_once(|| f());
|
||||
| ^^^^^^ help: replace the closure with the function itself: `&mut f`
|
||||
|
||||
error: redundant closure
|
||||
--> $DIR/eta.rs:323:26
|
||||
--> $DIR/eta.rs:324:26
|
||||
|
|
||||
LL | move || takes_fn_mut(|| f_used_once())
|
||||
| ^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `&mut f_used_once`
|
||||
|
||||
error: redundant closure
|
||||
--> $DIR/eta.rs:335:19
|
||||
--> $DIR/eta.rs:336:19
|
||||
|
|
||||
LL | array_opt.map(|a| a.as_slice());
|
||||
| ^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `<[u8; 3]>::as_slice`
|
||||
|
||||
error: redundant closure
|
||||
--> $DIR/eta.rs:338:19
|
||||
--> $DIR/eta.rs:339:19
|
||||
|
|
||||
LL | slice_opt.map(|s| s.len());
|
||||
| ^^^^^^^^^^^ help: replace the closure with the method itself: `<[u8]>::len`
|
||||
|
||||
error: redundant closure
|
||||
--> $DIR/eta.rs:341:17
|
||||
--> $DIR/eta.rs:342:17
|
||||
|
|
||||
LL | ptr_opt.map(|p| p.is_null());
|
||||
| ^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `<*const usize>::is_null`
|
||||
|
||||
error: redundant closure
|
||||
--> $DIR/eta.rs:345:17
|
||||
--> $DIR/eta.rs:346:17
|
||||
|
|
||||
LL | dyn_opt.map(|d| d.method_on_dyn());
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `<dyn TestTrait>::method_on_dyn`
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#![warn(clippy::from_iter_instead_of_collect)]
|
||||
#![allow(unused_imports, unused_tuple_struct_fields)]
|
||||
#![allow(clippy::useless_vec)]
|
||||
|
||||
use std::collections::{BTreeMap, BTreeSet, HashMap, VecDeque};
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#![warn(clippy::from_iter_instead_of_collect)]
|
||||
#![allow(unused_imports, unused_tuple_struct_fields)]
|
||||
#![allow(clippy::useless_vec)]
|
||||
|
||||
use std::collections::{BTreeMap, BTreeSet, HashMap, VecDeque};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
error: usage of `FromIterator::from_iter`
|
||||
--> $DIR/from_iter_instead_of_collect.rs:18:9
|
||||
--> $DIR/from_iter_instead_of_collect.rs:19:9
|
||||
|
|
||||
LL | <Self as FromIterator<bool>>::from_iter(iter.into_iter().copied())
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `iter.into_iter().copied().collect::<Self>()`
|
||||
|
|
@ -7,85 +7,85 @@ LL | <Self as FromIterator<bool>>::from_iter(iter.into_iter().copied())
|
|||
= note: `-D clippy::from-iter-instead-of-collect` implied by `-D warnings`
|
||||
|
||||
error: usage of `FromIterator::from_iter`
|
||||
--> $DIR/from_iter_instead_of_collect.rs:24:13
|
||||
--> $DIR/from_iter_instead_of_collect.rs:25:13
|
||||
|
|
||||
LL | let _ = Vec::from_iter(iter_expr);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `iter_expr.collect::<Vec<_>>()`
|
||||
|
||||
error: usage of `FromIterator::from_iter`
|
||||
--> $DIR/from_iter_instead_of_collect.rs:26:13
|
||||
--> $DIR/from_iter_instead_of_collect.rs:27:13
|
||||
|
|
||||
LL | let _ = HashMap::<usize, &i8>::from_iter(vec![5, 5, 5, 5].iter().enumerate());
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `vec![5, 5, 5, 5].iter().enumerate().collect::<HashMap<usize, &i8>>()`
|
||||
|
||||
error: usage of `FromIterator::from_iter`
|
||||
--> $DIR/from_iter_instead_of_collect.rs:31:19
|
||||
--> $DIR/from_iter_instead_of_collect.rs:32:19
|
||||
|
|
||||
LL | assert_eq!(a, Vec::from_iter(0..3));
|
||||
| ^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `(0..3).collect::<Vec<_>>()`
|
||||
|
||||
error: usage of `FromIterator::from_iter`
|
||||
--> $DIR/from_iter_instead_of_collect.rs:32:19
|
||||
--> $DIR/from_iter_instead_of_collect.rs:33:19
|
||||
|
|
||||
LL | assert_eq!(a, Vec::<i32>::from_iter(0..3));
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `(0..3).collect::<Vec<i32>>()`
|
||||
|
||||
error: usage of `FromIterator::from_iter`
|
||||
--> $DIR/from_iter_instead_of_collect.rs:34:17
|
||||
--> $DIR/from_iter_instead_of_collect.rs:35:17
|
||||
|
|
||||
LL | let mut b = VecDeque::from_iter(0..3);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `(0..3).collect::<VecDeque<_>>()`
|
||||
|
||||
error: usage of `FromIterator::from_iter`
|
||||
--> $DIR/from_iter_instead_of_collect.rs:37:17
|
||||
--> $DIR/from_iter_instead_of_collect.rs:38:17
|
||||
|
|
||||
LL | let mut b = VecDeque::<i32>::from_iter(0..3);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `(0..3).collect::<VecDeque<i32>>()`
|
||||
|
||||
error: usage of `FromIterator::from_iter`
|
||||
--> $DIR/from_iter_instead_of_collect.rs:42:21
|
||||
--> $DIR/from_iter_instead_of_collect.rs:43:21
|
||||
|
|
||||
LL | let mut b = collections::VecDeque::<i32>::from_iter(0..3);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `(0..3).collect::<collections::VecDeque<i32>>()`
|
||||
|
||||
error: usage of `FromIterator::from_iter`
|
||||
--> $DIR/from_iter_instead_of_collect.rs:47:14
|
||||
--> $DIR/from_iter_instead_of_collect.rs:48:14
|
||||
|
|
||||
LL | let bm = BTreeMap::from_iter(values.iter().cloned());
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `values.iter().cloned().collect::<BTreeMap<_, _>>()`
|
||||
|
||||
error: usage of `FromIterator::from_iter`
|
||||
--> $DIR/from_iter_instead_of_collect.rs:48:19
|
||||
--> $DIR/from_iter_instead_of_collect.rs:49:19
|
||||
|
|
||||
LL | let mut bar = BTreeMap::from_iter(bm.range(0..2));
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `bm.range(0..2).collect::<BTreeMap<_, _>>()`
|
||||
|
||||
error: usage of `FromIterator::from_iter`
|
||||
--> $DIR/from_iter_instead_of_collect.rs:51:19
|
||||
--> $DIR/from_iter_instead_of_collect.rs:52:19
|
||||
|
|
||||
LL | let mut bts = BTreeSet::from_iter(0..3);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `(0..3).collect::<BTreeSet<_>>()`
|
||||
|
||||
error: usage of `FromIterator::from_iter`
|
||||
--> $DIR/from_iter_instead_of_collect.rs:55:17
|
||||
--> $DIR/from_iter_instead_of_collect.rs:56:17
|
||||
|
|
||||
LL | let _ = collections::BTreeSet::from_iter(0..3);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `(0..3).collect::<collections::BTreeSet<_>>()`
|
||||
|
||||
error: usage of `FromIterator::from_iter`
|
||||
--> $DIR/from_iter_instead_of_collect.rs:56:17
|
||||
--> $DIR/from_iter_instead_of_collect.rs:57:17
|
||||
|
|
||||
LL | let _ = collections::BTreeSet::<u32>::from_iter(0..3);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `(0..3).collect::<collections::BTreeSet<u32>>()`
|
||||
|
||||
error: usage of `FromIterator::from_iter`
|
||||
--> $DIR/from_iter_instead_of_collect.rs:59:15
|
||||
--> $DIR/from_iter_instead_of_collect.rs:60:15
|
||||
|
|
||||
LL | for _i in Vec::from_iter([1, 2, 3].iter()) {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `[1, 2, 3].iter().collect::<Vec<_>>()`
|
||||
|
||||
error: usage of `FromIterator::from_iter`
|
||||
--> $DIR/from_iter_instead_of_collect.rs:60:15
|
||||
--> $DIR/from_iter_instead_of_collect.rs:61:15
|
||||
|
|
||||
LL | for _i in Vec::<&i32>::from_iter([1, 2, 3].iter()) {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `[1, 2, 3].iter().collect::<Vec<&i32>>()`
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
//@run-rustfix
|
||||
|
||||
#![allow(unused)]
|
||||
#![allow(clippy::useless_vec)]
|
||||
|
||||
use std::collections::HashSet;
|
||||
use std::collections::VecDeque;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
//@run-rustfix
|
||||
|
||||
#![allow(unused)]
|
||||
#![allow(clippy::useless_vec)]
|
||||
|
||||
use std::collections::HashSet;
|
||||
use std::collections::VecDeque;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
error: called `iter().cloned().collect()` on a slice to create a `Vec`. Calling `to_vec()` is both faster and more readable
|
||||
--> $DIR/iter_cloned_collect.rs:10:27
|
||||
--> $DIR/iter_cloned_collect.rs:11:27
|
||||
|
|
||||
LL | let v2: Vec<isize> = v.iter().cloned().collect();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `.to_vec()`
|
||||
|
|
@ -7,13 +7,13 @@ LL | let v2: Vec<isize> = v.iter().cloned().collect();
|
|||
= note: `-D clippy::iter-cloned-collect` implied by `-D warnings`
|
||||
|
||||
error: called `iter().cloned().collect()` on a slice to create a `Vec`. Calling `to_vec()` is both faster and more readable
|
||||
--> $DIR/iter_cloned_collect.rs:15:38
|
||||
--> $DIR/iter_cloned_collect.rs:16:38
|
||||
|
|
||||
LL | let _: Vec<isize> = vec![1, 2, 3].iter().cloned().collect();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `.to_vec()`
|
||||
|
||||
error: called `iter().cloned().collect()` on a slice to create a `Vec`. Calling `to_vec()` is both faster and more readable
|
||||
--> $DIR/iter_cloned_collect.rs:20:24
|
||||
--> $DIR/iter_cloned_collect.rs:21:24
|
||||
|
|
||||
LL | .to_bytes()
|
||||
| ________________________^
|
||||
|
|
@ -23,13 +23,13 @@ LL | | .collect();
|
|||
| |______________________^ help: try: `.to_vec()`
|
||||
|
||||
error: called `iter().cloned().collect()` on a slice to create a `Vec`. Calling `to_vec()` is both faster and more readable
|
||||
--> $DIR/iter_cloned_collect.rs:28:24
|
||||
--> $DIR/iter_cloned_collect.rs:29:24
|
||||
|
|
||||
LL | let _: Vec<_> = arr.iter().cloned().collect();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `.to_vec()`
|
||||
|
||||
error: called `iter().copied().collect()` on a slice to create a `Vec`. Calling `to_vec()` is both faster and more readable
|
||||
--> $DIR/iter_cloned_collect.rs:31:26
|
||||
--> $DIR/iter_cloned_collect.rs:32:26
|
||||
|
|
||||
LL | let _: Vec<isize> = v.iter().copied().collect();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `.to_vec()`
|
||||
|
|
|
|||
|
|
@ -71,6 +71,9 @@ fn main() {
|
|||
println!("{:?}", a);
|
||||
}
|
||||
|
||||
// https://github.com/rust-lang/rust-clippy/issues/2262#issuecomment-783979246
|
||||
let _x: i32 = [1, 2, 3].iter().sum();
|
||||
|
||||
// Do lint
|
||||
let mut x = [1, 2, 3];
|
||||
x.fill(123);
|
||||
|
|
|
|||
|
|
@ -71,6 +71,9 @@ fn main() {
|
|||
println!("{:?}", a);
|
||||
}
|
||||
|
||||
// https://github.com/rust-lang/rust-clippy/issues/2262#issuecomment-783979246
|
||||
let _x: i32 = vec![1, 2, 3].iter().sum();
|
||||
|
||||
// Do lint
|
||||
let mut x = vec![1, 2, 3];
|
||||
x.fill(123);
|
||||
|
|
|
|||
|
|
@ -61,34 +61,40 @@ LL | on_mut_slice(&mut vec![1; 2]);
|
|||
| ^^^^^^^^^^^^^^^ help: you can use a slice directly: `&mut [1; 2]`
|
||||
|
||||
error: useless use of `vec!`
|
||||
--> $DIR/vec.rs:75:17
|
||||
--> $DIR/vec.rs:75:19
|
||||
|
|
||||
LL | let _x: i32 = vec![1, 2, 3].iter().sum();
|
||||
| ^^^^^^^^^^^^^ help: you can use an array directly: `[1, 2, 3]`
|
||||
|
||||
error: useless use of `vec!`
|
||||
--> $DIR/vec.rs:78:17
|
||||
|
|
||||
LL | let mut x = vec![1, 2, 3];
|
||||
| ^^^^^^^^^^^^^ help: you can use an array directly: `[1, 2, 3]`
|
||||
|
||||
error: useless use of `vec!`
|
||||
--> $DIR/vec.rs:81:22
|
||||
--> $DIR/vec.rs:84:22
|
||||
|
|
||||
LL | let _x: &[i32] = &vec![1, 2, 3];
|
||||
| ^^^^^^^^^^^^^^ help: you can use a slice directly: `&[1, 2, 3]`
|
||||
|
||||
error: useless use of `vec!`
|
||||
--> $DIR/vec.rs:83:14
|
||||
--> $DIR/vec.rs:86:14
|
||||
|
|
||||
LL | for _ in vec![1, 2, 3] {}
|
||||
| ^^^^^^^^^^^^^ help: you can use an array directly: `[1, 2, 3]`
|
||||
|
||||
error: useless use of `vec!`
|
||||
--> $DIR/vec.rs:117:14
|
||||
--> $DIR/vec.rs:120:14
|
||||
|
|
||||
LL | for a in vec![1, 2, 3] {
|
||||
| ^^^^^^^^^^^^^ help: you can use an array directly: `[1, 2, 3]`
|
||||
|
||||
error: useless use of `vec!`
|
||||
--> $DIR/vec.rs:121:14
|
||||
--> $DIR/vec.rs:124:14
|
||||
|
|
||||
LL | for a in vec![String::new(), String::new()] {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can use an array directly: `[String::new(), String::new()]`
|
||||
|
||||
error: aborting due to 15 previous errors
|
||||
error: aborting due to 16 previous errors
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue