Skip to content

Conversation

@Tigls
Copy link

@Tigls Tigls commented Jan 1, 2026

Closes #16308

changelog: [strlen_on_c_strings]: changes suggestion to use CStr::count_bytes()

@rustbot rustbot added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties label Jan 1, 2026
@rustbot
Copy link
Collaborator

rustbot commented Jan 1, 2026

r? @dswij

rustbot has assigned @dswij.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

@dswij
Copy link
Member

dswij commented Jan 1, 2026

@Tigls CI is failing on fmt check

@dswij dswij added S-waiting-on-author Status: This is awaiting some action from the author. (Use `@rustbot ready` to update this status) and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties labels Jan 1, 2026
Copy link
Member

@samueltardieu samueltardieu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please add tests below/at the considered MSRV, and inside/outside const contexts?

View changes since this review

&& let ExprKind::MethodCall(path, self_arg, [], _) = recv.kind
&& !recv.span.from_expansion()
&& path.ident.name == sym::as_ptr
&& self.msrv.meets(cx, msrvs::CONST_BLOCKS)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the link between .count_bytes() and CONST_BLOCKS?

Also:

  • If the MSRV isn't met, the previous suggestion should still apply.
  • Different MSRV apply in and outside a const context.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, I didn't know I can add new names to MSRV enum, thought they are kind of fixed code names for versions.

But makes sense, all fixed now.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't forget to add tests for all combinations of MSRV/const contexts. You can look at how it's done in other tests by looking for the #[clippy::msrv] attribute.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like I can't call the libc::strlen in the const context. Since it is an FFI function, which is linked at runtime, it just won't compile. Does it mean I can safely remove the msrv branch for const context and keep only the branch for non-const contex, since the user won't be able to compile it anyway?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@samueltardieu let me know if you had time to have a look and close this

@rustbot
Copy link
Collaborator

rustbot commented Jan 1, 2026

Reminder, once the PR becomes ready for a review, use @rustbot ready.

@Tigls
Copy link
Author

Tigls commented Jan 5, 2026

@rustbot ready

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties and removed S-waiting-on-author Status: This is awaiting some action from the author. (Use `@rustbot ready` to update this status) labels Jan 5, 2026

declare_lint_pass!(StrlenOnCStrings => [STRLEN_ON_C_STRINGS]);
pub struct StrlenOnCStrings<'a> {
msrv: &'a Msrv,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Msrv is Copy, so it should be fine to store it by value

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

Comment on lines 85 to 102
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;
};
span_lint_and_sugg(
cx,
STRLEN_ON_C_STRINGS,
span,
"using `libc::strlen` on a `CString` or `CStr` value",
"try",
format!("{val_name}.{method_name}().len()"),
app,
);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code in the two branches is very similar. Imo it would be better to use span_lint_and_then and put the MSRV-dependent logic inside its closure.

@rustbot

This comment has been minimized.

@samueltardieu
Copy link
Member

@Tigls Your changes should be very easily adaptable to those merged in #16391. Once it's done, I'll review them (+ the msrv change).

r? samueltardieu

@rustbot
Copy link
Collaborator

rustbot commented Jan 13, 2026

This PR was rebased onto a different master commit. Here's a range-diff highlighting what actually changed.

Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers.

@rustbot

This comment has been minimized.

@rustbot rustbot added has-merge-commits PR has merge commits, merge with caution. S-waiting-on-author Status: This is awaiting some action from the author. (Use `@rustbot ready` to update this status) labels Jan 13, 2026
@rustbot rustbot removed S-waiting-on-author Status: This is awaiting some action from the author. (Use `@rustbot ready` to update this status) has-merge-commits PR has merge commits, merge with caution. labels Jan 13, 2026
Copy link
Member

@samueltardieu samueltardieu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's looking good. Could you please squash all the commits together?

View changes since this review

@rustbot rustbot added S-waiting-on-author Status: This is awaiting some action from the author. (Use `@rustbot ready` to update this status) and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties labels Jan 13, 2026
@Tigls
Copy link
Author

Tigls commented Jan 14, 2026

@rustbot ready

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties and removed S-waiting-on-author Status: This is awaiting some action from the author. (Use `@rustbot ready` to update this status) labels Jan 14, 2026
Copy link
Contributor

@ada4a ada4a left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@samueltardieu should we include this last change in this PR? If so, @Tigls, feel free to amend it into your last commit

View changes since this review

Comment on lines +96 to +104
let suggestion = if self.msrv.meets(cx, msrvs::CSTR_COUNT_BYTES) {
format!("{val_name}.count_bytes()")
} else if ty.is_diag_item(cx, sym::cstring_type) {
format!("{val_name}.as_bytes().len()")
} else if ty.is_lang_item(cx, LangItem::CStr) {
format!("{val_name}.to_bytes().len()")
} else {
return;
};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In #16391, it was decided that we should lint types that dereference to CStr as well, and just recommend to_bytes() to avoid complications with CString in particular (see #16391 (comment) for more context). Therefore it should be safe to simplify this to:

Suggested change
let suggestion = if self.msrv.meets(cx, msrvs::CSTR_COUNT_BYTES) {
format!("{val_name}.count_bytes()")
} else if ty.is_diag_item(cx, sym::cstring_type) {
format!("{val_name}.as_bytes().len()")
} else if ty.is_lang_item(cx, LangItem::CStr) {
format!("{val_name}.to_bytes().len()")
} else {
return;
};
let suggestion = if self.msrv.meets(cx, msrvs::CSTR_COUNT_BYTES) {
format!("{val_name}.count_bytes()")
} else {
format!("{val_name}.to_bytes().len()")
};

/// ### What it does
/// Checks for usage of `libc::strlen` on a `CString` or `CStr` value,
/// and suggest calling `as_bytes().len()` or `to_bytes().len()` respectively instead.
/// and suggest calling `count_bytes()`instead.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

small typo:

Suggested change
/// and suggest calling `count_bytes()`instead.
/// and suggest calling `count_bytes()` instead.

@samueltardieu
Copy link
Member

@samueltardieu should we include this last change in this PR? If so, @Tigls, feel free to amend it into your last commit

View changes since this review

Yes, that would be better indeed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

S-waiting-on-review Status: Awaiting review from the assignee but also interested parties

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Suggest Cstr::count_bytes in strlen_on_c_strings

5 participants