needless_pass_by_value: reference the innermost Option content

If types such as `Option<Option<String>>` are not used by value, then
`Option<Option<&String>>` will be suggested, instead of
`Option<&Option<String>>`.
This commit is contained in:
Samuel Tardieu 2025-03-11 20:59:03 +01:00
parent 8f280ff813
commit 35e6057e71
4 changed files with 83 additions and 17 deletions

View file

@ -1,10 +1,10 @@
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::is_self;
use clippy_utils::ptr::get_spans;
use clippy_utils::source::{SpanRangeExt, snippet};
use clippy_utils::ty::{
implements_trait, implements_trait_with_env_from_iter, is_copy, is_type_diagnostic_item, is_type_lang_item,
};
use clippy_utils::{is_self, peel_hir_ty_options};
use rustc_abi::ExternAbi;
use rustc_errors::{Applicability, Diag};
use rustc_hir::intravisit::FnKind;
@ -279,18 +279,13 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue {
}
}
let suggestion = if is_type_diagnostic_item(cx, ty, sym::Option)
&& let snip = snippet(cx, input.span, "_")
&& let Some((first, rest)) = snip.split_once('<')
{
format!("{first}<&{rest}")
} else {
format!("&{}", snippet(cx, input.span, "_"))
};
let inner_input = peel_hir_ty_options(cx, input);
let before_span = input.span.until(inner_input.span);
let after_span = before_span.shrink_to_hi().to(input.span.shrink_to_hi());
diag.span_suggestion(
input.span,
"consider taking a reference instead",
suggestion,
format!("{}&{}", snippet(cx, before_span, "_"), snippet(cx, after_span, "_")),
Applicability::MaybeIncorrect,
);
};