Skip to content

Commit ab5d55c

Browse files
committed
Add more receivers to useless_conversion
- `ControlFlow::map_break()` - `ControlFlow::map_continue()` - `Iterator::map()`
1 parent 9a692ec commit ab5d55c

File tree

5 files changed

+120
-47
lines changed

5 files changed

+120
-47
lines changed

clippy_lints/src/methods/mod.rs

+3
Original file line numberDiff line numberDiff line change
@@ -4984,6 +4984,9 @@ impl Methods {
49844984
manual_inspect::check(cx, expr, m_arg, name, span, &self.msrv);
49854985
crate::useless_conversion::check_function_application(cx, expr, recv, m_arg);
49864986
},
4987+
("map_break" | "map_continue", [m_arg]) => {
4988+
crate::useless_conversion::check_function_application(cx, expr, recv, m_arg);
4989+
},
49874990
("map_or", [def, map]) => {
49884991
option_map_or_none::check(cx, expr, recv, def, map);
49894992
manual_ok_or::check(cx, expr, recv, def, map);

clippy_lints/src/useless_conversion.rs

+19-3
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use rustc_lint::{LateContext, LateLintPass};
1414
use rustc_middle::traits::ObligationCause;
1515
use rustc_middle::ty::{self, AdtDef, EarlyBinder, GenericArg, GenericArgsRef, Ty, TypeVisitableExt};
1616
use rustc_session::impl_lint_pass;
17-
use rustc_span::{Span, sym};
17+
use rustc_span::{Span, Symbol, sym};
1818
use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
1919

2020
declare_clippy_lint! {
@@ -415,9 +415,25 @@ fn has_eligible_receiver(cx: &LateContext<'_>, recv: &Expr<'_>, expr: &Expr<'_>)
415415
let recv_ty = cx.typeck_results().expr_ty(recv);
416416
if is_inherent_method_call(cx, expr)
417417
&& let Some(recv_ty_defid) = recv_ty.ty_adt_def().map(AdtDef::did)
418-
&& let Some(diag_name) = cx.tcx.get_diagnostic_name(recv_ty_defid)
419-
&& matches!(diag_name, sym::Option | sym::Result)
420418
{
419+
if let Some(diag_name) = cx.tcx.get_diagnostic_name(recv_ty_defid)
420+
&& matches!(diag_name, sym::Option | sym::Result)
421+
{
422+
return true;
423+
}
424+
425+
// FIXME: Add ControlFlow diagnostic item
426+
let def_path = cx.get_def_path(recv_ty_defid);
427+
if def_path
428+
.iter()
429+
.map(Symbol::as_str)
430+
.zip(["core", "ops", "control_flow", "ControlFlow"])
431+
.all(|(sym, s)| sym == s)
432+
{
433+
return true;
434+
}
435+
}
436+
if is_trait_method(cx, expr, sym::Iterator) {
421437
return true;
422438
}
423439
false

tests/ui/useless_conversion.fixed

+16-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
44
#![allow(static_mut_refs)]
55

6+
use std::ops::ControlFlow;
7+
68
fn test_generic<T: Copy>(val: T) -> T {
79
let _ = val;
810
val
@@ -308,6 +310,13 @@ fn direct_application() {
308310
let _: Result<(), std::io::Error> = test_issue_3913();
309311
//~^ useless_conversion
310312

313+
let c: ControlFlow<()> = ControlFlow::Continue(());
314+
let _: ControlFlow<()> = c;
315+
//~^ useless_conversion
316+
let c: ControlFlow<()> = ControlFlow::Continue(());
317+
let _: ControlFlow<()> = c;
318+
//~^ useless_conversion
319+
311320
struct Absorb;
312321
impl From<()> for Absorb {
313322
fn from(_: ()) -> Self {
@@ -319,11 +328,17 @@ fn direct_application() {
319328
Self
320329
}
321330
}
331+
let _: Vec<u32> = [1u32].into_iter().collect();
332+
//~^ useless_conversion
322333

323334
// No lint for those
324335
let _: Result<Absorb, std::io::Error> = test_issue_3913().map(Into::into);
325336
let _: Result<(), Absorb> = test_issue_3913().map_err(Into::into);
326337
let _: Result<Absorb, std::io::Error> = test_issue_3913().map(From::from);
327338
let _: Result<(), Absorb> = test_issue_3913().map_err(From::from);
328-
let _: Vec<u32> = [1u32].into_iter().map(Into::into).collect();
339+
}
340+
341+
fn gen_identity<T>(x: [T; 3]) -> Vec<T> {
342+
x.into_iter().collect()
343+
//~^ useless_conversion
329344
}

tests/ui/useless_conversion.rs

+16-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
44
#![allow(static_mut_refs)]
55

6+
use std::ops::ControlFlow;
7+
68
fn test_generic<T: Copy>(val: T) -> T {
79
let _ = T::from(val);
810
val.into()
@@ -308,6 +310,13 @@ fn direct_application() {
308310
let _: Result<(), std::io::Error> = test_issue_3913().map_err(From::from);
309311
//~^ useless_conversion
310312

313+
let c: ControlFlow<()> = ControlFlow::Continue(());
314+
let _: ControlFlow<()> = c.map_break(Into::into);
315+
//~^ useless_conversion
316+
let c: ControlFlow<()> = ControlFlow::Continue(());
317+
let _: ControlFlow<()> = c.map_continue(Into::into);
318+
//~^ useless_conversion
319+
311320
struct Absorb;
312321
impl From<()> for Absorb {
313322
fn from(_: ()) -> Self {
@@ -319,11 +328,17 @@ fn direct_application() {
319328
Self
320329
}
321330
}
331+
let _: Vec<u32> = [1u32].into_iter().map(Into::into).collect();
332+
//~^ useless_conversion
322333

323334
// No lint for those
324335
let _: Result<Absorb, std::io::Error> = test_issue_3913().map(Into::into);
325336
let _: Result<(), Absorb> = test_issue_3913().map_err(Into::into);
326337
let _: Result<Absorb, std::io::Error> = test_issue_3913().map(From::from);
327338
let _: Result<(), Absorb> = test_issue_3913().map_err(From::from);
328-
let _: Vec<u32> = [1u32].into_iter().map(Into::into).collect();
339+
}
340+
341+
fn gen_identity<T>(x: [T; 3]) -> Vec<T> {
342+
x.into_iter().map(Into::into).collect()
343+
//~^ useless_conversion
329344
}

0 commit comments

Comments
 (0)