early-return earlier, and create suggestion-related things later
This commit is contained in:
Ada Alakbarova 2026-01-12 15:41:02 +01:00
parent 5ef494c536
commit 815407acb4
No known key found for this signature in database
4 changed files with 32 additions and 34 deletions

View file

@ -1,4 +1,4 @@
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::res::MaybeDef;
use clippy_utils::source::snippet_with_context;
use clippy_utils::visitors::is_expr_unsafe;
@ -48,6 +48,15 @@ impl<'tcx> LateLintPass<'tcx> for StrlenOnCStrings {
&& !recv.span.from_expansion()
&& path.ident.name == sym::as_ptr
{
let ty = cx.typeck_results().expr_ty(self_arg).peel_refs();
let method_name = if ty.is_diag_item(cx, sym::cstring_type) {
"as_bytes"
} else if ty.is_lang_item(cx, LangItem::CStr) {
"to_bytes"
} else {
return;
};
let ctxt = expr.span.ctxt();
let span = match cx.tcx.parent_hir_node(expr.hir_id) {
Node::Block(&Block {
@ -58,25 +67,16 @@ impl<'tcx> LateLintPass<'tcx> for StrlenOnCStrings {
_ => expr.span,
};
let ty = cx.typeck_results().expr_ty(self_arg).peel_refs();
let mut app = Applicability::MachineApplicable;
let val_name = snippet_with_context(cx, self_arg.span, ctxt, "..", &mut app).0;
let method_name = if ty.is_diag_item(cx, sym::cstring_type) {
"as_bytes"
} else if ty.is_lang_item(cx, LangItem::CStr) {
"to_bytes"
} else {
return;
};
span_lint_and_sugg(
span_lint_and_then(
cx,
STRLEN_ON_C_STRINGS,
span,
"using `libc::strlen` on a `CString` or `CStr` value",
"try",
format!("{val_name}.{method_name}().len()"),
app,
|diag| {
let mut app = Applicability::MachineApplicable;
let val_name = snippet_with_context(cx, self_arg.span, ctxt, "_", &mut app).0;
diag.span_suggestion(span, "use", format!("{val_name}.{method_name}().len()"), app);
},
);
}
}

View file

@ -1,7 +1,6 @@
#![warn(clippy::strlen_on_c_strings)]
#![allow(dead_code, clippy::manual_c_str_literals)]
#![allow(clippy::manual_c_str_literals)]
#[allow(unused)]
use libc::strlen;
use std::ffi::{CStr, CString};

View file

@ -1,7 +1,6 @@
#![warn(clippy::strlen_on_c_strings)]
#![allow(dead_code, clippy::manual_c_str_literals)]
#![allow(clippy::manual_c_str_literals)]
#[allow(unused)]
use libc::strlen;
use std::ffi::{CStr, CString};

View file

@ -1,47 +1,47 @@
error: using `libc::strlen` on a `CString` or `CStr` value
--> tests/ui/strlen_on_c_strings.rs:11:13
--> tests/ui/strlen_on_c_strings.rs:10:13
|
LL | let _ = unsafe { libc::strlen(cstring.as_ptr()) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `cstring.as_bytes().len()`
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `cstring.as_bytes().len()`
|
= note: `-D clippy::strlen-on-c-strings` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(clippy::strlen_on_c_strings)]`
error: using `libc::strlen` on a `CString` or `CStr` value
--> tests/ui/strlen_on_c_strings.rs:16:13
--> tests/ui/strlen_on_c_strings.rs:15:13
|
LL | let _ = unsafe { libc::strlen(cstr.as_ptr()) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `cstr.to_bytes().len()`
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `cstr.to_bytes().len()`
error: using `libc::strlen` on a `CString` or `CStr` value
--> tests/ui/strlen_on_c_strings.rs:19:13
--> tests/ui/strlen_on_c_strings.rs:18:13
|
LL | let _ = unsafe { strlen(cstr.as_ptr()) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `cstr.to_bytes().len()`
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `cstr.to_bytes().len()`
error: using `libc::strlen` on a `CString` or `CStr` value
--> tests/ui/strlen_on_c_strings.rs:23:22
--> tests/ui/strlen_on_c_strings.rs:22:22
|
LL | let _ = unsafe { strlen((*pcstr).as_ptr()) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(*pcstr).to_bytes().len()`
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `(*pcstr).to_bytes().len()`
error: using `libc::strlen` on a `CString` or `CStr` value
--> tests/ui/strlen_on_c_strings.rs:29:22
--> tests/ui/strlen_on_c_strings.rs:28:22
|
LL | let _ = unsafe { strlen(unsafe_identity(cstr).as_ptr()) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unsafe_identity(cstr).to_bytes().len()`
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `unsafe_identity(cstr).to_bytes().len()`
error: using `libc::strlen` on a `CString` or `CStr` value
--> tests/ui/strlen_on_c_strings.rs:31:13
--> tests/ui/strlen_on_c_strings.rs:30:13
|
LL | let _ = unsafe { strlen(unsafe { unsafe_identity(cstr) }.as_ptr()) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unsafe { unsafe_identity(cstr) }.to_bytes().len()`
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `unsafe { unsafe_identity(cstr) }.to_bytes().len()`
error: using `libc::strlen` on a `CString` or `CStr` value
--> tests/ui/strlen_on_c_strings.rs:35:22
--> tests/ui/strlen_on_c_strings.rs:34:22
|
LL | let _ = unsafe { strlen(f(cstr).as_ptr()) };
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `f(cstr).to_bytes().len()`
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `f(cstr).to_bytes().len()`
error: aborting due to 7 previous errors