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

Named format arguments can be used as positional #93415

Closed
CAD97 opened this issue Jan 28, 2022 · 16 comments
Closed

Named format arguments can be used as positional #93415

CAD97 opened this issue Jan 28, 2022 · 16 comments
Labels
A-edition-2024 Area: The 2024 edition A-fmt Area: `std::fmt` A-lints Area: Lints (warnings about flaws in source code) such as unused_mut. C-future-incompatibility Category: Future-incompatibility lints disposition-close This PR / issue is in PFCP or FCP with a disposition to close it. finished-final-comment-period The final comment period is finished for this PR / Issue. I-needs-decision Issue: In need of a decision. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.

Comments

@CAD97
Copy link
Contributor

CAD97 commented Jan 28, 2022

I tried this code:

fn main() {
    let what = "what?";
    println!("{a}{}", a=what);
}

I expected to see this happen:

error: 1 positional argument in format string, but no arguments were given
 --> <source>:3:18
  |
3 |     println!("{a}{}", a=what);
  |                  ^^

Instead, this happened: explanation

Standard Error

   Compiling playground v0.0.1 (/playground)
    Finished dev [unoptimized + debuginfo] target(s) in 1.94s
     Running `target/debug/playground`

Standard Output

what?what?

Meta

This happens on current 1.60.0-nightly (2022-01-27 21b4a9c), and back to rustc 1.12.01. On rustc 1.11.0, it gives

<std macros>:3:11: 3:36 error: invalid reference to argument `0` (no arguments given)
<std macros>:3 print ! ( concat ! ( $ fmt , "\n" ) , $ ( $ arg ) * ) ) ;
                         ^~~~~~~~~~~~~~~~~~~~~~~~~
<std macros>:3:11: 3:36 note: in this expansion of concat!
<std macros>:2:27: 2:58 note: in this expansion of format_args!
<std macros>:3:1: 3:54 note: in this expansion of print! (defined in <std macros>)
<source>:3:5: 3:37 note: in this expansion of println! (defined in <std macros>)

Given how old this "support" is, I don't know if this can be classified as a bug anymore, or if it's just more of a misfeature at this point. IMHO, this should at least get a lint, or even a future-compat lint if that's considered reasonable.

Footnotes

  1. So I guess this would be considered regression-from-stable-to-stable? 🙃

@CAD97 CAD97 added the C-bug Category: This is a bug. label Jan 28, 2022
@klensy
Copy link
Contributor

klensy commented Jan 28, 2022

Perhaps #93378?

@CAD97
Copy link
Contributor Author

CAD97 commented Jan 28, 2022

Looks to be it, beat me to it by a day it looks like. (I still think this working even with explicit named parameters should be linted against, though.)

@CAD97 CAD97 changed the title format_args!("{what}{}") works unexpectedly (named format arguments can be used as positional) Named format arguments can be used as positional Jan 28, 2022
@CAD97
Copy link
Contributor Author

CAD97 commented Jan 28, 2022

I restricted this just to the "named arguments can be used as positional" case, since #93378 is getting fixed for the more obviously bad case of println!("{what}{}").

@CAD97
Copy link
Contributor Author

CAD97 commented Jan 28, 2022

Note that if this gets upgraded to a hard error, #93394 can be backed out, as it exists just so that implicit captures don't count as positional arguments (but named arguments still do).

@m-ou-se
Copy link
Member

m-ou-se commented Jan 28, 2022

I agree with @CAD97 said: While it can be confusing, I'm not sure it's something we should consider a bug, as this behaviour has been stable for almost six years.

A lint that warns about it could be reasonable. Maybe something like this:

warning: positional argument in format string refers to named argument
 --> <source>:3:18
  |
3 |     println!("{a}{}", a=what);
  |                  ^^
help: use its name to avoid confusion
  |
3 |     println!("{a}{a}", a=what);
  |                   +

@Veetaha
Copy link
Contributor

Veetaha commented Jan 28, 2022

this behaviour has been stable for almost six years.

@m-ou-se I don't think this behavior was documented. I did stumble upon it even before opening #93378 when writing a derive with thiserror, but thought it could be a bug in that library. It surprised me to see the same unexpected behavior in standard formatting macros!

Since this behavior wasn't documented we shouldn't consider it as a valid usage of formatting macros. If we make it a hard error I am sure a bunch of code will break (probably revealing real bugs though!), but we can make it at least a compatibility warning similar to how we got rid of panic!("{}") behavior, saying that it is considered a bug and we intend to remove this in future versions of the language.

But, I'd rather give it to crater before we make a decision.

@m-ou-se
Copy link
Member

m-ou-se commented Jan 28, 2022

make it at least a compatibility warning similar to how we got rid of panic!("{}") behavior, saying that it is considered a bug and we intend to remove this in future versions of the language.

