Skip to content
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

new uninlined_format_args lint to inline explicit arguments #9233

Merged
merged 1 commit into from
Sep 26, 2022

Conversation

nyurik
Copy link
Contributor

@nyurik nyurik commented Jul 24, 2022

Implement #8368 - a new lint to inline format arguments such as print!("{}", var) into print!("{var}").

Supported cases

code suggestion comment
print!("{}", var) print!("{var}") simple variables
print!("{0}", var) print!("{var}") positional variables
print!("{v}", v=var) print!("{var}") named variables
print!("{0} {0}", var) print!("{var} {var}") aliased variables
print!("{0:1$}", var, width) print!("{var:width$}") width support
print!("{0:.1$}", var, prec) print!("{var:.prec$}") precision support
print!("{:.*}", prec, var) print!("{var:.prec$}") asterisk support

Known Problems

  • There may be a false positive if the format string is wrapped in a macro call:
# let var = 42;
macro_rules! no_param_str { () => { "{}" }; }
macro_rules! pass_through { ($expr:expr) => { $expr }; }
println!(no_param_str!(), var);
println!(pass_through!("{}"), var);
  • Format string uses an indexed argument that cannot be inlined.
    Supporting this case requires re-indexing of the format string.
    Until implemented, print!("{0}={1}", var, 1+2) should be changed to print!("{var}={0}", 1+2) by hand.

changelog: [uninlined_format_args]: A new lint to inline format arguments, i.e. print!("{}", var) into print!("{var}")

@rust-highfive
Copy link

Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @xFrednet (or someone else) soon.

Please see the contribution instructions for more information.

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties label Jul 24, 2022
@Alexendoo Alexendoo added S-blocked Status: marked as blocked ❌ on something else such as an RFC or other implementation work and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties labels Jul 24, 2022
Copy link
Member

@Alexendoo Alexendoo left a comment

Choose a reason for hiding this comment

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

👍

I had a look through most of the TODOs. Also worth mentioning you can use let chains rather than if_chain, it plays better with rust_analyzer (though also doesn't get automatically formatted yet)

clippy_lints/src/inline_format_args.rs Outdated Show resolved Hide resolved
clippy_lints/src/inline_format_args.rs Outdated Show resolved Hide resolved
clippy_lints/src/inline_format_args.rs Outdated Show resolved Hide resolved
clippy_lints/src/inline_format_args.rs Outdated Show resolved Hide resolved
@nyurik
Copy link
Contributor Author

nyurik commented Jul 25, 2022

Thanks @Alexendoo for the review! I made a number of changes based on that, but still a few todos. My biggest concern is how to detect if an argument is also used as precision and/or width. I know some format-related work is being done in the rustc, and there seem to be at least 3 devs involved, so I wonder who/how can coordinate these efforts to be consistent and reuse each other's work.

@est31
Copy link
Member

est31 commented Jul 25, 2022

If it's not in your TODOs yet, the lint should be integrated into the MSRV system of clippy and be gated on 1.58.0, as that's when format capturing was added.

@bors
Copy link
Contributor

bors commented Jul 25, 2022

☔ The latest upstream changes (presumably #9243) made this pull request unmergeable. Please resolve the merge conflicts.

@nyurik
Copy link
Contributor Author

nyurik commented Jul 25, 2022

@est31 thx, fixed. I think I am done with this lint -- it now solves the majority of cases, and it avoids expanding width/precision arguments by checking if the argument span contains a $ symbol. Not ideal, but much better than nothing.

@nyurik nyurik marked this pull request as ready for review July 25, 2022 18:33
@Alexendoo Alexendoo linked an issue Jul 25, 2022 that may be closed by this pull request
@xFrednet
Copy link
Member

@Alexendoo Do you want to take over the full review? I believe you know the format macro better than me. If you don't have the time, feel free to give it back. I should have more time for Clippy again 🙃

@Alexendoo
Copy link
Member

Sure! Sounds good to me. I'll take a full look at it once it's unblocked

@xFrednet
Copy link
Member

Awesome, thank you!

r? @Alexendoo

@rust-highfive rust-highfive assigned Alexendoo and unassigned xFrednet Jul 26, 2022
@nyurik
Copy link
Contributor Author

nyurik commented Jul 26, 2022

Thx @Alexendoo ! Is there something i can do to help the #8518 ? Are there any fundamental blocks on that, or is it juts a matter of patiently waiting? :)

@Alexendoo
Copy link
Member

Yeah just a matter of waiting for the large amount of reviewer bandwidth needed

@bors
Copy link
Contributor

bors commented Aug 2, 2022

☔ The latest upstream changes (presumably #9264) made this pull request unmergeable. Please resolve the merge conflicts.

Copy link
Member

@flip1995 flip1995 left a comment

Choose a reason for hiding this comment

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

Thanks for this PR! I learned something about the format macro and what is possible with it.

The impl LGTM overall, but some housekeeping, like documentation, has to be done still.

clippy_lints/src/inline_format_args.rs Outdated Show resolved Hide resolved
clippy_utils/src/macros.rs Outdated Show resolved Hide resolved
tests/ui/inline_format_args.rs Outdated Show resolved Hide resolved
tests/ui/inline_format_args.rs Outdated Show resolved Hide resolved
tests/ui/inline_format_args.rs Outdated Show resolved Hide resolved
tests/ui/inline_format_args.rs Outdated Show resolved Hide resolved
clippy_lints/src/inline_format_args.rs Outdated Show resolved Hide resolved
@nyurik
Copy link
Contributor Author

nyurik commented Aug 19, 2022

@flip1995 thanks for the review! I addressed some of your points, and made a few clarifications. I am still in a bit of a limbo state - waiting for the upstream #8518 conflicts to be resolved, plus now there is #9349 - so I am not certain at which point I should start resolving conflicts and getting it back to the "ready to merge" state again.

@flip1995
Copy link
Member

No worries. Let's get the other PRs merged first. You can work on this as you see fit. But also feel free to just let this PR sit as-is until we resolved the other issues.

@Alexendoo
Copy link
Member

Personally I'm inclined to leave it as a known issue for now. It's not limited to just this lint, any other lint working with string literals may have a problem with this style of proc macro, print_literal is affected at least

I plan to replace expand_past_previous_comma with something more robust, I can probably catch this issue at the same time with that

@nyurik
Copy link
Contributor Author

nyurik commented Sep 24, 2022

@Alexendoo ok, thx, I squashed and cleaned up the PR - should be in a good state now. I also added a few more unit tests that would also fail until your changes.

@nyurik nyurik changed the title new needless-format-args lint to inline explicit arguments new uninlined_format_args lint to inline explicit arguments Sep 24, 2022
clippy_lints/src/format_args.rs Outdated Show resolved Hide resolved
Cargo.toml Outdated Show resolved Hide resolved
clippy_lints/src/format_args.rs Show resolved Hide resolved
Copy link
Member

@Alexendoo Alexendoo left a comment

Choose a reason for hiding this comment

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

Looks good! Just some documentation nits and then it's good for merging

Thank you for the endurance 😄

clippy_lints/src/format_args.rs Outdated Show resolved Hide resolved
clippy_lints/src/format_args.rs Outdated Show resolved Hide resolved
clippy_lints/src/format_args.rs Outdated Show resolved Hide resolved
@Alexendoo
Copy link
Member

Good ol' update_lints :D

Could give it one final squash too

@nyurik
Copy link
Contributor Author

nyurik commented Sep 25, 2022

Bummer, I can't, I'm at a playground))))

@nyurik
Copy link
Contributor Author

nyurik commented Sep 25, 2022

I'll do it in a bit. Thanks for all the help!!!

Implement rust-lang#8368 - a new
lint to inline format arguments such as `print!("{}", var)` into
`print!("{var}")`.

code | suggestion | comment
---|---|---
`print!("{}", var)` | `print!("{var}")` |  simple variables
`print!("{0}", var)` | `print!("{var}")` |  positional variables
`print!("{v}", v=var)` | `print!("{var}")` |  named variables
`print!("{0} {0}", var)` | `print!("{var} {var}")` |  aliased variables
`print!("{0:1$}", var, width)` | `print!("{var:width$}")` |  width
support
`print!("{0:.1$}", var, prec)` | `print!("{var:.prec$}")` |  precision
support
`print!("{:.*}", prec, var)` | `print!("{var:.prec$}")` |  asterisk
support

code | suggestion | comment
---|---|---
`print!("{0}={1}", var, 1+2)` | `print!("{var}={0}", 1+2)` | Format
string uses an indexed argument that cannot be inlined.  Supporting this
case requires re-indexing of the format string.

changelog: [`uninlined_format_args`]: A new lint to inline format
arguments, i.e. `print!("{}", var)` into `print!("{var}")`
@nyurik
Copy link
Contributor Author

nyurik commented Sep 26, 2022

@Alexendoo ok, I think it's finally ready 😀

@Alexendoo
Copy link
Member

Awesome, thanks @nyurik!

@bors r+

@bors
Copy link
Contributor

bors commented Sep 26, 2022

📌 Commit 5a71bbd has been approved by Alexendoo

It is now in the queue for this repository.

@bors
Copy link
Contributor

bors commented Sep 26, 2022

⌛ Testing commit 5a71bbd with merge cf93865...

@bors
Copy link
Contributor

bors commented Sep 26, 2022

☀️ Test successful - checks-action_dev_test, checks-action_remark_test, checks-action_test
Approved by: Alexendoo
Pushing cf93865 to master...

@bors bors merged commit cf93865 into rust-lang:master Sep 26, 2022
@nyurik nyurik deleted the capture-vars branch September 26, 2022 11:09
bors added a commit that referenced this pull request Oct 4, 2022
fallout: fix tests to allow uninlined_format_args

In order to switch `clippy::uninlined_format_args` from pedantic to style, all existing tests must not raise a warning. I did not want to change the actual tests, so this is a relatively minor change that:

* add `#![allow(clippy::uninlined_format_args)]` where needed
* normalizes all allow/deny/warn attributes
   * all allow attributes are grouped together
   * sorted alphabetically
   * the `clippy::*` attributes are listed separate from the other ones.
   * deny and warn attributes are listed before the allowed ones

See also #9233, #9525, #9527

cc: `@llogiq` `@Alexendoo`

changelog: none
bors added a commit that referenced this pull request Oct 13, 2022
Change uninlined_format_args into a style lint

As [previously discussed](#9233 (comment)), the `uninlined_format_args` should probably be a part of the default style because `println!("{}", foo)` is not as concise or easy to understand as `println!("{foo}")`

changelog: [`uninlined_format_args`]: change to be the default `style`
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.

New lint: suggest using "implicit named arguments"
7 participants