-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
RFC: Implement Debug, Eq, PartialEq, and Hash for libc structs #2235
Conversation
I was unable to macrologize my way to the feature gated version though I don't recall why not. Iam strongly in favour of sorting this out. The rust API guidelines were not as fleshed out at the time, and now they provide more motivation to do this. Questions:
|
Addressing your questions in turn:
I don't believe there should be any. These types shouldn't change size with these traits implemented on them. And there won't be a conflict from the traits being implemented multiple times, because they only be implemented within this crate.
Yes we can. Or did you mean should we quantify this before accepting this RFC?
Yes, the RFC addresses this. And this will also occur for
I don't know what this question is driving at. Is this a technical question or a utility question? I think the utility of Debug is pretty apparent at the struct level, but at the field level these 256, 512, and 1024 byte arrays will likely not have much utility when output as part of debugging output. That being said, who are we to restrict this. It might be useful for downstream users. And I can't think of a technical reason why we shouldn't implement |
Regarding the long compile times as well, as part of a test we could remove all arrays that are too long from all internal datatypes and then derive all of these traits and directly compare the compile times of the crate from scratch and then when also modifying a single struct. This should give us a pretty good sense of the damage there. |
Back in the rust-lang/libc#302 I noted that:
However as of 0.3 this is no longer true - I guess this change in policy was made to improve compile times. It's terribly frustrating that we feel we have to hobble our code because the compiler is slow. It's true that - from the individual crate's point of view - the user experience may be made better by not implementing otherwise desirable traits. But the Rust world would be so much improved if compile times could be improved so that this was a non-issue... Therefore, I'm of the opinion that we should anyway derive (I'm only half-joking. Rhetoric aside, it is a fact that as of today |
LGTM, I think this can be merged as is. However, implementation-wise, I am strongly against adding manual trait implementations to libc. They complicate the implementation, raise the barrier of entry, and increase the maintenance burden when things do change. I think that after merging what can be done is derive the traits for all types for which this can happen automatically. That is already a huge improvement and better than nothing. For all other types: I think time is better spent fixing deriving traits for arrays. We don't need to ship this RFC all at once. We can do this incrementally. |
@Susurrus do you know what the concrete impact would be on compile times to add these implementations by default? Optionally as well? I think it'd be good to evaluate the weight of the drawback here |
@alexcrichton No I don't. I mentioned testing this above in a previous comment |
So I implemented a quick test on Just did a test here locally. I checked out master (bbda50d20937e570df5ec857eea0e2a098e76b2d).
Then after resetting a clean compile took:
|
Is this something we want to enable in an opt-in way anyways? If so, let's just add a feature to libc that we disable by default. That way those who want to implement or test this can add it without affecting others, and their work is not lost (that is, these things can be upstreamed to libc). Once we reach close to complete implementations on tier 1, somebody just has to provide a table of compile-times for all tier 1 platforms here, with and without auto-deriving traits. And we will be able to make a more informed decision about whether to enable this by default for everybody or not. But in any case, those who need it will still be able to use it by opt-in into it, so if they put in some work to help here this work won't be lost. |
@Susurrus I'd imagine the compile time doesn't change much with an opt-in feature, but can you confirm that? If so then I think we should switch to an opt-in feature by default and I think we can land this. |
That is a good question when talking about this as a feature, are we going to make this opt-in or opt-out. I'd suggest opt-out so that the largest number of people will use use it and the people who get slow compiles can opt-out as needed. I'll whip something up in the next few days, I didn't save my work from the previous tests for this. I wasn't expecting there to be so much implementation for an RFC to actually do the implementation! |
@Susurrus I would make it opt-in at first (do not enable it by default, but extend the build scripts to test this configuration). By making it opt-in the feature is initially We can then see how much enabling the feature impacts libc's build times. Libc compiles pretty fast, so if it has a 2-3x compile-time increase, then that might still be ok. However, if it has a 100x compile-time increase, then that would not be ok. We would all agree that this would then be a technical problem to be solved in rustc, but until the problem is solved we wouldn't be able to enable the feature by default without making Rust worse for everybody using it. In any case, those who want to use the feature would still be able to do so. |
So I just tested this locally with an opt-out feature flag, and it's within the noise margin for a build without any of these changes. So if we use an off-by-default feature flag for this, there should be minimal cost. I'll also push a branch for my testing that has this code and link to it from the RFC so people can confirm my findings. |
@Susurrus What's the compile-time cost when these are enabled? Could you provide any numbers? |
@gnzlbg I already posted those numbers earlier in this thread. |
@Susurrus my worry with an opt-out flag is that it'll basically be impossible to opt-out for heavily depended on crates like |
So it goes from 0.9s to 2.3s, I think that's acceptable and that we should try to enable this by default once the feature is done. |
0181bff
to
7567306
Compare
Alright, I've revised this RFC a bit and tried to put all suggestions under the |
Ah sorry I think I missed the original location of where the compile times were measured, did that also include optimized builds? |
@alexcrichton Could you be more specific? It's pretty easy for me to run compilation tests with my |
@Susurrus just try them all. Supposing that the feature that conditionally enables deriving impls is called without std, debug, w/o deriving impls
without std, release, w/o deriving impls
with std, debug, w/o deriving impls
with std, release, w/o deriving impls
Maybe you could add these results to the RFC so that people don't have to scan the thread to look for them. |
@gnzlbg's suggestions are exactly (and more!) what I would have recommended! |
+1 for the approach in #2235 (comment). @rfcbot concern |
Please note that for a default feature to be disabled, every single dependent crate needs to opt out. For a crate as widely depended-on as libc, adding a default feature is almost indistinguishable from adding always-on functionality without a feature flag. So the only two options worth considering IMO are:
|
There does not appear to be full consensus about the "features" situation yet, and it might be impossible to agree on this till everyone can try the implementation and see how it impacts them. So I would suggest to just leave this as an "Unresolved Question". Whoever implements this (probably @Susurrus ) should just gate this behind one Once the implementation is merged into As @SimonSapin mentions, gating this behind features also has a cost. If the compile-time costs turn out to be as minimal as in @Susurrus PoC, it might not even be worth it to have a feature at all. |
My point is that default features are not effective. Having these impls behind opt-in/non-default features sounds fine to me. |
@gnzlbg my conclusion is the same as @SimonSapin's, we should have these as off-by-default features for now. I agree with @SimonSapin that on-by-default features for |
So I chatted with @alexcrichton on Zulip and they convinced me that we should definitely put this behind a feature. Compile times might be a non-issue right now, but I still don't know how I feel about adding one feature per trait to derive like @dtolnay suggests. I believe that we would have to at least test that Arguably, @alexcrichton argument applies here as well. If |
So what do I need to do to move this forward now? I'm a little confused about next steps. I'm fine with putting this behind a feature flag. Should I update the RFC to specify that and leave the naming and exact number of features as an unresolved question? |
Okay, thanks Alex. I'll update the RFC appropriately when I get a chance. |
I updated the RFC. changed the name to |
@rfcbot resolve |
🔔 This is now entering its final comment period, as per the review above. 🔔 |
The final comment period, with a disposition to merge, as per the review above, is now complete. |
With the RFC comment period complete, what're the next steps here? |
Someone needs to click the merge button, but also work can start on the implementation. |
Huzzah! This RFC has been merged! Tracking issue: rust-lang/rust#57715 |
Rendered
Tracking issue
CC previous discussion holders from rust-lang/libc#302: @alexcrichton @kamalmarhubi @dimbleby