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

Add new lint [positional_named_format_parameters] #9040

Merged
merged 1 commit into from
Aug 16, 2022
Merged

Add new lint [positional_named_format_parameters] #9040

merged 1 commit into from
Aug 16, 2022

Conversation

miam-miam
Copy link
Contributor

@miam-miam miam-miam commented Jun 23, 2022

Please write a short comment explaining your change (or "none" for internal only changes)

changelog: Add new lint [positional_named_format_parameters] to warn when named parameters in format strings are used as positional arguments.

@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 @dswij (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 Jun 23, 2022
@dswij
Copy link
Member

dswij commented Jul 15, 2022

Thanks for the PR and welcome!

Sorry, haven't had the time to take a look at this. I will get to it asap this week when I have the time

Copy link
Member

@dswij dswij 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 the patience! The changes in the PR look great to me and is certainly a nice addition! Just some comments

clippy_lints/src/write.rs Outdated Show resolved Hide resolved
clippy_lints/src/write.rs Outdated Show resolved Hide resolved
clippy_lints/src/write.rs Outdated Show resolved Hide resolved
tests/ui/unused_named_parameter.rs Outdated Show resolved Hide resolved
@miam-miam
Copy link
Contributor Author

Hmmm it looks like the exact same lint was added directly to rustc for release 1.64.0 (rust-lang/rust#98580). What were the chances of that?

@miam-miam miam-miam closed this Jul 18, 2022
@estebank
Copy link
Contributor

@miam-miam100 it might still be worth it to have a clippy lint against named params ever being referred to positionally, which would be noisier/stricter than what this PR and rustc do. That way rustc avoids false positives but there's still a mechanism to detect "iffy" cases.

@miam-miam
Copy link
Contributor Author

Hmmm so if I've understood correctly we should have a lint that prevents you from writing this?

println!("hello {world} {}", world = "world");

@estebank
Copy link
Contributor

Exactly.

@miam-miam miam-miam reopened this Jul 18, 2022
@miam-miam miam-miam changed the title Add new lint [unused_named_parameter] Add new lint [positional_named_format_parameters] Jul 18, 2022
@miam-miam
Copy link
Contributor Author

miam-miam commented Jul 21, 2022

I don't know what rustc version clippy is using but it looks like my two errors are due to these two PRs not being merged in yet: rust-lang/rust#99263 and rust-lang/rust#99480. @dswij Do you know what I can do? Do I just have to wait?

@dswij
Copy link
Member

dswij commented Jul 22, 2022

I believe clippy uses the toolchain version defined here: https://github.com/rust-lang/rust-clippy/blob/master/rust-toolchain.

The job failed when trying to apply the fix for the lint 😕.
Did this pass on your local machine?

@miam-miam
Copy link
Contributor Author

The changes do not currently pass on my local machine as the toolchain version clippy uses does not include the changes I need for the lint to work correctly. However you are correct in saying that the rust fix file was incorrectly written and has now been fixed.

@dswij
Copy link
Member

dswij commented Jul 22, 2022

That makes sense. We can wait for the weekly sync then. The next scheduled one is pretty soon (by the next 24 hours). We can come back and rebase the PR afterward.

@nyurik
Copy link
Contributor

nyurik commented Jul 24, 2022

I have been hacking on a var inlining lint available since 1.58 - it is based on another possibly conflicting pr #9233

I could really use the code 1)to check if an argument is an alias to another argument or width or precision, 2) get the spans of all three possible usages so I can inline vars and 3) possibly share the same code between rustc and clippy (keep all buggy parsing code in one place 😀). I have written some test cases you might want to use, eg with some unexpected whitespaces.

Awesome to see so much format-related work!

@miam-miam
Copy link
Contributor Author

That's awesome, that does not sound all too easy so I wish you the best of luck on that! I added the test cases to my code which look like they should all pass once we update the nightly version.

@miam-miam
Copy link
Contributor Author

Nice! Successfully rebased, @dswij feel free to review me whenever you are free.

Copy link
Contributor

@nyurik nyurik left a comment

Choose a reason for hiding this comment

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

@miam-miam100 I made a tiny suggestion, but the bigger question is how this PR should be merged with the @Alexendoo 's #8518 -- it seems both make a number of significant changes to the clippy_lints/src/write.rs, nearly rewriting it. Would it make sense to perhaps base your PR on top of @Alexendoo 's, so that all of them use late context?

clippy_lints/src/write.rs Outdated Show resolved Hide resolved
@miam-miam
Copy link
Contributor Author

Hmmm I'm not sure that is a great idea since we don't know when that PR will land and this PR does not really benefit from the late pass in any way.

@nyurik
Copy link
Contributor

nyurik commented Jul 28, 2022

@miam-miam100 my interest is getting the #9233 in, which I was basing on #8518. I am not yet certain I need to base my lint on #8518, or if I can do it all with the early context. Perhaps your PR could be refactored a bit so that we can have shared functions to parse params and get back the spans? My main requirement:

  • detect format!(...) - the string and all arguments
  • find spans for each part of the parameter: {<arg>:<width>$.<precision>} --> struct FormatStrArg { arg: Span, widthArg: Optional<Span>, precisionArg: Optional<Span> } (note that the arg span could be empty, but must be present, whereas width/precision cannot be empty, but could be None)
  • for each arg and non-missing width/precision in FormatStrArg, find corresponding argument that can be analyzed checked if it is it a local var / a fn parameter, or is it something else.

