mirror of
https://github.com/rust-lang/rust-clippy
synced 2024-11-23 21:23:56 +00:00
fix: incorrect suggestions generated by manual_retain
lint
This commit is contained in:
parent
9eb2b225f8
commit
b5a2192628
4 changed files with 333 additions and 66 deletions
|
@ -11,6 +11,7 @@ use rustc_lint::{LateContext, LateLintPass};
|
||||||
use rustc_semver::RustcVersion;
|
use rustc_semver::RustcVersion;
|
||||||
use rustc_session::impl_lint_pass;
|
use rustc_session::impl_lint_pass;
|
||||||
use rustc_span::symbol::sym;
|
use rustc_span::symbol::sym;
|
||||||
|
use rustc_span::Span;
|
||||||
|
|
||||||
const ACCEPTABLE_METHODS: [&[&str]; 5] = [
|
const ACCEPTABLE_METHODS: [&[&str]; 5] = [
|
||||||
&paths::BINARYHEAP_ITER,
|
&paths::BINARYHEAP_ITER,
|
||||||
|
@ -28,6 +29,7 @@ const ACCEPTABLE_TYPES: [(rustc_span::Symbol, Option<RustcVersion>); 7] = [
|
||||||
(sym::Vec, None),
|
(sym::Vec, None),
|
||||||
(sym::VecDeque, None),
|
(sym::VecDeque, None),
|
||||||
];
|
];
|
||||||
|
const MAP_TYPES: [rustc_span::Symbol; 2] = [sym::BTreeMap, sym::HashMap];
|
||||||
|
|
||||||
declare_clippy_lint! {
|
declare_clippy_lint! {
|
||||||
/// ### What it does
|
/// ### What it does
|
||||||
|
@ -44,6 +46,7 @@ declare_clippy_lint! {
|
||||||
/// ```no_run
|
/// ```no_run
|
||||||
/// let mut vec = vec![0, 1, 2];
|
/// let mut vec = vec![0, 1, 2];
|
||||||
/// vec.retain(|x| x % 2 == 0);
|
/// vec.retain(|x| x % 2 == 0);
|
||||||
|
/// vec.retain(|x| x % 2 == 0);
|
||||||
/// ```
|
/// ```
|
||||||
#[clippy::version = "1.64.0"]
|
#[clippy::version = "1.64.0"]
|
||||||
pub MANUAL_RETAIN,
|
pub MANUAL_RETAIN,
|
||||||
|
@ -74,9 +77,9 @@ impl<'tcx> LateLintPass<'tcx> for ManualRetain {
|
||||||
&& let Some(collect_def_id) = cx.typeck_results().type_dependent_def_id(collect_expr.hir_id)
|
&& let Some(collect_def_id) = cx.typeck_results().type_dependent_def_id(collect_expr.hir_id)
|
||||||
&& cx.tcx.is_diagnostic_item(sym::iterator_collect_fn, collect_def_id)
|
&& cx.tcx.is_diagnostic_item(sym::iterator_collect_fn, collect_def_id)
|
||||||
{
|
{
|
||||||
check_into_iter(cx, parent_expr, left_expr, target_expr, &self.msrv);
|
check_into_iter(cx, left_expr, target_expr, parent_expr.span, &self.msrv);
|
||||||
check_iter(cx, parent_expr, left_expr, target_expr, &self.msrv);
|
check_iter(cx, left_expr, target_expr, parent_expr.span, &self.msrv);
|
||||||
check_to_owned(cx, parent_expr, left_expr, target_expr, &self.msrv);
|
check_to_owned(cx, left_expr, target_expr, parent_expr.span, &self.msrv);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,9 +88,9 @@ impl<'tcx> LateLintPass<'tcx> for ManualRetain {
|
||||||
|
|
||||||
fn check_into_iter(
|
fn check_into_iter(
|
||||||
cx: &LateContext<'_>,
|
cx: &LateContext<'_>,
|
||||||
parent_expr: &hir::Expr<'_>,
|
|
||||||
left_expr: &hir::Expr<'_>,
|
left_expr: &hir::Expr<'_>,
|
||||||
target_expr: &hir::Expr<'_>,
|
target_expr: &hir::Expr<'_>,
|
||||||
|
parent_expr_span: Span,
|
||||||
msrv: &Msrv,
|
msrv: &Msrv,
|
||||||
) {
|
) {
|
||||||
if let hir::ExprKind::MethodCall(_, into_iter_expr, [_], _) = &target_expr.kind
|
if let hir::ExprKind::MethodCall(_, into_iter_expr, [_], _) = &target_expr.kind
|
||||||
|
@ -98,16 +101,39 @@ fn check_into_iter(
|
||||||
&& Some(into_iter_def_id) == cx.tcx.lang_items().into_iter_fn()
|
&& Some(into_iter_def_id) == cx.tcx.lang_items().into_iter_fn()
|
||||||
&& match_acceptable_type(cx, left_expr, msrv)
|
&& match_acceptable_type(cx, left_expr, msrv)
|
||||||
&& SpanlessEq::new(cx).eq_expr(left_expr, struct_expr)
|
&& SpanlessEq::new(cx).eq_expr(left_expr, struct_expr)
|
||||||
|
&& let hir::ExprKind::MethodCall(_, _, [closure_expr], _) = target_expr.kind
|
||||||
|
&& let hir::ExprKind::Closure(closure) = closure_expr.kind
|
||||||
|
&& let filter_body = cx.tcx.hir().body(closure.body)
|
||||||
|
&& let [filter_params] = filter_body.params
|
||||||
{
|
{
|
||||||
suggest(cx, parent_expr, left_expr, target_expr);
|
if match_map_type(cx, left_expr) {
|
||||||
|
if let hir::PatKind::Tuple([key_pat, value_pat], _) = filter_params.pat.kind {
|
||||||
|
if let Some(sugg) = make_sugg(cx, key_pat, value_pat, left_expr, filter_body) {
|
||||||
|
make_span_lint_and_sugg(cx, parent_expr_span, sugg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Cannot lint other cases because `retain` requires two parameters
|
||||||
|
} else {
|
||||||
|
// Can always move because `retain` and `filter` have the same bound on the predicate
|
||||||
|
// for other types
|
||||||
|
make_span_lint_and_sugg(
|
||||||
|
cx,
|
||||||
|
parent_expr_span,
|
||||||
|
format!(
|
||||||
|
"{}.retain({})",
|
||||||
|
snippet(cx, left_expr.span, ".."),
|
||||||
|
snippet(cx, closure_expr.span, "..")
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_iter(
|
fn check_iter(
|
||||||
cx: &LateContext<'_>,
|
cx: &LateContext<'_>,
|
||||||
parent_expr: &hir::Expr<'_>,
|
|
||||||
left_expr: &hir::Expr<'_>,
|
left_expr: &hir::Expr<'_>,
|
||||||
target_expr: &hir::Expr<'_>,
|
target_expr: &hir::Expr<'_>,
|
||||||
|
parent_expr_span: Span,
|
||||||
msrv: &Msrv,
|
msrv: &Msrv,
|
||||||
) {
|
) {
|
||||||
if let hir::ExprKind::MethodCall(_, filter_expr, [], _) = &target_expr.kind
|
if let hir::ExprKind::MethodCall(_, filter_expr, [], _) = &target_expr.kind
|
||||||
|
@ -122,16 +148,50 @@ fn check_iter(
|
||||||
&& match_acceptable_def_path(cx, iter_expr_def_id)
|
&& match_acceptable_def_path(cx, iter_expr_def_id)
|
||||||
&& match_acceptable_type(cx, left_expr, msrv)
|
&& match_acceptable_type(cx, left_expr, msrv)
|
||||||
&& SpanlessEq::new(cx).eq_expr(left_expr, struct_expr)
|
&& SpanlessEq::new(cx).eq_expr(left_expr, struct_expr)
|
||||||
|
&& let hir::ExprKind::MethodCall(_, _, [closure_expr], _) = filter_expr.kind
|
||||||
|
&& let hir::ExprKind::Closure(closure) = closure_expr.kind
|
||||||
|
&& let filter_body = cx.tcx.hir().body(closure.body)
|
||||||
|
&& let [filter_params] = filter_body.params
|
||||||
{
|
{
|
||||||
suggest(cx, parent_expr, left_expr, filter_expr);
|
match filter_params.pat.kind {
|
||||||
|
// hir::PatKind::Binding(_, _, _, None) => {
|
||||||
|
// // Be conservative now. Do nothing here.
|
||||||
|
// // TODO: Ideally, we can rewrite the lambda by stripping one level of reference
|
||||||
|
// },
|
||||||
|
hir::PatKind::Tuple([_, _], _) => {
|
||||||
|
// the `&&` reference for the `filter` method will be auto derefed to `ref`
|
||||||
|
// so, we can directly use the lambda
|
||||||
|
// https://doc.rust-lang.org/reference/patterns.html#binding-modes
|
||||||
|
make_span_lint_and_sugg(
|
||||||
|
cx,
|
||||||
|
parent_expr_span,
|
||||||
|
format!(
|
||||||
|
"{}.retain({})",
|
||||||
|
snippet(cx, left_expr.span, ".."),
|
||||||
|
snippet(cx, closure_expr.span, "..")
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
hir::PatKind::Ref(pat, _) => make_span_lint_and_sugg(
|
||||||
|
cx,
|
||||||
|
parent_expr_span,
|
||||||
|
format!(
|
||||||
|
"{}.retain(|{}| {})",
|
||||||
|
snippet(cx, left_expr.span, ".."),
|
||||||
|
snippet(cx, pat.span, ".."),
|
||||||
|
snippet(cx, filter_body.value.span, "..")
|
||||||
|
),
|
||||||
|
),
|
||||||
|
_ => {},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_to_owned(
|
fn check_to_owned(
|
||||||
cx: &LateContext<'_>,
|
cx: &LateContext<'_>,
|
||||||
parent_expr: &hir::Expr<'_>,
|
|
||||||
left_expr: &hir::Expr<'_>,
|
left_expr: &hir::Expr<'_>,
|
||||||
target_expr: &hir::Expr<'_>,
|
target_expr: &hir::Expr<'_>,
|
||||||
|
parent_expr_span: Span,
|
||||||
msrv: &Msrv,
|
msrv: &Msrv,
|
||||||
) {
|
) {
|
||||||
if msrv.meets(msrvs::STRING_RETAIN)
|
if msrv.meets(msrvs::STRING_RETAIN)
|
||||||
|
@ -147,43 +207,25 @@ fn check_to_owned(
|
||||||
&& let ty = cx.typeck_results().expr_ty(str_expr).peel_refs()
|
&& let ty = cx.typeck_results().expr_ty(str_expr).peel_refs()
|
||||||
&& is_type_lang_item(cx, ty, hir::LangItem::String)
|
&& is_type_lang_item(cx, ty, hir::LangItem::String)
|
||||||
&& SpanlessEq::new(cx).eq_expr(left_expr, str_expr)
|
&& SpanlessEq::new(cx).eq_expr(left_expr, str_expr)
|
||||||
{
|
&& let hir::ExprKind::MethodCall(_, _, [closure_expr], _) = filter_expr.kind
|
||||||
suggest(cx, parent_expr, left_expr, filter_expr);
|
&& let hir::ExprKind::Closure(closure) = closure_expr.kind
|
||||||
}
|
&& let filter_body = cx.tcx.hir().body(closure.body)
|
||||||
}
|
|
||||||
|
|
||||||
fn suggest(cx: &LateContext<'_>, parent_expr: &hir::Expr<'_>, left_expr: &hir::Expr<'_>, filter_expr: &hir::Expr<'_>) {
|
|
||||||
if let hir::ExprKind::MethodCall(_, _, [closure], _) = filter_expr.kind
|
|
||||||
&& let hir::ExprKind::Closure(&hir::Closure { body, .. }) = closure.kind
|
|
||||||
&& let filter_body = cx.tcx.hir().body(body)
|
|
||||||
&& let [filter_params] = filter_body.params
|
&& let [filter_params] = filter_body.params
|
||||||
&& let Some(sugg) = match filter_params.pat.kind {
|
|
||||||
hir::PatKind::Binding(_, _, filter_param_ident, None) => Some(format!(
|
|
||||||
"{}.retain(|{filter_param_ident}| {})",
|
|
||||||
snippet(cx, left_expr.span, ".."),
|
|
||||||
snippet(cx, filter_body.value.span, "..")
|
|
||||||
)),
|
|
||||||
hir::PatKind::Tuple([key_pat, value_pat], _) => make_sugg(cx, key_pat, value_pat, left_expr, filter_body),
|
|
||||||
hir::PatKind::Ref(pat, _) => match pat.kind {
|
|
||||||
hir::PatKind::Binding(_, _, filter_param_ident, None) => Some(format!(
|
|
||||||
"{}.retain(|{filter_param_ident}| {})",
|
|
||||||
snippet(cx, left_expr.span, ".."),
|
|
||||||
snippet(cx, filter_body.value.span, "..")
|
|
||||||
)),
|
|
||||||
_ => None,
|
|
||||||
},
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
{
|
{
|
||||||
span_lint_and_sugg(
|
if let hir::PatKind::Ref(pat, _) = filter_params.pat.kind {
|
||||||
cx,
|
make_span_lint_and_sugg(
|
||||||
MANUAL_RETAIN,
|
cx,
|
||||||
parent_expr.span,
|
parent_expr_span,
|
||||||
"this expression can be written more simply using `.retain()`",
|
format!(
|
||||||
"consider calling `.retain()` instead",
|
"{}.retain(|{}| {})",
|
||||||
sugg,
|
snippet(cx, left_expr.span, ".."),
|
||||||
Applicability::MachineApplicable,
|
snippet(cx, pat.span, ".."),
|
||||||
);
|
snippet(cx, filter_body.value.span, "..")
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
// Be conservative now. Do nothing for the `Binding` case.
|
||||||
|
// TODO: Ideally, we can rewrite the lambda by stripping one level of reference
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -229,3 +271,20 @@ fn match_acceptable_type(cx: &LateContext<'_>, expr: &hir::Expr<'_>, msrv: &Msrv
|
||||||
&& acceptable_msrv.map_or(true, |acceptable_msrv| msrv.meets(acceptable_msrv))
|
&& acceptable_msrv.map_or(true, |acceptable_msrv| msrv.meets(acceptable_msrv))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn match_map_type(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> bool {
|
||||||
|
let expr_ty = cx.typeck_results().expr_ty(expr).peel_refs();
|
||||||
|
MAP_TYPES.iter().any(|ty| is_type_diagnostic_item(cx, expr_ty, *ty))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn make_span_lint_and_sugg(cx: &LateContext<'_>, span: Span, sugg: String) {
|
||||||
|
span_lint_and_sugg(
|
||||||
|
cx,
|
||||||
|
MANUAL_RETAIN,
|
||||||
|
span,
|
||||||
|
"this expression can be written more simply using `.retain()`",
|
||||||
|
"consider calling `.retain()` instead",
|
||||||
|
sugg,
|
||||||
|
Applicability::MachineApplicable,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
|
@ -14,6 +14,9 @@ fn main() {
|
||||||
_msrv_153();
|
_msrv_153();
|
||||||
_msrv_126();
|
_msrv_126();
|
||||||
_msrv_118();
|
_msrv_118();
|
||||||
|
|
||||||
|
issue_10393();
|
||||||
|
issue_12081();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn binary_heap_retain() {
|
fn binary_heap_retain() {
|
||||||
|
@ -23,6 +26,11 @@ fn binary_heap_retain() {
|
||||||
binary_heap.retain(|x| x % 2 == 0);
|
binary_heap.retain(|x| x % 2 == 0);
|
||||||
binary_heap.retain(|x| x % 2 == 0);
|
binary_heap.retain(|x| x % 2 == 0);
|
||||||
|
|
||||||
|
// Do lint, because we use pattern matching
|
||||||
|
let mut tuples = BinaryHeap::from([(0, 1), (1, 2), (2, 3)]);
|
||||||
|
tuples.retain(|(ref x, ref y)| *x == 0);
|
||||||
|
tuples.retain(|(x, y)| *x == 0);
|
||||||
|
|
||||||
// Do not lint, because type conversion is performed
|
// Do not lint, because type conversion is performed
|
||||||
binary_heap = binary_heap
|
binary_heap = binary_heap
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
@ -55,6 +63,9 @@ fn btree_map_retain() {
|
||||||
btree_map.retain(|_, &mut v| v % 2 == 0);
|
btree_map.retain(|_, &mut v| v % 2 == 0);
|
||||||
btree_map.retain(|k, &mut v| (k % 2 == 0) && (v % 2 == 0));
|
btree_map.retain(|k, &mut v| (k % 2 == 0) && (v % 2 == 0));
|
||||||
|
|
||||||
|
// Do not lint, because the parameters are not matched in tuple pattern
|
||||||
|
btree_map = btree_map.into_iter().filter(|t| t.0 % 2 == 0).collect();
|
||||||
|
|
||||||
// Do not lint.
|
// Do not lint.
|
||||||
btree_map = btree_map
|
btree_map = btree_map
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
@ -76,6 +87,11 @@ fn btree_set_retain() {
|
||||||
btree_set.retain(|x| x % 2 == 0);
|
btree_set.retain(|x| x % 2 == 0);
|
||||||
btree_set.retain(|x| x % 2 == 0);
|
btree_set.retain(|x| x % 2 == 0);
|
||||||
|
|
||||||
|
// Do lint, because we use pattern matching
|
||||||
|
let mut tuples = BTreeSet::from([(0, 1), (1, 2), (2, 3)]);
|
||||||
|
tuples.retain(|(ref x, ref y)| *x == 0);
|
||||||
|
tuples.retain(|(x, y)| *x == 0);
|
||||||
|
|
||||||
// Do not lint, because type conversion is performed
|
// Do not lint, because type conversion is performed
|
||||||
btree_set = btree_set
|
btree_set = btree_set
|
||||||
.iter()
|
.iter()
|
||||||
|
@ -108,6 +124,9 @@ fn hash_map_retain() {
|
||||||
hash_map.retain(|_, &mut v| v % 2 == 0);
|
hash_map.retain(|_, &mut v| v % 2 == 0);
|
||||||
hash_map.retain(|k, &mut v| (k % 2 == 0) && (v % 2 == 0));
|
hash_map.retain(|k, &mut v| (k % 2 == 0) && (v % 2 == 0));
|
||||||
|
|
||||||
|
// Do not lint, because the parameters are not matched in tuple pattern
|
||||||
|
hash_map = hash_map.into_iter().filter(|t| t.0 % 2 == 0).collect();
|
||||||
|
|
||||||
// Do not lint.
|
// Do not lint.
|
||||||
hash_map = hash_map
|
hash_map = hash_map
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
@ -128,6 +147,11 @@ fn hash_set_retain() {
|
||||||
hash_set.retain(|x| x % 2 == 0);
|
hash_set.retain(|x| x % 2 == 0);
|
||||||
hash_set.retain(|x| x % 2 == 0);
|
hash_set.retain(|x| x % 2 == 0);
|
||||||
|
|
||||||
|
// Do lint, because we use pattern matching
|
||||||
|
let mut tuples = HashSet::from([(0, 1), (1, 2), (2, 3)]);
|
||||||
|
tuples.retain(|(ref x, ref y)| *x == 0);
|
||||||
|
tuples.retain(|(x, y)| *x == 0);
|
||||||
|
|
||||||
// Do not lint, because type conversion is performed
|
// Do not lint, because type conversion is performed
|
||||||
hash_set = hash_set.into_iter().filter(|x| x % 2 == 0).collect::<HashSet<i8>>();
|
hash_set = hash_set.into_iter().filter(|x| x % 2 == 0).collect::<HashSet<i8>>();
|
||||||
hash_set = hash_set
|
hash_set = hash_set
|
||||||
|
@ -157,6 +181,9 @@ fn string_retain() {
|
||||||
// Do lint.
|
// Do lint.
|
||||||
s.retain(|c| c != 'o');
|
s.retain(|c| c != 'o');
|
||||||
|
|
||||||
|
// Do not lint, because we need to rewrite the lambda
|
||||||
|
s = s.chars().filter(|c| *c != 'o').to_owned().collect();
|
||||||
|
|
||||||
// Do not lint, because this expression is not assign.
|
// Do not lint, because this expression is not assign.
|
||||||
let mut bar: String = s.chars().filter(|&c| c != 'o').to_owned().collect();
|
let mut bar: String = s.chars().filter(|&c| c != 'o').to_owned().collect();
|
||||||
|
|
||||||
|
@ -171,6 +198,11 @@ fn vec_retain() {
|
||||||
vec.retain(|x| x % 2 == 0);
|
vec.retain(|x| x % 2 == 0);
|
||||||
vec.retain(|x| x % 2 == 0);
|
vec.retain(|x| x % 2 == 0);
|
||||||
|
|
||||||
|
// Do lint, because we use pattern matching
|
||||||
|
let mut tuples = vec![(0, 1), (1, 2), (2, 3)];
|
||||||
|
tuples.retain(|(ref x, ref y)| *x == 0);
|
||||||
|
tuples.retain(|(x, y)| *x == 0);
|
||||||
|
|
||||||
// Do not lint, because type conversion is performed
|
// Do not lint, because type conversion is performed
|
||||||
vec = vec.into_iter().filter(|x| x % 2 == 0).collect::<Vec<i8>>();
|
vec = vec.into_iter().filter(|x| x % 2 == 0).collect::<Vec<i8>>();
|
||||||
vec = vec.iter().filter(|&x| x % 2 == 0).copied().collect::<Vec<i8>>();
|
vec = vec.iter().filter(|&x| x % 2 == 0).copied().collect::<Vec<i8>>();
|
||||||
|
@ -246,3 +278,27 @@ fn _msrv_118() {
|
||||||
let mut hash_map: HashMap<i8, i8> = (0..8).map(|x| (x, x * 10)).collect();
|
let mut hash_map: HashMap<i8, i8> = (0..8).map(|x| (x, x * 10)).collect();
|
||||||
hash_map = hash_map.into_iter().filter(|(k, _)| k % 2 == 0).collect();
|
hash_map = hash_map.into_iter().filter(|(k, _)| k % 2 == 0).collect();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn issue_10393() {
|
||||||
|
// Do lint
|
||||||
|
let mut vec = vec![(0, 1), (1, 2), (2, 3)];
|
||||||
|
vec.retain(|(x, y)| *x == 0);
|
||||||
|
|
||||||
|
// Do lint
|
||||||
|
let mut tuples = vec![(true, -2), (false, 3)];
|
||||||
|
tuples.retain(|(_, n)| *n > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn issue_12081() {
|
||||||
|
let mut vec = vec![0, 1, 2];
|
||||||
|
|
||||||
|
// Do lint
|
||||||
|
vec.retain(|&x| x == 0);
|
||||||
|
vec.retain(|&x| x == 0);
|
||||||
|
vec.retain(|&x| x == 0);
|
||||||
|
|
||||||
|
// Do lint
|
||||||
|
vec.retain(|x| *x == 0);
|
||||||
|
vec.retain(|x| *x == 0);
|
||||||
|
vec.retain(|x| *x == 0);
|
||||||
|
}
|
||||||
|
|
|
@ -14,6 +14,9 @@ fn main() {
|
||||||
_msrv_153();
|
_msrv_153();
|
||||||
_msrv_126();
|
_msrv_126();
|
||||||
_msrv_118();
|
_msrv_118();
|
||||||
|
|
||||||
|
issue_10393();
|
||||||
|
issue_12081();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn binary_heap_retain() {
|
fn binary_heap_retain() {
|
||||||
|
@ -23,6 +26,11 @@ fn binary_heap_retain() {
|
||||||
binary_heap = binary_heap.iter().filter(|&x| x % 2 == 0).copied().collect();
|
binary_heap = binary_heap.iter().filter(|&x| x % 2 == 0).copied().collect();
|
||||||
binary_heap = binary_heap.iter().filter(|&x| x % 2 == 0).cloned().collect();
|
binary_heap = binary_heap.iter().filter(|&x| x % 2 == 0).cloned().collect();
|
||||||
|
|
||||||
|
// Do lint, because we use pattern matching
|
||||||
|
let mut tuples = BinaryHeap::from([(0, 1), (1, 2), (2, 3)]);
|
||||||
|
tuples = tuples.iter().filter(|(ref x, ref y)| *x == 0).copied().collect();
|
||||||
|
tuples = tuples.iter().filter(|(x, y)| *x == 0).copied().collect();
|
||||||
|
|
||||||
// Do not lint, because type conversion is performed
|
// Do not lint, because type conversion is performed
|
||||||
binary_heap = binary_heap
|
binary_heap = binary_heap
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
@ -58,6 +66,9 @@ fn btree_map_retain() {
|
||||||
.filter(|(k, v)| (k % 2 == 0) && (v % 2 == 0))
|
.filter(|(k, v)| (k % 2 == 0) && (v % 2 == 0))
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
|
// Do not lint, because the parameters are not matched in tuple pattern
|
||||||
|
btree_map = btree_map.into_iter().filter(|t| t.0 % 2 == 0).collect();
|
||||||
|
|
||||||
// Do not lint.
|
// Do not lint.
|
||||||
btree_map = btree_map
|
btree_map = btree_map
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
@ -79,6 +90,11 @@ fn btree_set_retain() {
|
||||||
btree_set = btree_set.iter().filter(|&x| x % 2 == 0).cloned().collect();
|
btree_set = btree_set.iter().filter(|&x| x % 2 == 0).cloned().collect();
|
||||||
btree_set = btree_set.into_iter().filter(|x| x % 2 == 0).collect();
|
btree_set = btree_set.into_iter().filter(|x| x % 2 == 0).collect();
|
||||||
|
|
||||||
|
// Do lint, because we use pattern matching
|
||||||
|
let mut tuples = BTreeSet::from([(0, 1), (1, 2), (2, 3)]);
|
||||||
|
tuples = tuples.iter().filter(|(ref x, ref y)| *x == 0).copied().collect();
|
||||||
|
tuples = tuples.iter().filter(|(x, y)| *x == 0).copied().collect();
|
||||||
|
|
||||||
// Do not lint, because type conversion is performed
|
// Do not lint, because type conversion is performed
|
||||||
btree_set = btree_set
|
btree_set = btree_set
|
||||||
.iter()
|
.iter()
|
||||||
|
@ -114,6 +130,9 @@ fn hash_map_retain() {
|
||||||
.filter(|(k, v)| (k % 2 == 0) && (v % 2 == 0))
|
.filter(|(k, v)| (k % 2 == 0) && (v % 2 == 0))
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
|
// Do not lint, because the parameters are not matched in tuple pattern
|
||||||
|
hash_map = hash_map.into_iter().filter(|t| t.0 % 2 == 0).collect();
|
||||||
|
|
||||||
// Do not lint.
|
// Do not lint.
|
||||||
hash_map = hash_map
|
hash_map = hash_map
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
@ -134,6 +153,11 @@ fn hash_set_retain() {
|
||||||
hash_set = hash_set.iter().filter(|&x| x % 2 == 0).copied().collect();
|
hash_set = hash_set.iter().filter(|&x| x % 2 == 0).copied().collect();
|
||||||
hash_set = hash_set.iter().filter(|&x| x % 2 == 0).cloned().collect();
|
hash_set = hash_set.iter().filter(|&x| x % 2 == 0).cloned().collect();
|
||||||
|
|
||||||
|
// Do lint, because we use pattern matching
|
||||||
|
let mut tuples = HashSet::from([(0, 1), (1, 2), (2, 3)]);
|
||||||
|
tuples = tuples.iter().filter(|(ref x, ref y)| *x == 0).copied().collect();
|
||||||
|
tuples = tuples.iter().filter(|(x, y)| *x == 0).copied().collect();
|
||||||
|
|
||||||
// Do not lint, because type conversion is performed
|
// Do not lint, because type conversion is performed
|
||||||
hash_set = hash_set.into_iter().filter(|x| x % 2 == 0).collect::<HashSet<i8>>();
|
hash_set = hash_set.into_iter().filter(|x| x % 2 == 0).collect::<HashSet<i8>>();
|
||||||
hash_set = hash_set
|
hash_set = hash_set
|
||||||
|
@ -163,6 +187,9 @@ fn string_retain() {
|
||||||
// Do lint.
|
// Do lint.
|
||||||
s = s.chars().filter(|&c| c != 'o').to_owned().collect();
|
s = s.chars().filter(|&c| c != 'o').to_owned().collect();
|
||||||
|
|
||||||
|
// Do not lint, because we need to rewrite the lambda
|
||||||
|
s = s.chars().filter(|c| *c != 'o').to_owned().collect();
|
||||||
|
|
||||||
// Do not lint, because this expression is not assign.
|
// Do not lint, because this expression is not assign.
|
||||||
let mut bar: String = s.chars().filter(|&c| c != 'o').to_owned().collect();
|
let mut bar: String = s.chars().filter(|&c| c != 'o').to_owned().collect();
|
||||||
|
|
||||||
|
@ -177,6 +204,11 @@ fn vec_retain() {
|
||||||
vec = vec.iter().filter(|&x| x % 2 == 0).cloned().collect();
|
vec = vec.iter().filter(|&x| x % 2 == 0).cloned().collect();
|
||||||
vec = vec.into_iter().filter(|x| x % 2 == 0).collect();
|
vec = vec.into_iter().filter(|x| x % 2 == 0).collect();
|
||||||
|
|
||||||
|
// Do lint, because we use pattern matching
|
||||||
|
let mut tuples = vec![(0, 1), (1, 2), (2, 3)];
|
||||||
|
tuples = tuples.iter().filter(|(ref x, ref y)| *x == 0).copied().collect();
|
||||||
|
tuples = tuples.iter().filter(|(x, y)| *x == 0).copied().collect();
|
||||||
|
|
||||||
// Do not lint, because type conversion is performed
|
// Do not lint, because type conversion is performed
|
||||||
vec = vec.into_iter().filter(|x| x % 2 == 0).collect::<Vec<i8>>();
|
vec = vec.into_iter().filter(|x| x % 2 == 0).collect::<Vec<i8>>();
|
||||||
vec = vec.iter().filter(|&x| x % 2 == 0).copied().collect::<Vec<i8>>();
|
vec = vec.iter().filter(|&x| x % 2 == 0).copied().collect::<Vec<i8>>();
|
||||||
|
@ -252,3 +284,27 @@ fn _msrv_118() {
|
||||||
let mut hash_map: HashMap<i8, i8> = (0..8).map(|x| (x, x * 10)).collect();
|
let mut hash_map: HashMap<i8, i8> = (0..8).map(|x| (x, x * 10)).collect();
|
||||||
hash_map = hash_map.into_iter().filter(|(k, _)| k % 2 == 0).collect();
|
hash_map = hash_map.into_iter().filter(|(k, _)| k % 2 == 0).collect();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn issue_10393() {
|
||||||
|
// Do lint
|
||||||
|
let mut vec = vec![(0, 1), (1, 2), (2, 3)];
|
||||||
|
vec = vec.into_iter().filter(|(x, y)| *x == 0).collect();
|
||||||
|
|
||||||
|
// Do lint
|
||||||
|
let mut tuples = vec![(true, -2), (false, 3)];
|
||||||
|
tuples = tuples.into_iter().filter(|(_, n)| *n > 0).collect();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn issue_12081() {
|
||||||
|
let mut vec = vec![0, 1, 2];
|
||||||
|
|
||||||
|
// Do lint
|
||||||
|
vec = vec.iter().filter(|&&x| x == 0).copied().collect();
|
||||||
|
vec = vec.iter().filter(|&&x| x == 0).cloned().collect();
|
||||||
|
vec = vec.into_iter().filter(|&x| x == 0).collect();
|
||||||
|
|
||||||
|
// Do lint
|
||||||
|
vec = vec.iter().filter(|&x| *x == 0).copied().collect();
|
||||||
|
vec = vec.iter().filter(|&x| *x == 0).cloned().collect();
|
||||||
|
vec = vec.into_iter().filter(|x| *x == 0).collect();
|
||||||
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
error: this expression can be written more simply using `.retain()`
|
error: this expression can be written more simply using `.retain()`
|
||||||
--> $DIR/manual_retain.rs:22:5
|
--> $DIR/manual_retain.rs:25:5
|
||||||
|
|
|
|
||||||
LL | binary_heap = binary_heap.into_iter().filter(|x| x % 2 == 0).collect();
|
LL | binary_heap = binary_heap.into_iter().filter(|x| x % 2 == 0).collect();
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `binary_heap.retain(|x| x % 2 == 0)`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `binary_heap.retain(|x| x % 2 == 0)`
|
||||||
|
@ -8,31 +8,43 @@ LL | binary_heap = binary_heap.into_iter().filter(|x| x % 2 == 0).collect();
|
||||||
= help: to override `-D warnings` add `#[allow(clippy::manual_retain)]`
|
= help: to override `-D warnings` add `#[allow(clippy::manual_retain)]`
|
||||||
|
|
||||||
error: this expression can be written more simply using `.retain()`
|
error: this expression can be written more simply using `.retain()`
|
||||||
--> $DIR/manual_retain.rs:23:5
|
--> $DIR/manual_retain.rs:26:5
|
||||||
|
|
|
|
||||||
LL | binary_heap = binary_heap.iter().filter(|&x| x % 2 == 0).copied().collect();
|
LL | binary_heap = binary_heap.iter().filter(|&x| x % 2 == 0).copied().collect();
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `binary_heap.retain(|x| x % 2 == 0)`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `binary_heap.retain(|x| x % 2 == 0)`
|
||||||
|
|
||||||
error: this expression can be written more simply using `.retain()`
|
error: this expression can be written more simply using `.retain()`
|
||||||
--> $DIR/manual_retain.rs:24:5
|
--> $DIR/manual_retain.rs:27:5
|
||||||
|
|
|
|
||||||
LL | binary_heap = binary_heap.iter().filter(|&x| x % 2 == 0).cloned().collect();
|
LL | binary_heap = binary_heap.iter().filter(|&x| x % 2 == 0).cloned().collect();
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `binary_heap.retain(|x| x % 2 == 0)`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `binary_heap.retain(|x| x % 2 == 0)`
|
||||||
|
|
||||||
error: this expression can be written more simply using `.retain()`
|
error: this expression can be written more simply using `.retain()`
|
||||||
--> $DIR/manual_retain.rs:54:5
|
--> $DIR/manual_retain.rs:31:5
|
||||||
|
|
|
||||||
|
LL | tuples = tuples.iter().filter(|(ref x, ref y)| *x == 0).copied().collect();
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `tuples.retain(|(ref x, ref y)| *x == 0)`
|
||||||
|
|
||||||
|
error: this expression can be written more simply using `.retain()`
|
||||||
|
--> $DIR/manual_retain.rs:32:5
|
||||||
|
|
|
||||||
|
LL | tuples = tuples.iter().filter(|(x, y)| *x == 0).copied().collect();
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `tuples.retain(|(x, y)| *x == 0)`
|
||||||
|
|
||||||
|
error: this expression can be written more simply using `.retain()`
|
||||||
|
--> $DIR/manual_retain.rs:62:5
|
||||||
|
|
|
|
||||||
LL | btree_map = btree_map.into_iter().filter(|(k, _)| k % 2 == 0).collect();
|
LL | btree_map = btree_map.into_iter().filter(|(k, _)| k % 2 == 0).collect();
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `btree_map.retain(|k, _| k % 2 == 0)`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `btree_map.retain(|k, _| k % 2 == 0)`
|
||||||
|
|
||||||
error: this expression can be written more simply using `.retain()`
|
error: this expression can be written more simply using `.retain()`
|
||||||
--> $DIR/manual_retain.rs:55:5
|
--> $DIR/manual_retain.rs:63:5
|
||||||
|
|
|
|
||||||
LL | btree_map = btree_map.into_iter().filter(|(_, v)| v % 2 == 0).collect();
|
LL | btree_map = btree_map.into_iter().filter(|(_, v)| v % 2 == 0).collect();
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `btree_map.retain(|_, &mut v| v % 2 == 0)`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `btree_map.retain(|_, &mut v| v % 2 == 0)`
|
||||||
|
|
||||||
error: this expression can be written more simply using `.retain()`
|
error: this expression can be written more simply using `.retain()`
|
||||||
--> $DIR/manual_retain.rs:56:5
|
--> $DIR/manual_retain.rs:64:5
|
||||||
|
|
|
|
||||||
LL | / btree_map = btree_map
|
LL | / btree_map = btree_map
|
||||||
LL | | .into_iter()
|
LL | | .into_iter()
|
||||||
|
@ -41,37 +53,49 @@ LL | | .collect();
|
||||||
| |__________________^ help: consider calling `.retain()` instead: `btree_map.retain(|k, &mut v| (k % 2 == 0) && (v % 2 == 0))`
|
| |__________________^ help: consider calling `.retain()` instead: `btree_map.retain(|k, &mut v| (k % 2 == 0) && (v % 2 == 0))`
|
||||||
|
|
||||||
error: this expression can be written more simply using `.retain()`
|
error: this expression can be written more simply using `.retain()`
|
||||||
--> $DIR/manual_retain.rs:78:5
|
--> $DIR/manual_retain.rs:89:5
|
||||||
|
|
|
|
||||||
LL | btree_set = btree_set.iter().filter(|&x| x % 2 == 0).copied().collect();
|
LL | btree_set = btree_set.iter().filter(|&x| x % 2 == 0).copied().collect();
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `btree_set.retain(|x| x % 2 == 0)`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `btree_set.retain(|x| x % 2 == 0)`
|
||||||
|
|
||||||
error: this expression can be written more simply using `.retain()`
|
error: this expression can be written more simply using `.retain()`
|
||||||
--> $DIR/manual_retain.rs:79:5
|
--> $DIR/manual_retain.rs:90:5
|
||||||
|
|
|
|
||||||
LL | btree_set = btree_set.iter().filter(|&x| x % 2 == 0).cloned().collect();
|
LL | btree_set = btree_set.iter().filter(|&x| x % 2 == 0).cloned().collect();
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `btree_set.retain(|x| x % 2 == 0)`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `btree_set.retain(|x| x % 2 == 0)`
|
||||||
|
|
||||||
error: this expression can be written more simply using `.retain()`
|
error: this expression can be written more simply using `.retain()`
|
||||||
--> $DIR/manual_retain.rs:80:5
|
--> $DIR/manual_retain.rs:91:5
|
||||||
|
|
|
|
||||||
LL | btree_set = btree_set.into_iter().filter(|x| x % 2 == 0).collect();
|
LL | btree_set = btree_set.into_iter().filter(|x| x % 2 == 0).collect();
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `btree_set.retain(|x| x % 2 == 0)`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `btree_set.retain(|x| x % 2 == 0)`
|
||||||
|
|
||||||
error: this expression can be written more simply using `.retain()`
|
error: this expression can be written more simply using `.retain()`
|
||||||
--> $DIR/manual_retain.rs:110:5
|
--> $DIR/manual_retain.rs:95:5
|
||||||
|
|
|
||||||
|
LL | tuples = tuples.iter().filter(|(ref x, ref y)| *x == 0).copied().collect();
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `tuples.retain(|(ref x, ref y)| *x == 0)`
|
||||||
|
|
||||||
|
error: this expression can be written more simply using `.retain()`
|
||||||
|
--> $DIR/manual_retain.rs:96:5
|
||||||
|
|
|
||||||
|
LL | tuples = tuples.iter().filter(|(x, y)| *x == 0).copied().collect();
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `tuples.retain(|(x, y)| *x == 0)`
|
||||||
|
|
||||||
|
error: this expression can be written more simply using `.retain()`
|
||||||
|
--> $DIR/manual_retain.rs:126:5
|
||||||
|
|
|
|
||||||
LL | hash_map = hash_map.into_iter().filter(|(k, _)| k % 2 == 0).collect();
|
LL | hash_map = hash_map.into_iter().filter(|(k, _)| k % 2 == 0).collect();
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `hash_map.retain(|k, _| k % 2 == 0)`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `hash_map.retain(|k, _| k % 2 == 0)`
|
||||||
|
|
||||||
error: this expression can be written more simply using `.retain()`
|
error: this expression can be written more simply using `.retain()`
|
||||||
--> $DIR/manual_retain.rs:111:5
|
--> $DIR/manual_retain.rs:127:5
|
||||||
|
|
|
|
||||||
LL | hash_map = hash_map.into_iter().filter(|(_, v)| v % 2 == 0).collect();
|
LL | hash_map = hash_map.into_iter().filter(|(_, v)| v % 2 == 0).collect();
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `hash_map.retain(|_, &mut v| v % 2 == 0)`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `hash_map.retain(|_, &mut v| v % 2 == 0)`
|
||||||
|
|
||||||
error: this expression can be written more simply using `.retain()`
|
error: this expression can be written more simply using `.retain()`
|
||||||
--> $DIR/manual_retain.rs:112:5
|
--> $DIR/manual_retain.rs:128:5
|
||||||
|
|
|
|
||||||
LL | / hash_map = hash_map
|
LL | / hash_map = hash_map
|
||||||
LL | | .into_iter()
|
LL | | .into_iter()
|
||||||
|
@ -80,64 +104,136 @@ LL | | .collect();
|
||||||
| |__________________^ help: consider calling `.retain()` instead: `hash_map.retain(|k, &mut v| (k % 2 == 0) && (v % 2 == 0))`
|
| |__________________^ help: consider calling `.retain()` instead: `hash_map.retain(|k, &mut v| (k % 2 == 0) && (v % 2 == 0))`
|
||||||
|
|
||||||
error: this expression can be written more simply using `.retain()`
|
error: this expression can be written more simply using `.retain()`
|
||||||
--> $DIR/manual_retain.rs:133:5
|
--> $DIR/manual_retain.rs:152:5
|
||||||
|
|
|
|
||||||
LL | hash_set = hash_set.into_iter().filter(|x| x % 2 == 0).collect();
|
LL | hash_set = hash_set.into_iter().filter(|x| x % 2 == 0).collect();
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `hash_set.retain(|x| x % 2 == 0)`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `hash_set.retain(|x| x % 2 == 0)`
|
||||||
|
|
||||||
error: this expression can be written more simply using `.retain()`
|
error: this expression can be written more simply using `.retain()`
|
||||||
--> $DIR/manual_retain.rs:134:5
|
--> $DIR/manual_retain.rs:153:5
|
||||||
|
|
|
|
||||||
LL | hash_set = hash_set.iter().filter(|&x| x % 2 == 0).copied().collect();
|
LL | hash_set = hash_set.iter().filter(|&x| x % 2 == 0).copied().collect();
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `hash_set.retain(|x| x % 2 == 0)`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `hash_set.retain(|x| x % 2 == 0)`
|
||||||
|
|
||||||
error: this expression can be written more simply using `.retain()`
|
error: this expression can be written more simply using `.retain()`
|
||||||
--> $DIR/manual_retain.rs:135:5
|
--> $DIR/manual_retain.rs:154:5
|
||||||
|
|
|
|
||||||
LL | hash_set = hash_set.iter().filter(|&x| x % 2 == 0).cloned().collect();
|
LL | hash_set = hash_set.iter().filter(|&x| x % 2 == 0).cloned().collect();
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `hash_set.retain(|x| x % 2 == 0)`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `hash_set.retain(|x| x % 2 == 0)`
|
||||||
|
|
||||||
error: this expression can be written more simply using `.retain()`
|
error: this expression can be written more simply using `.retain()`
|
||||||
--> $DIR/manual_retain.rs:164:5
|
--> $DIR/manual_retain.rs:158:5
|
||||||
|
|
|
||||||
|
LL | tuples = tuples.iter().filter(|(ref x, ref y)| *x == 0).copied().collect();
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `tuples.retain(|(ref x, ref y)| *x == 0)`
|
||||||
|
|
||||||
|
error: this expression can be written more simply using `.retain()`
|
||||||
|
--> $DIR/manual_retain.rs:159:5
|
||||||
|
|
|
||||||
|
LL | tuples = tuples.iter().filter(|(x, y)| *x == 0).copied().collect();
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `tuples.retain(|(x, y)| *x == 0)`
|
||||||
|
|
||||||
|
error: this expression can be written more simply using `.retain()`
|
||||||
|
--> $DIR/manual_retain.rs:188:5
|
||||||
|
|
|
|
||||||
LL | s = s.chars().filter(|&c| c != 'o').to_owned().collect();
|
LL | s = s.chars().filter(|&c| c != 'o').to_owned().collect();
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `s.retain(|c| c != 'o')`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `s.retain(|c| c != 'o')`
|
||||||
|
|
||||||
error: this expression can be written more simply using `.retain()`
|
error: this expression can be written more simply using `.retain()`
|
||||||
--> $DIR/manual_retain.rs:176:5
|
--> $DIR/manual_retain.rs:203:5
|
||||||
|
|
|
|
||||||
LL | vec = vec.iter().filter(|&x| x % 2 == 0).copied().collect();
|
LL | vec = vec.iter().filter(|&x| x % 2 == 0).copied().collect();
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `vec.retain(|x| x % 2 == 0)`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `vec.retain(|x| x % 2 == 0)`
|
||||||
|
|
||||||
error: this expression can be written more simply using `.retain()`
|
error: this expression can be written more simply using `.retain()`
|
||||||
--> $DIR/manual_retain.rs:177:5
|
--> $DIR/manual_retain.rs:204:5
|
||||||
|
|
|
|
||||||
LL | vec = vec.iter().filter(|&x| x % 2 == 0).cloned().collect();
|
LL | vec = vec.iter().filter(|&x| x % 2 == 0).cloned().collect();
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `vec.retain(|x| x % 2 == 0)`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `vec.retain(|x| x % 2 == 0)`
|
||||||
|
|
||||||
error: this expression can be written more simply using `.retain()`
|
error: this expression can be written more simply using `.retain()`
|
||||||
--> $DIR/manual_retain.rs:178:5
|
--> $DIR/manual_retain.rs:205:5
|
||||||
|
|
|
|
||||||
LL | vec = vec.into_iter().filter(|x| x % 2 == 0).collect();
|
LL | vec = vec.into_iter().filter(|x| x % 2 == 0).collect();
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `vec.retain(|x| x % 2 == 0)`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `vec.retain(|x| x % 2 == 0)`
|
||||||
|
|
||||||
error: this expression can be written more simply using `.retain()`
|
error: this expression can be written more simply using `.retain()`
|
||||||
--> $DIR/manual_retain.rs:200:5
|
--> $DIR/manual_retain.rs:209:5
|
||||||
|
|
|
||||||
|
LL | tuples = tuples.iter().filter(|(ref x, ref y)| *x == 0).copied().collect();
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `tuples.retain(|(ref x, ref y)| *x == 0)`
|
||||||
|
|
||||||
|
error: this expression can be written more simply using `.retain()`
|
||||||
|
--> $DIR/manual_retain.rs:210:5
|
||||||
|
|
|
||||||
|
LL | tuples = tuples.iter().filter(|(x, y)| *x == 0).copied().collect();
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `tuples.retain(|(x, y)| *x == 0)`
|
||||||
|
|
||||||
|
error: this expression can be written more simply using `.retain()`
|
||||||
|
--> $DIR/manual_retain.rs:232:5
|
||||||
|
|
|
|
||||||
LL | vec_deque = vec_deque.iter().filter(|&x| x % 2 == 0).copied().collect();
|
LL | vec_deque = vec_deque.iter().filter(|&x| x % 2 == 0).copied().collect();
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `vec_deque.retain(|x| x % 2 == 0)`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `vec_deque.retain(|x| x % 2 == 0)`
|
||||||
|
|
||||||
error: this expression can be written more simply using `.retain()`
|
error: this expression can be written more simply using `.retain()`
|
||||||
--> $DIR/manual_retain.rs:201:5
|
--> $DIR/manual_retain.rs:233:5
|
||||||
|
|
|
|
||||||
LL | vec_deque = vec_deque.iter().filter(|&x| x % 2 == 0).cloned().collect();
|
LL | vec_deque = vec_deque.iter().filter(|&x| x % 2 == 0).cloned().collect();
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `vec_deque.retain(|x| x % 2 == 0)`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `vec_deque.retain(|x| x % 2 == 0)`
|
||||||
|
|
||||||
error: this expression can be written more simply using `.retain()`
|
error: this expression can be written more simply using `.retain()`
|
||||||
--> $DIR/manual_retain.rs:202:5
|
--> $DIR/manual_retain.rs:234:5
|
||||||
|
|
|
|
||||||
LL | vec_deque = vec_deque.into_iter().filter(|x| x % 2 == 0).collect();
|
LL | vec_deque = vec_deque.into_iter().filter(|x| x % 2 == 0).collect();
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `vec_deque.retain(|x| x % 2 == 0)`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `vec_deque.retain(|x| x % 2 == 0)`
|
||||||
|
|
||||||
error: aborting due to 22 previous errors
|
error: this expression can be written more simply using `.retain()`
|
||||||
|
--> $DIR/manual_retain.rs:291:5
|
||||||
|
|
|
||||||
|
LL | vec = vec.into_iter().filter(|(x, y)| *x == 0).collect();
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `vec.retain(|(x, y)| *x == 0)`
|
||||||
|
|
||||||
|
error: this expression can be written more simply using `.retain()`
|
||||||
|
--> $DIR/manual_retain.rs:295:5
|
||||||
|
|
|
||||||
|
LL | tuples = tuples.into_iter().filter(|(_, n)| *n > 0).collect();
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `tuples.retain(|(_, n)| *n > 0)`
|
||||||
|
|
||||||
|
error: this expression can be written more simply using `.retain()`
|
||||||
|
--> $DIR/manual_retain.rs:302:5
|
||||||
|
|
|
||||||
|
LL | vec = vec.iter().filter(|&&x| x == 0).copied().collect();
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `vec.retain(|&x| x == 0)`
|
||||||
|
|
||||||
|
error: this expression can be written more simply using `.retain()`
|
||||||
|
--> $DIR/manual_retain.rs:303:5
|
||||||
|
|
|
||||||
|
LL | vec = vec.iter().filter(|&&x| x == 0).cloned().collect();
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `vec.retain(|&x| x == 0)`
|
||||||
|
|
||||||
|
error: this expression can be written more simply using `.retain()`
|
||||||
|
--> $DIR/manual_retain.rs:304:5
|
||||||
|
|
|
||||||
|
LL | vec = vec.into_iter().filter(|&x| x == 0).collect();
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `vec.retain(|&x| x == 0)`
|
||||||
|
|
||||||
|
error: this expression can be written more simply using `.retain()`
|
||||||
|
--> $DIR/manual_retain.rs:307:5
|
||||||
|
|
|
||||||
|
LL | vec = vec.iter().filter(|&x| *x == 0).copied().collect();
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `vec.retain(|x| *x == 0)`
|
||||||
|
|
||||||
|
error: this expression can be written more simply using `.retain()`
|
||||||
|
--> $DIR/manual_retain.rs:308:5
|
||||||
|
|
|
||||||
|
LL | vec = vec.iter().filter(|&x| *x == 0).cloned().collect();
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `vec.retain(|x| *x == 0)`
|
||||||
|
|
||||||
|
error: this expression can be written more simply using `.retain()`
|
||||||
|
--> $DIR/manual_retain.rs:309:5
|
||||||
|
|
|
||||||
|
LL | vec = vec.into_iter().filter(|x| *x == 0).collect();
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `vec.retain(|x| *x == 0)`
|
||||||
|
|
||||||
|
error: aborting due to 38 previous errors
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue