Skip to content

Add new useless_concat lint #13829

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
May 19, 2025

Conversation

GuillaumeGomez
Copy link
Member

Fixes #13793.

Interestingly enough, to actually check that the macro call has at least two arguments, we need to use the rust lexer after getting the original source code snippet.

changelog: Add new useless_concat lint

@rustbot
Copy link
Collaborator

rustbot commented Dec 14, 2024

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

@rustbot rustbot added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties label Dec 14, 2024
@GuillaumeGomez GuillaumeGomez force-pushed the useless-concat branch 2 times, most recently from 4918abc to b92d91b Compare December 15, 2024 20:51
@GuillaumeGomez
Copy link
Member Author

Finally was able to only trigger the lint when appropriate.

@GuillaumeGomez
Copy link
Member Author

r? clippy

@rustbot rustbot assigned y21 and unassigned dswij Dec 25, 2024
@GuillaumeGomez
Copy link
Member Author

Fixed dogfood. :)

github-merge-queue bot pushed a commit that referenced this pull request Dec 30, 2024
I discovered that there were paths declared in `clippy_utils::paths` in
#13829 so moving a few
remaining hardcoded ones in one place.

changelog: Move more def paths into `clippy_utils::paths`

r? @y21
@GuillaumeGomez
Copy link
Member Author

Fixed merge conflicts. If there is nothing else, should we start the FCP?

Copy link
Member

@y21 y21 left a comment

Choose a reason for hiding this comment

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

I have a few more comments, but I'm going to open the FCP already because they shouldn't require major changes

let literal = match literal {
Some(lit) => {
// Literals can also be number, so we need to check this case too.
if lit.starts_with('"') {
Copy link
Member

Choose a reason for hiding this comment

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

This also needs to handle r"" strings and character literals

Copy link
Member Author

Choose a reason for hiding this comment

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

You cannot have '', no?

Comment on lines 64 to 67
// `builtin` macros don't seem to be found in `def_path_res`...
if path == ["core", "macros", "builtin", "concat"] {
return true;
}
Copy link
Member

Choose a reason for hiding this comment

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

I'm guessing this probably happens because it's a macro_rules! macro and gets resolved at core::concat by def_path_res. Anyway, usually we put #[expect(clippy::invalid_paths)] on the const in paths.rs instead of hardcoding it in the source here though. Can you do that instead?

Copy link
Member Author

Choose a reason for hiding this comment

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

👍

@y21
Copy link
Member

y21 commented Feb 12, 2025

@y21 y21 added S-final-comment-period Status: final comment period it will be merged unless new objections are raised (~1 week) and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties labels Feb 12, 2025
@y21 y21 added S-waiting-on-author Status: This is awaiting some action from the author. (Use `@rustbot ready` to update this status) and removed S-final-comment-period Status: final comment period it will be merged unless new objections are raised (~1 week) labels Feb 22, 2025
@rustbot

This comment has been minimized.

@GuillaumeGomez
Copy link
Member Author

Sorry for the (way too long) delay. Finally applied suggestions. Thanks a lot for them!

@GuillaumeGomez
Copy link
Member Author

And fixed CI failure. :)

Copy link
Contributor

@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 won't work properly with suffixed numeric literals: concat!(1f32) should be replaced by "1" as the builtin macro ignores the suffix, not by "1f32". However, the whole part before the suffix must be kept: concat!(1.000f32) must expand into "1.000".

Also, concat!('c') should be replaced by "c", not "'c'".

It also looks like concat!(true) and concat!(false) are not handled while they could.

Reference in the compiler

@GuillaumeGomez
Copy link
Member Author

Thanks! Updated and added tests for each case.

@samueltardieu
Copy link
Contributor

You'll have to rebase when #14784 is merged.

@GuillaumeGomez
Copy link
Member Author

Rebased!

Copy link
Contributor

@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.

This will fail in at least those two situations:

  • concat!('"') will suggest """ (escaping is missing)
  • concat!(1_f32) will suggest 1_ (underscore should be removed)

@GuillaumeGomez
Copy link
Member Author

Good catch, thanks! Handled these cases as well.

Copy link
Contributor

@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.

Yet another round of non-conforming substitution:

  • concat!(1__f32) suggests "1_" instead of the expected "1" (yes, you can use as many underscores as you like as part of the input)
  • concat!(0xf_f32) suggests "0xf" instead of "65530"
  • concat!(1_2) suggests "1_2" instead of "12"
  • concat!(1___2.00__100___f32) suggests "1___2.00__100__" instead of "12.00100"
  • As we're at it, concat!('\'') could suggest "'" instead of "'" (no need for escaping anymore)

Isn't there a way to invoke the compiler macro programmatically on the token stream once you've determined that there is only one argument? That would cover all those cases, and maybe even more, and simplify the code a lot.

@GuillaumeGomez
Copy link
Member Author

That would be much better indeed... Let's ask today at the conference if someone has an idea. =D

@samueltardieu
Copy link
Contributor

samueltardieu commented May 13, 2025

That would be much better indeed... Let's ask today at the conference if someone has an idea. =D

Now that I think about it… isn't the result of the expansion right under our noses in the HIR, even being the trigger for this lint? Checking the arguments, then issuing the string with proper escaping should be enough. WDYT? No need for replicating the macro call, it has been done by the compiler already.

@GuillaumeGomez GuillaumeGomez force-pushed the useless-concat branch 2 times, most recently from 16049de to 3a4bfb4 Compare May 14, 2025 16:50
Copy link
Contributor

@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.

Other that the version and the reformatting, fine with me! You should also fix dogfood for the unlined format arg.

@samueltardieu
Copy link
Contributor

@rustbot label S-blocked

I'd like to check something before it gets merged, it looks like I can trigger an ICE when I merge this with my snippet diagnostics patch, I'll remove the block ASAP.

@rustbot rustbot added the S-blocked Status: marked as blocked ❌ on something else such as an RFC or other implementation work label May 19, 2025
@samueltardieu
Copy link
Contributor

There is indeed a problem with obtaining the snippet for the declare_tool_lint!() macro source, but this PR handles this properly. I'll investigate the other problem separately. Thanks!

I'll merge it since I approved the FCP a long time ago, and since did many reviews of this code back and forth.

@rustbot review
r? @samueltardieu

@rustbot rustbot assigned samueltardieu and unassigned y21 May 19, 2025
@samueltardieu samueltardieu removed the S-blocked Status: marked as blocked ❌ on something else such as an RFC or other implementation work label May 19, 2025
@samueltardieu samueltardieu added this pull request to the merge queue May 19, 2025
Merged via the queue into rust-lang:master with commit ebc2a68 May 19, 2025
11 checks passed
@GuillaumeGomez GuillaumeGomez deleted the useless-concat branch May 19, 2025 15:28
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.

Add useless_concat
5 participants