Sure, that's basically the same lint that was already suggested. Whether we tag that as a future compaibility lint or not is debatable. I don't see any reason to make this stronger than a warning. A warning helps against bugs, but anything stronger doesn't really seem to have much extra value. I don't think it makes sense to warn if any of your dependencies trigger the lint, for example.

But, I'd rather give it to crater before we make a decision.

As Rust usage outside of open-source grows, Crater is becoming less and less a reliable indicator for these sort of things. Especially since it mostly tests libraries, while print!()ing is probably way more common in binaries.

@estebank
Copy link
Contributor

estebank commented Jul 8, 2022

#98580 will lint against named args used only as named, so it won't trigger for this case.

@estebank
Copy link
Contributor

rust-lang/rust-clippy#9040 will cover this case.

Michael-F-Bryan added a commit to Michael-F-Bryan/wapm-cli that referenced this issue Aug 17, 2022
@CAD97
Copy link
Contributor Author

CAD97 commented Jul 30, 2023

This warns on the current stable (1.71):

warning: named argument `a` is not used by name
 --> src/main.rs:3:23
  |
3 |     println!("{a}{}", a=what);
  |                  --   ^ this named argument is referred to by position in formatting string
  |                  |
  |                  this formatting argument uses named argument `a` by position
  |
  = note: `#[warn(named_arguments_used_positionally)]` on by default
help: use the named argument by name to avoid ambiguity
  |
3 |     println!("{a}{a}", a=what);
  |                   +

I think we should consider making this a hard error in edition2024, but otherwise this issue can be considered resolved.

@CAD97
Copy link
Contributor Author

CAD97 commented Jul 30, 2023

@rustbot label -needs-triage-legacy

@estebank estebank added A-lints Area: Lints (warnings about flaws in source code) such as unused_mut. I-needs-decision Issue: In need of a decision. C-future-incompatibility Category: Future-incompatibility lints T-libs Relevant to the library team, which will review and decide on the PR/issue. A-fmt Area: `std::fmt` A-edition-2024 Area: The 2024 edition and removed C-bug Category: This is a bug. labels Jul 31, 2023
@m-ou-se m-ou-se added T-libs-api Relevant to the library API team, which will review and decide on the PR/issue. and removed T-libs Relevant to the library team, which will review and decide on the PR/issue. labels Aug 2, 2023
@m-ou-se
Copy link
Member

m-ou-se commented Aug 2, 2023

As mentioned above, this is still accepted but gives a warning now. We can still consider making this a hard error in a future edition.

I don't think it's worth it doing anything edition-specific here. A warning seems just fine. I don't think we'd gain anything by changing format_args!() to completely reject these cases.

@rfcbot close

@rfcbot
Copy link

rfcbot commented Aug 2, 2023

Team member @m-ou-se has proposed to close this. The next step is review by the rest of the tagged team members:

No concerns currently listed.

Once a majority of reviewers approve (and at most 2 approvals are outstanding), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up!

See this document for info about what commands tagged team members can give me.

@rfcbot rfcbot added the proposed-final-comment-period Proposed to merge/close by relevant subteam, see T-<team> label. Will enter FCP once signed off. label Aug 2, 2023
@rfcbot rfcbot added disposition-close This PR / issue is in PFCP or FCP with a disposition to close it. final-comment-period In the final comment period and will be merged soon unless new substantive objections are raised. labels Aug 2, 2023
@rfcbot
Copy link

rfcbot commented Aug 2, 2023

🔔 This is now entering its final comment period, as per the review above. 🔔

@rfcbot rfcbot removed the proposed-final-comment-period Proposed to merge/close by relevant subteam, see T-<team> label. Will enter FCP once signed off. label Aug 2, 2023
@rfcbot rfcbot added finished-final-comment-period The final comment period is finished for this PR / Issue. to-announce Announce this issue on triage meeting and removed final-comment-period In the final comment period and will be merged soon unless new substantive objections are raised. labels Aug 12, 2023
@rfcbot
Copy link

rfcbot commented Aug 12, 2023

The final comment period, with a disposition to close, as per the review above, is now complete.

As the automated representative of the governance process, I would like to thank the author for their work and everyone else who contributed.

@CAD97
Copy link
Contributor Author

CAD97 commented Aug 12, 2023

Per FCP, closing as completed.

@CAD97 CAD97 closed this as completed Aug 12, 2023
@apiraino apiraino removed the to-announce Announce this issue on triage meeting label Aug 18, 2023
@fmease fmease added A-lints Area: Lints (warnings about flaws in source code) such as unused_mut. and removed A-lints Area: Lints (warnings about flaws in source code) such as unused_mut. labels Dec 21, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-edition-2024 Area: The 2024 edition A-fmt Area: `std::fmt` A-lints Area: Lints (warnings about flaws in source code) such as unused_mut. C-future-incompatibility Category: Future-incompatibility lints disposition-close This PR / issue is in PFCP or FCP with a disposition to close it. finished-final-comment-period The final comment period is finished for this PR / Issue. I-needs-decision Issue: In need of a decision. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

10 participants