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:
bors 2023-06-12 16:25:59 +00:00
commit da56c3502a
16 changed files with 124 additions and 117 deletions

View file

@ -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,

View file

@ -2,6 +2,7 @@
#![warn(clippy::cloned_instead_of_copied)]
#![allow(unused)]
#![allow(clippy::useless_vec)]
fn main() {
// yay

View file

@ -2,6 +2,7 @@
#![warn(clippy::cloned_instead_of_copied)]
#![allow(unused)]
#![allow(clippy::useless_vec)]
fn main() {
// yay

View file

@ -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`

View file

@ -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};

View file

@ -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};

View file

@ -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`

View file

@ -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};

View file

@ -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};

View file

@ -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>>()`

View file

@ -1,6 +1,7 @@
//@run-rustfix
#![allow(unused)]
#![allow(clippy::useless_vec)]
use std::collections::HashSet;
use std::collections::VecDeque;

View file

@ -1,6 +1,7 @@
//@run-rustfix
#![allow(unused)]
#![allow(clippy::useless_vec)]
use std::collections::HashSet;
use std::collections::VecDeque;

View file

@ -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()`

View file

@ -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);

View file

@ -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);

View file

@ -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