Skip to content

Conversation

@Artur-Sulej
Copy link

@Artur-Sulej Artur-Sulej commented Jul 6, 2025

changelog: [decimal_bit_mask]: add a new lint that detects the use of decimal literals as bit masks in bitwise operations. Using decimal literals for bit masks can obscure the intended bit pattern and reduce code readability. This lint encourages the use of binary (0b...) or hexadecimal (0x...) notation to make bit patterns explicit and easier to understand at a glance.

Addresses issue: #1775


Example:

let masked = x & 15; // Bad: decimal literal as bit mask
let masked = x & 0b1111; // Good: bit pattern is explicit

Summary Notes

Managed by @rustbot—see help for details

@github-actions
Copy link

github-actions bot commented Jul 6, 2025

Lintcheck changes for 12ab9f6

Lint Added Removed Changed
clippy::decimal_bit_mask 238 0 0

This comment will be updated if you push new changes

@rustbot rustbot added S-blocked Status: marked as blocked ❌ on something else such as an RFC or other implementation work A-lint Area: New lints labels Jul 6, 2025
@Artur-Sulej
Copy link
Author

Although I annotated my test with //~ decimal_bit_mask, Clippy still reports the lint as an unmatched diagnostic and the test fails.
Any idea what I might be missing?

@Artur-Sulej Artur-Sulej marked this pull request as ready for review September 3, 2025 20:27
@rustbot
Copy link
Collaborator

rustbot commented Sep 3, 2025

r? @llogiq

rustbot has assigned @llogiq.
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

@rustbot rustbot added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties label Sep 3, 2025
@rustbot

This comment has been minimized.

@rustbot
Copy link
Collaborator

rustbot commented Sep 15, 2025

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.

@samueltardieu samueltardieu added S-waiting-on-author Status: This is awaiting some action from the author. (Use `@rustbot ready` to update this status) and removed S-blocked Status: marked as blocked ❌ on something else such as an RFC or other implementation work S-waiting-on-review Status: Awaiting review from the assignee but also interested parties labels Sep 17, 2025
99 | 0b1010; //~ decimal_bit_mask
99 ^ 0b1010; //~ decimal_bit_mask
0xD | 99; //~ decimal_bit_mask
88 & 99; //~ decimal_bit_mask
Copy link
Contributor

Choose a reason for hiding this comment

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

Although I annotated my test with //~ decimal_bit_mask, Clippy still reports the lint as an unmatched diagnostic and the test fails.
Any idea what I might be missing?

That's because in this case, you're firing the lint twice, once for each operand, so you'll need to add a second error mark. That's the easiest to do by bringing them to under the linted expression:

Suggested change
88 & 99; //~ decimal_bit_mask
88 & 99;
//~^ decimal_bit_mask
//~| decimal_bit_mask
  • ^ means the lint should happen on the line above the comment
  • | "attaches" the error mark to another one on a neighbouring line (in this case the //~^ decimal_bit_mask directly above), and will expect a lint at the same location (in this case, the line containing 88 & 99;)

Comment on lines +39 to +49
Expr {
kind: kind1,
span: span1,
..
},
Expr {
kind: kind2,
span: span2,
..
},
) = &e.kind
Copy link
Contributor

Choose a reason for hiding this comment

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

It would be a bit more concise to have these simply as left and right, and then use left.span, right.kind etc. throughout the code

span_lint(
cx,
DECIMAL_BIT_MASK,
e.span,
Copy link
Contributor

Choose a reason for hiding this comment

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

You can improve the output by pointing the lint at the exact operand that is decimal -- for example, here you would use span1 (or left.span, as per previous comment)

cx,
DECIMAL_BIT_MASK,
e.span,
"Using decimal literal for bit mask. Consider using binary (0b...) or hexadecimal (0x...) notation for better readability.",
Copy link
Contributor

Choose a reason for hiding this comment

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

The second sentence should be emitted separately, as a help message -- see https://doc.rust-lang.org/clippy/development/emitting_lints.html#emitting-a-lint-1 for more info.

Try using span_lint_and_help here

Comment on lines +65 to +67
&& let Some(snippet) = snippet_opt(cx, *span2)
&& !snippet.starts_with("0b")
&& !snippet.starts_with("0x")
Copy link
Contributor

Choose a reason for hiding this comment

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

You can use SpanRangeExt::get_source_code here to avoid allocating a String (which is what snippet_opt does)

                && let Some(snippet) = span2.get_source_text(cx)

In fact, since you're only using the snippet to check its contents, you can get away with SpanRangeExt::check_source_code:

Suggested change
&& let Some(snippet) = snippet_opt(cx, *span2)
&& !snippet.starts_with("0b")
&& !snippet.starts_with("0x")
&& span2.check_source_text(cx, |src| !src.starts_with("0b") && !src.starts_with("0x"))

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

Labels

A-lint Area: New lints needs-fcp S-waiting-on-author Status: This is awaiting some action from the author. (Use `@rustbot ready` to update this status)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants