improve diagnostics

This commit is contained in:
Ada Alakbarova 2025-10-21 15:43:17 +02:00
parent c5215b6d84
commit cb33ccd3fe
No known key found for this signature in database
2 changed files with 83 additions and 28 deletions

View file

@ -1,7 +1,8 @@
use clippy_config::Conf;
use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg};
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::msrvs::Msrv;
use clippy_utils::res::{MaybeDef, MaybeQPath, MaybeResPath};
use clippy_utils::source::snippet_with_context;
use clippy_utils::{is_none_pattern, msrvs, peel_hir_expr_refs, sym};
use rustc_errors::Applicability;
use rustc_hir::def::{DefKind, Res};
@ -133,19 +134,22 @@ fn check_as_ref(cx: &LateContext<'_>, expr: &Expr<'_>, span: Span, msrv: Msrv) {
},
)
{
if let Some(snippet) = clippy_utils::source::snippet_opt(cx, callee.span) {
span_lint_and_sugg(
cx,
MANUAL_OPTION_AS_SLICE,
span,
"use `Option::as_slice`",
"use",
format!("{snippet}.as_slice()"),
Applicability::MachineApplicable,
);
} else {
span_lint(cx, MANUAL_OPTION_AS_SLICE, span, "use `Option_as_slice`");
}
span_lint_and_then(
cx,
MANUAL_OPTION_AS_SLICE,
span,
"manual implementation of `Option::as_slice`",
|diag| {
let mut app = Applicability::MachineApplicable;
let callee = snippet_with_context(cx, callee.span, expr.span.ctxt(), "_", &mut app).0;
diag.span_suggestion_verbose(
span,
"use `Option::as_slice` directly",
format!("{callee}.as_slice()"),
app,
);
},
);
}
}

View file

@ -1,4 +1,4 @@
error: use `Option::as_slice`
error: manual implementation of `Option::as_slice`
--> tests/ui/manual_option_as_slice.rs:5:9
|
LL | _ = match x.as_ref() {
@ -7,12 +7,21 @@ LL | |
LL | | Some(f) => std::slice::from_ref(f),
LL | | None => &[],
LL | | };
| |_____^ help: use: `x.as_slice()`
| |_____^
|
= note: `-D clippy::manual-option-as-slice` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(clippy::manual_option_as_slice)]`
help: use `Option::as_slice` directly
|
LL - _ = match x.as_ref() {
LL -
LL - Some(f) => std::slice::from_ref(f),
LL - None => &[],
LL - };
LL + _ = x.as_slice();
|
error: use `Option::as_slice`
error: manual implementation of `Option::as_slice`
--> tests/ui/manual_option_as_slice.rs:11:9
|
LL | _ = if let Some(f) = x.as_ref() {
@ -23,37 +32,79 @@ LL | | std::slice::from_ref(f)
LL | | } else {
LL | | &[]
LL | | };
| |_____^ help: use: `x.as_slice()`
| |_____^
|
help: use `Option::as_slice` directly
|
LL - _ = if let Some(f) = x.as_ref() {
LL -
LL -
LL - std::slice::from_ref(f)
LL - } else {
LL - &[]
LL - };
LL + _ = x.as_slice();
|
error: use `Option::as_slice`
error: manual implementation of `Option::as_slice`
--> tests/ui/manual_option_as_slice.rs:19:9
|
LL | _ = x.as_ref().map_or(&[][..], std::slice::from_ref);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `x.as_slice()`
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: use `Option::as_slice` directly
|
LL - _ = x.as_ref().map_or(&[][..], std::slice::from_ref);
LL + _ = x.as_slice();
|
error: use `Option::as_slice`
error: manual implementation of `Option::as_slice`
--> tests/ui/manual_option_as_slice.rs:22:9
|
LL | _ = x.as_ref().map_or_else(Default::default, std::slice::from_ref);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `x.as_slice()`
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: use `Option::as_slice` directly
|
LL - _ = x.as_ref().map_or_else(Default::default, std::slice::from_ref);
LL + _ = x.as_slice();
|
error: use `Option::as_slice`
error: manual implementation of `Option::as_slice`
--> tests/ui/manual_option_as_slice.rs:25:9
|
LL | _ = x.as_ref().map(std::slice::from_ref).unwrap_or_default();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `x.as_slice()`
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: use `Option::as_slice` directly
|
LL - _ = x.as_ref().map(std::slice::from_ref).unwrap_or_default();
LL + _ = x.as_slice();
|
error: use `Option::as_slice`
error: manual implementation of `Option::as_slice`
--> tests/ui/manual_option_as_slice.rs:28:9
|
LL | _ = x.as_ref().map_or_else(|| &[42][..0], std::slice::from_ref);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `x.as_slice()`
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: use `Option::as_slice` directly
|
LL - _ = x.as_ref().map_or_else(|| &[42][..0], std::slice::from_ref);
LL + _ = x.as_slice();
|
error: use `Option::as_slice`
error: manual implementation of `Option::as_slice`
--> tests/ui/manual_option_as_slice.rs:33:13
|
LL | _ = x.as_ref().map_or_else(<&[_]>::default, from_ref);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `x.as_slice()`
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: use `Option::as_slice` directly
|
LL - _ = x.as_ref().map_or_else(<&[_]>::default, from_ref);
LL + _ = x.as_slice();
|
error: aborting due to 7 previous errors