Rollup merge of #108626 - ozkanonur:consistent-json-docs, r=aDotInTheVoid
rustdoc-json: switch from HashMap to FxHashMap to fix non-determinism Using `HashMap` in `rustdoc_json_types::Crate` were causing creating randomly ordered objects in the json doc files. Which might cause problems to people who are doing comparison on those files specially in CI pipelines. See https://github.com/rust-lang/rust/issues/103785#issuecomment-1307425590 This PR fixes that issue and extends the coverage of `tests/run-make/rustdoc-verify-output-files` testing ability.
This commit is contained in:
commit
03c1e4d4ff
@ -2287,6 +2287,7 @@ dependencies = [
|
|||||||
"anyhow",
|
"anyhow",
|
||||||
"clap 4.1.4",
|
"clap 4.1.4",
|
||||||
"fs-err",
|
"fs-err",
|
||||||
|
"rustc-hash",
|
||||||
"rustdoc-json-types",
|
"rustdoc-json-types",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
@ -4850,6 +4851,7 @@ dependencies = [
|
|||||||
name = "rustdoc-json-types"
|
name = "rustdoc-json-types"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"rustc-hash",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
]
|
]
|
||||||
|
@ -8,6 +8,7 @@ path = "lib.rs"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
|
rustc-hash = "1.1.0"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
|
@ -3,10 +3,9 @@
|
|||||||
//! These types are the public API exposed through the `--output-format json` flag. The [`Crate`]
|
//! 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.
|
//! struct is the root of the JSON blob and all other items are contained within.
|
||||||
|
|
||||||
use std::collections::HashMap;
|
use rustc_hash::FxHashMap;
|
||||||
use std::path::PathBuf;
|
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
/// rustdoc format-version.
|
/// rustdoc format-version.
|
||||||
pub const FORMAT_VERSION: u32 = 24;
|
pub const FORMAT_VERSION: u32 = 24;
|
||||||
@ -24,11 +23,11 @@ pub struct Crate {
|
|||||||
pub includes_private: bool,
|
pub includes_private: bool,
|
||||||
/// A collection of all items in the local crate as well as some external traits and their
|
/// A collection of all items in the local crate as well as some external traits and their
|
||||||
/// items that are referenced locally.
|
/// items that are referenced locally.
|
||||||
pub index: HashMap<Id, Item>,
|
pub index: FxHashMap<Id, Item>,
|
||||||
/// Maps IDs to fully qualified paths and other info helpful for generating links.
|
/// Maps IDs to fully qualified paths and other info helpful for generating links.
|
||||||
pub paths: HashMap<Id, ItemSummary>,
|
pub paths: FxHashMap<Id, ItemSummary>,
|
||||||
/// Maps `crate_id` of items to a crate name and html_root_url if it exists.
|
/// Maps `crate_id` of items to a crate name and html_root_url if it exists.
|
||||||
pub external_crates: HashMap<u32, ExternalCrate>,
|
pub external_crates: FxHashMap<u32, ExternalCrate>,
|
||||||
/// A single version number to be used in the future when making backwards incompatible changes
|
/// A single version number to be used in the future when making backwards incompatible changes
|
||||||
/// to the JSON output.
|
/// to the JSON output.
|
||||||
pub format_version: u32,
|
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
|
/// 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
|
/// defined. Currently, this is the full path to where the item was defined. Eg
|
||||||
/// [`String`] is currently `["alloc", "string", "String"]` and [`HashMap`] is
|
/// [`String`] is currently `["alloc", "string", "String"]` and [`HashMap`][`std::collections::HashMap`]
|
||||||
/// `["std", "collections", "hash", "map", "HashMap"]`, but this is subject to change.
|
/// is `["std", "collections", "hash", "map", "HashMap"]`, but this is subject to change.
|
||||||
pub path: Vec<String>,
|
pub path: Vec<String>,
|
||||||
/// Whether this item is a struct, trait, macro, etc.
|
/// Whether this item is a struct, trait, macro, etc.
|
||||||
pub kind: ItemKind,
|
pub kind: ItemKind,
|
||||||
@ -80,7 +79,7 @@ pub struct Item {
|
|||||||
/// Some("") if there is some documentation but it is empty (EG `#[doc = ""]`).
|
/// Some("") if there is some documentation but it is empty (EG `#[doc = ""]`).
|
||||||
pub docs: Option<String>,
|
pub docs: Option<String>,
|
||||||
/// 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
|
/// 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<String, Id>,
|
pub links: FxHashMap<String, Id>,
|
||||||
/// Stringified versions of the attributes on this item (e.g. `"#[inline]"`)
|
/// Stringified versions of the attributes on this item (e.g. `"#[inline]"`)
|
||||||
pub attrs: Vec<String>,
|
pub attrs: Vec<String>,
|
||||||
pub deprecation: Option<Deprecation>,
|
pub deprecation: Option<Deprecation>,
|
||||||
|
@ -9,6 +9,7 @@ edition = "2021"
|
|||||||
anyhow = "1.0.62"
|
anyhow = "1.0.62"
|
||||||
clap = { version = "4.0.15", features = ["derive"] }
|
clap = { version = "4.0.15", features = ["derive"] }
|
||||||
fs-err = "2.8.1"
|
fs-err = "2.8.1"
|
||||||
|
rustc-hash = "1.1.0"
|
||||||
rustdoc-json-types = { version = "0.1.0", path = "../../rustdoc-json-types" }
|
rustdoc-json-types = { version = "0.1.0", path = "../../rustdoc-json-types" }
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
serde_json = "1.0.85"
|
serde_json = "1.0.85"
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
use std::collections::HashMap;
|
use rustc_hash::FxHashMap;
|
||||||
|
|
||||||
use rustdoc_json_types::{Crate, Item, ItemKind, ItemSummary, Visibility, FORMAT_VERSION};
|
use rustdoc_json_types::{Crate, Item, ItemKind, ItemSummary, Visibility, FORMAT_VERSION};
|
||||||
|
|
||||||
use crate::json_find::SelectorPart;
|
use crate::json_find::SelectorPart;
|
||||||
@ -27,7 +26,7 @@ fn errors_on_missing_links() {
|
|||||||
root: id("0"),
|
root: id("0"),
|
||||||
crate_version: None,
|
crate_version: None,
|
||||||
includes_private: false,
|
includes_private: false,
|
||||||
index: HashMap::from_iter([(
|
index: FxHashMap::from_iter([(
|
||||||
id("0"),
|
id("0"),
|
||||||
Item {
|
Item {
|
||||||
name: Some("root".to_owned()),
|
name: Some("root".to_owned()),
|
||||||
@ -36,7 +35,7 @@ fn errors_on_missing_links() {
|
|||||||
span: None,
|
span: None,
|
||||||
visibility: Visibility::Public,
|
visibility: Visibility::Public,
|
||||||
docs: None,
|
docs: None,
|
||||||
links: HashMap::from_iter([("Not Found".to_owned(), id("1"))]),
|
links: FxHashMap::from_iter([("Not Found".to_owned(), id("1"))]),
|
||||||
attrs: vec![],
|
attrs: vec![],
|
||||||
deprecation: None,
|
deprecation: None,
|
||||||
inner: ItemEnum::Module(Module {
|
inner: ItemEnum::Module(Module {
|
||||||
@ -46,8 +45,8 @@ fn errors_on_missing_links() {
|
|||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
)]),
|
)]),
|
||||||
paths: HashMap::new(),
|
paths: FxHashMap::default(),
|
||||||
external_crates: HashMap::new(),
|
external_crates: FxHashMap::default(),
|
||||||
format_version: rustdoc_json_types::FORMAT_VERSION,
|
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"),
|
root: id("0:0:1572"),
|
||||||
crate_version: None,
|
crate_version: None,
|
||||||
includes_private: false,
|
includes_private: false,
|
||||||
index: HashMap::from_iter([
|
index: FxHashMap::from_iter([
|
||||||
(
|
(
|
||||||
id("0:0:1572"),
|
id("0:0:1572"),
|
||||||
Item {
|
Item {
|
||||||
@ -83,7 +82,7 @@ fn errors_on_local_in_paths_and_not_index() {
|
|||||||
span: None,
|
span: None,
|
||||||
visibility: Visibility::Public,
|
visibility: Visibility::Public,
|
||||||
docs: None,
|
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(),
|
attrs: Vec::new(),
|
||||||
deprecation: None,
|
deprecation: None,
|
||||||
inner: ItemEnum::Module(Module {
|
inner: ItemEnum::Module(Module {
|
||||||
@ -102,14 +101,14 @@ fn errors_on_local_in_paths_and_not_index() {
|
|||||||
span: None,
|
span: None,
|
||||||
visibility: Visibility::Public,
|
visibility: Visibility::Public,
|
||||||
docs: None,
|
docs: None,
|
||||||
links: HashMap::default(),
|
links: FxHashMap::default(),
|
||||||
attrs: Vec::new(),
|
attrs: Vec::new(),
|
||||||
deprecation: None,
|
deprecation: None,
|
||||||
inner: ItemEnum::Primitive(Primitive { name: "i32".to_owned(), impls: vec![] }),
|
inner: ItemEnum::Primitive(Primitive { name: "i32".to_owned(), impls: vec![] }),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
]),
|
]),
|
||||||
paths: HashMap::from_iter([(
|
paths: FxHashMap::from_iter([(
|
||||||
id("0:1:1571"),
|
id("0:1:1571"),
|
||||||
ItemSummary {
|
ItemSummary {
|
||||||
crate_id: 0,
|
crate_id: 0,
|
||||||
@ -117,7 +116,7 @@ fn errors_on_local_in_paths_and_not_index() {
|
|||||||
kind: ItemKind::Primitive,
|
kind: ItemKind::Primitive,
|
||||||
},
|
},
|
||||||
)]),
|
)]),
|
||||||
external_crates: HashMap::default(),
|
external_crates: FxHashMap::default(),
|
||||||
format_version: rustdoc_json_types::FORMAT_VERSION,
|
format_version: rustdoc_json_types::FORMAT_VERSION,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -137,7 +136,7 @@ fn checks_local_crate_id_is_correct() {
|
|||||||
root: id("root"),
|
root: id("root"),
|
||||||
crate_version: None,
|
crate_version: None,
|
||||||
includes_private: false,
|
includes_private: false,
|
||||||
index: HashMap::from_iter([(
|
index: FxHashMap::from_iter([(
|
||||||
id("root"),
|
id("root"),
|
||||||
Item {
|
Item {
|
||||||
id: id("root"),
|
id: id("root"),
|
||||||
@ -146,7 +145,7 @@ fn checks_local_crate_id_is_correct() {
|
|||||||
span: None,
|
span: None,
|
||||||
visibility: Visibility::Public,
|
visibility: Visibility::Public,
|
||||||
docs: None,
|
docs: None,
|
||||||
links: HashMap::default(),
|
links: FxHashMap::default(),
|
||||||
attrs: Vec::new(),
|
attrs: Vec::new(),
|
||||||
deprecation: None,
|
deprecation: None,
|
||||||
inner: ItemEnum::Module(Module {
|
inner: ItemEnum::Module(Module {
|
||||||
@ -156,8 +155,8 @@ fn checks_local_crate_id_is_correct() {
|
|||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
)]),
|
)]),
|
||||||
paths: HashMap::default(),
|
paths: FxHashMap::default(),
|
||||||
external_crates: HashMap::default(),
|
external_crates: FxHashMap::default(),
|
||||||
format_version: FORMAT_VERSION,
|
format_version: FORMAT_VERSION,
|
||||||
};
|
};
|
||||||
check(&krate, &[]);
|
check(&krate, &[]);
|
||||||
|
@ -22,15 +22,11 @@ all:
|
|||||||
# Check if expected json file is generated
|
# Check if expected json file is generated
|
||||||
[ -e $(OUTPUT_DIR)/foobar.json ]
|
[ -e $(OUTPUT_DIR)/foobar.json ]
|
||||||
|
|
||||||
# TODO
|
# Copy first json output to check if it's exactly same after second compilation
|
||||||
# We should re-generate json doc once again and compare the diff with previously
|
cp -R $(OUTPUT_DIR)/foobar.json $(TMP_OUTPUT_DIR)/foobar.json
|
||||||
# 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.
|
|
||||||
|
|
||||||
# remove generated json doc
|
# Generate json doc on the same output
|
||||||
rm $(OUTPUT_DIR)/foobar.json
|
$(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)
|
$(DIFF) -r -q $(OUTPUT_DIR) $(TMP_OUTPUT_DIR)
|
||||||
|
Loading…
Reference in New Issue
Block a user