-
Notifications
You must be signed in to change notification settings - Fork 20
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
Replace Debug::{key_with, value_with}
with DebugMap::entry_with
#563
Comments
If this is accepted, I'll immediately submit an implementation of this change |
See the original ACP (#288) for additional context. Adding a new You'll note in the implementation PR for |
|
How would you implement |
Note that this requires the |
Ok, fair points, I agree I overlooked those cases, let's keep |
Regarding the issue of additional panic machinery: can you check whether the compiler is capable of optimizing away the assert? And if it isn't, possibly the functions could be modified to make it easier for the compiler to do so (e.g. small always-inline functions containing the state checks that then call larger functions). |
Just checked, and the asserts are not removed when calling Checked the following code using #![feature(debug_closure_helpers)]
#[no_mangle]
pub fn fmt_entry(f: &mut std::fmt::Formatter, k: &str, v: &str) -> std::fmt::Result {
f.debug_map()
.key_with(|f| f.write_str(k))
.value_with(|f| f.write_str(v))
.finish()
}
fn main() {
println!("{}", std::fmt::from_fn(|f| fmt_entry(f, "key", "value")));
} |
On Tue, Mar 25, 2025 at 11:50:03AM -0700, Tim Kurdov wrote:
Just checked, and the asserts are not removed when calling `key_with` & `value_with` right after each other.
Thank you for checking! It would be worth experimenting with a few
approaches to see if there's a way to get the compiler to be able to
optimize out the asserts.
|
This characterization does not reflect what is shown to me in the search. The search returns 14 files + "540 identical files found across repositories" (forks) which I will disregard. Of the 14, there is 1 that calls The useful sample size is small. In some sense 1/3 is practically all ("all but 2") but it's also not the evidence that the ACP makes it seem. |
We discussed this ACP in the most recent standard library API team meeting. #563 (comment) and #563 (comment) were compelling reasons that removing As far as keeping We talked about there being 3 ways to supply formatting logic for a key and value:
The most utility to be expected from let do_print_key = ...;
let do_print_value = ...;
- f.key_with(do_print_key);
- f.value_with(do_print_value);
+ f.entry_with(do_print_key, do_print_value); But as you can see, the amount of improvement here is still negligible. If one line is desired aesthetically, this is substantially identical to If either key or value can be passed in way 1, - f.key(&k);
- f.value_with(|f| {
- ...
- });
+ f.entry_with(
+ |f| k.fmt(f),
+ |f| {
+ ...
+ },
+ ); If one or both are passed in way 2, - f.key_with(|f| {
- ...
- });
- f.value_with(|f| {
- ...
- });
+ f.entry_with(
+ |f| {
+ ...
+ },
+ |f| {
+ ...
+ },
+ ); For "Reduces the possibility of a logical error", we did not buy this as a rationale. In our estimation adding For "Reduces code size", assuming this refers to compiled binary size not source code, there is a possibility this can be turned into a rationale but the ACP doesn't have that data. There is precedent in work like rust-lang/rust#98190 (comment) that agglomerating common sequences of fmt function calls can shave bytes off of debug code. Currently we do not expect the effect to be significant when considering how niche this part of the API already is going to be. |
Proposal
Replace the (currently nightly) methods for printing the Debug repr of a map's key & value with one method for both.
Problem statement
To ensure that the methods
key_with
&value_with
are called in the right order,DebugMap
remembers whetherkey_with
was called without an accompanyingvalue_with
call, and if the order is violated, it panics. This setup makes it easier to commit a logical error that will crash the app at runtime, and unnecessarily increases code size with a conditional panicSolution sketch
This approach:
Links and related work
This sample of code on Github suggests that practically all of
DebugMap::key_with
invocations are immediately followed by an invocation ofDebugMap::value_with
, which raises a question of "do they really have to be 2 separate functions?"What happens now?
This issue contains an API change proposal (or ACP) and is part of the libs-api team feature lifecycle. Once this issue is filed, the libs-api team will review open proposals as capability becomes available. Current response times do not have a clear estimate, but may be up to several months.
Possible responses
The libs team may respond in various different ways. First, the team will consider the problem (this doesn't require any concrete solution or alternatives to have been proposed):
Second, if there's a concrete solution:
The text was updated successfully, but these errors were encountered: