diff --git a/clippy_lints/src/methods/case_sensitive_file_extension_comparisons.rs b/clippy_lints/src/methods/case_sensitive_file_extension_comparisons.rs index b6ec0fba6cf..0b3bf22743f 100644 --- a/clippy_lints/src/methods/case_sensitive_file_extension_comparisons.rs +++ b/clippy_lints/src/methods/case_sensitive_file_extension_comparisons.rs @@ -1,6 +1,6 @@ use clippy_utils::diagnostics::span_lint_and_then; +use clippy_utils::source::snippet_opt; use clippy_utils::source::{indent_of, reindent_multiline}; -use clippy_utils::sugg::Sugg; use clippy_utils::ty::is_type_lang_item; use if_chain::if_chain; use rustc_ast::ast::LitKind; @@ -19,8 +19,10 @@ pub(super) fn check<'tcx>( arg: &'tcx Expr<'_>, ) { if let ExprKind::MethodCall(path_segment, ..) = recv.kind { - let method_name = path_segment.ident.name.as_str(); - if method_name == "to_lowercase" || method_name == "to_uppercase" { + if matches!( + path_segment.ident.name.as_str(), + "to_lowercase" | "to_uppercase" | "to_ascii_lowercase" | "to_ascii_uppercase" + ) { return; } } @@ -45,28 +47,29 @@ pub(super) fn check<'tcx>( "case-sensitive file extension comparison", |diag| { diag.help("consider using a case-insensitive comparison instead"); - let mut recv_source = Sugg::hir(cx, recv, "").to_string(); + if let Some(mut recv_source) = snippet_opt(cx, recv.span) { - if is_type_lang_item(cx, recv_ty, LangItem::String) { - recv_source = format!("&{recv_source}"); + if !cx.typeck_results().expr_ty(recv).is_ref() { + recv_source = format!("&{recv_source}"); + } + + let suggestion_source = reindent_multiline( + format!( + "std::path::Path::new({}) + .extension() + .map_or(false, |ext| ext.eq_ignore_ascii_case(\"{}\"))", + recv_source, ext_str.strip_prefix('.').unwrap()).into(), + true, + Some(indent_of(cx, call_span).unwrap_or(0) + 4) + ); + + diag.span_suggestion( + recv.span.to(call_span), + "use std::path::Path", + suggestion_source, + Applicability::MaybeIncorrect, + ); } - - let suggestion_source = reindent_multiline( - format!( - "std::path::Path::new({}) - .extension() - .map_or(false, |ext| ext.eq_ignore_ascii_case(\"{}\"))", - recv_source, ext_str.strip_prefix('.').unwrap()).into(), - true, - Some(indent_of(cx, call_span).unwrap_or(0) + 4) - ); - - diag.span_suggestion( - recv.span.to(call_span), - "use std::path::Path", - suggestion_source, - Applicability::MaybeIncorrect, - ); } ); } diff --git a/tests/ui/case_sensitive_file_extension_comparisons.fixed b/tests/ui/case_sensitive_file_extension_comparisons.fixed index a19ed1ddcd5..5fbaa64db39 100644 --- a/tests/ui/case_sensitive_file_extension_comparisons.fixed +++ b/tests/ui/case_sensitive_file_extension_comparisons.fixed @@ -25,6 +25,13 @@ fn main() { .extension() .map_or(false, |ext| ext.eq_ignore_ascii_case("ext12")); + // The fixup should preserve the indentation level + { + let _ = std::path::Path::new("str") + .extension() + .map_or(false, |ext| ext.eq_ignore_ascii_case("ext12")); + } + // The test struct should not trigger the lint failure with .ext12 TestStruct {}.ends_with(".ext12"); diff --git a/tests/ui/case_sensitive_file_extension_comparisons.rs b/tests/ui/case_sensitive_file_extension_comparisons.rs index ad56b7296f7..3c0d4821f9f 100644 --- a/tests/ui/case_sensitive_file_extension_comparisons.rs +++ b/tests/ui/case_sensitive_file_extension_comparisons.rs @@ -19,6 +19,11 @@ fn main() { let _ = String::new().ends_with(".ext12"); let _ = "str".ends_with(".ext12"); + // The fixup should preserve the indentation level + { + let _ = "str".ends_with(".ext12"); + } + // The test struct should not trigger the lint failure with .ext12 TestStruct {}.ends_with(".ext12"); diff --git a/tests/ui/case_sensitive_file_extension_comparisons.stderr b/tests/ui/case_sensitive_file_extension_comparisons.stderr index b5c8e4b4fe6..44c8e3fdf74 100644 --- a/tests/ui/case_sensitive_file_extension_comparisons.stderr +++ b/tests/ui/case_sensitive_file_extension_comparisons.stderr @@ -42,7 +42,21 @@ LL ~ .map_or(false, |ext| ext.eq_ignore_ascii_case("ext12")); | error: case-sensitive file extension comparison - --> $DIR/case_sensitive_file_extension_comparisons.rs:26:13 + --> $DIR/case_sensitive_file_extension_comparisons.rs:24:17 + | +LL | let _ = "str".ends_with(".ext12"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider using a case-insensitive comparison instead +help: use std::path::Path + | +LL ~ let _ = std::path::Path::new("str") +LL + .extension() +LL ~ .map_or(false, |ext| ext.eq_ignore_ascii_case("ext12")); + | + +error: case-sensitive file extension comparison + --> $DIR/case_sensitive_file_extension_comparisons.rs:31:13 | LL | let _ = String::new().ends_with(".EXT12"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -56,7 +70,7 @@ LL ~ .map_or(false, |ext| ext.eq_ignore_ascii_case("EXT12")); | error: case-sensitive file extension comparison - --> $DIR/case_sensitive_file_extension_comparisons.rs:27:13 + --> $DIR/case_sensitive_file_extension_comparisons.rs:32:13 | LL | let _ = "str".ends_with(".EXT12"); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -69,5 +83,5 @@ LL + .extension() LL ~ .map_or(false, |ext| ext.eq_ignore_ascii_case("EXT12")); | -error: aborting due to 5 previous errors +error: aborting due to 6 previous errors