Do you think your functions could produce this result? If so, I could base my work on top of your PR that doesn't try to change the overall structure of the format code. Thx!

@miam-miam
Copy link
Contributor Author

miam-miam commented Jul 28, 2022

Ah well fortunately for you, all those things are directly exposed by rustc.

All the arg, width and precision spans are given, as you can see here (https://github.com/miam-miam100/rust-clippy/blob/631525a21fa3b4bd0c495da11c3b1c0eec84c5ff/clippy_lints/src/write.rs#L543).

As for checking if the corresponding argument is a local var (checking if it is an ident) you can do that here https://github.com/miam-miam100/rust-clippy/blob/631525a21fa3b4bd0c495da11c3b1c0eec84c5ff/clippy_lints/src/write.rs#L667.

From what you've told me you should just be able to check that there and get the whole lint working without any extra work.

@Alexendoo
Copy link
Member

To explain the situation a bit, write.rs currently uses a pre-expansion pass, a variant of an early pass that runs before macro expansion has happened

/// Register all pre expansion lints
///
/// Pre-expansion lints run before any macro expansion has happened.
///
/// Note that due to the architecture of the compiler, currently `cfg_attr` attributes on crate
/// level (i.e `#![cfg_attr(...)]`) will still be expanded even when using a pre-expansion pass.
///
/// Used in `./src/driver.rs`.
pub fn register_pre_expansion_lints(store: &mut rustc_lint::LintStore, sess: &Session, conf: &Conf) {
// NOTE: Do not add any more pre-expansion passes. These should be removed eventually.

The plan is to move away from the pre-expansion pass as it has a few issues, as an example for this lint:

// lib.rs
#![allow(clippy::positional_named_format_parameters)]

mod foo;
fn x() {
    // this would still trigger the lint, ignoring the crate wide allow
    println!("hello {world} {}", world = "world");
}

Since it would be pretty unlikely someone will want to allow this lint, I'm fine with it being added to write.rs in the meanwhile. As you say the rewrite may take a while to be merged as it's a rather large change

For #9233 I could see people wanting to allow it crate wide however, either due to personal taste or to avoid churn. For that reason I think it should stick to a late pass. Some time in the next few days I'll see if it's feasible to split off the clippy_utils::macro changes into their own PR so you don't have to wait for the whole thing @nyurik, as well as adding the missing details you need

@nyurik
Copy link
Contributor

nyurik commented Jul 29, 2022

@Alexendoo thank you for the detailed answer! What are you thoughts about integrating the new rustc format string parsing capabilities like rustc_parse_format::Parser, i.e. as used in here?

Copy link
Member

@dswij dswij left a comment

Choose a reason for hiding this comment

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

The lint itself looks great, just the lint description that can be improved, IMO.

Can you help squash the commits, and after that, I think it's good to merge.

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

@nyurik Yeah, just waiting for the next sync that includes rust-lang/rust#99987, I'll ping you in the PR once it's ready

@miam-miam
Copy link
Contributor Author

Right that's great thanks, I'm currently on holiday so I'll do that when I get back. (a week's time)

@miam-miam
Copy link
Contributor Author

@dswij All squashed!

@dswij
Copy link
Member

dswij commented Aug 16, 2022

Huge thanks for this @miam-miam100! This is a nice lint to have for sure.

@bors r+

@bors
Copy link
Contributor

bors commented Aug 16, 2022

📌 Commit 9ffddf5 has been approved by dswij

It is now in the queue for this repository.

@bors
Copy link
Contributor

bors commented Aug 16, 2022

⌛ Testing commit 9ffddf5 with merge 86ac6e8...

@bors
Copy link
Contributor

bors commented Aug 16, 2022

☀️ Test successful - checks-action_dev_test, checks-action_remark_test, checks-action_test
Approved by: dswij
Pushing 86ac6e8 to master...

@bors bors merged commit 86ac6e8 into rust-lang:master Aug 16, 2022
@bors bors mentioned this pull request Aug 16, 2022
bors added a commit that referenced this pull request Aug 19, 2022
Refactor `FormatArgsExpn`

It now for each format argument `{..}` has:
- The `Expr` it points to, and how it does so (named/named inline/numbered/implicit)
- The parsed `FormatSpec` (format trait/fill/align/etc., the precision/width and any value they point to)
- Many spans

The caller no longer needs to pair up arguments to their value, or separately interpret the `specs` `Expr`s when it isn't `None`

The gist is that it combines the result of [`rustc_parse_format::Parser`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_parse_format/struct.Parser.html) with the macro expansion itself

This unfortunately makes the code a bit longer, however we need to use both as neither have all the information we're after. `rustc_parse_format` doesn't have the information to resolve named arguments to their values. The macro expansion doesn't contain whether the positions are implicit/numbered/named, or the spans for format arguments

Wanted by #9233 and #8518 to be able to port the changes from #9040

Also fixes #8643, previously the format args seem to have been paired up with the wrong values somehow

changelog: [`format_in_format_args`]: Fix false positive due to misattributed arguments

r? `@flip1995`
cc `@nyurik`
@xFrednet xFrednet mentioned this pull request Nov 1, 2022
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.

7 participants