From 0dfc121147a50c4a48735317498be7ad0c3d63aa Mon Sep 17 00:00:00 2001 From: Albert Larsan <74931857+albertlarsan68@users.noreply.github.com> Date: Wed, 25 Jan 2023 15:25:54 +0000 Subject: [PATCH 1/3] Generate unstable docs with items under feature Add the items to the autogenerated stubs Make unstable-book-gen use the top stage instead of stage 0 Generate the full docs, only print and save optional notes --- Cargo.lock | 3 + src/bootstrap/src/core/build_steps/doc.rs | 8 + src/bootstrap/src/tests/builder.rs | 4 +- .../src/library-features/allocator-api.md | 8 - .../src/library-features/c-variadic.md | 8 - .../src/library-features/c-void-variant.md | 5 - .../src/library-features/concat-idents.md | 8 - .../src/library-features/core-intrinsics.md | 5 - .../src/library-features/core-panic.md | 5 - .../library-features/core-private-bignum.md | 5 - .../core-private-diy-float.md | 5 - .../src/library-features/dec2flt.md | 5 - .../src/library-features/derive-clone-copy.md | 5 - .../src/library-features/derive-eq.md | 5 - .../src/library-features/fd-read.md | 5 - .../unstable-book/src/library-features/fd.md | 5 - .../src/library-features/flt2dec.md | 5 - .../src/library-features/fmt-internals.md | 5 - .../src/library-features/fn-traits.md | 10 - .../internal-output-capture.md | 5 - .../src/library-features/is-sorted.md | 8 - .../library-features/libstd-sys-internals.md | 5 - .../src/library-features/print-internals.md | 5 - .../library-features/profiler-runtime-lib.md | 5 - .../unstable-book/src/library-features/rt.md | 5 - .../src/library-features/sort-internals.md | 5 - .../src/library-features/str-internals.md | 5 - .../src/library-features/test.md | 6 - .../thread-local-internals.md | 5 - .../src/library-features/trace-macros.md | 8 - .../library-features/update-panic-count.md | 5 - .../src/library-features/windows-c.md | 5 - .../src/library-features/windows-handle.md | 5 - .../src/library-features/windows-net.md | 5 - .../src/library-features/windows-stdio.md | 5 - src/tools/unstable-book-gen/Cargo.toml | 5 + src/tools/unstable-book-gen/src/issue.md | 9 + src/tools/unstable-book-gen/src/main.rs | 178 ++++++++++++++++-- src/tools/unstable-book-gen/src/no-issue.md | 7 + src/tools/unstable-book-gen/src/stub-issue.md | 2 +- .../unstable-book-gen/src/stub-no-issue.md | 2 +- 41 files changed, 203 insertions(+), 196 deletions(-) delete mode 100644 src/doc/unstable-book/src/library-features/c-void-variant.md delete mode 100644 src/doc/unstable-book/src/library-features/core-intrinsics.md delete mode 100644 src/doc/unstable-book/src/library-features/core-panic.md delete mode 100644 src/doc/unstable-book/src/library-features/core-private-bignum.md delete mode 100644 src/doc/unstable-book/src/library-features/core-private-diy-float.md delete mode 100644 src/doc/unstable-book/src/library-features/dec2flt.md delete mode 100644 src/doc/unstable-book/src/library-features/derive-clone-copy.md delete mode 100644 src/doc/unstable-book/src/library-features/derive-eq.md delete mode 100644 src/doc/unstable-book/src/library-features/fd-read.md delete mode 100644 src/doc/unstable-book/src/library-features/fd.md delete mode 100644 src/doc/unstable-book/src/library-features/flt2dec.md delete mode 100644 src/doc/unstable-book/src/library-features/fmt-internals.md delete mode 100644 src/doc/unstable-book/src/library-features/internal-output-capture.md delete mode 100644 src/doc/unstable-book/src/library-features/libstd-sys-internals.md delete mode 100644 src/doc/unstable-book/src/library-features/print-internals.md delete mode 100644 src/doc/unstable-book/src/library-features/profiler-runtime-lib.md delete mode 100644 src/doc/unstable-book/src/library-features/rt.md delete mode 100644 src/doc/unstable-book/src/library-features/sort-internals.md delete mode 100644 src/doc/unstable-book/src/library-features/str-internals.md delete mode 100644 src/doc/unstable-book/src/library-features/thread-local-internals.md delete mode 100644 src/doc/unstable-book/src/library-features/update-panic-count.md delete mode 100644 src/doc/unstable-book/src/library-features/windows-c.md delete mode 100644 src/doc/unstable-book/src/library-features/windows-handle.md delete mode 100644 src/doc/unstable-book/src/library-features/windows-net.md delete mode 100644 src/doc/unstable-book/src/library-features/windows-stdio.md create mode 100644 src/tools/unstable-book-gen/src/issue.md create mode 100644 src/tools/unstable-book-gen/src/no-issue.md diff --git a/Cargo.lock b/Cargo.lock index ab33f6f030a7e..24728717670da 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5906,6 +5906,9 @@ name = "unstable-book-gen" version = "0.1.0" dependencies = [ "num-traits", + "rustdoc-json-types", + "serde_json", + "syn", "tidy", ] diff --git a/src/bootstrap/src/core/build_steps/doc.rs b/src/bootstrap/src/core/build_steps/doc.rs index 628a4ece8e904..cb1c1aca758f0 100644 --- a/src/bootstrap/src/core/build_steps/doc.rs +++ b/src/bootstrap/src/core/build_steps/doc.rs @@ -965,6 +965,13 @@ impl Step for UnstableBookGen { fn run(self, builder: &Builder<'_>) { let target = self.target; + let host = builder.build.build; + + builder.ensure(Std { + stage: builder.top_stage, + target: host, + format: DocumentationFormat::JSON, + }); builder.info(&format!("Generating unstable book md files ({target})")); let out = builder.md_doc_out(target).join("unstable-book"); @@ -974,6 +981,7 @@ impl Step for UnstableBookGen { cmd.arg(builder.src.join("library")); cmd.arg(builder.src.join("compiler")); cmd.arg(builder.src.join("src")); + cmd.arg(builder.json_doc_out(host)); cmd.arg(out); builder.run(&mut cmd); diff --git a/src/bootstrap/src/tests/builder.rs b/src/bootstrap/src/tests/builder.rs index 96139f7b099ce..f1b0a81d31bf2 100644 --- a/src/bootstrap/src/tests/builder.rs +++ b/src/bootstrap/src/tests/builder.rs @@ -312,7 +312,7 @@ mod dist { // Make sure rustdoc is only built once. assert_eq!( first(cache.all::()), - &[tool::Rustdoc { compiler: Compiler { host: a, stage: 2 } },] + &[tool::Rustdoc { compiler: Compiler { host: a, stage: 2 } }] ); } @@ -636,7 +636,7 @@ mod dist { // stage minus 1 if --stage is not 0. Very confusing! assert_eq!( first(builder.cache.all::()), - &[tool::Rustdoc { compiler: Compiler { host: a, stage: 2 } },] + &[tool::Rustdoc { compiler: Compiler { host: a, stage: 2 } }] ); } diff --git a/src/doc/unstable-book/src/library-features/allocator-api.md b/src/doc/unstable-book/src/library-features/allocator-api.md index 9f045ce08a433..18af8f08b6867 100644 --- a/src/doc/unstable-book/src/library-features/allocator-api.md +++ b/src/doc/unstable-book/src/library-features/allocator-api.md @@ -1,11 +1,3 @@ -# `allocator_api` - -The tracking issue for this feature is [#32838] - -[#32838]: https://github.com/rust-lang/rust/issues/32838 - ------------------------- - Sometimes you want the memory for one collection to use a different allocator than the memory for another collection. In this case, replacing the global allocator is not a workable option. Instead, diff --git a/src/doc/unstable-book/src/library-features/c-variadic.md b/src/doc/unstable-book/src/library-features/c-variadic.md index 77762116e6b1c..6d2fe86d0610a 100644 --- a/src/doc/unstable-book/src/library-features/c-variadic.md +++ b/src/doc/unstable-book/src/library-features/c-variadic.md @@ -1,11 +1,3 @@ -# `c_variadic` - -The tracking issue for this feature is: [#44930] - -[#44930]: https://github.com/rust-lang/rust/issues/44930 - ------------------------- - The `c_variadic` library feature exposes the `VaList` structure, Rust's analogue of C's `va_list` type. diff --git a/src/doc/unstable-book/src/library-features/c-void-variant.md b/src/doc/unstable-book/src/library-features/c-void-variant.md deleted file mode 100644 index a2fdc99363007..0000000000000 --- a/src/doc/unstable-book/src/library-features/c-void-variant.md +++ /dev/null @@ -1,5 +0,0 @@ -# `c_void_variant` - -This feature is internal to the Rust compiler and is not intended for general use. - ------------------------- diff --git a/src/doc/unstable-book/src/library-features/concat-idents.md b/src/doc/unstable-book/src/library-features/concat-idents.md index 73f6cfa21787e..b181f8c4c0bc2 100644 --- a/src/doc/unstable-book/src/library-features/concat-idents.md +++ b/src/doc/unstable-book/src/library-features/concat-idents.md @@ -1,11 +1,3 @@ -# `concat_idents` - -The tracking issue for this feature is: [#29599] - -[#29599]: https://github.com/rust-lang/rust/issues/29599 - ------------------------- - The `concat_idents` feature adds a macro for concatenating multiple identifiers into one identifier. diff --git a/src/doc/unstable-book/src/library-features/core-intrinsics.md b/src/doc/unstable-book/src/library-features/core-intrinsics.md deleted file mode 100644 index 28ad3525ef7a6..0000000000000 --- a/src/doc/unstable-book/src/library-features/core-intrinsics.md +++ /dev/null @@ -1,5 +0,0 @@ -# `core_intrinsics` - -This feature is internal to the Rust compiler and is not intended for general use. - ------------------------- diff --git a/src/doc/unstable-book/src/library-features/core-panic.md b/src/doc/unstable-book/src/library-features/core-panic.md deleted file mode 100644 index c197588404c93..0000000000000 --- a/src/doc/unstable-book/src/library-features/core-panic.md +++ /dev/null @@ -1,5 +0,0 @@ -# `core_panic` - -This feature is internal to the Rust compiler and is not intended for general use. - ------------------------- diff --git a/src/doc/unstable-book/src/library-features/core-private-bignum.md b/src/doc/unstable-book/src/library-features/core-private-bignum.md deleted file mode 100644 index f85811c545e43..0000000000000 --- a/src/doc/unstable-book/src/library-features/core-private-bignum.md +++ /dev/null @@ -1,5 +0,0 @@ -# `core_private_bignum` - -This feature is internal to the Rust compiler and is not intended for general use. - ------------------------- diff --git a/src/doc/unstable-book/src/library-features/core-private-diy-float.md b/src/doc/unstable-book/src/library-features/core-private-diy-float.md deleted file mode 100644 index 8465921d673b1..0000000000000 --- a/src/doc/unstable-book/src/library-features/core-private-diy-float.md +++ /dev/null @@ -1,5 +0,0 @@ -# `core_private_diy_float` - -This feature is internal to the Rust compiler and is not intended for general use. - ------------------------- diff --git a/src/doc/unstable-book/src/library-features/dec2flt.md b/src/doc/unstable-book/src/library-features/dec2flt.md deleted file mode 100644 index 311ab4adcfd75..0000000000000 --- a/src/doc/unstable-book/src/library-features/dec2flt.md +++ /dev/null @@ -1,5 +0,0 @@ -# `dec2flt` - -This feature is internal to the Rust compiler and is not intended for general use. - ------------------------- diff --git a/src/doc/unstable-book/src/library-features/derive-clone-copy.md b/src/doc/unstable-book/src/library-features/derive-clone-copy.md deleted file mode 100644 index cc603911cbd29..0000000000000 --- a/src/doc/unstable-book/src/library-features/derive-clone-copy.md +++ /dev/null @@ -1,5 +0,0 @@ -# `derive_clone_copy` - -This feature is internal to the Rust compiler and is not intended for general use. - ------------------------- diff --git a/src/doc/unstable-book/src/library-features/derive-eq.md b/src/doc/unstable-book/src/library-features/derive-eq.md deleted file mode 100644 index 68a275f5419d4..0000000000000 --- a/src/doc/unstable-book/src/library-features/derive-eq.md +++ /dev/null @@ -1,5 +0,0 @@ -# `derive_eq` - -This feature is internal to the Rust compiler and is not intended for general use. - ------------------------- diff --git a/src/doc/unstable-book/src/library-features/fd-read.md b/src/doc/unstable-book/src/library-features/fd-read.md deleted file mode 100644 index e78d4330abfc0..0000000000000 --- a/src/doc/unstable-book/src/library-features/fd-read.md +++ /dev/null @@ -1,5 +0,0 @@ -# `fd_read` - -This feature is internal to the Rust compiler and is not intended for general use. - ------------------------- diff --git a/src/doc/unstable-book/src/library-features/fd.md b/src/doc/unstable-book/src/library-features/fd.md deleted file mode 100644 index 0414244285ba7..0000000000000 --- a/src/doc/unstable-book/src/library-features/fd.md +++ /dev/null @@ -1,5 +0,0 @@ -# `fd` - -This feature is internal to the Rust compiler and is not intended for general use. - ------------------------- diff --git a/src/doc/unstable-book/src/library-features/flt2dec.md b/src/doc/unstable-book/src/library-features/flt2dec.md deleted file mode 100644 index 15e62a3a7dad0..0000000000000 --- a/src/doc/unstable-book/src/library-features/flt2dec.md +++ /dev/null @@ -1,5 +0,0 @@ -# `flt2dec` - -This feature is internal to the Rust compiler and is not intended for general use. - ------------------------- diff --git a/src/doc/unstable-book/src/library-features/fmt-internals.md b/src/doc/unstable-book/src/library-features/fmt-internals.md deleted file mode 100644 index 7cbe3c89a6441..0000000000000 --- a/src/doc/unstable-book/src/library-features/fmt-internals.md +++ /dev/null @@ -1,5 +0,0 @@ -# `fmt_internals` - -This feature is internal to the Rust compiler and is not intended for general use. - ------------------------- diff --git a/src/doc/unstable-book/src/library-features/fn-traits.md b/src/doc/unstable-book/src/library-features/fn-traits.md index 180184146d1a0..f358cb4b126b2 100644 --- a/src/doc/unstable-book/src/library-features/fn-traits.md +++ b/src/doc/unstable-book/src/library-features/fn-traits.md @@ -1,13 +1,3 @@ -# `fn_traits` - -The tracking issue for this feature is [#29625] - -See Also: [`unboxed_closures`](../language-features/unboxed-closures.md) - -[#29625]: https://github.com/rust-lang/rust/issues/29625 - ----- - The `fn_traits` feature allows for implementation of the [`Fn*`] traits for creating custom closure-like types. diff --git a/src/doc/unstable-book/src/library-features/internal-output-capture.md b/src/doc/unstable-book/src/library-features/internal-output-capture.md deleted file mode 100644 index 7e1241fce985a..0000000000000 --- a/src/doc/unstable-book/src/library-features/internal-output-capture.md +++ /dev/null @@ -1,5 +0,0 @@ -# `internal_output_capture` - -This feature is internal to the Rust compiler and is not intended for general use. - ------------------------- diff --git a/src/doc/unstable-book/src/library-features/is-sorted.md b/src/doc/unstable-book/src/library-features/is-sorted.md index e3b7dc3b28eb2..26385e9f6f978 100644 --- a/src/doc/unstable-book/src/library-features/is-sorted.md +++ b/src/doc/unstable-book/src/library-features/is-sorted.md @@ -1,11 +1,3 @@ -# `is_sorted` - -The tracking issue for this feature is: [#53485] - -[#53485]: https://github.com/rust-lang/rust/issues/53485 - ------------------------- - Add the methods `is_sorted`, `is_sorted_by` and `is_sorted_by_key` to `[T]`; add the methods `is_sorted`, `is_sorted_by` and `is_sorted_by_key` to `Iterator`. diff --git a/src/doc/unstable-book/src/library-features/libstd-sys-internals.md b/src/doc/unstable-book/src/library-features/libstd-sys-internals.md deleted file mode 100644 index 1b53faa8a0071..0000000000000 --- a/src/doc/unstable-book/src/library-features/libstd-sys-internals.md +++ /dev/null @@ -1,5 +0,0 @@ -# `libstd_sys_internals` - -This feature is internal to the Rust compiler and is not intended for general use. - ------------------------- diff --git a/src/doc/unstable-book/src/library-features/print-internals.md b/src/doc/unstable-book/src/library-features/print-internals.md deleted file mode 100644 index a68557872af55..0000000000000 --- a/src/doc/unstable-book/src/library-features/print-internals.md +++ /dev/null @@ -1,5 +0,0 @@ -# `print_internals` - -This feature is internal to the Rust compiler and is not intended for general use. - ------------------------- diff --git a/src/doc/unstable-book/src/library-features/profiler-runtime-lib.md b/src/doc/unstable-book/src/library-features/profiler-runtime-lib.md deleted file mode 100644 index a01f1e73ab404..0000000000000 --- a/src/doc/unstable-book/src/library-features/profiler-runtime-lib.md +++ /dev/null @@ -1,5 +0,0 @@ -# `profiler_runtime_lib` - -This feature is internal to the Rust compiler and is not intended for general use. - ------------------------- diff --git a/src/doc/unstable-book/src/library-features/rt.md b/src/doc/unstable-book/src/library-features/rt.md deleted file mode 100644 index 007acc207a655..0000000000000 --- a/src/doc/unstable-book/src/library-features/rt.md +++ /dev/null @@ -1,5 +0,0 @@ -# `rt` - -This feature is internal to the Rust compiler and is not intended for general use. - ------------------------- diff --git a/src/doc/unstable-book/src/library-features/sort-internals.md b/src/doc/unstable-book/src/library-features/sort-internals.md deleted file mode 100644 index 6f2385e53008a..0000000000000 --- a/src/doc/unstable-book/src/library-features/sort-internals.md +++ /dev/null @@ -1,5 +0,0 @@ -# `sort_internals` - -This feature is internal to the Rust compiler and is not intended for general use. - ------------------------- diff --git a/src/doc/unstable-book/src/library-features/str-internals.md b/src/doc/unstable-book/src/library-features/str-internals.md deleted file mode 100644 index af8ef056dbe27..0000000000000 --- a/src/doc/unstable-book/src/library-features/str-internals.md +++ /dev/null @@ -1,5 +0,0 @@ -# `str_internals` - -This feature is internal to the Rust compiler and is not intended for general use. - ------------------------- diff --git a/src/doc/unstable-book/src/library-features/test.md b/src/doc/unstable-book/src/library-features/test.md index c99584e5fb397..87730a3c3c92c 100644 --- a/src/doc/unstable-book/src/library-features/test.md +++ b/src/doc/unstable-book/src/library-features/test.md @@ -1,9 +1,3 @@ -# `test` - -The tracking issue for this feature is: None. - ------------------------- - The internals of the `test` crate are unstable, behind the `test` flag. The most widely used part of the `test` crate are benchmark tests, which can test the performance of your code. Let's make our `src/lib.rs` look like this diff --git a/src/doc/unstable-book/src/library-features/thread-local-internals.md b/src/doc/unstable-book/src/library-features/thread-local-internals.md deleted file mode 100644 index e1cdcc339d229..0000000000000 --- a/src/doc/unstable-book/src/library-features/thread-local-internals.md +++ /dev/null @@ -1,5 +0,0 @@ -# `thread_local_internals` - -This feature is internal to the Rust compiler and is not intended for general use. - ------------------------- diff --git a/src/doc/unstable-book/src/library-features/trace-macros.md b/src/doc/unstable-book/src/library-features/trace-macros.md index 41aa286e69bfb..7fd0ff392f0b6 100644 --- a/src/doc/unstable-book/src/library-features/trace-macros.md +++ b/src/doc/unstable-book/src/library-features/trace-macros.md @@ -1,11 +1,3 @@ -# `trace_macros` - -The tracking issue for this feature is [#29598]. - -[#29598]: https://github.com/rust-lang/rust/issues/29598 - ------------------------- - With `trace_macros` you can trace the expansion of macros in your code. ## Examples diff --git a/src/doc/unstable-book/src/library-features/update-panic-count.md b/src/doc/unstable-book/src/library-features/update-panic-count.md deleted file mode 100644 index d315647ba1049..0000000000000 --- a/src/doc/unstable-book/src/library-features/update-panic-count.md +++ /dev/null @@ -1,5 +0,0 @@ -# `update_panic_count` - -This feature is internal to the Rust compiler and is not intended for general use. - ------------------------- diff --git a/src/doc/unstable-book/src/library-features/windows-c.md b/src/doc/unstable-book/src/library-features/windows-c.md deleted file mode 100644 index 3f833eb3d093e..0000000000000 --- a/src/doc/unstable-book/src/library-features/windows-c.md +++ /dev/null @@ -1,5 +0,0 @@ -# `windows_c` - -This feature is internal to the Rust compiler and is not intended for general use. - ------------------------- diff --git a/src/doc/unstable-book/src/library-features/windows-handle.md b/src/doc/unstable-book/src/library-features/windows-handle.md deleted file mode 100644 index f47a8425045b9..0000000000000 --- a/src/doc/unstable-book/src/library-features/windows-handle.md +++ /dev/null @@ -1,5 +0,0 @@ -# `windows_handle` - -This feature is internal to the Rust compiler and is not intended for general use. - ------------------------- diff --git a/src/doc/unstable-book/src/library-features/windows-net.md b/src/doc/unstable-book/src/library-features/windows-net.md deleted file mode 100644 index 174960d4f0048..0000000000000 --- a/src/doc/unstable-book/src/library-features/windows-net.md +++ /dev/null @@ -1,5 +0,0 @@ -# `windows_net` - -This feature is internal to the Rust compiler and is not intended for general use. - ------------------------- diff --git a/src/doc/unstable-book/src/library-features/windows-stdio.md b/src/doc/unstable-book/src/library-features/windows-stdio.md deleted file mode 100644 index 4d361442386a2..0000000000000 --- a/src/doc/unstable-book/src/library-features/windows-stdio.md +++ /dev/null @@ -1,5 +0,0 @@ -# `windows_stdio` - -This feature is internal to the Rust compiler and is not intended for general use. - ------------------------- diff --git a/src/tools/unstable-book-gen/Cargo.toml b/src/tools/unstable-book-gen/Cargo.toml index 73e5a91bec70a..3945deafc6b51 100644 --- a/src/tools/unstable-book-gen/Cargo.toml +++ b/src/tools/unstable-book-gen/Cargo.toml @@ -7,6 +7,11 @@ edition = "2021" [dependencies] tidy = { path = "../tidy" } + +serde_json = "1" +rustdoc-json-types = { path = "../../rustdoc-json-types" } +syn = { version = "1", features = ["full"] } + # not actually needed but required for now to unify the feature selection of # `num-traits` between this and `rustbook` num-traits = "0.2" diff --git a/src/tools/unstable-book-gen/src/issue.md b/src/tools/unstable-book-gen/src/issue.md new file mode 100644 index 0000000000000..665c95c25aaff --- /dev/null +++ b/src/tools/unstable-book-gen/src/issue.md @@ -0,0 +1,9 @@ +# `{name}` + +The tracking issue for this feature is: [#{issue}] +{items} +[#{issue}]: https://github.com/rust-lang/rust/issues/{issue} + +------------------------ + +{notes} diff --git a/src/tools/unstable-book-gen/src/main.rs b/src/tools/unstable-book-gen/src/main.rs index a9830a3840d1a..80e46b882e5b8 100644 --- a/src/tools/unstable-book-gen/src/main.rs +++ b/src/tools/unstable-book-gen/src/main.rs @@ -1,8 +1,10 @@ //! Auto-generate stub docs for the unstable book use std::collections::BTreeSet; +use std::collections::HashMap; use std::env; use std::fs::{self, write}; +use std::io::BufReader; use std::path::Path; use tidy::features::{collect_lang_features, collect_lib_features, Features}; use tidy::t; @@ -11,13 +13,121 @@ use tidy::unstable_book::{ LIB_FEATURES_DIR, PATH_STR, }; -fn generate_stub_issue(path: &Path, name: &str, issue: u32) { - let content = format!(include_str!("stub-issue.md"), name = name, issue = issue); +use rustdoc_json_types::{Crate, Id}; +use syn::{parse::Parser, Ident, Lit, Meta, NestedMeta}; + +// (item path, doc url) +fn full_path(krate: &Crate, item: &Id) -> Option<(String, String)> { + let item_summary = krate.paths.get(item)?; + let kind = &item_summary.kind; + let kind_str = serde_json::to_string(kind).ok()?; + let mut url = String::from("https://doc.rust-lang.org/nightly/"); + let mut iter = item_summary.path.iter(); + iter.next_back(); + url.push_str(&iter.cloned().collect::>().join("/")); + url.push('/'); + url.push_str(kind_str.trim_matches('"')); + url.push('.'); + url.push_str(item_summary.path.last().unwrap()); + url.push_str(".html"); + Some((item_summary.path.join("::"), url)) +} + +fn is_ident(ident: &Ident, name: &str) -> bool { + *ident == Ident::new(name, ident.span()) +} + +/// Returns an unstable feature -> (item path, doc url) mapping. +pub fn load_rustdoc_json_metadata(doc_dir: &Path) -> HashMap> { + let mut all_items = HashMap::new(); + + for file in fs::read_dir(doc_dir).expect("failed to list files in directory") { + let entry = file.expect("failed to list file in directory"); + let file = fs::File::open(entry.path()).expect("failed to open file"); + let krate: Crate = + serde_json::from_reader(BufReader::new(file)).expect("failed to parse JSON docs"); + + let mut crate_items = HashMap::new(); + for (id, item) in &krate.index { + if item.name.is_none() { + continue; + } + let unstable_feature = item.attrs.iter().find_map(|attr: &String| { + let Ok(parsed) = syn::Attribute::parse_outer.parse_str(attr).map(|mut v| v.swap_remove(0)) else {return None}; + + // Make sure this is an `unstable` attribute. + if !is_ident(parsed.path.get_ident()?, "unstable") { + return None; + } + + // Given `#[unstable(feature = "xyz")]`, return `(feature = "xyz")`. + let list = match parsed.parse_meta() { + Ok(Meta::List(list)) => list, + _ => return None, + }; + + // Given a `NestedMeta` like `feature = "xyz"`, returns `xyz`. + let get_feature_name = |nested: &_| { + match nested { + NestedMeta::Meta(Meta::NameValue(name_value)) => { + if !is_ident(name_value.path.get_ident()?, "feature") { + return None; + } + match &name_value.lit { + Lit::Str(s) => Some(s.value()), + _ => None, + } + } + _ => None, + } + }; + + for nested in list.nested.iter() { + if let Some(feat) = get_feature_name(nested) { + return Some(feat); + } + } + + None + }); + if let Some(feat) = unstable_feature { + crate_items.insert(id, feat); + } + } + + for (item, feat) in + crate_items.into_iter().flat_map(|(item, feat)| Some((full_path(&krate, item)?, feat))) + { + all_items.insert(item, feat.to_owned()); + } + } + + let mut out: HashMap<_, Vec<_>> = HashMap::new(); + for (item, feature) in all_items { + out.entry(feature).or_default().push(item); + } + + out +} + +fn generate_stub_issue(path: &Path, name: &str, issue: u32, items: &str) { + let content = format!(include_str!("stub-issue.md"), name = name, issue = issue, items = items); t!(write(path, content), path); } -fn generate_stub_no_issue(path: &Path, name: &str) { - let content = format!(include_str!("stub-no-issue.md"), name = name); +fn generate_stub_no_issue(path: &Path, name: &str, items: &str) { + let content = format!(include_str!("stub-no-issue.md"), name = name, items = items); + t!(write(path, content), path); +} + +fn generate_issue(path: &Path, name: &str, issue: u32, items: &str, notes: &str) { + let content = + format!(include_str!("issue.md"), name = name, issue = issue, items = items, notes = notes); + t!(write(path, content), path); +} + +fn generate_no_issue(path: &Path, name: &str, items: &str, notes: &str) { + let content = format!(include_str!("no-issue.md"), name = name, items = items, notes = notes); t!(write(path, content), path); } @@ -48,7 +158,7 @@ fn generate_summary(path: &Path, lang_features: &Features, lib_features: &Featur t!(write(&summary_path, content), summary_path); } -fn generate_unstable_book_files(src: &Path, out: &Path, features: &Features) { +fn generate_unstable_book_files_lang(src: &Path, out: &Path, features: &Features) { let unstable_features = collect_unstable_feature_names(features); let unstable_section_file_names = collect_unstable_book_section_file_names(src); t!(fs::create_dir_all(&out)); @@ -59,9 +169,50 @@ fn generate_unstable_book_files(src: &Path, out: &Path, features: &Features) { let feature = &features[&feature_name_underscore]; if let Some(issue) = feature.tracking_issue { - generate_stub_issue(&out_file_path, &feature_name_underscore, issue.get()); + generate_stub_issue(&out_file_path, &feature_name_underscore, issue.get(), ""); + } else { + generate_stub_no_issue(&out_file_path, &feature_name_underscore, ""); + } + } +} + +fn generate_unstable_book_files_lib(src: &Path, doc: &Path, out: &Path, features: &Features) { + let unstable_features = collect_unstable_feature_names(features); + let unstable_section_file_names = collect_unstable_book_section_file_names(src); + let features_items = load_rustdoc_json_metadata(doc); + t!(fs::create_dir_all(&out)); + for feature_name in &unstable_features { + let feature_name_underscore = feature_name.replace('-', "_"); + let file_name = format!("{feature_name}.md"); + let out_file_path = out.join(&file_name); + let feature = &features[&feature_name_underscore]; + let items = features_items.get(&feature_name_underscore).map(|v| { + format!( + "\nItems:\n\n{}", + v.iter().map(|(path, url)| format!("- [`{path}`]({url})\n")).collect::() + ) + }); + let notes = if unstable_section_file_names.contains(feature_name) { + fs::read_to_string(src.join(&file_name)).unwrap() + } else { + String::from("") + }; + + if let Some(issue) = feature.tracking_issue { + generate_issue( + &out_file_path, + &feature_name_underscore, + issue.get(), + &items.unwrap_or_default(), + ¬es, + ); } else { - generate_stub_no_issue(&out_file_path, &feature_name_underscore); + generate_no_issue( + &out_file_path, + &feature_name_underscore, + &items.unwrap_or_default(), + ¬es, + ); } } } @@ -72,7 +223,9 @@ fn copy_recursive(from: &Path, to: &Path) { let t = t!(e.metadata()); let dest = &to.join(e.file_name()); if t.is_file() { - t!(fs::copy(&e.path(), dest)); + if !dest.exists() { + t!(fs::copy(&e.path(), dest)); + } } else if t.is_dir() { t!(fs::create_dir_all(dest)); copy_recursive(&e.path(), dest); @@ -84,10 +237,12 @@ fn main() { let library_path_str = env::args_os().nth(1).expect("library/ path required"); let compiler_path_str = env::args_os().nth(2).expect("compiler/ path required"); let src_path_str = env::args_os().nth(3).expect("src/ path required"); - let dest_path_str = env::args_os().nth(4).expect("destination path required"); + let doc_path_str = env::args_os().nth(4).expect("json docs required"); + let dest_path_str = env::args_os().nth(5).expect("destination path required"); let library_path = Path::new(&library_path_str); let compiler_path = Path::new(&compiler_path_str); let src_path = Path::new(&src_path_str); + let doc_path = Path::new(&doc_path_str); let dest_path = Path::new(&dest_path_str); let lang_features = collect_lang_features(compiler_path, &mut false); @@ -100,13 +255,14 @@ fn main() { t!(fs::create_dir_all(&dest_path)); - generate_unstable_book_files( + generate_unstable_book_files_lang( &doc_src_path.join(LANG_FEATURES_DIR), &dest_path.join(LANG_FEATURES_DIR), &lang_features, ); - generate_unstable_book_files( + generate_unstable_book_files_lib( &doc_src_path.join(LIB_FEATURES_DIR), + doc_path, &dest_path.join(LIB_FEATURES_DIR), &lib_features, ); diff --git a/src/tools/unstable-book-gen/src/no-issue.md b/src/tools/unstable-book-gen/src/no-issue.md new file mode 100644 index 0000000000000..f2aa69366e5c9 --- /dev/null +++ b/src/tools/unstable-book-gen/src/no-issue.md @@ -0,0 +1,7 @@ +# `{name}` +{items} +This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. + +------------------------ + +{notes} diff --git a/src/tools/unstable-book-gen/src/stub-issue.md b/src/tools/unstable-book-gen/src/stub-issue.md index 8698fb7278f6a..8928613cd59ee 100644 --- a/src/tools/unstable-book-gen/src/stub-issue.md +++ b/src/tools/unstable-book-gen/src/stub-issue.md @@ -1,7 +1,7 @@ # `{name}` The tracking issue for this feature is: [#{issue}] - +{items} [#{issue}]: https://github.com/rust-lang/rust/issues/{issue} ------------------------ diff --git a/src/tools/unstable-book-gen/src/stub-no-issue.md b/src/tools/unstable-book-gen/src/stub-no-issue.md index 3da140633d0f7..e2245c0f6b6ef 100644 --- a/src/tools/unstable-book-gen/src/stub-no-issue.md +++ b/src/tools/unstable-book-gen/src/stub-no-issue.md @@ -1,5 +1,5 @@ # `{name}` - +{items} This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. ------------------------ From f2735b7994007ce156dfdb17e33f56aa43aacfe6 Mon Sep 17 00:00:00 2001 From: Albert Larsan <74931857+albertlarsan68@users.noreply.github.com> Date: Fri, 10 Feb 2023 14:14:13 +0000 Subject: [PATCH 2/3] Make the link generation work for more cases --- src/tools/unstable-book-gen/src/main.rs | 113 ++++++++++++++++-------- 1 file changed, 78 insertions(+), 35 deletions(-) diff --git a/src/tools/unstable-book-gen/src/main.rs b/src/tools/unstable-book-gen/src/main.rs index 80e46b882e5b8..7f91e7a841f20 100644 --- a/src/tools/unstable-book-gen/src/main.rs +++ b/src/tools/unstable-book-gen/src/main.rs @@ -20,19 +20,63 @@ use syn::{parse::Parser, Ident, Lit, Meta, NestedMeta}; fn full_path(krate: &Crate, item: &Id) -> Option<(String, String)> { let item_summary = krate.paths.get(item)?; let kind = &item_summary.kind; - let kind_str = serde_json::to_string(kind).ok()?; + let kind_str = match kind { + rustdoc_json_types::ItemKind::AssocConst => todo!("assoc_const"), + rustdoc_json_types::ItemKind::AssocType => todo!("assoc_type"), + rustdoc_json_types::ItemKind::Constant => "constant", + rustdoc_json_types::ItemKind::Enum => "enum", + rustdoc_json_types::ItemKind::ExternCrate => todo!("extern_crate"), + rustdoc_json_types::ItemKind::ForeignType => todo!("foreign_type"), + rustdoc_json_types::ItemKind::Function => "fn", + rustdoc_json_types::ItemKind::Impl => todo!("impl"), + rustdoc_json_types::ItemKind::Import => todo!("import"), + rustdoc_json_types::ItemKind::Keyword => todo!("keyword"), + rustdoc_json_types::ItemKind::Macro => "macro", + rustdoc_json_types::ItemKind::Module => "index", + rustdoc_json_types::ItemKind::OpaqueTy => todo!("opaque_ty"), + rustdoc_json_types::ItemKind::Primitive => "primitive", + rustdoc_json_types::ItemKind::ProcAttribute => todo!("proc_attribute"), + rustdoc_json_types::ItemKind::ProcDerive => todo!("proc_derive"), + rustdoc_json_types::ItemKind::Static => "static", + rustdoc_json_types::ItemKind::Struct => "struct", + rustdoc_json_types::ItemKind::StructField => todo!("struct_field"), + rustdoc_json_types::ItemKind::Trait => "trait", + rustdoc_json_types::ItemKind::TraitAlias => "trait_alias", + rustdoc_json_types::ItemKind::Typedef => "type", + rustdoc_json_types::ItemKind::Union => todo!("union"), + rustdoc_json_types::ItemKind::Variant => { + return Some((item_summary.path.join("::"), specialcase_variant(&item_summary.path))); + } + }; let mut url = String::from("https://doc.rust-lang.org/nightly/"); let mut iter = item_summary.path.iter(); - iter.next_back(); + if !matches!(kind, rustdoc_json_types::ItemKind::Module) { + iter.next_back(); + } url.push_str(&iter.cloned().collect::>().join("/")); url.push('/'); - url.push_str(kind_str.trim_matches('"')); - url.push('.'); - url.push_str(item_summary.path.last().unwrap()); + url.push_str(kind_str); + if !matches!(kind, rustdoc_json_types::ItemKind::Module) { + url.push('.'); + url.push_str(item_summary.path.last().unwrap()); + } url.push_str(".html"); Some((item_summary.path.join("::"), url)) } +fn specialcase_variant(path: &[String]) -> String { + let mut iter = path.iter(); + let mut out = String::from("https://doc.rust-lang.org/nightly/"); + let variant = iter.next_back(); + let enum_name = iter.next_back(); + out.push_str(&iter.cloned().collect::>().join("/")); + out.push_str("/enum."); + out.push_str(enum_name.unwrap()); + out.push_str(".html#variant."); + out.push_str(variant.unwrap()); + out +} + fn is_ident(ident: &Ident, name: &str) -> bool { *ident == Ident::new(name, ident.span()) } @@ -41,6 +85,20 @@ fn is_ident(ident: &Ident, name: &str) -> bool { pub fn load_rustdoc_json_metadata(doc_dir: &Path) -> HashMap> { let mut all_items = HashMap::new(); + // Given a `NestedMeta` like `feature = "xyz"`, returns `xyz`. + let get_feature_name = |nested: &_| match nested { + NestedMeta::Meta(Meta::NameValue(name_value)) => { + if !is_ident(name_value.path.get_ident()?, "feature") { + return None; + } + match &name_value.lit { + Lit::Str(s) => Some(s.value()), + _ => None, + } + } + _ => None, + }; + for file in fs::read_dir(doc_dir).expect("failed to list files in directory") { let entry = file.expect("failed to list file in directory"); let file = fs::File::open(entry.path()).expect("failed to open file"); @@ -53,41 +111,26 @@ pub fn load_rustdoc_json_metadata(doc_dir: &Path) -> HashMap list, + _ => continue, + }; - // Given `#[unstable(feature = "xyz")]`, return `(feature = "xyz")`. - let list = match parsed.parse_meta() { - Ok(Meta::List(list)) => list, - _ => return None, - }; - - // Given a `NestedMeta` like `feature = "xyz"`, returns `xyz`. - let get_feature_name = |nested: &_| { - match nested { - NestedMeta::Meta(Meta::NameValue(name_value)) => { - if !is_ident(name_value.path.get_ident()?, "feature") { - return None; - } - match &name_value.lit { - Lit::Str(s) => Some(s.value()), - _ => None, - } + for nested in list.nested.iter() { + if let Some(feat) = get_feature_name(nested) { + return Some(feat); } - _ => None, - } - }; - - for nested in list.nested.iter() { - if let Some(feat) = get_feature_name(nested) { - return Some(feat); } } - None }); if let Some(feat) = unstable_feature { From ab4e80661af88bbeedb1d89ef6f7065ea8da6047 Mon Sep 17 00:00:00 2001 From: Albert Larsan <74931857+albertlarsan68@users.noreply.github.com> Date: Tue, 17 Oct 2023 17:08:23 +0000 Subject: [PATCH 3/3] Finish rebasing --- Cargo.lock | 2 +- src/bootstrap/src/core/build_steps/doc.rs | 11 ++++++----- src/tools/unstable-book-gen/src/main.rs | 8 ++++++-- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 24728717670da..fc29b02c1fac4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5908,7 +5908,7 @@ dependencies = [ "num-traits", "rustdoc-json-types", "serde_json", - "syn", + "syn 1.0.109", "tidy", ] diff --git a/src/bootstrap/src/core/build_steps/doc.rs b/src/bootstrap/src/core/build_steps/doc.rs index cb1c1aca758f0..b4ad046061244 100644 --- a/src/bootstrap/src/core/build_steps/doc.rs +++ b/src/bootstrap/src/core/build_steps/doc.rs @@ -967,11 +967,12 @@ impl Step for UnstableBookGen { let target = self.target; let host = builder.build.build; - builder.ensure(Std { - stage: builder.top_stage, - target: host, - format: DocumentationFormat::JSON, - }); + builder.ensure(Std::new( + builder.top_stage, + self.target, + builder, + DocumentationFormat::JSON, + )); builder.info(&format!("Generating unstable book md files ({target})")); let out = builder.md_doc_out(target).join("unstable-book"); diff --git a/src/tools/unstable-book-gen/src/main.rs b/src/tools/unstable-book-gen/src/main.rs index 7f91e7a841f20..59eb9ba02707a 100644 --- a/src/tools/unstable-book-gen/src/main.rs +++ b/src/tools/unstable-book-gen/src/main.rs @@ -111,9 +111,13 @@ pub fn load_rustdoc_json_metadata(doc_dir: &Path) -> HashMap