-
Notifications
You must be signed in to change notification settings - Fork 1.7k
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
Add new useless_concat
lint
#13829
Conversation
4918abc
to
b92d91b
Compare
Finally was able to only trigger the lint when appropriate. |
r? clippy |
b92d91b
to
1b635c0
Compare
87b000c
to
8e6092c
Compare
Fixed dogfood. :) |
8e6092c
to
6e39181
Compare
Fixed merge conflicts. If there is nothing else, should we start the FCP? |
There was a problem hiding this 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
clippy_lints/src/useless_concat.rs
Outdated
let literal = match literal { | ||
Some(lit) => { | ||
// Literals can also be number, so we need to check this case too. | ||
if lit.starts_with('"') { |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You cannot have ''
, no?
// `builtin` macros don't seem to be found in `def_path_res`... | ||
if path == ["core", "macros", "builtin", "concat"] { | ||
return true; | ||
} |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
This comment has been minimized.
This comment has been minimized.
6e39181
to
a56792a
Compare
Sorry for the (way too long) delay. Finally applied suggestions. Thanks a lot for them! |
a56792a
to
42f4fd6
Compare
And fixed CI failure. :) |
There was a problem hiding this 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.
9e93fb3
to
6019bfc
Compare
Thanks! Updated and added tests for each case. |
You'll have to rebase when #14784 is merged. |
6019bfc
to
b83678b
Compare
Rebased! |
There was a problem hiding this 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 suggest1_
(underscore should be removed)
b83678b
to
c1e2a7f
Compare
Good catch, thanks! Handled these cases as well. |
There was a problem hiding this 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.
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. |
16049de
to
3a4bfb4
Compare
There was a problem hiding this 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.
3a4bfb4
to
0d25090
Compare
@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. |
There is indeed a problem with obtaining the snippet for the 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 |
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