-
-
Notifications
You must be signed in to change notification settings - Fork 14.5k
Do not deduplicate captured args while expanding format_args!
#149926
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
base: main
Are you sure you want to change the base?
Conversation
|
Some changes occurred in src/tools/clippy cc @rust-lang/clippy Some changes occurred in compiler/rustc_ast_lowering/src/format.rs cc @m-ou-se |
|
r? @spastorino rustbot has assigned @spastorino. Use |
This comment has been minimized.
This comment has been minimized.
|
@rustbot author |
fb523ee to
3ebdaa4
Compare
|
@rustbot ready |
|
Nominating as per #145739 (comment) |
|
It'd be worth adding a test for the drop behavior. |
3ebdaa4 to
af89685
Compare
|
Given that this makes more sense for the language, along with the clean crater results and the intuition that it'd be surprising if anything actually leaned on this, I propose: @rfcbot fcp merge lang |
|
Team member @traviscross has proposed to merge 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! cc @rust-lang/lang-advisors: FCP proposed for lang, please feel free to register concerns. |
|
I don't think we should do this. It will make the generated code for I don't want to end up in a situation where it would make sense for Clippy to suggest something like: Adding @rust-rfcbot concern equivalence |
|
@rfcbot fcp reviewed |
|
🔔 This is now entering its final comment period, as per the review above. 🔔 |
|
@BurntSushi wrote:
Got it. I personally would not want to see such a lint, and would rather see us avoid pushing people to do that. But it sounds like we're aligned on @dianne's current approach, assuming the implementation is as feasible as expected. |
|
I like the simplification of not trying to dedup things. I was glad to read the conversation about the concern, though -- that was insightful. @rfcbot reviewed |
|
@RalfJung wrote:
I'm not convinced deduplication is "arbitrary"; an equally reasonable fix is to just explicitly document this behaviour. I don't see why Also, I do have a real-world example of the perf issue @m-ou-se pointed out for complex |
|
@nia-e I believe that even if the parameters are deduplicated, the Deduplication only means that the buffer (created by May I know how much performance gain did the deduplicating get you? |
|
@theemathas I'd have to somehow locally profile the cloud backend under load which is perhaps a bit difficult 😅 but a significant amount of time is spent inside that bit of code. If the actual calls to |
|
@nia-e I don't think deduplicating the Display calls is feasible, at least without a lot of reworking of the formatting machinery. Much of the formatting machinery must work in a setting where allocation isn't available. Storing a string to write it out twice requires allocation. |
|
@theemathas In that case RIP that idea, but the performance argument applies regardless. Deduplicating the pointers inside |
|
I think we're making a mistake if we accept this. Today, Clippy's Because these two lines are considered equivalent. The change proposed in this PR makes these two lines no longer equivalent. After this change, the user is either expected to be okay with a subtle performance hit, or to apply this seemingly useless change to keep things the same: The only suggestion to prevent that in the common case is by making the format_args!() builtin macro way more magical, by changing how it expands depending on whether arguments refer to a local variable. While this is technically implementable, this is simply not a reasonable/acceptable change. As I mentioned above, this would make the macro beyond reasonably magical and above all hard to maintain. To be extra clear: as the implementor and maintainer of the format_args builtin macro: I will not accept such a change.
@joshtriplett Such an implementation is not feasible/reasonable. We will end up in a situation where users who care about performance will need to add things like
I don't think we should accept that. Using the same captured argument multiple times is very normal and even suggested by Clippy today. It'd be a bad developer experience if in Rust 1.58 we suggest that users change I would not feel great sending out a bunch of PRs to projects on GitHub adding It is true that for many projects a slight performance hit for formatting doesn't matter much, but using that to argue for changes like this is exactly what makes Rust's string formatting something that's currently being avoided on embedded platforms. I've been working for years to try to improve the situation. But changes like the one in FCP here are pushing in the opposite direction, making the situation worse. Consistency for funny weird edge cases like #145739 is great, but please let's not use that as an argument for making the real world experience of and performance of Rust worse. |
|
We discussed this in today's @rust-lang/libs-api meeting. This issue has been going back and forth for a while. At this point, rather than arguing over the feasibility or non-feasibility of an optimization, we felt like we'd like to see the code of the optimization and evaluate that. Knowing that it's possible, seeing whether it looks maintainable, and knowing how much or how little code it takes, would affect our decision on this. @rfcbot concern lets-see-the-optimization @dianne, would you be able to show us a PR for the optimization? |
|
Deduplication feels wrong to me in the context of #145739, but m-ou-se arguments seem right to me here. Do I understand correctly that this introduces a tension with potential future extensions like: println!("{a.b} {a.b}");because deduplicating these would require deduplicating expressions, not just identifiers? My guess is that stopping deduplication opens the door to such extensions, and sticking to deduplication instead makes them less realistic. (although I am having a hard time reasoning about my sentence here with all these stacked negations) I am okay with a future without |
Or alternatively, defining increasingly complex rules like "we deduplicate the We would have to define those because they'd affect the semantics of the program. If we ensure that we only deduplicate as an as-if optimization that isn't semantically visible, the user doesn't have to care about deduplication as a complicating factor, they can just treat it as an optimization.
The ability to format |
|
As the author of this PR, I approached this work under the assumption that it was a fairly straightforward and uncontroversial change, based on the discussions in #145739 I didn't expect the topic to be this debatable, and had I known that upfront, I might have reconsidered taking this on, since I'm not deeply familiar with the formatting. For that reason, I've mostly stayed quiet so far. I don't feel I have particularly strong insights to add beyond what's already been discussed. Apologies if this PR caused extra discussion or confusion; that wasn't my intention 😢 |
|
@ShoyuVanilla you don't have to be sorry! You just had the bad luck of stumbling into a superficially simple problem that has some deep subtle issues. This happens occasionally when one builds a complicated system such as a programming language, but we can't predict which issues it affects. It's nor your fault that these issues exist. :) I'm sorry this turned out to be heavier than you thought. |
There's also the only-slightly more complex rule of Also, to be clear: the above rule would allow us to move forward with implementing (and even stabilizing) |
|
Do we expect |
I've got a half-baked PR that does the optimization for captured formatted arguments: #152480. It's missing the equivalent optimization for captured width and precision arguments for now, since I think that would be more invasive. Plus, when attempting to preserve the behavior of writing the args out separately, I'm not sure this is the right thing to do, especially given that width/precision messiness. Hopefully the draft PR makes things a bit clearer at least? |
You didn't do anything wrong here. We're having a vigorous discussion about whether we should do this, but none of that was caused by your PR; we appreciate you doing the work on this. |
Resolves #145739
I ran crater with #149291.
While there are still a few seemingly flaky, spurious results, no crates appear to be affected by this breaking change.
The only hit from the lint was
https://github.com/multiversx/mx-sdk-rs/blob/813927c03a7b512a3c6ef9a15690eaf87872cc5c/framework/meta-lib/src/tools/rustc_version_warning.rs#L19-L30,
which performs formatting on consts of type
::semver::Version. These constants contain a nested::semver::Identifier(Version.pre.identifier) that has a custom destructor. However, this case is not impacted by the change, so no breakage is expected.