-
Notifications
You must be signed in to change notification settings - Fork 13.2k
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
Change one FxHashMap
to FxIndexMap
in librustdoc
#138871
base: master
Are you sure you want to change the base?
Conversation
r? @notriddle rustbot has assigned @notriddle. Use |
Woah, massive congratz on tracking this down. Is this enough to guarantee reproducible output between hosts? Relying on rust/src/librustdoc/json/mod.rs Line 147 in f8c27df
If reproducible output between hosts is a thing we want to guarantee (and you want to rely on), this defiantly needs a test. This should be What's your use-case for reproducibility across operating systems? Once again, thanks for taking all the time to debug this. |
I honestly don't know. For the cases I've tried (a lib.rs with just
I did a quick search and I couldn't find anywhere that field was To elaborate, here is where elements are read out of the rust/src/librustdoc/json/mod.rs Line 261 in aa8f0fd
If elements are read out in different orders on different operating systems, they will be assigned different ids. I couldn't immediately find anything similar for
Something like the following?
Oooooh... So everything that appears in the JSON file comes from definitions in the lib.rs. Is that the idea?
I have a library that generates wrappers for standard library functions. One of its correctness checks is to generate a JSON file with rustdoc and compare it to a file that was already generated. Currently, the test passes only when the JSON file is generated, and the test is run, on the same operating system. Merging this will allow that restriction to be lifted.
🙏 |
Eventually that becomes part of the output here: rust/src/librustdoc/json/mod.rs Lines 252 to 256 in f8c27df
rust/src/librustdoc/json/mod.rs Lines 300 to 301 in f8c27df
rust/src/librustdoc/json/mod.rs Lines 109 to 117 in f8c27df
so it'd get iterated over to convert to json by serde.
Yeah, but that'd mean needing to update that checked-in file whenever anything about the json output changes, and that's a pretty high mainenence burden that i'd like to avoid if at all possible. I'm happy to pay the cost now to get a test in place, but I'd like to then be able to forget it exists until it catches actuall breakage (rather than a json format change that's still reproducible).
Almost. The test would probably need to be split across a few input files/crates given that this is |
👍
That makes sense to me.
But then what sort of a test do you imagine? Here is what I am struggling with. The test will run on some platform X. The test will produce some JSON and verify that it would be the same if it were produced on platform Y. The only way I can think to do that is to have a pre-generated JSON that the test compares against. Sorry if I am being dense, but is there another way? |
Ideally we'd """""just""""" compare the json on one host with the json on another. But I don't think our CI lets us have results "cross over" between runners like that. CC @jieyouxu, any ideas here? |
@bors try @rust-timer queue |
This comment has been minimized.
This comment has been minimized.
⌛ Trying commit fb97d2f with merge 10b0e2d102a660fa773d90e67f8249911a5a205a... |
…<try> Change one `FxHashMap` to `FxIndexMap` in librustdoc This PR changes one `FxHashMap` to `FxIndexMap` in librustdoc's cache and adds a comment explaining why (i.e., to promote reproducibility across operating systems). I have been [trying to understand](rust-lang/rustdoc-types#44) why the following command produces different results on Linux and MacOS when run on a project whose lib.rs contains only `#![no_std]`: ```sh cargo rustdoc --target x86_64-unknown-linux-gnu -Zbuild-std -- -Z unstable-options --output-format=json ``` I obtained a partial answer in that elements were being read out of this `FxHashMap` in different orders, even when the elements were inserted in the same order: https://github.com/rust-lang/rust/blob/aa8f0fd7163a2f23aa958faed30c9c2b77b934a5/src/librustdoc/formats/cache.rs#L50 I [opened an issue](rust-lang/hashbrown#612) on the Hashbrown repo to see whether this was a bug. The response I got was that if one wants the elements to be read out in the same order, one should use something like `FxIndexMap`. cc: `@aDotInTheVoid`
☀️ Try build successful - checks-actions |
This comment has been minimized.
This comment has been minimized.
Finished benchmarking commit (10b0e2d): comparison URL. Overall result: ❌ regressions - no action neededBenchmarking this pull request likely means that it is perf-sensitive, so we're automatically marking it as not fit for rolling up. While you can manually mark this PR as fit for rollup, we strongly recommend not doing so since this PR may lead to changes in compiler perf. @bors rollup=never Instruction countThis is the most reliable metric that we have; it was used to determine the overall result at the top of this comment. However, even this metric can sometimes exhibit noise.
Max RSS (memory usage)Results (primary -2.0%)This is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.
CyclesResults (primary -2.8%)This is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.
Binary sizeThis benchmark run did not return any relevant results for this metric. Bootstrap: 777.618s -> 777.935s (0.04%) |
I'll take a look at this in a bit. |
And you would be right. Neither rustc nor rustdoc (nor anything really) may rely on rust/compiler/rustc_lint/src/internal.rs Lines 78 to 89 in 6e8abb5
which flags attempts to rely on iteration order of hash maps. |
That's not currently a thing that the CI jobs can support, unfortunately. Also, are jsons between different hosts necessarily identical? |
To the best of my knowledge, if the JSON files differ, the programs that consume them can still function correctly. More specifically, the differences we're talking about involve the assignment of ids, which are largely arbitrary anyway. What's weird though is when you run rustdoc with something like If we're willing to live with those minor differences, then no change to librustdoc is needed. But if it's "this should be fixed"-level weird, then something like this PR is needed. |
Yeah, that's what I'm alluding to, because different host platforms will necessarily have different implementation details. IMO, I don't think we can really test that the json is being consistent across different host platforms unless there's a platform-independent way to influence this specific |
I ran into the rust/library/std/src/collections/hash/map.rs Lines 545 to 549 in 65899c0
I'll do some digging and reply. Also, I'll mark this PR as draft for now. |
@smoelius it's because those are |
Oh. Is there a way to enable that lint for rustdoc code? EDIT: If the answer's not obvious, I can dig. |
Possibly, but I would not recommend it. Those are intentionally |
This PR changes one
FxHashMap
toFxIndexMap
in librustdoc's cache and adds a comment explaining why (i.e., to promote reproducibility across operating systems).I have been trying to understand why the following command produces different results on Linux and MacOS when run on a project whose lib.rs contains only
#![no_std]
:I obtained a partial answer in that elements were being read out of this
FxHashMap
in different orders, even when the elements were inserted in the same order:rust/src/librustdoc/formats/cache.rs
Line 50 in aa8f0fd
I opened an issue on the Hashbrown repo to see whether this was a bug. The response I got was that if one wants the elements to be read out in the same order, one should use something like
FxIndexMap
.cc: @aDotInTheVoid
TODO
index
field (Change oneFxHashMap
toFxIndexMap
in librustdoc #138871 (comment))