diff --git a/Cargo.lock b/Cargo.lock index 6a1525f7530..48c907ae62d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2294,6 +2294,7 @@ dependencies = [ "anyhow", "clap 4.1.4", "fs-err", + "rustc-hash", "rustdoc-json-types", "serde", "serde_json", @@ -4846,6 +4847,7 @@ dependencies = [ name = "rustdoc-json-types" version = "0.1.0" dependencies = [ + "rustc-hash", "serde", "serde_json", ] diff --git a/src/rustdoc-json-types/Cargo.toml b/src/rustdoc-json-types/Cargo.toml index d60699efd36..d63caa7ad70 100644 --- a/src/rustdoc-json-types/Cargo.toml +++ b/src/rustdoc-json-types/Cargo.toml @@ -8,6 +8,7 @@ path = "lib.rs" [dependencies] serde = { version = "1.0", features = ["derive"] } +rustc-hash = "1.1.0" [dev-dependencies] serde_json = "1.0" diff --git a/src/rustdoc-json-types/lib.rs b/src/rustdoc-json-types/lib.rs index 387d5787dfc..4c210291b11 100644 --- a/src/rustdoc-json-types/lib.rs +++ b/src/rustdoc-json-types/lib.rs @@ -3,10 +3,9 @@ //! These types are the public API exposed through the `--output-format json` flag. The [`Crate`] //! struct is the root of the JSON blob and all other items are contained within. -use std::collections::HashMap; -use std::path::PathBuf; - +use rustc_hash::FxHashMap; use serde::{Deserialize, Serialize}; +use std::path::PathBuf; /// rustdoc format-version. pub const FORMAT_VERSION: u32 = 24; @@ -24,11 +23,11 @@ pub struct Crate { pub includes_private: bool, /// A collection of all items in the local crate as well as some external traits and their /// items that are referenced locally. - pub index: HashMap, + pub index: FxHashMap, /// Maps IDs to fully qualified paths and other info helpful for generating links. - pub paths: HashMap, + pub paths: FxHashMap, /// Maps `crate_id` of items to a crate name and html_root_url if it exists. - pub external_crates: HashMap, + pub external_crates: FxHashMap, /// A single version number to be used in the future when making backwards incompatible changes /// to the JSON output. pub format_version: u32, @@ -54,8 +53,8 @@ pub struct ItemSummary { /// /// Note that items can appear in multiple paths, and the one chosen is implementation /// defined. Currently, this is the full path to where the item was defined. Eg - /// [`String`] is currently `["alloc", "string", "String"]` and [`HashMap`] is - /// `["std", "collections", "hash", "map", "HashMap"]`, but this is subject to change. + /// [`String`] is currently `["alloc", "string", "String"]` and [`HashMap`][`std::collections::HashMap`] + /// is `["std", "collections", "hash", "map", "HashMap"]`, but this is subject to change. pub path: Vec, /// Whether this item is a struct, trait, macro, etc. pub kind: ItemKind, @@ -80,7 +79,7 @@ pub struct Item { /// Some("") if there is some documentation but it is empty (EG `#[doc = ""]`). pub docs: Option, /// This mapping resolves [intra-doc links](https://github.com/rust-lang/rfcs/blob/master/text/1946-intra-rustdoc-links.md) from the docstring to their IDs - pub links: HashMap, + pub links: FxHashMap, /// Stringified versions of the attributes on this item (e.g. `"#[inline]"`) pub attrs: Vec, pub deprecation: Option, diff --git a/src/tools/jsondoclint/Cargo.toml b/src/tools/jsondoclint/Cargo.toml index 8990310a4f4..1318a1f4476 100644 --- a/src/tools/jsondoclint/Cargo.toml +++ b/src/tools/jsondoclint/Cargo.toml @@ -9,6 +9,7 @@ edition = "2021" anyhow = "1.0.62" clap = { version = "4.0.15", features = ["derive"] } fs-err = "2.8.1" +rustc-hash = "1.1.0" rustdoc-json-types = { version = "0.1.0", path = "../../rustdoc-json-types" } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0.85" diff --git a/src/tools/jsondoclint/src/validator/tests.rs b/src/tools/jsondoclint/src/validator/tests.rs index 1ef41ff123a..95a56a9dfac 100644 --- a/src/tools/jsondoclint/src/validator/tests.rs +++ b/src/tools/jsondoclint/src/validator/tests.rs @@ -1,5 +1,4 @@ -use std::collections::HashMap; - +use rustc_hash::FxHashMap; use rustdoc_json_types::{Crate, Item, ItemKind, ItemSummary, Visibility, FORMAT_VERSION}; use crate::json_find::SelectorPart; @@ -27,7 +26,7 @@ fn errors_on_missing_links() { root: id("0"), crate_version: None, includes_private: false, - index: HashMap::from_iter([( + index: FxHashMap::from_iter([( id("0"), Item { name: Some("root".to_owned()), @@ -36,7 +35,7 @@ fn errors_on_missing_links() { span: None, visibility: Visibility::Public, docs: None, - links: HashMap::from_iter([("Not Found".to_owned(), id("1"))]), + links: FxHashMap::from_iter([("Not Found".to_owned(), id("1"))]), attrs: vec![], deprecation: None, inner: ItemEnum::Module(Module { @@ -46,8 +45,8 @@ fn errors_on_missing_links() { }), }, )]), - paths: HashMap::new(), - external_crates: HashMap::new(), + paths: FxHashMap::default(), + external_crates: FxHashMap::default(), format_version: rustdoc_json_types::FORMAT_VERSION, }; @@ -73,7 +72,7 @@ fn errors_on_local_in_paths_and_not_index() { root: id("0:0:1572"), crate_version: None, includes_private: false, - index: HashMap::from_iter([ + index: FxHashMap::from_iter([ ( id("0:0:1572"), Item { @@ -83,7 +82,7 @@ fn errors_on_local_in_paths_and_not_index() { span: None, visibility: Visibility::Public, docs: None, - links: HashMap::from_iter([(("prim@i32".to_owned(), id("0:1:1571")))]), + links: FxHashMap::from_iter([(("prim@i32".to_owned(), id("0:1:1571")))]), attrs: Vec::new(), deprecation: None, inner: ItemEnum::Module(Module { @@ -102,14 +101,14 @@ fn errors_on_local_in_paths_and_not_index() { span: None, visibility: Visibility::Public, docs: None, - links: HashMap::default(), + links: FxHashMap::default(), attrs: Vec::new(), deprecation: None, inner: ItemEnum::Primitive(Primitive { name: "i32".to_owned(), impls: vec![] }), }, ), ]), - paths: HashMap::from_iter([( + paths: FxHashMap::from_iter([( id("0:1:1571"), ItemSummary { crate_id: 0, @@ -117,7 +116,7 @@ fn errors_on_local_in_paths_and_not_index() { kind: ItemKind::Primitive, }, )]), - external_crates: HashMap::default(), + external_crates: FxHashMap::default(), format_version: rustdoc_json_types::FORMAT_VERSION, }; @@ -137,7 +136,7 @@ fn checks_local_crate_id_is_correct() { root: id("root"), crate_version: None, includes_private: false, - index: HashMap::from_iter([( + index: FxHashMap::from_iter([( id("root"), Item { id: id("root"), @@ -146,7 +145,7 @@ fn checks_local_crate_id_is_correct() { span: None, visibility: Visibility::Public, docs: None, - links: HashMap::default(), + links: FxHashMap::default(), attrs: Vec::new(), deprecation: None, inner: ItemEnum::Module(Module { @@ -156,8 +155,8 @@ fn checks_local_crate_id_is_correct() { }), }, )]), - paths: HashMap::default(), - external_crates: HashMap::default(), + paths: FxHashMap::default(), + external_crates: FxHashMap::default(), format_version: FORMAT_VERSION, }; check(&krate, &[]); diff --git a/tests/run-make/rustdoc-verify-output-files/Makefile b/tests/run-make/rustdoc-verify-output-files/Makefile index bfabbbc6586..0666122e8ab 100644 --- a/tests/run-make/rustdoc-verify-output-files/Makefile +++ b/tests/run-make/rustdoc-verify-output-files/Makefile @@ -22,15 +22,11 @@ all: # Check if expected json file is generated [ -e $(OUTPUT_DIR)/foobar.json ] - # TODO - # We should re-generate json doc once again and compare the diff with previously - # generated one. Because layout of json docs changes in each compilation, we can't - # do that currently. - # - # See https://github.com/rust-lang/rust/issues/103785#issuecomment-1307425590 for details. + # Copy first json output to check if it's exactly same after second compilation + cp -R $(OUTPUT_DIR)/foobar.json $(TMP_OUTPUT_DIR)/foobar.json - # remove generated json doc - rm $(OUTPUT_DIR)/foobar.json + # Generate json doc on the same output + $(RUSTDOC) src/lib.rs --crate-name foobar --crate-type lib --out-dir $(OUTPUT_DIR) -Z unstable-options --output-format json - # Check if json doc compilation broke any of the html files generated previously + # Check if all docs(including both json and html formats) are still the same after multiple compilations $(DIFF) -r -q $(OUTPUT_DIR) $(TMP_OUTPUT_DIR)