From f9669e4caf219512b34546a13f39d80179511259 Mon Sep 17 00:00:00 2001 From: lapla-cogito Date: Sat, 1 Feb 2025 15:20:34 +0900 Subject: [PATCH] add MSRV check for `lines_filter_map_ok` --- book/src/lint_configuration.md | 1 + clippy_config/src/conf.rs | 1 + clippy_lints/src/lib.rs | 2 +- clippy_lints/src/lines_filter_map_ok.rs | 24 +++++++++++++++++++++--- clippy_utils/src/msrvs.rs | 1 + tests/ui/lines_filter_map_ok.fixed | 7 +++++++ tests/ui/lines_filter_map_ok.rs | 7 +++++++ 7 files changed, 39 insertions(+), 4 deletions(-) diff --git a/book/src/lint_configuration.md b/book/src/lint_configuration.md index b8f9fff9c613..998668fabf02 100644 --- a/book/src/lint_configuration.md +++ b/book/src/lint_configuration.md @@ -740,6 +740,7 @@ The minimum rust version that the project supports. Defaults to the `rust-versio * [`index_refutable_slice`](https://rust-lang.github.io/rust-clippy/master/index.html#index_refutable_slice) * [`iter_kv_map`](https://rust-lang.github.io/rust-clippy/master/index.html#iter_kv_map) * [`legacy_numeric_constants`](https://rust-lang.github.io/rust-clippy/master/index.html#legacy_numeric_constants) +* [`lines_filter_map_ok`](https://rust-lang.github.io/rust-clippy/master/index.html#lines_filter_map_ok) * [`manual_bits`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_bits) * [`manual_c_str_literals`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_c_str_literals) * [`manual_clamp`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_clamp) diff --git a/clippy_config/src/conf.rs b/clippy_config/src/conf.rs index 552141476f3a..cefcf81bcf06 100644 --- a/clippy_config/src/conf.rs +++ b/clippy_config/src/conf.rs @@ -609,6 +609,7 @@ define_Conf! { index_refutable_slice, iter_kv_map, legacy_numeric_constants, + lines_filter_map_ok, manual_bits, manual_c_str_literals, manual_clamp, diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index 4b700673d0f8..4da3160ee24e 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -900,7 +900,7 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) { store.register_late_pass(move |_| Box::new(manual_main_separator_str::ManualMainSeparatorStr::new(conf))); store.register_late_pass(|_| Box::new(unnecessary_struct_initialization::UnnecessaryStruct)); store.register_late_pass(move |_| Box::new(unnecessary_box_returns::UnnecessaryBoxReturns::new(conf))); - store.register_late_pass(|_| Box::new(lines_filter_map_ok::LinesFilterMapOk)); + store.register_late_pass(move |_| Box::new(lines_filter_map_ok::LinesFilterMapOk::new(conf))); store.register_late_pass(|_| Box::new(tests_outside_test_module::TestsOutsideTestModule)); store.register_late_pass(|_| Box::new(manual_slice_size_calculation::ManualSliceSizeCalculation)); store.register_early_pass(move || Box::new(excessive_nesting::ExcessiveNesting::new(conf))); diff --git a/clippy_lints/src/lines_filter_map_ok.rs b/clippy_lints/src/lines_filter_map_ok.rs index 8206c75927b7..8c237191405a 100644 --- a/clippy_lints/src/lines_filter_map_ok.rs +++ b/clippy_lints/src/lines_filter_map_ok.rs @@ -1,12 +1,26 @@ +use clippy_config::Conf; use clippy_utils::diagnostics::span_lint_and_then; +use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::ty::is_type_diagnostic_item; use clippy_utils::{is_diag_item_method, is_trait_method, path_to_local_id}; use rustc_errors::Applicability; use rustc_hir::{Body, Closure, Expr, ExprKind}; use rustc_lint::{LateContext, LateLintPass}; -use rustc_session::declare_lint_pass; +use rustc_session::impl_lint_pass; use rustc_span::sym; +pub struct LinesFilterMapOk { + msrv: Msrv, +} + +impl LinesFilterMapOk { + pub fn new(conf: &Conf) -> Self { + Self { + msrv: conf.msrv.clone(), + } + } +} + declare_clippy_lint! { /// ### What it does /// Checks for usage of `lines.filter_map(Result::ok)` or `lines.flat_map(Result::ok)` @@ -55,11 +69,13 @@ declare_clippy_lint! { suspicious, "filtering `std::io::Lines` with `filter_map()`, `flat_map()`, or `flatten()` might cause an infinite loop" } -declare_lint_pass!(LinesFilterMapOk => [LINES_FILTER_MAP_OK]); + +impl_lint_pass!(LinesFilterMapOk => [LINES_FILTER_MAP_OK]); impl LateLintPass<'_> for LinesFilterMapOk { fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) { - if let ExprKind::MethodCall(fm_method, fm_receiver, fm_args, fm_span) = expr.kind + if self.msrv.meets(msrvs::MAP_WHILE) + && let ExprKind::MethodCall(fm_method, fm_receiver, fm_args, fm_span) = expr.kind && is_trait_method(cx, expr, sym::Iterator) && let fm_method_str = fm_method.ident.as_str() && matches!(fm_method_str, "filter_map" | "flat_map" | "flatten") @@ -85,6 +101,8 @@ impl LateLintPass<'_> for LinesFilterMapOk { ); } } + + extract_msrv_attr!(LateContext); } fn should_lint(cx: &LateContext<'_>, args: &[Expr<'_>], method_str: &str) -> bool { diff --git a/clippy_utils/src/msrvs.rs b/clippy_utils/src/msrvs.rs index d73cb7e35611..34c575c66be5 100644 --- a/clippy_utils/src/msrvs.rs +++ b/clippy_utils/src/msrvs.rs @@ -34,6 +34,7 @@ msrv_aliases! { 1,62,0 { BOOL_THEN_SOME, DEFAULT_ENUM_ATTRIBUTE, CONST_EXTERN_C_FN } 1,59,0 { THREAD_LOCAL_CONST_INIT } 1,58,0 { FORMAT_ARGS_CAPTURE, PATTERN_TRAIT_CHAR_ARRAY, CONST_RAW_PTR_DEREF } + 1,57,0 { MAP_WHILE } 1,56,0 { CONST_FN_UNION } 1,55,0 { SEEK_REWIND } 1,54,0 { INTO_KEYS } diff --git a/tests/ui/lines_filter_map_ok.fixed b/tests/ui/lines_filter_map_ok.fixed index 621115cc1325..ae388ec39a15 100644 --- a/tests/ui/lines_filter_map_ok.fixed +++ b/tests/ui/lines_filter_map_ok.fixed @@ -31,3 +31,10 @@ fn main() -> io::Result<()> { io::stdin().lines().filter_map(|x| x.err()).for_each(|_| ()); Ok(()) } + +#[clippy::msrv = "1.56"] +fn msrv_check() { + let _lines = BufReader::new(std::fs::File::open("some-path").unwrap()) + .lines() + .filter_map(Result::ok); +} diff --git a/tests/ui/lines_filter_map_ok.rs b/tests/ui/lines_filter_map_ok.rs index a86efbd66862..4f486534e9b0 100644 --- a/tests/ui/lines_filter_map_ok.rs +++ b/tests/ui/lines_filter_map_ok.rs @@ -31,3 +31,10 @@ fn main() -> io::Result<()> { io::stdin().lines().filter_map(|x| x.err()).for_each(|_| ()); Ok(()) } + +#[clippy::msrv = "1.56"] +fn msrv_check() { + let _lines = BufReader::new(std::fs::File::open("some-path").unwrap()) + .lines() + .filter_map(Result::ok); +}