From cbf0e3b038be533e89d6ce34d583421c59266eb7 Mon Sep 17 00:00:00 2001 From: Saphereye Date: Tue, 2 Dec 2025 22:20:00 +0530 Subject: [PATCH 01/14] init --- src/librustdoc/config.rs | 5 ++ src/librustdoc/core.rs | 11 ++- src/librustdoc/formats/cache.rs | 10 ++- src/librustdoc/lib.rs | 8 +++ src/librustdoc/passes/mod.rs | 7 ++ src/librustdoc/passes/strip_deprecated.rs | 84 +++++++++++++++++++++++ 6 files changed, 122 insertions(+), 3 deletions(-) create mode 100644 src/librustdoc/passes/strip_deprecated.rs diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs index 5d16dff24c69a..3b544ff7ffbac 100644 --- a/src/librustdoc/config.rs +++ b/src/librustdoc/config.rs @@ -272,6 +272,8 @@ pub(crate) struct RenderOptions { pub(crate) document_private: bool, /// Document items that have `doc(hidden)`. pub(crate) document_hidden: bool, + /// Exclude items explicitly marked #[deprecated]. + pub(crate) exclude_deprecated: bool, /// If `true`, generate a JSON file in the crate folder instead of HTML redirection files. pub(crate) generate_redirect_map: bool, /// Show the memory layout of types in the docs. @@ -447,6 +449,7 @@ impl Options { WhenDocumentPrivate => println!(" (when --document-private-items)"), WhenNotDocumentPrivate => println!(" (when not --document-private-items)"), WhenNotDocumentHidden => println!(" (when not --document-hidden-items)"), + WhenExcludeDeprecated => println!(" (when --exclude-deprecated-items)"), } } @@ -788,6 +791,7 @@ impl Options { let test_runtool_args = matches.opt_strs("test-runtool-arg"); let document_private = matches.opt_present("document-private-items"); let document_hidden = matches.opt_present("document-hidden-items"); + let exclude_deprecated = matches.opt_present("exclude-deprecated-items"); let run_check = matches.opt_present("check"); let generate_redirect_map = matches.opt_present("generate-redirect-map"); let show_type_layout = matches.opt_present("show-type-layout"); @@ -888,6 +892,7 @@ impl Options { markdown_playground_url, document_private, document_hidden, + exclude_deprecated, generate_redirect_map, show_type_layout, unstable_features, diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 6e70f5b41c426..79aeb7cc90a21 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -147,6 +147,10 @@ impl<'tcx> DocContext<'tcx> { pub(crate) fn document_hidden(&self) -> bool { self.cache.document_hidden } + /// If `--exclude-deprecated-items` was passed to rustdoc. + pub(crate) fn exclude_deprecated(&self) -> bool { + self.cache.exclude_deprecated + } } /// Creates a new `DiagCtxt` that can be used to emit warnings and errors. @@ -384,7 +388,11 @@ pub(crate) fn run_global_ctxt( impl_trait_bounds: Default::default(), generated_synthetics: Default::default(), auto_traits, - cache: Cache::new(render_options.document_private, render_options.document_hidden), + cache: Cache::new( + render_options.document_private, + render_options.document_hidden, + render_options.exclude_deprecated, + ), inlined: FxHashSet::default(), output_format, show_coverage, @@ -434,6 +442,7 @@ pub(crate) fn run_global_ctxt( WhenDocumentPrivate => ctxt.document_private(), WhenNotDocumentPrivate => !ctxt.document_private(), WhenNotDocumentHidden => !ctxt.document_hidden(), + WhenExcludeDeprecated => ctxt.exclude_deprecated(), }; if run { debug!("running pass {}", p.pass.name); diff --git a/src/librustdoc/formats/cache.rs b/src/librustdoc/formats/cache.rs index 56f10b03d62de..501358ad89904 100644 --- a/src/librustdoc/formats/cache.rs +++ b/src/librustdoc/formats/cache.rs @@ -93,6 +93,8 @@ pub(crate) struct Cache { /// Whether to document hidden items. /// This is stored in `Cache` so it doesn't need to be passed through all rustdoc functions. pub(crate) document_hidden: bool, + /// Whether to exclude items explicitly marked `#[deprecated]`. + pub(crate) exclude_deprecated: bool, /// Crates marked with [`#[doc(masked)]`][doc_masked]. /// @@ -143,8 +145,12 @@ struct CacheBuilder<'a, 'tcx> { } impl Cache { - pub(crate) fn new(document_private: bool, document_hidden: bool) -> Self { - Cache { document_private, document_hidden, ..Cache::default() } + pub(crate) fn new( + document_private: bool, + document_hidden: bool, + exclude_deprecated: bool, + ) -> Self { + Cache { document_private, document_hidden, exclude_deprecated, ..Cache::default() } } fn parent_stack_last_impl_and_trait_id(&self) -> (Option, Option) { diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index e4601bfb20d7d..57d57d1e46c1c 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -254,6 +254,14 @@ fn opts() -> Vec { "document items that have doc(hidden)", "", ), + opt( + Unstable, + FlagMulti, + "", + "exclude-deprecated-items", + "exclude items that are explicitly marked #[deprecated]", + "", + ), opt(Stable, FlagMulti, "", "test", "run code examples as tests", ""), opt(Stable, Multi, "", "test-args", "arguments to pass to the test runner", "ARGS"), opt( diff --git a/src/librustdoc/passes/mod.rs b/src/librustdoc/passes/mod.rs index a1e8e75306235..bca20ec2c4260 100644 --- a/src/librustdoc/passes/mod.rs +++ b/src/librustdoc/passes/mod.rs @@ -20,6 +20,9 @@ pub(crate) use self::strip_private::STRIP_PRIVATE; mod strip_priv_imports; pub(crate) use self::strip_priv_imports::STRIP_PRIV_IMPORTS; +mod strip_deprecated; +pub(crate) use self::strip_deprecated::STRIP_DEPRECATED; + mod propagate_doc_cfg; pub(crate) use self::propagate_doc_cfg::PROPAGATE_DOC_CFG; @@ -71,6 +74,8 @@ pub(crate) enum Condition { WhenNotDocumentPrivate, /// When `--document-hidden-items` is not passed. WhenNotDocumentHidden, + /// When `--exclude-deprecated-items` is passed. + WhenExcludeDeprecated, } /// The full list of passes. @@ -82,6 +87,7 @@ pub(crate) const PASSES: &[Pass] = &[ STRIP_HIDDEN, STRIP_PRIVATE, STRIP_PRIV_IMPORTS, + STRIP_DEPRECATED, PROPAGATE_STABILITY, COLLECT_INTRA_DOC_LINKS, COLLECT_TRAIT_IMPLS, @@ -99,6 +105,7 @@ pub(crate) const DEFAULT_PASSES: &[ConditionalPass] = &[ ConditionalPass::new(STRIP_HIDDEN, WhenNotDocumentHidden), ConditionalPass::new(STRIP_PRIVATE, WhenNotDocumentPrivate), ConditionalPass::new(STRIP_PRIV_IMPORTS, WhenDocumentPrivate), + ConditionalPass::new(STRIP_DEPRECATED, WhenExcludeDeprecated), ConditionalPass::always(COLLECT_INTRA_DOC_LINKS), ConditionalPass::always(PROPAGATE_STABILITY), ConditionalPass::always(RUN_LINTS), diff --git a/src/librustdoc/passes/strip_deprecated.rs b/src/librustdoc/passes/strip_deprecated.rs new file mode 100644 index 0000000000000..7a1fc458be86f --- /dev/null +++ b/src/librustdoc/passes/strip_deprecated.rs @@ -0,0 +1,84 @@ +use rustc_middle::ty::TyCtxt; +use tracing::debug; + +use crate::clean::{self, Item, ItemIdSet}; +use crate::core::DocContext; +use crate::fold::{DocFolder, strip_item}; +use crate::passes::{ImplStripper, Pass}; + +/// Strips items that are explicitly marked with `#[deprecated]`. +pub(crate) const STRIP_DEPRECATED: Pass = Pass { + name: "strip-deprecated", + run: Some(strip_deprecated), + description: "strips all items explicitly marked #[deprecated]", +}; + +pub(crate) fn strip_deprecated(krate: clean::Crate, cx: &mut DocContext<'_>) -> clean::Crate { + // If the flag isn't set, this pass is a no-op. + if !cx.exclude_deprecated() { + return krate; + } + + let mut retained = ItemIdSet::default(); + let is_json_output = cx.is_json_output(); + + // First, strip all explicitly deprecated items. + let krate = { + let mut stripper = DeprecatedStripper { retained: &mut retained, tcx: cx.tcx }; + stripper.fold_crate(krate) + }; + + // Then, strip impls referencing stripped items. + let mut impl_stripper = ImplStripper { + tcx: cx.tcx, + retained: &retained, + cache: &cx.cache, + is_json_output, + document_private: cx.document_private(), + document_hidden: cx.document_hidden(), + }; + + impl_stripper.fold_crate(krate) +} + +struct DeprecatedStripper<'a, 'tcx> { + retained: &'a mut ItemIdSet, + tcx: TyCtxt<'tcx>, +} + +impl DocFolder for DeprecatedStripper<'_, '_> { + fn fold_item(&mut self, i: Item) -> Option { + // If this is a re-export of a deprecated item, remove the import entirely. + if let clean::ImportItem(clean::Import { source, .. }) = &i.kind + && let Some(source_did) = source.did + { + if self.tcx.lookup_deprecation(source_did).is_some() { + debug!("strip_deprecated: stripping re-export of deprecated item {:?}", i.name); + return None; + } + } + + // Determine whether this item itself is explicitly deprecated. + let is_explicitly_deprecated = i + .def_id() + .is_some_and(|did| self.tcx.lookup_deprecation(did).is_some()); + + if is_explicitly_deprecated { + debug!("strip_deprecated: stripping {:?} {:?}", i.type_(), i.name); + // For certain kinds, keep a stripped placeholder to preserve structure, + // similar to how strip_hidden handles fields/variants/modules. + match i.kind { + clean::StructFieldItem(..) | clean::ModuleItem(..) | clean::VariantItem(..) => { + // Recurse to allow nested items to be processed, then strip. + let recursed = self.fold_item_recur(i); + return Some(strip_item(recursed)); + } + _ => return None, + } + } + + // Keep the item, remember it as retained, and recurse. + self.retained.insert(i.item_id); + Some(self.fold_item_recur(i)) + } +} From 0e8dfd944116e6b1475953f33f13960d8bce4f31 Mon Sep 17 00:00:00 2001 From: Saphereye Date: Tue, 2 Dec 2025 22:58:58 +0530 Subject: [PATCH 02/14] fmt --- src/librustdoc/passes/strip_deprecated.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/librustdoc/passes/strip_deprecated.rs b/src/librustdoc/passes/strip_deprecated.rs index 7a1fc458be86f..f3eb4f2310389 100644 --- a/src/librustdoc/passes/strip_deprecated.rs +++ b/src/librustdoc/passes/strip_deprecated.rs @@ -59,9 +59,8 @@ impl DocFolder for DeprecatedStripper<'_, '_> { } // Determine whether this item itself is explicitly deprecated. - let is_explicitly_deprecated = i - .def_id() - .is_some_and(|did| self.tcx.lookup_deprecation(did).is_some()); + let is_explicitly_deprecated = + i.def_id().is_some_and(|did| self.tcx.lookup_deprecation(did).is_some()); if is_explicitly_deprecated { debug!("strip_deprecated: stripping {:?} {:?}", i.type_(), i.name); From 82c0c4869a573f3c5ed509eb2bb943e82e0614d8 Mon Sep 17 00:00:00 2001 From: Saphereye Date: Tue, 2 Dec 2025 23:47:50 +0530 Subject: [PATCH 03/14] added new arg to test to get it running --- src/librustdoc/clean/types/tests.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustdoc/clean/types/tests.rs b/src/librustdoc/clean/types/tests.rs index 9499507b2c0f9..ec52799f4dd3a 100644 --- a/src/librustdoc/clean/types/tests.rs +++ b/src/librustdoc/clean/types/tests.rs @@ -72,7 +72,7 @@ fn should_not_trim() { fn is_same_generic() { use crate::clean::types::{PrimitiveType, Type}; use crate::formats::cache::Cache; - let cache = Cache::new(false, false); + let cache = Cache::new(false, false, false); let generic = Type::Generic(rustc_span::symbol::sym::Any); let unit = Type::Primitive(PrimitiveType::Unit); assert!(!generic.is_doc_subtype_of(&unit, &cache)); From 0e42d62bf8f399760b8681351b4a7634c485dad4 Mon Sep 17 00:00:00 2001 From: Saphereye Date: Wed, 3 Dec 2025 18:29:40 +0530 Subject: [PATCH 04/14] changed exclusion of symbols, to simply hiding them --- src/librustdoc/config.rs | 9 ++- src/librustdoc/core.rs | 7 +- src/librustdoc/formats/cache.rs | 8 +-- src/librustdoc/html/render/context.rs | 14 +++- src/librustdoc/html/render/mod.rs | 4 ++ src/librustdoc/html/render/print_item.rs | 24 +++++++ src/librustdoc/lib.rs | 4 +- src/librustdoc/passes/mod.rs | 7 -- src/librustdoc/passes/strip_deprecated.rs | 83 ----------------------- 9 files changed, 52 insertions(+), 108 deletions(-) delete mode 100644 src/librustdoc/passes/strip_deprecated.rs diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs index 3b544ff7ffbac..135513f6def1d 100644 --- a/src/librustdoc/config.rs +++ b/src/librustdoc/config.rs @@ -272,8 +272,8 @@ pub(crate) struct RenderOptions { pub(crate) document_private: bool, /// Document items that have `doc(hidden)`. pub(crate) document_hidden: bool, - /// Exclude items explicitly marked #[deprecated]. - pub(crate) exclude_deprecated: bool, + /// Hide items marked deprecated from listings, but pages and links still generated. + pub(crate) hide_deprecated: bool, /// If `true`, generate a JSON file in the crate folder instead of HTML redirection files. pub(crate) generate_redirect_map: bool, /// Show the memory layout of types in the docs. @@ -449,7 +449,6 @@ impl Options { WhenDocumentPrivate => println!(" (when --document-private-items)"), WhenNotDocumentPrivate => println!(" (when not --document-private-items)"), WhenNotDocumentHidden => println!(" (when not --document-hidden-items)"), - WhenExcludeDeprecated => println!(" (when --exclude-deprecated-items)"), } } @@ -791,7 +790,7 @@ impl Options { let test_runtool_args = matches.opt_strs("test-runtool-arg"); let document_private = matches.opt_present("document-private-items"); let document_hidden = matches.opt_present("document-hidden-items"); - let exclude_deprecated = matches.opt_present("exclude-deprecated-items"); + let hide_deprecated = matches.opt_present("hide-deprecated-items"); let run_check = matches.opt_present("check"); let generate_redirect_map = matches.opt_present("generate-redirect-map"); let show_type_layout = matches.opt_present("show-type-layout"); @@ -892,7 +891,7 @@ impl Options { markdown_playground_url, document_private, document_hidden, - exclude_deprecated, + hide_deprecated, generate_redirect_map, show_type_layout, unstable_features, diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 79aeb7cc90a21..a115a33f48bf5 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -147,10 +147,6 @@ impl<'tcx> DocContext<'tcx> { pub(crate) fn document_hidden(&self) -> bool { self.cache.document_hidden } - /// If `--exclude-deprecated-items` was passed to rustdoc. - pub(crate) fn exclude_deprecated(&self) -> bool { - self.cache.exclude_deprecated - } } /// Creates a new `DiagCtxt` that can be used to emit warnings and errors. @@ -391,7 +387,7 @@ pub(crate) fn run_global_ctxt( cache: Cache::new( render_options.document_private, render_options.document_hidden, - render_options.exclude_deprecated, + render_options.hide_deprecated, ), inlined: FxHashSet::default(), output_format, @@ -442,7 +438,6 @@ pub(crate) fn run_global_ctxt( WhenDocumentPrivate => ctxt.document_private(), WhenNotDocumentPrivate => !ctxt.document_private(), WhenNotDocumentHidden => !ctxt.document_hidden(), - WhenExcludeDeprecated => ctxt.exclude_deprecated(), }; if run { debug!("running pass {}", p.pass.name); diff --git a/src/librustdoc/formats/cache.rs b/src/librustdoc/formats/cache.rs index 501358ad89904..a0dd8b5086140 100644 --- a/src/librustdoc/formats/cache.rs +++ b/src/librustdoc/formats/cache.rs @@ -93,8 +93,8 @@ pub(crate) struct Cache { /// Whether to document hidden items. /// This is stored in `Cache` so it doesn't need to be passed through all rustdoc functions. pub(crate) document_hidden: bool, - /// Whether to exclude items explicitly marked `#[deprecated]`. - pub(crate) exclude_deprecated: bool, + /// Whether to hide items explicitly marked `#[deprecated]` from listings. + pub(crate) hide_deprecated: bool, /// Crates marked with [`#[doc(masked)]`][doc_masked]. /// @@ -148,9 +148,9 @@ impl Cache { pub(crate) fn new( document_private: bool, document_hidden: bool, - exclude_deprecated: bool, + hide_deprecated: bool, ) -> Self { - Cache { document_private, document_hidden, exclude_deprecated, ..Cache::default() } + Cache { document_private, document_hidden, hide_deprecated, ..Cache::default() } } fn parent_stack_last_impl_and_trait_id(&self) -> (Option, Option) { diff --git a/src/librustdoc/html/render/context.rs b/src/librustdoc/html/render/context.rs index e42997d5b4a14..2c6a442901ee6 100644 --- a/src/librustdoc/html/render/context.rs +++ b/src/librustdoc/html/render/context.rs @@ -313,11 +313,19 @@ impl<'tcx> Context<'tcx> { let mut map: BTreeMap<_, Vec<_>> = BTreeMap::new(); let mut inserted: FxHashMap> = FxHashMap::default(); + let hide_deprecated = self.shared.cache.hide_deprecated; + let tcx = self.tcx(); + for item in &m.items { if item.is_stripped() { continue; } + if hide_deprecated && item.deprecation(tcx).is_some() { + // Hide deprecated items from sidebar listings. + continue; + } + let short = item.type_(); let myname = match item.name { None => continue, @@ -866,7 +874,11 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> { self.shared.fs.write(joint_dst, buf)?; if !self.info.render_redirect_pages { - self.shared.all.borrow_mut().append(full_path(self, item), &item_type); + let hide_deprecated = self.shared.cache.hide_deprecated; + let is_deprecated = item.deprecation(self.tcx()).is_some(); + if !(hide_deprecated && is_deprecated) { + self.shared.all.borrow_mut().append(full_path(self, item), &item_type); + } } // If the item is a macro, redirect from the old macro URL (with !) // to the new one (without). diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 8740b5935973c..284d8666ae99a 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -1584,6 +1584,10 @@ fn render_deref_methods( } fn should_render_item(item: &clean::Item, deref_mut_: bool, tcx: TyCtxt<'_>) -> bool { + if item.deprecation(tcx).is_some() { + return false; + } + let self_type_opt = match item.kind { clean::MethodItem(ref method, _) => method.decl.receiver_type(), clean::RequiredMethodItem(ref method) => method.decl.receiver_type(), diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index 0c511738d7c8a..ba765bf96d143 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -412,6 +412,30 @@ fn item_module(cx: &Context<'_>, item: &clean::Item, items: &[clean::Item]) -> i )?; for (_, myitem) in ¬_stripped_items[&type_] { + // Skip deprecated items in module listings when the flag is enabled. + if cx.shared.cache.hide_deprecated { + // Direct deprecation on the item + if myitem.deprecation(tcx).is_some() { + continue; + } + // Deprecated reexports/imports + match myitem.kind { + clean::ImportItem(ref import) => { + if let Some(import_def_id) = import.source.did { + if tcx.lookup_deprecation(import_def_id).is_some() { + continue; + } + } + } + clean::ExternCrateItem { .. } => { + let def_id = myitem.item_id.expect_def_id(); + if tcx.lookup_deprecation(def_id).is_some() { + continue; + } + } + _ => {} + } + } match myitem.kind { clean::ExternCrateItem { ref src } => { use crate::html::format::print_anchor; diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 57d57d1e46c1c..337701173d822 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -258,8 +258,8 @@ fn opts() -> Vec { Unstable, FlagMulti, "", - "exclude-deprecated-items", - "exclude items that are explicitly marked #[deprecated]", + "hide-deprecated-items", + "Hide items marked deprecated from listings, but pages and links still generated.", "", ), opt(Stable, FlagMulti, "", "test", "run code examples as tests", ""), diff --git a/src/librustdoc/passes/mod.rs b/src/librustdoc/passes/mod.rs index bca20ec2c4260..a1e8e75306235 100644 --- a/src/librustdoc/passes/mod.rs +++ b/src/librustdoc/passes/mod.rs @@ -20,9 +20,6 @@ pub(crate) use self::strip_private::STRIP_PRIVATE; mod strip_priv_imports; pub(crate) use self::strip_priv_imports::STRIP_PRIV_IMPORTS; -mod strip_deprecated; -pub(crate) use self::strip_deprecated::STRIP_DEPRECATED; - mod propagate_doc_cfg; pub(crate) use self::propagate_doc_cfg::PROPAGATE_DOC_CFG; @@ -74,8 +71,6 @@ pub(crate) enum Condition { WhenNotDocumentPrivate, /// When `--document-hidden-items` is not passed. WhenNotDocumentHidden, - /// When `--exclude-deprecated-items` is passed. - WhenExcludeDeprecated, } /// The full list of passes. @@ -87,7 +82,6 @@ pub(crate) const PASSES: &[Pass] = &[ STRIP_HIDDEN, STRIP_PRIVATE, STRIP_PRIV_IMPORTS, - STRIP_DEPRECATED, PROPAGATE_STABILITY, COLLECT_INTRA_DOC_LINKS, COLLECT_TRAIT_IMPLS, @@ -105,7 +99,6 @@ pub(crate) const DEFAULT_PASSES: &[ConditionalPass] = &[ ConditionalPass::new(STRIP_HIDDEN, WhenNotDocumentHidden), ConditionalPass::new(STRIP_PRIVATE, WhenNotDocumentPrivate), ConditionalPass::new(STRIP_PRIV_IMPORTS, WhenDocumentPrivate), - ConditionalPass::new(STRIP_DEPRECATED, WhenExcludeDeprecated), ConditionalPass::always(COLLECT_INTRA_DOC_LINKS), ConditionalPass::always(PROPAGATE_STABILITY), ConditionalPass::always(RUN_LINTS), diff --git a/src/librustdoc/passes/strip_deprecated.rs b/src/librustdoc/passes/strip_deprecated.rs deleted file mode 100644 index f3eb4f2310389..0000000000000 --- a/src/librustdoc/passes/strip_deprecated.rs +++ /dev/null @@ -1,83 +0,0 @@ -use rustc_middle::ty::TyCtxt; -use tracing::debug; - -use crate::clean::{self, Item, ItemIdSet}; -use crate::core::DocContext; -use crate::fold::{DocFolder, strip_item}; -use crate::passes::{ImplStripper, Pass}; - -/// Strips items that are explicitly marked with `#[deprecated]`. -pub(crate) const STRIP_DEPRECATED: Pass = Pass { - name: "strip-deprecated", - run: Some(strip_deprecated), - description: "strips all items explicitly marked #[deprecated]", -}; - -pub(crate) fn strip_deprecated(krate: clean::Crate, cx: &mut DocContext<'_>) -> clean::Crate { - // If the flag isn't set, this pass is a no-op. - if !cx.exclude_deprecated() { - return krate; - } - - let mut retained = ItemIdSet::default(); - let is_json_output = cx.is_json_output(); - - // First, strip all explicitly deprecated items. - let krate = { - let mut stripper = DeprecatedStripper { retained: &mut retained, tcx: cx.tcx }; - stripper.fold_crate(krate) - }; - - // Then, strip impls referencing stripped items. - let mut impl_stripper = ImplStripper { - tcx: cx.tcx, - retained: &retained, - cache: &cx.cache, - is_json_output, - document_private: cx.document_private(), - document_hidden: cx.document_hidden(), - }; - - impl_stripper.fold_crate(krate) -} - -struct DeprecatedStripper<'a, 'tcx> { - retained: &'a mut ItemIdSet, - tcx: TyCtxt<'tcx>, -} - -impl DocFolder for DeprecatedStripper<'_, '_> { - fn fold_item(&mut self, i: Item) -> Option { - // If this is a re-export of a deprecated item, remove the import entirely. - if let clean::ImportItem(clean::Import { source, .. }) = &i.kind - && let Some(source_did) = source.did - { - if self.tcx.lookup_deprecation(source_did).is_some() { - debug!("strip_deprecated: stripping re-export of deprecated item {:?}", i.name); - return None; - } - } - - // Determine whether this item itself is explicitly deprecated. - let is_explicitly_deprecated = - i.def_id().is_some_and(|did| self.tcx.lookup_deprecation(did).is_some()); - - if is_explicitly_deprecated { - debug!("strip_deprecated: stripping {:?} {:?}", i.type_(), i.name); - // For certain kinds, keep a stripped placeholder to preserve structure, - // similar to how strip_hidden handles fields/variants/modules. - match i.kind { - clean::StructFieldItem(..) | clean::ModuleItem(..) | clean::VariantItem(..) => { - // Recurse to allow nested items to be processed, then strip. - let recursed = self.fold_item_recur(i); - return Some(strip_item(recursed)); - } - _ => return None, - } - } - - // Keep the item, remember it as retained, and recurse. - self.retained.insert(i.item_id); - Some(self.fold_item_recur(i)) - } -} From 55e82a24a3530d7ed44fa93b3d75aeb8fe0c31b1 Mon Sep 17 00:00:00 2001 From: Saphereye Date: Wed, 3 Dec 2025 18:32:32 +0530 Subject: [PATCH 05/14] updating default output test --- tests/run-make/rustdoc-default-output/output-default.stdout | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/run-make/rustdoc-default-output/output-default.stdout b/tests/run-make/rustdoc-default-output/output-default.stdout index 49eaf7e2e1e0e..ae6c54ce241a4 100644 --- a/tests/run-make/rustdoc-default-output/output-default.stdout +++ b/tests/run-make/rustdoc-default-output/output-default.stdout @@ -33,6 +33,8 @@ Options: document private items --document-hidden-items document items that have doc(hidden) + --hide-deprecated-items + Hide items marked deprecated from listings, but pages and links still generated. --test run code examples as tests --test-args ARGS arguments to pass to the test runner From 92446ca0a80556d0c68e2919c3052a0c6246539b Mon Sep 17 00:00:00 2001 From: Saphereye Date: Wed, 3 Dec 2025 19:12:50 +0530 Subject: [PATCH 06/14] doc issue --- tests/run-make/rustdoc-default-output/output-default.stdout | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/run-make/rustdoc-default-output/output-default.stdout b/tests/run-make/rustdoc-default-output/output-default.stdout index ae6c54ce241a4..987f214f075e9 100644 --- a/tests/run-make/rustdoc-default-output/output-default.stdout +++ b/tests/run-make/rustdoc-default-output/output-default.stdout @@ -34,7 +34,8 @@ Options: --document-hidden-items document items that have doc(hidden) --hide-deprecated-items - Hide items marked deprecated from listings, but pages and links still generated. + Hide items marked deprecated from listings, but pages + and links still generated. --test run code examples as tests --test-args ARGS arguments to pass to the test runner From 227391baeb9bfef989a6344a725aaf2be2f130b3 Mon Sep 17 00:00:00 2001 From: Saphereye Date: Wed, 3 Dec 2025 20:00:01 +0530 Subject: [PATCH 07/14] no way --- tests/run-make/rustdoc-default-output/output-default.stdout | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/run-make/rustdoc-default-output/output-default.stdout b/tests/run-make/rustdoc-default-output/output-default.stdout index 987f214f075e9..18759f69362d3 100644 --- a/tests/run-make/rustdoc-default-output/output-default.stdout +++ b/tests/run-make/rustdoc-default-output/output-default.stdout @@ -33,7 +33,7 @@ Options: document private items --document-hidden-items document items that have doc(hidden) - --hide-deprecated-items + --hide-deprecated-items Hide items marked deprecated from listings, but pages and links still generated. --test run code examples as tests From 0bed7415da5c5d5afa11bca265cf5011fb472943 Mon Sep 17 00:00:00 2001 From: Saphereye Date: Sat, 6 Dec 2025 12:11:23 +0530 Subject: [PATCH 08/14] Add flag to hide unstable options in docs --- src/librustdoc/config.rs | 4 ++ src/librustdoc/core.rs | 1 + src/librustdoc/formats/cache.rs | 11 +++- src/librustdoc/html/render/context.rs | 19 +++++-- src/librustdoc/html/render/mod.rs | 12 ++++ src/librustdoc/html/render/print_item.rs | 57 ++++++++++++------- src/librustdoc/lib.rs | 8 +++ .../output-default.stdout | 3 + 8 files changed, 89 insertions(+), 26 deletions(-) diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs index 135513f6def1d..517fa978dbfbb 100644 --- a/src/librustdoc/config.rs +++ b/src/librustdoc/config.rs @@ -274,6 +274,8 @@ pub(crate) struct RenderOptions { pub(crate) document_hidden: bool, /// Hide items marked deprecated from listings, but pages and links still generated. pub(crate) hide_deprecated: bool, + /// Hide items marked unstable from listings, but pages and links still generated. + pub(crate) hide_unstable: bool, /// If `true`, generate a JSON file in the crate folder instead of HTML redirection files. pub(crate) generate_redirect_map: bool, /// Show the memory layout of types in the docs. @@ -791,6 +793,7 @@ impl Options { let document_private = matches.opt_present("document-private-items"); let document_hidden = matches.opt_present("document-hidden-items"); let hide_deprecated = matches.opt_present("hide-deprecated-items"); + let hide_unstable = matches.opt_present("hide-unstable-options"); let run_check = matches.opt_present("check"); let generate_redirect_map = matches.opt_present("generate-redirect-map"); let show_type_layout = matches.opt_present("show-type-layout"); @@ -892,6 +895,7 @@ impl Options { document_private, document_hidden, hide_deprecated, + hide_unstable, generate_redirect_map, show_type_layout, unstable_features, diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index a115a33f48bf5..5fdc255c616bb 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -388,6 +388,7 @@ pub(crate) fn run_global_ctxt( render_options.document_private, render_options.document_hidden, render_options.hide_deprecated, + render_options.hide_unstable, ), inlined: FxHashSet::default(), output_format, diff --git a/src/librustdoc/formats/cache.rs b/src/librustdoc/formats/cache.rs index a0dd8b5086140..936491d5cbb9e 100644 --- a/src/librustdoc/formats/cache.rs +++ b/src/librustdoc/formats/cache.rs @@ -95,6 +95,8 @@ pub(crate) struct Cache { pub(crate) document_hidden: bool, /// Whether to hide items explicitly marked `#[deprecated]` from listings. pub(crate) hide_deprecated: bool, + /// Whether to hide items that are unstable from listings. + pub(crate) hide_unstable: bool, /// Crates marked with [`#[doc(masked)]`][doc_masked]. /// @@ -149,8 +151,15 @@ impl Cache { document_private: bool, document_hidden: bool, hide_deprecated: bool, + hide_unstable: bool, ) -> Self { - Cache { document_private, document_hidden, hide_deprecated, ..Cache::default() } + Cache { + document_private, + document_hidden, + hide_deprecated, + hide_unstable, + ..Cache::default() + } } fn parent_stack_last_impl_and_trait_id(&self) -> (Option, Option) { diff --git a/src/librustdoc/html/render/context.rs b/src/librustdoc/html/render/context.rs index 2c6a442901ee6..564f9f82a9986 100644 --- a/src/librustdoc/html/render/context.rs +++ b/src/librustdoc/html/render/context.rs @@ -314,6 +314,7 @@ impl<'tcx> Context<'tcx> { let mut inserted: FxHashMap> = FxHashMap::default(); let hide_deprecated = self.shared.cache.hide_deprecated; + let hide_unstable = self.shared.cache.hide_unstable; let tcx = self.tcx(); for item in &m.items { @@ -321,8 +322,13 @@ impl<'tcx> Context<'tcx> { continue; } - if hide_deprecated && item.deprecation(tcx).is_some() { - // Hide deprecated items from sidebar listings. + let is_deprecated = item.deprecation(tcx).is_some(); + let is_unstable = item + .stability(tcx) + .is_some_and(|s| s.is_unstable() && s.feature != sym::rustc_private); + + if (hide_deprecated && is_deprecated) || (hide_unstable && is_unstable) { + // Hide deprecated/unstable items from sidebar listings. continue; } @@ -875,8 +881,13 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> { if !self.info.render_redirect_pages { let hide_deprecated = self.shared.cache.hide_deprecated; - let is_deprecated = item.deprecation(self.tcx()).is_some(); - if !(hide_deprecated && is_deprecated) { + let hide_unstable = self.shared.cache.hide_unstable; + let tcx = self.tcx(); + let is_deprecated = item.deprecation(tcx).is_some(); + let is_unstable = item + .stability(tcx) + .is_some_and(|s| s.is_unstable() && s.feature != sym::rustc_private); + if !(hide_deprecated && is_deprecated) && !(hide_unstable && is_unstable) { self.shared.all.borrow_mut().append(full_path(self, item), &item_type); } } diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 284d8666ae99a..7c47a4a52fd79 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -1791,6 +1791,18 @@ fn render_impl( } }; + // Skip deprecated/unstable associated items when flags are enabled. + let hide_deprecated = cx.shared.cache.hide_deprecated; + let hide_unstable = cx.shared.cache.hide_unstable; + let tcx = cx.tcx(); + let is_deprecated = item.deprecation(tcx).is_some(); + let is_unstable = item + .stability(tcx) + .is_some_and(|s| s.is_unstable() && s.feature != sym::rustc_private); + if (hide_deprecated && is_deprecated) || (hide_unstable && is_unstable) { + return Ok(()); + } + let in_trait_class = if trait_.is_some() { " trait-impl" } else { "" }; let mut doc_buffer = String::new(); diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index ba765bf96d143..a1ef94e8548d0 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -412,29 +412,44 @@ fn item_module(cx: &Context<'_>, item: &clean::Item, items: &[clean::Item]) -> i )?; for (_, myitem) in ¬_stripped_items[&type_] { - // Skip deprecated items in module listings when the flag is enabled. - if cx.shared.cache.hide_deprecated { - // Direct deprecation on the item - if myitem.deprecation(tcx).is_some() { - continue; - } - // Deprecated reexports/imports - match myitem.kind { - clean::ImportItem(ref import) => { - if let Some(import_def_id) = import.source.did { - if tcx.lookup_deprecation(import_def_id).is_some() { - continue; - } - } - } - clean::ExternCrateItem { .. } => { - let def_id = myitem.item_id.expect_def_id(); - if tcx.lookup_deprecation(def_id).is_some() { - continue; - } + // Skip deprecated/unstable items in module listings when the flags are enabled. + let hide_deprecated = cx.shared.cache.hide_deprecated; + let hide_unstable = cx.shared.cache.hide_unstable; + + // Direct attributes on the item + let is_deprecated_item = myitem.deprecation(tcx).is_some(); + let is_unstable_item = myitem + .stability(tcx) + .is_some_and(|s| s.is_unstable() && s.feature != sym::rustc_private); + + // Reexports/imports/extern crate metadata + let (is_deprecated_reexport, is_unstable_reexport) = match myitem.kind { + clean::ImportItem(ref import) => { + if let Some(import_def_id) = import.source.did { + let depr = tcx.lookup_deprecation(import_def_id).is_some(); + let unst = tcx + .lookup_stability(import_def_id) + .is_some_and(|s| s.is_unstable() && s.feature != sym::rustc_private); + (depr, unst) + } else { + (false, false) } - _ => {} } + clean::ExternCrateItem { .. } => { + let def_id = myitem.item_id.expect_def_id(); + let depr = tcx.lookup_deprecation(def_id).is_some(); + let unst = tcx + .lookup_stability(def_id) + .is_some_and(|s| s.is_unstable() && s.feature != sym::rustc_private); + (depr, unst) + } + _ => (false, false), + }; + + if (hide_deprecated && (is_deprecated_item || is_deprecated_reexport)) + || (hide_unstable && (is_unstable_item || is_unstable_reexport)) + { + continue; } match myitem.kind { clean::ExternCrateItem { ref src } => { diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 337701173d822..3c5c52246e788 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -262,6 +262,14 @@ fn opts() -> Vec { "Hide items marked deprecated from listings, but pages and links still generated.", "", ), + opt( + Unstable, + FlagMulti, + "", + "hide-unstable-options", + "Hide items marked unstable from listings, but pages and links still generated.", + "", + ), opt(Stable, FlagMulti, "", "test", "run code examples as tests", ""), opt(Stable, Multi, "", "test-args", "arguments to pass to the test runner", "ARGS"), opt( diff --git a/tests/run-make/rustdoc-default-output/output-default.stdout b/tests/run-make/rustdoc-default-output/output-default.stdout index 18759f69362d3..be611fabe61a4 100644 --- a/tests/run-make/rustdoc-default-output/output-default.stdout +++ b/tests/run-make/rustdoc-default-output/output-default.stdout @@ -36,6 +36,9 @@ Options: --hide-deprecated-items Hide items marked deprecated from listings, but pages and links still generated. + --hide-unstable-options + Hide items marked unstable from listings, but pages + and links still generated. --test run code examples as tests --test-args ARGS arguments to pass to the test runner From 080d765b37278812e7ec730d08d08ff21ee3ddfc Mon Sep 17 00:00:00 2001 From: Saphereye Date: Sat, 6 Dec 2025 12:24:44 +0530 Subject: [PATCH 09/14] fmt --- src/librustdoc/html/render/print_item.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index a1ef94e8548d0..0a4f38b4a4c8f 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -427,9 +427,9 @@ fn item_module(cx: &Context<'_>, item: &clean::Item, items: &[clean::Item]) -> i clean::ImportItem(ref import) => { if let Some(import_def_id) = import.source.did { let depr = tcx.lookup_deprecation(import_def_id).is_some(); - let unst = tcx - .lookup_stability(import_def_id) - .is_some_and(|s| s.is_unstable() && s.feature != sym::rustc_private); + let unst = tcx.lookup_stability(import_def_id).is_some_and(|s| { + s.is_unstable() && s.feature != sym::rustc_private + }); (depr, unst) } else { (false, false) From a978b84e94de4d30886c81bd08c96291c055724a Mon Sep 17 00:00:00 2001 From: Saphereye Date: Sat, 6 Dec 2025 14:08:53 +0530 Subject: [PATCH 10/14] update tests --- src/librustdoc/clean/types/tests.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustdoc/clean/types/tests.rs b/src/librustdoc/clean/types/tests.rs index ec52799f4dd3a..9211cf8050d8b 100644 --- a/src/librustdoc/clean/types/tests.rs +++ b/src/librustdoc/clean/types/tests.rs @@ -72,7 +72,7 @@ fn should_not_trim() { fn is_same_generic() { use crate::clean::types::{PrimitiveType, Type}; use crate::formats::cache::Cache; - let cache = Cache::new(false, false, false); + let cache = Cache::new(false, false, false, false); let generic = Type::Generic(rustc_span::symbol::sym::Any); let unit = Type::Primitive(PrimitiveType::Unit); assert!(!generic.is_doc_subtype_of(&unit, &cache)); From 67cacc3fc661750e167a9b8b23e155381b6a207c Mon Sep 17 00:00:00 2001 From: Saphereye Date: Thu, 11 Dec 2025 18:14:38 +0530 Subject: [PATCH 11/14] reverting my changes to make it cleaner to work with --- src/librustdoc/clean/types/tests.rs | 2 +- src/librustdoc/config.rs | 8 ---- src/librustdoc/core.rs | 7 +--- src/librustdoc/formats/cache.rs | 19 +-------- src/librustdoc/html/render/context.rs | 25 +----------- src/librustdoc/html/render/mod.rs | 16 -------- src/librustdoc/html/render/print_item.rs | 39 ------------------- src/librustdoc/lib.rs | 16 -------- .../output-default.stdout | 6 --- 9 files changed, 5 insertions(+), 133 deletions(-) diff --git a/src/librustdoc/clean/types/tests.rs b/src/librustdoc/clean/types/tests.rs index 9211cf8050d8b..9499507b2c0f9 100644 --- a/src/librustdoc/clean/types/tests.rs +++ b/src/librustdoc/clean/types/tests.rs @@ -72,7 +72,7 @@ fn should_not_trim() { fn is_same_generic() { use crate::clean::types::{PrimitiveType, Type}; use crate::formats::cache::Cache; - let cache = Cache::new(false, false, false, false); + let cache = Cache::new(false, false); let generic = Type::Generic(rustc_span::symbol::sym::Any); let unit = Type::Primitive(PrimitiveType::Unit); assert!(!generic.is_doc_subtype_of(&unit, &cache)); diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs index 517fa978dbfbb..5d16dff24c69a 100644 --- a/src/librustdoc/config.rs +++ b/src/librustdoc/config.rs @@ -272,10 +272,6 @@ pub(crate) struct RenderOptions { pub(crate) document_private: bool, /// Document items that have `doc(hidden)`. pub(crate) document_hidden: bool, - /// Hide items marked deprecated from listings, but pages and links still generated. - pub(crate) hide_deprecated: bool, - /// Hide items marked unstable from listings, but pages and links still generated. - pub(crate) hide_unstable: bool, /// If `true`, generate a JSON file in the crate folder instead of HTML redirection files. pub(crate) generate_redirect_map: bool, /// Show the memory layout of types in the docs. @@ -792,8 +788,6 @@ impl Options { let test_runtool_args = matches.opt_strs("test-runtool-arg"); let document_private = matches.opt_present("document-private-items"); let document_hidden = matches.opt_present("document-hidden-items"); - let hide_deprecated = matches.opt_present("hide-deprecated-items"); - let hide_unstable = matches.opt_present("hide-unstable-options"); let run_check = matches.opt_present("check"); let generate_redirect_map = matches.opt_present("generate-redirect-map"); let show_type_layout = matches.opt_present("show-type-layout"); @@ -894,8 +888,6 @@ impl Options { markdown_playground_url, document_private, document_hidden, - hide_deprecated, - hide_unstable, generate_redirect_map, show_type_layout, unstable_features, diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 5fdc255c616bb..6e70f5b41c426 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -384,12 +384,7 @@ pub(crate) fn run_global_ctxt( impl_trait_bounds: Default::default(), generated_synthetics: Default::default(), auto_traits, - cache: Cache::new( - render_options.document_private, - render_options.document_hidden, - render_options.hide_deprecated, - render_options.hide_unstable, - ), + cache: Cache::new(render_options.document_private, render_options.document_hidden), inlined: FxHashSet::default(), output_format, show_coverage, diff --git a/src/librustdoc/formats/cache.rs b/src/librustdoc/formats/cache.rs index 936491d5cbb9e..56f10b03d62de 100644 --- a/src/librustdoc/formats/cache.rs +++ b/src/librustdoc/formats/cache.rs @@ -93,10 +93,6 @@ pub(crate) struct Cache { /// Whether to document hidden items. /// This is stored in `Cache` so it doesn't need to be passed through all rustdoc functions. pub(crate) document_hidden: bool, - /// Whether to hide items explicitly marked `#[deprecated]` from listings. - pub(crate) hide_deprecated: bool, - /// Whether to hide items that are unstable from listings. - pub(crate) hide_unstable: bool, /// Crates marked with [`#[doc(masked)]`][doc_masked]. /// @@ -147,19 +143,8 @@ struct CacheBuilder<'a, 'tcx> { } impl Cache { - pub(crate) fn new( - document_private: bool, - document_hidden: bool, - hide_deprecated: bool, - hide_unstable: bool, - ) -> Self { - Cache { - document_private, - document_hidden, - hide_deprecated, - hide_unstable, - ..Cache::default() - } + pub(crate) fn new(document_private: bool, document_hidden: bool) -> Self { + Cache { document_private, document_hidden, ..Cache::default() } } fn parent_stack_last_impl_and_trait_id(&self) -> (Option, Option) { diff --git a/src/librustdoc/html/render/context.rs b/src/librustdoc/html/render/context.rs index 564f9f82a9986..e42997d5b4a14 100644 --- a/src/librustdoc/html/render/context.rs +++ b/src/librustdoc/html/render/context.rs @@ -313,25 +313,11 @@ impl<'tcx> Context<'tcx> { let mut map: BTreeMap<_, Vec<_>> = BTreeMap::new(); let mut inserted: FxHashMap> = FxHashMap::default(); - let hide_deprecated = self.shared.cache.hide_deprecated; - let hide_unstable = self.shared.cache.hide_unstable; - let tcx = self.tcx(); - for item in &m.items { if item.is_stripped() { continue; } - let is_deprecated = item.deprecation(tcx).is_some(); - let is_unstable = item - .stability(tcx) - .is_some_and(|s| s.is_unstable() && s.feature != sym::rustc_private); - - if (hide_deprecated && is_deprecated) || (hide_unstable && is_unstable) { - // Hide deprecated/unstable items from sidebar listings. - continue; - } - let short = item.type_(); let myname = match item.name { None => continue, @@ -880,16 +866,7 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> { self.shared.fs.write(joint_dst, buf)?; if !self.info.render_redirect_pages { - let hide_deprecated = self.shared.cache.hide_deprecated; - let hide_unstable = self.shared.cache.hide_unstable; - let tcx = self.tcx(); - let is_deprecated = item.deprecation(tcx).is_some(); - let is_unstable = item - .stability(tcx) - .is_some_and(|s| s.is_unstable() && s.feature != sym::rustc_private); - if !(hide_deprecated && is_deprecated) && !(hide_unstable && is_unstable) { - self.shared.all.borrow_mut().append(full_path(self, item), &item_type); - } + self.shared.all.borrow_mut().append(full_path(self, item), &item_type); } // If the item is a macro, redirect from the old macro URL (with !) // to the new one (without). diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 7c47a4a52fd79..8740b5935973c 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -1584,10 +1584,6 @@ fn render_deref_methods( } fn should_render_item(item: &clean::Item, deref_mut_: bool, tcx: TyCtxt<'_>) -> bool { - if item.deprecation(tcx).is_some() { - return false; - } - let self_type_opt = match item.kind { clean::MethodItem(ref method, _) => method.decl.receiver_type(), clean::RequiredMethodItem(ref method) => method.decl.receiver_type(), @@ -1791,18 +1787,6 @@ fn render_impl( } }; - // Skip deprecated/unstable associated items when flags are enabled. - let hide_deprecated = cx.shared.cache.hide_deprecated; - let hide_unstable = cx.shared.cache.hide_unstable; - let tcx = cx.tcx(); - let is_deprecated = item.deprecation(tcx).is_some(); - let is_unstable = item - .stability(tcx) - .is_some_and(|s| s.is_unstable() && s.feature != sym::rustc_private); - if (hide_deprecated && is_deprecated) || (hide_unstable && is_unstable) { - return Ok(()); - } - let in_trait_class = if trait_.is_some() { " trait-impl" } else { "" }; let mut doc_buffer = String::new(); diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index 0a4f38b4a4c8f..0c511738d7c8a 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -412,45 +412,6 @@ fn item_module(cx: &Context<'_>, item: &clean::Item, items: &[clean::Item]) -> i )?; for (_, myitem) in ¬_stripped_items[&type_] { - // Skip deprecated/unstable items in module listings when the flags are enabled. - let hide_deprecated = cx.shared.cache.hide_deprecated; - let hide_unstable = cx.shared.cache.hide_unstable; - - // Direct attributes on the item - let is_deprecated_item = myitem.deprecation(tcx).is_some(); - let is_unstable_item = myitem - .stability(tcx) - .is_some_and(|s| s.is_unstable() && s.feature != sym::rustc_private); - - // Reexports/imports/extern crate metadata - let (is_deprecated_reexport, is_unstable_reexport) = match myitem.kind { - clean::ImportItem(ref import) => { - if let Some(import_def_id) = import.source.did { - let depr = tcx.lookup_deprecation(import_def_id).is_some(); - let unst = tcx.lookup_stability(import_def_id).is_some_and(|s| { - s.is_unstable() && s.feature != sym::rustc_private - }); - (depr, unst) - } else { - (false, false) - } - } - clean::ExternCrateItem { .. } => { - let def_id = myitem.item_id.expect_def_id(); - let depr = tcx.lookup_deprecation(def_id).is_some(); - let unst = tcx - .lookup_stability(def_id) - .is_some_and(|s| s.is_unstable() && s.feature != sym::rustc_private); - (depr, unst) - } - _ => (false, false), - }; - - if (hide_deprecated && (is_deprecated_item || is_deprecated_reexport)) - || (hide_unstable && (is_unstable_item || is_unstable_reexport)) - { - continue; - } match myitem.kind { clean::ExternCrateItem { ref src } => { use crate::html::format::print_anchor; diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 3c5c52246e788..e4601bfb20d7d 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -254,22 +254,6 @@ fn opts() -> Vec { "document items that have doc(hidden)", "", ), - opt( - Unstable, - FlagMulti, - "", - "hide-deprecated-items", - "Hide items marked deprecated from listings, but pages and links still generated.", - "", - ), - opt( - Unstable, - FlagMulti, - "", - "hide-unstable-options", - "Hide items marked unstable from listings, but pages and links still generated.", - "", - ), opt(Stable, FlagMulti, "", "test", "run code examples as tests", ""), opt(Stable, Multi, "", "test-args", "arguments to pass to the test runner", "ARGS"), opt( diff --git a/tests/run-make/rustdoc-default-output/output-default.stdout b/tests/run-make/rustdoc-default-output/output-default.stdout index be611fabe61a4..49eaf7e2e1e0e 100644 --- a/tests/run-make/rustdoc-default-output/output-default.stdout +++ b/tests/run-make/rustdoc-default-output/output-default.stdout @@ -33,12 +33,6 @@ Options: document private items --document-hidden-items document items that have doc(hidden) - --hide-deprecated-items - Hide items marked deprecated from listings, but pages - and links still generated. - --hide-unstable-options - Hide items marked unstable from listings, but pages - and links still generated. --test run code examples as tests --test-args ARGS arguments to pass to the test runner From 3cac658bfd653340da37ff72083c7cc8dece2aec Mon Sep 17 00:00:00 2001 From: Saphereye Date: Thu, 11 Dec 2025 20:01:51 +0530 Subject: [PATCH 12/14] main page hiding is working --- src/librustdoc/html/render/sidebar.rs | 28 +- src/librustdoc/html/static/css/rustdoc.css | 3235 +++++++++++--------- src/librustdoc/html/static/js/settings.js | 12 + src/librustdoc/html/static/js/storage.js | 6 + 4 files changed, 1746 insertions(+), 1535 deletions(-) diff --git a/src/librustdoc/html/render/sidebar.rs b/src/librustdoc/html/render/sidebar.rs index df9e8631bbdd6..ebbc8d8ef484e 100644 --- a/src/librustdoc/html/render/sidebar.rs +++ b/src/librustdoc/html/render/sidebar.rs @@ -453,14 +453,36 @@ fn sidebar_assoc_items<'a>( LinkBlock::new( Link::new("implementations", "Associated Constants"), "associatedconstant", - assoc_consts, + assoc_consts + .into_iter() + .map(|l| { + // Inject non-visual marker for deprecated filtering in sidebar entries + // by appending a hidden span to the displayed name. + // Note: we rely on `Link::new` to accept enriched HTML for the name. + Link::new(l.href.clone(), format!("{}", l.name)) + }) + .collect(), ), LinkBlock::new( Link::new("implementations", "Associated Types"), "associatedtype", - assoc_types, + assoc_types + .into_iter() + .map(|l| { + Link::new(l.href.clone(), format!("{}", l.name)) + }) + .collect(), + ), + LinkBlock::new( + Link::new("implementations", "Methods"), + "method", + methods + .into_iter() + .map(|l| { + Link::new(l.href.clone(), format!("{}", l.name)) + }) + .collect(), ), - LinkBlock::new(Link::new("implementations", "Methods"), "method", methods), ]; if v.iter().any(|i| i.inner_impl().trait_.is_some()) { diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index 7f47856948493..c684f6cf8fc3e 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -1,4 +1,6 @@ /* ignore-tidy-filelength */ + + /* When static files are updated, their suffixes need to be updated. 1. In the top directory run: @@ -50,244 +52,271 @@ xmlns="http://www.w3.org/2000/svg" fill="black" height="18px">\ --prev-arrow-image: url('data:image/svg+xml,'); - --next-arrow-image: url('data:image/svg+xml,'); - --expand-arrow-image: url('data:image/svg+xml,'); - --collapse-arrow-image: url('data:image/svg+xml,'); - --hamburger-image: url('data:image/svg+xml,\ '); } :root.sans-serif { - --font-family: "Fira Sans", sans-serif; - --font-family-code: "Fira Mono", monospace; + --font-family: "Fira Sans", sans-serif; + --font-family-code: "Fira Mono", monospace; } /* See FiraSans-LICENSE.txt for the Fira Sans license. */ @font-face { - font-family: 'Fira Sans'; - font-style: normal; - font-weight: 400; - src: local('Fira Sans'), - url("FiraSans-Regular-0fe48ade.woff2") format("woff2"); - font-display: swap; + font-family: "Fira Sans"; + font-style: normal; + font-weight: 400; + src: + local("Fira Sans"), + url("FiraSans-Regular-0fe48ade.woff2") format("woff2"); + font-display: swap; } @font-face { - font-family: 'Fira Sans'; - font-style: italic; - font-weight: 400; - src: local('Fira Sans Italic'), - url("FiraSans-Italic-81dc35de.woff2") format("woff2"); - font-display: swap; + font-family: "Fira Sans"; + font-style: italic; + font-weight: 400; + src: + local("Fira Sans Italic"), + url("FiraSans-Italic-81dc35de.woff2") format("woff2"); + font-display: swap; } @font-face { - font-family: 'Fira Sans'; - font-style: normal; - font-weight: 500; - src: local('Fira Sans Medium'), - url("FiraSans-Medium-e1aa3f0a.woff2") format("woff2"); - font-display: swap; + font-family: "Fira Sans"; + font-style: normal; + font-weight: 500; + src: + local("Fira Sans Medium"), + url("FiraSans-Medium-e1aa3f0a.woff2") format("woff2"); + font-display: swap; } @font-face { - font-family: 'Fira Sans'; - font-style: italic; - font-weight: 500; - src: local('Fira Sans Medium Italic'), - url("FiraSans-MediumItalic-ccf7e434.woff2") format("woff2"); - font-display: swap; + font-family: "Fira Sans"; + font-style: italic; + font-weight: 500; + src: + local("Fira Sans Medium Italic"), + url("FiraSans-MediumItalic-ccf7e434.woff2") format("woff2"); + font-display: swap; } @font-face { - font-family: 'Fira Mono'; - font-style: normal; - font-weight: 400; - src: local('Fira Mono'), - url("FiraMono-Regular-87c26294.woff2") format("woff2"); - font-display: swap; + font-family: "Fira Mono"; + font-style: normal; + font-weight: 400; + src: + local("Fira Mono"), + url("FiraMono-Regular-87c26294.woff2") format("woff2"); + font-display: swap; } @font-face { - font-family: 'Fira Mono'; - font-style: normal; - font-weight: 500; - src: local('Fira Mono Medium'), - url("FiraMono-Medium-86f75c8c.woff2") format("woff2"); - font-display: swap; + font-family: "Fira Mono"; + font-style: normal; + font-weight: 500; + src: + local("Fira Mono Medium"), + url("FiraMono-Medium-86f75c8c.woff2") format("woff2"); + font-display: swap; } /* See SourceSerif4-LICENSE.md for the Source Serif 4 license. */ @font-face { - font-family: 'Source Serif 4'; - font-style: normal; - font-weight: 400; - src: local('Source Serif 4'), - url("SourceSerif4-Regular-6b053e98.ttf.woff2") format("woff2"); - font-display: swap; + font-family: "Source Serif 4"; + font-style: normal; + font-weight: 400; + src: + local("Source Serif 4"), + url("SourceSerif4-Regular-6b053e98.ttf.woff2") format("woff2"); + font-display: swap; } @font-face { - font-family: 'Source Serif 4'; - font-style: italic; - font-weight: 400; - src: local('Source Serif 4 Italic'), - url("SourceSerif4-It-ca3b17ed.ttf.woff2") format("woff2"); - font-display: swap; + font-family: "Source Serif 4"; + font-style: italic; + font-weight: 400; + src: + local("Source Serif 4 Italic"), + url("SourceSerif4-It-ca3b17ed.ttf.woff2") format("woff2"); + font-display: swap; } @font-face { - font-family: 'Source Serif 4'; - font-style: normal; - font-weight: 500; - src: local('Source Serif 4 Semibold'), - url("SourceSerif4-Semibold-457a13ac.ttf.woff2") format("woff2"); - font-display: swap; + font-family: "Source Serif 4"; + font-style: normal; + font-weight: 500; + src: + local("Source Serif 4 Semibold"), + url("SourceSerif4-Semibold-457a13ac.ttf.woff2") format("woff2"); + font-display: swap; } @font-face { - font-family: 'Source Serif 4'; - font-style: normal; - font-weight: 700; - src: local('Source Serif 4 Bold'), - url("SourceSerif4-Bold-6d4fd4c0.ttf.woff2") format("woff2"); - font-display: swap; + font-family: "Source Serif 4"; + font-style: normal; + font-weight: 700; + src: + local("Source Serif 4 Bold"), + url("SourceSerif4-Bold-6d4fd4c0.ttf.woff2") format("woff2"); + font-display: swap; } /* See SourceCodePro-LICENSE.txt for the Source Code Pro license. */ @font-face { - font-family: 'Source Code Pro'; - font-style: normal; - font-weight: 400; - /* Avoid using locally installed font because bad versions are in circulation: + font-family: "Source Code Pro"; + font-style: normal; + font-weight: 400; + /* Avoid using locally installed font because bad versions are in circulation: * see https://github.com/rust-lang/rust/issues/24355 */ - src: url("SourceCodePro-Regular-8badfe75.ttf.woff2") format("woff2"); - font-display: swap; + src: url("SourceCodePro-Regular-8badfe75.ttf.woff2") format("woff2"); + font-display: swap; } @font-face { - font-family: 'Source Code Pro'; - font-style: italic; - font-weight: 400; - src: url("SourceCodePro-It-fc8b9304.ttf.woff2") format("woff2"); - font-display: swap; + font-family: "Source Code Pro"; + font-style: italic; + font-weight: 400; + src: url("SourceCodePro-It-fc8b9304.ttf.woff2") format("woff2"); + font-display: swap; } @font-face { - font-family: 'Source Code Pro'; - font-style: normal; - font-weight: 600; - src: url("SourceCodePro-Semibold-aa29a496.ttf.woff2") format("woff2"); - font-display: swap; + font-family: "Source Code Pro"; + font-style: normal; + font-weight: 600; + src: url("SourceCodePro-Semibold-aa29a496.ttf.woff2") format("woff2"); + font-display: swap; } /* Avoid using legacy CJK serif fonts in Windows like Batang. */ @font-face { - font-family: 'NanumBarunGothic'; - src: url("NanumBarunGothic-13b3dcba.ttf.woff2") format("woff2"); - font-display: swap; - unicode-range: U+AC00-D7AF, U+1100-11FF, U+3130-318F, U+A960-A97F, U+D7B0-D7FF; + font-family: "NanumBarunGothic"; + src: url("NanumBarunGothic-13b3dcba.ttf.woff2") format("woff2"); + font-display: swap; + unicode-range: + U+AC00-D7AF, U+1100-11FF, U+3130-318F, U+A960-A97F, U+D7B0-D7FF; } * { - box-sizing: border-box; + box-sizing: border-box; } /* General structure and fonts */ +.hide-depr dt:has(.stab.deprecated), +.hide-depr dt:has(.stab.deprecated) + dd { + display: none; +} + body { - /* Line spacing at least 1.5 per Web Content Accessibility Guidelines + /* Line spacing at least 1.5 per Web Content Accessibility Guidelines https://www.w3.org/WAI/WCAG21/Understanding/visual-presentation.html */ - font: 1rem/1.5 var(--font-family); - margin: 0; - position: relative; - /* We use overflow-wrap: break-word for Safari, which doesn't recognize + font: 1rem/1.5 var(--font-family); + margin: 0; + position: relative; + /* We use overflow-wrap: break-word for Safari, which doesn't recognize `anywhere`: https://developer.mozilla.org/en-US/docs/Web/CSS/overflow-wrap */ - overflow-wrap: break-word; - /* Then override it with `anywhere`, which is required to make non-Safari browsers break + overflow-wrap: break-word; + /* Then override it with `anywhere`, which is required to make non-Safari browsers break more aggressively when we want them to. */ - overflow-wrap: anywhere; - font-feature-settings: "kern", "liga"; - background-color: var(--main-background-color); - color: var(--main-color); + overflow-wrap: anywhere; + font-feature-settings: "kern", "liga"; + background-color: var(--main-background-color); + color: var(--main-color); } h1 { - font-size: 1.5rem; /* 24px */ + font-size: 1.5rem; /* 24px */ } h2 { - font-size: 1.375rem; /* 22px */ + font-size: 1.375rem; /* 22px */ } h3 { - font-size: 1.25rem; /* 20px */ -} -h1, h2, h3, h4, h5, h6 { - font-weight: 500; -} -h1, h2, h3, h4 { - margin: 25px 0 15px 0; - padding-bottom: 6px; -} -.docblock h3, .docblock h4, h5, h6 { - margin: 15px 0 5px 0; + font-size: 1.25rem; /* 20px */ +} +h1, +h2, +h3, +h4, +h5, +h6 { + font-weight: 500; +} +h1, +h2, +h3, +h4 { + margin: 25px 0 15px 0; + padding-bottom: 6px; +} +.docblock h3, +.docblock h4, +h5, +h6 { + margin: 15px 0 5px 0; } .docblock > h2:first-child, .docblock > h3:first-child, .docblock > h4:first-child, .docblock > h5:first-child, .docblock > h6:first-child { - margin-top: 0; + margin-top: 0; } .main-heading h1 { - margin: 0; - padding: 0; - grid-area: main-heading-h1; - /* We use overflow-wrap: break-word for Safari, which doesn't recognize + margin: 0; + padding: 0; + grid-area: main-heading-h1; + /* We use overflow-wrap: break-word for Safari, which doesn't recognize `anywhere`: https://developer.mozilla.org/en-US/docs/Web/CSS/overflow-wrap */ - overflow-wrap: break-word; - /* Then override it with `anywhere`, which is required to make non-Safari browsers break + overflow-wrap: break-word; + /* Then override it with `anywhere`, which is required to make non-Safari browsers break more aggressively when we want them to. */ - overflow-wrap: anywhere; + overflow-wrap: anywhere; } .main-heading { - position: relative; - display: grid; - grid-template-areas: - "main-heading-breadcrumbs main-heading-breadcrumbs" - "main-heading-h1 main-heading-toolbar" - "main-heading-sub-heading main-heading-toolbar"; - grid-template-columns: minmax(105px, 1fr) minmax(0, max-content); - grid-template-rows: minmax(25px, min-content) min-content min-content; - padding-bottom: 6px; - margin-bottom: 15px; + position: relative; + display: grid; + grid-template-areas: + "main-heading-breadcrumbs main-heading-breadcrumbs" + "main-heading-h1 main-heading-toolbar" + "main-heading-sub-heading main-heading-toolbar"; + grid-template-columns: minmax(105px, 1fr) minmax(0, max-content); + grid-template-rows: minmax(25px, min-content) min-content min-content; + padding-bottom: 6px; + margin-bottom: 15px; } .search-results-main-heading { - grid-template-areas: - "main-heading-breadcrumbs main-heading-placeholder" - "main-heading-breadcrumbs main-heading-toolbar " - "main-heading-h1 main-heading-toolbar "; + grid-template-areas: + "main-heading-breadcrumbs main-heading-placeholder" + "main-heading-breadcrumbs main-heading-toolbar " + "main-heading-h1 main-heading-toolbar "; } .search-results-main-heading nav.sub { - grid-area: main-heading-h1; - align-items: end; - margin: 4px 0 8px 0; + grid-area: main-heading-h1; + align-items: end; + margin: 4px 0 8px 0; } .rustdoc-breadcrumbs { - grid-area: main-heading-breadcrumbs; - line-height: 1.25; - padding-top: 5px; - position: relative; - z-index: 1; + grid-area: main-heading-breadcrumbs; + line-height: 1.25; + padding-top: 5px; + position: relative; + z-index: 1; } .search-switcher { - grid-area: main-heading-breadcrumbs; - line-height: 1.5; - display: flex; - color: var(--main-color); - align-items: baseline; - white-space: nowrap; - padding-top: 8px; - min-height: 34px; + grid-area: main-heading-breadcrumbs; + line-height: 1.5; + display: flex; + color: var(--main-color); + align-items: baseline; + white-space: nowrap; + padding-top: 8px; + min-height: 34px; } .rustdoc-breadcrumbs a { - padding: 5px 0 7px; + padding: 5px 0 7px; } /* The only headings that get underlines are: Markdown-generated headings within the top-doc @@ -297,30 +326,32 @@ h1, h2, h3, h4 { .content h2, .top-doc .docblock > h3, .top-doc .docblock > h4 { - border-bottom: 1px solid var(--headings-border-bottom-color); + border-bottom: 1px solid var(--headings-border-bottom-color); } /* while line-height 1.5 is required for any "block of text", which WCAG defines as more than one sentence, it looks weird for very large main headers */ -h1, h2 { - line-height: 1.25; - padding-top: 3px; - padding-bottom: 9px; +h1, +h2 { + line-height: 1.25; + padding-top: 3px; + padding-bottom: 9px; } h3.code-header { - font-size: 1.125rem; /* 18px */ + font-size: 1.125rem; /* 18px */ } h4.code-header { - font-size: 1rem; + font-size: 1rem; } .code-header { - font-weight: 600; - margin: 0; - padding: 0; - white-space: pre-wrap; + font-weight: 600; + margin: 0; + padding: 0; + white-space: pre-wrap; } -.structfield, .sub-variant-field { - margin: 0.6em 0; +.structfield, +.sub-variant-field { + margin: 0.6em 0; } #crate-search, @@ -341,7 +372,7 @@ summary.hideme, .search-switcher, /* This selector is for the items listed in the "all items" page. */ ul.all-items { - font-family: "Fira Sans", Arial, NanumBarunGothic, sans-serif; + font-family: "Fira Sans", Arial, NanumBarunGothic, sans-serif; } #toggle-all-docs, @@ -357,438 +388,475 @@ h1 a, .search-results li, .stab, .result-name i { - color: var(--main-color); + color: var(--main-color); } -span.enum, a.enum, -span.struct, a.struct, -span.union, a.union, -span.primitive, a.primitive, -span.type, a.type, -span.foreigntype, a.foreigntype { - color: var(--type-link-color); +span.enum, +a.enum, +span.struct, +a.struct, +span.union, +a.union, +span.primitive, +a.primitive, +span.type, +a.type, +span.foreigntype, +a.foreigntype { + color: var(--type-link-color); } -span.trait, a.trait, -span.traitalias, a.traitalias { - color: var(--trait-link-color); +span.trait, +a.trait, +span.traitalias, +a.traitalias { + color: var(--trait-link-color); } -span.associatedtype, a.associatedtype, -span.constant, a.constant, -span.static, a.static { - color: var(--assoc-item-link-color); +span.associatedtype, +a.associatedtype, +span.constant, +a.constant, +span.static, +a.static { + color: var(--assoc-item-link-color); } -span.fn, a.fn, -span.method, a.method, -span.tymethod, a.tymethod { - color: var(--function-link-color); +span.fn, +a.fn, +span.method, +a.method, +span.tymethod, +a.tymethod { + color: var(--function-link-color); } -span.attr, a.attr, -span.derive, a.derive, -span.macro, a.macro { - color: var(--macro-link-color); +span.attr, +a.attr, +span.derive, +a.derive, +span.macro, +a.macro { + color: var(--macro-link-color); } -span.mod, a.mod { - color: var(--mod-link-color); +span.mod, +a.mod { + color: var(--mod-link-color); } -span.keyword, a.keyword { - color: var(--keyword-link-color); +span.keyword, +a.keyword { + color: var(--keyword-link-color); } -span.attribute, a.attribute { - color: var(--attribute-link-color); +span.attribute, +a.attribute { + color: var(--attribute-link-color); } a { - color: var(--link-color); - text-decoration: none; + color: var(--link-color); + text-decoration: none; } -ol, ul { - padding-left: 24px; +ol, +ul { + padding-left: 24px; } -ul ul, ol ul, ul ol, ol ol { - margin-bottom: .625em; +ul ul, +ol ul, +ul ol, +ol ol { + margin-bottom: 0.625em; } -p, .docblock > .warning { - /* Paragraph spacing at least 1.5 times line spacing per Web Content Accessibility Guidelines. +p, +.docblock > .warning { + /* Paragraph spacing at least 1.5 times line spacing per Web Content Accessibility Guidelines. Line-height is 1.5rem, so line spacing is .5rem; .75em is 1.5 times that. https://www.w3.org/WAI/WCAG21/Understanding/visual-presentation.html */ - margin: 0 0 .75em 0; + margin: 0 0 0.75em 0; } /* For the last child of a div, the margin will be taken care of by the margin-top of the next item. */ -p:last-child, .docblock > .warning:last-child { - margin: 0; +p:last-child, +.docblock > .warning:last-child { + margin: 0; } /* Fix some style changes due to normalize.css 8 */ button { - /* Buttons on Safari have different default padding than other platforms. Make them the same. */ - padding: 1px 6px; - /* Opinionated tweak: use pointer cursor as clickability signifier. */ - cursor: pointer; + /* Buttons on Safari have different default padding than other platforms. Make them the same. */ + padding: 1px 6px; + /* Opinionated tweak: use pointer cursor as clickability signifier. */ + cursor: pointer; } /* end tweaks for normalize.css 8 */ button#toggle-all-docs { - padding: 0; - background: none; - border: none; - /* iOS button gradient: https://stackoverflow.com/q/5438567 */ - -webkit-appearance: none; - opacity: 1; + padding: 0; + background: none; + border: none; + /* iOS button gradient: https://stackoverflow.com/q/5438567 */ + -webkit-appearance: none; + opacity: 1; } .rustdoc { - display: flex; - flex-direction: row; - flex-wrap: nowrap; + display: flex; + flex-direction: row; + flex-wrap: nowrap; } main { - position: relative; - flex-grow: 1; - padding: 10px 15px 40px 45px; - min-width: 0; /* avoid growing beyond the size limit */ + position: relative; + flex-grow: 1; + padding: 10px 15px 40px 45px; + min-width: 0; /* avoid growing beyond the size limit */ } .src main { - padding: 15px; + padding: 15px; } .width-limiter { - max-width: 960px; - margin-right: auto; + max-width: 960px; + margin-right: auto; } details:not(.toggle) summary { - margin-bottom: .6em; + margin-bottom: 0.6em; } -code, pre, .code-header, .type-signature { - font-family: var(--font-family-code); +code, +pre, +.code-header, +.type-signature { + font-family: var(--font-family-code); } -.docblock code, .item-table dd code { - border-radius: 3px; - padding: 0 0.125em; +.docblock code, +.item-table dd code { + border-radius: 3px; + padding: 0 0.125em; } -.docblock pre code, .item-table dd pre code { - padding: 0; +.docblock pre code, +.item-table dd pre code { + padding: 0; } pre { - padding: 14px; - line-height: 1.5; /* https://github.com/rust-lang/rust/issues/105906 */ + padding: 14px; + line-height: 1.5; /* https://github.com/rust-lang/rust/issues/105906 */ } pre.item-decl { - overflow-x: auto; + overflow-x: auto; } /* This rule allows to have scrolling on the X axis. */ .item-decl .type-contents-toggle { - contain: initial; + contain: initial; } .src .content pre { - padding: 20px; - padding-left: 16px; + padding: 20px; + padding-left: 16px; } img { - max-width: 100%; + max-width: 100%; } .logo-container { - /* zero text boxes so that computed line height = image height exactly */ - line-height: 0; - display: block; + /* zero text boxes so that computed line height = image height exactly */ + line-height: 0; + display: block; } .rust-logo { - filter: var(--rust-logo-filter); + filter: var(--rust-logo-filter); } .sidebar { - font-size: 0.875rem; - flex: 0 0 var(--desktop-sidebar-width); - width: var(--desktop-sidebar-width); - overflow-y: scroll; - overscroll-behavior: contain; - position: sticky; - height: 100vh; - top: 0; - left: 0; - z-index: var(--desktop-sidebar-z-index); - /* resize indicator: hide this when on touch or mobile */ - border-right: solid 1px var(--sidebar-border-color); + font-size: 0.875rem; + flex: 0 0 var(--desktop-sidebar-width); + width: var(--desktop-sidebar-width); + overflow-y: scroll; + overscroll-behavior: contain; + position: sticky; + height: 100vh; + top: 0; + left: 0; + z-index: var(--desktop-sidebar-z-index); + /* resize indicator: hide this when on touch or mobile */ + border-right: solid 1px var(--sidebar-border-color); } .rustdoc.src .sidebar { - flex-basis: 50px; - width: 50px; - overflow-x: hidden; - /* The sidebar is by default hidden */ - overflow-y: hidden; + flex-basis: 50px; + width: 50px; + overflow-x: hidden; + /* The sidebar is by default hidden */ + overflow-y: hidden; } .hide-sidebar .sidebar, .hide-sidebar .sidebar-resizer { - display: none; + display: none; } .sidebar-resizer { - touch-action: none; - width: 9px; - cursor: ew-resize; - z-index: calc(var(--desktop-sidebar-z-index) + 1); - position: fixed; - height: 100%; - left: var(--desktop-sidebar-width); - display: flex; - align-items: center; - justify-content: flex-start; - color: var(--right-side-color); + touch-action: none; + width: 9px; + cursor: ew-resize; + z-index: calc(var(--desktop-sidebar-z-index) + 1); + position: fixed; + height: 100%; + left: var(--desktop-sidebar-width); + display: flex; + align-items: center; + justify-content: flex-start; + color: var(--right-side-color); } .sidebar-resizer::before { - content: ""; - border-right: dotted 2px currentColor; - width: 2px; - height: 12px; + content: ""; + border-right: dotted 2px currentColor; + width: 2px; + height: 12px; } .sidebar-resizer::after { - content: ""; - border-right: dotted 2px currentColor; - width: 2px; - height: 16px; + content: ""; + border-right: dotted 2px currentColor; + width: 2px; + height: 16px; } .rustdoc.src .sidebar-resizer { - /* when closed, place resizer glow on top of the normal src sidebar border (no need to + /* when closed, place resizer glow on top of the normal src sidebar border (no need to worry about sidebar) */ - left: 49px; + left: 49px; } .src-sidebar-expanded .src .sidebar-resizer { - /* for src sidebar, gap is already provided by 1px border on sidebar itself, so place resizer + /* for src sidebar, gap is already provided by 1px border on sidebar itself, so place resizer to right of it */ - left: var(--src-sidebar-width); + left: var(--src-sidebar-width); } .sidebar-resizing { - -moz-user-select: none; - -webkit-user-select: none; - -ms-user-select: none; - user-select: none; + -moz-user-select: none; + -webkit-user-select: none; + -ms-user-select: none; + user-select: none; } .sidebar-resizing * { - cursor: ew-resize !important; + cursor: ew-resize !important; } .sidebar-resizing .sidebar { - position: fixed; - border-right: solid 2px var(--sidebar-resizer-active); + position: fixed; + border-right: solid 2px var(--sidebar-resizer-active); } .sidebar-resizing > body { - padding-left: var(--resizing-sidebar-width); + padding-left: var(--resizing-sidebar-width); } .sidebar-resizer:hover, .sidebar-resizer:active, .sidebar-resizer:focus, .sidebar-resizer.active { - width: 10px; - margin: 0; - /* when active or hovered, place resizer glow on top of the sidebar (right next to, or even + width: 10px; + margin: 0; + /* when active or hovered, place resizer glow on top of the sidebar (right next to, or even on top of, the scrollbar) */ - left: calc(var(--desktop-sidebar-width) - 1px); - border-left: solid 1px var(--sidebar-resizer-hover); - color: var(--sidebar-resizer-hover); + left: calc(var(--desktop-sidebar-width) - 1px); + border-left: solid 1px var(--sidebar-resizer-hover); + color: var(--sidebar-resizer-hover); } .src-sidebar-expanded .rustdoc.src .sidebar-resizer:hover, .src-sidebar-expanded .rustdoc.src .sidebar-resizer:active, .src-sidebar-expanded .rustdoc.src .sidebar-resizer:focus, .src-sidebar-expanded .rustdoc.src .sidebar-resizer.active { - /* when active or hovered, place resizer glow on top of the normal src sidebar border */ - left: calc(var(--src-sidebar-width) - 1px); + /* when active or hovered, place resizer glow on top of the normal src sidebar border */ + left: calc(var(--src-sidebar-width) - 1px); } @media (pointer: coarse) { - .sidebar-resizer { - /* too easy to hit the resizer while trying to hit the [-] toggle */ - display: none !important; - } - .sidebar { - /* resize indicator: hide this when on touch or mobile */ - border-right: none; - } + .sidebar-resizer { + /* too easy to hit the resizer while trying to hit the [-] toggle */ + display: none !important; + } + .sidebar { + /* resize indicator: hide this when on touch or mobile */ + border-right: none; + } } .sidebar-resizer.active { - /* make the resize tool bigger when actually resizing, to avoid :hover styles on other stuff + /* make the resize tool bigger when actually resizing, to avoid :hover styles on other stuff while resizing */ - padding: 0 140px; - width: calc(140px + 140px + 9px + 2px); - margin-left: -140px; - border-left: none; - color: var(--sidebar-resizer-active); + padding: 0 140px; + width: calc(140px + 140px + 9px + 2px); + margin-left: -140px; + border-left: none; + color: var(--sidebar-resizer-active); } -.sidebar, rustdoc-topbar, .sidebar-menu-toggle, +.sidebar, +rustdoc-topbar, +.sidebar-menu-toggle, #src-sidebar { - background-color: var(--sidebar-background-color); + background-color: var(--sidebar-background-color); } .src .sidebar > * { - visibility: hidden; + visibility: hidden; } .src-sidebar-expanded .src .sidebar { - overflow-y: auto; - flex-basis: var(--src-sidebar-width); - width: var(--src-sidebar-width); + overflow-y: auto; + flex-basis: var(--src-sidebar-width); + width: var(--src-sidebar-width); } .src-sidebar-expanded .src .sidebar > * { - visibility: visible; + visibility: visible; } #all-types { - margin-top: 1em; + margin-top: 1em; } /* Improve the scrollbar display on firefox */ * { - scrollbar-width: initial; - scrollbar-color: var(--scrollbar-color); + scrollbar-width: initial; + scrollbar-color: var(--scrollbar-color); } .sidebar { - scrollbar-width: thin; - scrollbar-color: var(--scrollbar-color); + scrollbar-width: thin; + scrollbar-color: var(--scrollbar-color); } /* Improve the scrollbar display on webkit-based browsers */ ::-webkit-scrollbar { - width: 12px; + width: 12px; } .sidebar::-webkit-scrollbar { - width: 8px; + width: 8px; } ::-webkit-scrollbar-track { - -webkit-box-shadow: inset 0; - background-color: var(--scrollbar-track-background-color); + -webkit-box-shadow: inset 0; + background-color: var(--scrollbar-track-background-color); } .sidebar::-webkit-scrollbar-track { - background-color: var(--scrollbar-track-background-color); + background-color: var(--scrollbar-track-background-color); } -::-webkit-scrollbar-thumb, .sidebar::-webkit-scrollbar-thumb { - background-color: var(--scrollbar-thumb-background-color); +::-webkit-scrollbar-thumb, +.sidebar::-webkit-scrollbar-thumb { + background-color: var(--scrollbar-thumb-background-color); } /* Everything else */ .hidden { - display: none !important; + display: none !important; } .logo-container > img { - height: 48px; - width: 48px; + height: 48px; + width: 48px; } -ul.block, .block li, .block ul { - padding: 0; - margin: 0; - list-style: none; +ul.block, +.block li, +.block ul { + padding: 0; + margin: 0; + list-style: none; } .block ul a { - padding-left: 1rem; + padding-left: 1rem; } .sidebar-elems a, .sidebar > h2 a { - display: block; - padding: 0.25rem; /* 4px */ - margin-right: 0.25rem; - /* extend click target to far edge of screen (mile wide bar) */ - border-left: solid var(--sidebar-elems-left-padding) transparent; - margin-left: calc(-0.25rem - var(--sidebar-elems-left-padding)); - background-clip: border-box; + display: block; + padding: 0.25rem; /* 4px */ + margin-right: 0.25rem; + /* extend click target to far edge of screen (mile wide bar) */ + border-left: solid var(--sidebar-elems-left-padding) transparent; + margin-left: calc(-0.25rem - var(--sidebar-elems-left-padding)); + background-clip: border-box; } -.hide-toc #rustdoc-toc, .hide-toc .in-crate { - display: none; +.hide-toc #rustdoc-toc, +.hide-toc .in-crate { + display: none; } .hide-modnav #rustdoc-modnav { - display: none; + display: none; } .sidebar h2 { - text-wrap: balance; - overflow-wrap: anywhere; - padding: 0; - margin: 0.7rem 0; + text-wrap: balance; + overflow-wrap: anywhere; + padding: 0; + margin: 0.7rem 0; } .sidebar h3 { - text-wrap: balance; - overflow-wrap: anywhere; - font-size: 1.125rem; /* 18px */ - padding: 0; - margin: 0; + text-wrap: balance; + overflow-wrap: anywhere; + font-size: 1.125rem; /* 18px */ + padding: 0; + margin: 0; } .sidebar-elems, .sidebar > .version, .sidebar > h2 { - padding-left: var(--sidebar-elems-left-padding); + padding-left: var(--sidebar-elems-left-padding); } .sidebar a { - color: var(--sidebar-link-color); + color: var(--sidebar-link-color); } .sidebar .current, .sidebar .current a, .sidebar-crate a.logo-container:hover + h2 a, .sidebar a:hover:not(.logo-container) { - background-color: var(--sidebar-current-link-background-color); + background-color: var(--sidebar-current-link-background-color); } .sidebar-elems .block { - margin-bottom: 2em; + margin-bottom: 2em; } .sidebar-elems .block li a { - white-space: nowrap; - text-overflow: ellipsis; - overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + overflow: hidden; } .sidebar-crate { - display: flex; - align-items: center; - justify-content: center; - /* there's a 10px padding at the top of
, and a 4px margin at the + display: flex; + align-items: center; + justify-content: center; + /* there's a 10px padding at the top of
, and a 4px margin at the top of the search form. To line them up, add them. */ - margin: 14px 32px 1rem; - row-gap: 10px; - column-gap: 32px; - flex-wrap: wrap; + margin: 14px 32px 1rem; + row-gap: 10px; + column-gap: 32px; + flex-wrap: wrap; } .sidebar-crate h2 { - flex-grow: 1; - /* This setup with the margins and row-gap is designed to make flex-wrap + flex-grow: 1; + /* This setup with the margins and row-gap is designed to make flex-wrap work the way we want. If they're in the side-by-side lockup, there should be a 16px margin to the left of the logo (visually the same as the 24px one on everything else, which are not giant circles) and 8px @@ -796,22 +864,22 @@ ul.block, .block li, .block ul { the logo needs to have the same margin on both sides of itself (to center properly) and the crate name and version need 24px on their left margin. */ - margin: 0 -8px; - /* To align this with the search bar, it should not be centered, even when + margin: 0 -8px; + /* To align this with the search bar, it should not be centered, even when the logo is. */ - align-self: start; + align-self: start; } .sidebar-crate .logo-container { - /* The logo is expected to have 8px "slop" along its edges, so we can optically + /* The logo is expected to have 8px "slop" along its edges, so we can optically center it. */ - margin: 0 calc(-16px - var(--sidebar-elems-left-padding)); - padding: 0 var(--sidebar-elems-left-padding); - text-align: center; + margin: 0 calc(-16px - var(--sidebar-elems-left-padding)); + padding: 0 var(--sidebar-elems-left-padding); + text-align: center; } .sidebar-crate .logo-container img { - /* When in a horizontal logo lockup, the highlight color of the crate name menu item + /* When in a horizontal logo lockup, the highlight color of the crate name menu item extends underneath the actual logo (in a vertical lockup, that background highlight extends to the left edge of the screen). @@ -840,21 +908,22 @@ ul.block, .block li, .block ul { | (R) │ std │ | └─────┘ */ - margin-top: -16px; - border-top: solid 16px transparent; - box-sizing: content-box; - position: relative; - background-clip: border-box; - z-index: 1; + margin-top: -16px; + border-top: solid 16px transparent; + box-sizing: content-box; + position: relative; + background-clip: border-box; + z-index: 1; } .sidebar-crate h2 a { - display: block; - /* extend click target to far edge of screen (mile wide bar) */ - border-left: solid var(--sidebar-elems-left-padding) transparent; - background-clip: border-box; - margin: 0 calc(-24px + 0.25rem) 0 calc(-0.2rem - var(--sidebar-elems-left-padding)); - /* Align the sidebar crate link with the search bar, which have different + display: block; + /* extend click target to far edge of screen (mile wide bar) */ + border-left: solid var(--sidebar-elems-left-padding) transparent; + background-clip: border-box; + margin: 0 calc(-24px + 0.25rem) 0 + calc(-0.2rem - var(--sidebar-elems-left-padding)); + /* Align the sidebar crate link with the search bar, which have different font sizes. | | font-size | line-height | total line-height | padding-y | total | @@ -867,366 +936,408 @@ ul.block, .block li, .block ul { 2x = 16px - 0.57rem x = ( 16px - 0.57rem ) / 2 */ - padding: calc( ( 16px - 0.57rem ) / 2 ) 0.25rem; - padding-left: 0.2rem; + padding: calc((16px - 0.57rem) / 2) 0.25rem; + padding-left: 0.2rem; } .sidebar-crate h2 .version { - display: block; - font-weight: normal; - font-size: 1rem; - overflow-wrap: break-word; + display: block; + font-weight: normal; + font-size: 1rem; + overflow-wrap: break-word; } .sidebar-crate + .version { - margin-top: -1rem; - margin-bottom: 1rem; + margin-top: -1rem; + margin-bottom: 1rem; } rustdoc-topbar { - display: none; + display: none; } .rustdoc .example-wrap { - display: flex; - position: relative; - margin-bottom: 10px; + display: flex; + position: relative; + margin-bottom: 10px; } .rustdoc .example-wrap > pre, .rustdoc .scraped-example .src-line-numbers, .rustdoc .scraped-example .src-line-numbers > pre { - border-radius: 6px; + border-radius: 6px; } .rustdoc .scraped-example { - position: relative; + position: relative; } /* For the last child of a div, the margin will be taken care of by the margin-top of the next item. */ .rustdoc .example-wrap:last-child { - margin-bottom: 0px; + margin-bottom: 0px; } .rustdoc .example-wrap pre { - margin: 0; - flex-grow: 1; + margin: 0; + flex-grow: 1; } .scraped-example:not(.expanded) .example-wrap { - /* scrape-examples.js has a constant DEFAULT_MAX_LINES (call it N) for the number + /* scrape-examples.js has a constant DEFAULT_MAX_LINES (call it N) for the number * of lines shown in the un-expanded example code viewer. This pre needs to have * a max-height equal to line-height * N. The line-height is currently 1.5em, * and we include additional 10px for padding. */ - max-height: calc(1.5em * 5 + 10px); + max-height: calc(1.5em * 5 + 10px); } .more-scraped-examples .scraped-example:not(.expanded) .example-wrap { - max-height: calc(1.5em * 10 + 10px); + max-height: calc(1.5em * 10 + 10px); } .rustdoc:not(.src) .scraped-example:not(.expanded) .src-line-numbers, .rustdoc:not(.src) .scraped-example:not(.expanded) .src-line-numbers > pre, .rustdoc:not(.src) .scraped-example:not(.expanded) pre.rust { - padding-bottom: 0; - /* See above comment, should be the same max-height. */ - overflow: auto hidden; + padding-bottom: 0; + /* See above comment, should be the same max-height. */ + overflow: auto hidden; } .rustdoc:not(.src) .scraped-example .src-line-numbers { - padding-top: 0; + padding-top: 0; } .rustdoc:not(.src) .scraped-example.expanded .src-line-numbers { - padding-bottom: 0; + padding-bottom: 0; } .rustdoc:not(.src) .example-wrap pre { - overflow: auto; + overflow: auto; } .example-wrap code { - position: relative; + position: relative; } .example-wrap pre code span { - display: inline; + display: inline; } -.example-wrap.digits-1 { --example-wrap-digits-count: 1ch; } -.example-wrap.digits-2 { --example-wrap-digits-count: 2ch; } -.example-wrap.digits-3 { --example-wrap-digits-count: 3ch; } -.example-wrap.digits-4 { --example-wrap-digits-count: 4ch; } -.example-wrap.digits-5 { --example-wrap-digits-count: 5ch; } -.example-wrap.digits-6 { --example-wrap-digits-count: 6ch; } -.example-wrap.digits-7 { --example-wrap-digits-count: 7ch; } -.example-wrap.digits-8 { --example-wrap-digits-count: 8ch; } -.example-wrap.digits-9 { --example-wrap-digits-count: 9ch; } +.example-wrap.digits-1 { + --example-wrap-digits-count: 1ch; +} +.example-wrap.digits-2 { + --example-wrap-digits-count: 2ch; +} +.example-wrap.digits-3 { + --example-wrap-digits-count: 3ch; +} +.example-wrap.digits-4 { + --example-wrap-digits-count: 4ch; +} +.example-wrap.digits-5 { + --example-wrap-digits-count: 5ch; +} +.example-wrap.digits-6 { + --example-wrap-digits-count: 6ch; +} +.example-wrap.digits-7 { + --example-wrap-digits-count: 7ch; +} +.example-wrap.digits-8 { + --example-wrap-digits-count: 8ch; +} +.example-wrap.digits-9 { + --example-wrap-digits-count: 9ch; +} .example-wrap .expansion { - position: relative; - display: inline; + position: relative; + display: inline; } .example-wrap .expansion > input { - display: block; - position: absolute; - appearance: none; - content: '↕'; - left: -20px; - top: 0; - border: 1px solid var(--border-color); - border-radius: 4px; - cursor: pointer; - color: var(--main-color); - padding: 0 2px; - line-height: 20px; + display: block; + position: absolute; + appearance: none; + content: "↕"; + left: -20px; + top: 0; + border: 1px solid var(--border-color); + border-radius: 4px; + cursor: pointer; + color: var(--main-color); + padding: 0 2px; + line-height: 20px; } .example-wrap .expansion > input::after { - content: "↕"; + content: "↕"; } .example-wrap .expansion .expanded { - display: none; - color: var(--main-color); + display: none; + color: var(--main-color); } .example-wrap .expansion > input:checked ~ .expanded, .example-wrap .expansion > input:checked ~ * .expanded { - display: inherit; + display: inherit; } .example-wrap .expansion > input:checked ~ .original, .example-wrap .expansion > input:checked ~ * .original { - display: none; + display: none; } .example-wrap [data-nosnippet] { - width: calc(var(--example-wrap-digits-count) + var(--line-number-padding) * 2); + width: calc( + var(--example-wrap-digits-count) + var(--line-number-padding) * 2 + ); } .example-wrap pre > code { - padding-left: calc( - var(--example-wrap-digits-count) + var(--line-number-padding) * 2 - + var(--line-number-right-margin)); + padding-left: calc( + var(--example-wrap-digits-count) + var(--line-number-padding) * 2 + + var(--line-number-right-margin) + ); } .src .example-wrap .expansion [data-nosnippet] { - /* FIXME: Once is solved, uncomment + /* FIXME: Once is solved, uncomment next line and remove the two other rules. */ - /*left: calc(( + /*left: calc(( var(--example-wrap-digits-count) + var(--line-number-padding) * 2 + var(--line-number-right-margin)) * -1);*/ - position: initial; - margin-left: calc(( - var(--example-wrap-digits-count) + var(--line-number-padding) * 2 - + var(--line-number-right-margin)) * -1); + position: initial; + margin-left: calc( + ( + var(--example-wrap-digits-count) + var(--line-number-padding) * + 2 + var(--line-number-right-margin) + ) * + -1 + ); } .example-wrap [data-nosnippet] { - color: var(--src-line-numbers-span-color); - text-align: right; - display: inline-block; - margin-right: var(--line-number-right-margin); - -moz-user-select: none; - -webkit-user-select: none; - -ms-user-select: none; - user-select: none; - padding: 0 var(--line-number-padding); - position: absolute; - left: 0; + color: var(--src-line-numbers-span-color); + text-align: right; + display: inline-block; + margin-right: var(--line-number-right-margin); + -moz-user-select: none; + -webkit-user-select: none; + -ms-user-select: none; + user-select: none; + padding: 0 var(--line-number-padding); + position: absolute; + left: 0; } .example-wrap pre > code { - position: relative; - display: block; + position: relative; + display: block; } :root.word-wrap-source-code .example-wrap pre > code { - word-break: break-all; - white-space: pre-wrap; + word-break: break-all; + white-space: pre-wrap; } :root.word-wrap-source-code .example-wrap pre > code * { - word-break: break-all; + word-break: break-all; } .example-wrap [data-nosnippet]:target { - border-right: none; + border-right: none; } .example-wrap .line-highlighted[data-nosnippet] { - background-color: var(--src-line-number-highlighted-background-color); + background-color: var(--src-line-number-highlighted-background-color); } .example-wrap.hide-lines [data-nosnippet] { - display: none; + display: none; } .search-loading { - text-align: center; + text-align: center; } .item-table dd { - overflow-wrap: break-word; - overflow-wrap: anywhere; + overflow-wrap: break-word; + overflow-wrap: anywhere; } /* Wrap non-pre code blocks (`text`) but not (```text```). */ .docblock :not(pre) > code, .item-table dd code { - white-space: pre-wrap; + white-space: pre-wrap; } -.top-doc .docblock h2 { font-size: 1.375rem; } -.top-doc .docblock h3 { font-size: 1.25rem; } +.top-doc .docblock h2 { + font-size: 1.375rem; +} +.top-doc .docblock h3 { + font-size: 1.25rem; +} .top-doc .docblock h4, .top-doc .docblock h5 { - font-size: 1.125rem; + font-size: 1.125rem; } .top-doc .docblock h6 { - font-size: 1rem; + font-size: 1rem; } -.docblock h5 { font-size: 1rem; } -.docblock h6 { font-size: 0.875rem; } +.docblock h5 { + font-size: 1rem; +} +.docblock h6 { + font-size: 0.875rem; +} .docblock { - margin-left: var(--docblock-indent); - position: relative; + margin-left: var(--docblock-indent); + position: relative; } .docblock > :not(.more-examples-toggle):not(.example-wrap) { - max-width: 100%; - overflow-x: auto; + max-width: 100%; + overflow-x: auto; } .sub-heading { - font-size: 1rem; - flex-grow: 0; - grid-area: main-heading-sub-heading; - line-height: 1.25; - padding-bottom: 4px; + font-size: 1rem; + flex-grow: 0; + grid-area: main-heading-sub-heading; + line-height: 1.25; + padding-bottom: 4px; } -.main-heading rustdoc-toolbar, .main-heading .out-of-band { - grid-area: main-heading-toolbar; +.main-heading rustdoc-toolbar, +.main-heading .out-of-band { + grid-area: main-heading-toolbar; } rustdoc-toolbar { - display: flex; - flex-direction: row; - flex-wrap: nowrap; - min-height: 60px; + display: flex; + flex-direction: row; + flex-wrap: nowrap; + min-height: 60px; } -.docblock code, .item-table dd code, -pre, .rustdoc.src .example-wrap, .example-wrap .src-line-numbers { - background-color: var(--code-block-background-color); - border-radius: var(--code-block-border-radius); - /* code blocks within links (such as in most intra-doc links) should be underlined */ - text-decoration: inherit; +.docblock code, +.item-table dd code, +pre, +.rustdoc.src .example-wrap, +.example-wrap .src-line-numbers { + background-color: var(--code-block-background-color); + border-radius: var(--code-block-border-radius); + /* code blocks within links (such as in most intra-doc links) should be underlined */ + text-decoration: inherit; } #main-content { - position: relative; + position: relative; } .docblock table { - margin: .5em 0; - border-collapse: collapse; + margin: 0.5em 0; + border-collapse: collapse; } -.docblock table td, .docblock table th { - padding: .5em; - border: 1px solid var(--border-color); +.docblock table td, +.docblock table th { + padding: 0.5em; + border: 1px solid var(--border-color); } .docblock table tbody tr:nth-child(2n) { - background: var(--table-alt-row-background-color); + background: var(--table-alt-row-background-color); } -.docblock .stab, .item-table dd .stab, .docblock p code { - display: inline-block; +.docblock .stab, +.item-table dd .stab, +.docblock p code { + display: inline-block; } .docblock li { - margin-bottom: .4em; + margin-bottom: 0.4em; } .docblock li p:not(:last-child) { - /* This margin is voluntarily smaller than `.docblock li` to keep the visual + /* This margin is voluntarily smaller than `.docblock li` to keep the visual list element items separated while also having a visual separation (although smaller) for paragraphs. */ - margin-bottom: .3em; + margin-bottom: 0.3em; } /* "where ..." clauses with block display are also smaller */ div.where { - white-space: pre-wrap; - font-size: 0.875rem; + white-space: pre-wrap; + font-size: 0.875rem; } .item-info { - display: block; - margin-left: var(--docblock-indent); + display: block; + margin-left: var(--docblock-indent); } .impl-items > .item-info { - /* Margin of docblocks + margin of impl block items. */ - margin-left: calc(var(--docblock-indent) + var(--impl-items-indent)); + /* Margin of docblocks + margin of impl block items. */ + margin-left: calc(var(--docblock-indent) + var(--impl-items-indent)); } .item-info code { - font-size: 0.875rem; + font-size: 0.875rem; } #main-content > .item-info { - margin-left: 0; + margin-left: 0; } nav.sub { - flex-grow: 1; - flex-flow: row nowrap; - display: flex; - align-items: start; - margin-top: 4px; + flex-grow: 1; + flex-flow: row nowrap; + display: flex; + align-items: start; + margin-top: 4px; } .search-form { - position: relative; - display: flex; - height: 34px; - flex-grow: 1; + position: relative; + display: flex; + height: 34px; + flex-grow: 1; } .src nav.sub { - margin: 0 0 -10px 0; + margin: 0 0 -10px 0; } .section-header { - /* fields use tags, but should get their own lines */ - display: block; - position: relative; + /* fields use tags, but should get their own lines */ + display: block; + position: relative; } -.section-header:hover > .anchor, .impl:hover > .anchor, -.trait-impl:hover > .anchor, .variant:hover > .anchor { - display: initial; +.section-header:hover > .anchor, +.impl:hover > .anchor, +.trait-impl:hover > .anchor, +.variant:hover > .anchor { + display: initial; } .anchor { - display: none; - position: absolute; - left: -0.5em; - background: none !important; + display: none; + position: absolute; + left: -0.5em; + background: none !important; } .anchor.field { - left: -5px; + left: -5px; } .section-header > .anchor { - left: -15px; - padding-right: 8px; + left: -15px; + padding-right: 8px; } h2.section-header > .anchor { - padding-right: 6px; + padding-right: 6px; } a.doc-anchor { - color: var(--main-color); - display: none; - position: absolute; - left: -17px; - /* We add this padding so that when the cursor moves from the heading's text to the anchor, + color: var(--main-color); + display: none; + position: absolute; + left: -17px; + /* We add this padding so that when the cursor moves from the heading's text to the anchor, the anchor doesn't disappear. */ - padding-right: 10px; - /* And this padding is used to make the anchor larger and easier to click on. */ - padding-left: 3px; + padding-right: 10px; + /* And this padding is used to make the anchor larger and easier to click on. */ + padding-left: 3px; } *:hover > .doc-anchor { - display: block; + display: block; } /* If the first element of the top doc block is a heading, we don't want to ever display its anchor because of the `[-]` element which would overlap with it. */ .top-doc > .docblock > *:first-child > .doc-anchor { - display: none !important; + display: none !important; } .main-heading a:hover, @@ -1235,10 +1346,12 @@ because of the `[-]` element which would overlap with it. */ .docblock a:not(.scrape-help):not(.tooltip):hover:not(.doc-anchor), .item-table dd a:not(.scrape-help):not(.tooltip):hover, .item-info a { - text-decoration: underline; + text-decoration: underline; } -.crate.block li.current a { font-weight: 500; } +.crate.block li.current a { + font-weight: 500; +} /* In most contexts we use `overflow-wrap: anywhere` to ensure that we can wrap as much as needed on mobile (see @@ -1262,519 +1375,529 @@ because of the `[-]` element which would overlap with it. */ */ table, .item-table { - overflow-wrap: break-word; + overflow-wrap: break-word; } .item-table { - padding: 0; - margin: 0; - width: 100%; + padding: 0; + margin: 0; + width: 100%; } .item-table > dt { - padding-right: 1.25rem; + padding-right: 1.25rem; } .item-table > dd { - margin-inline-start: 0; - margin-left: 0; + margin-inline-start: 0; + margin-left: 0; } #crate-search-div { - /* ensures that 100% in properties of #crate-search-div:after + /* ensures that 100% in properties of #crate-search-div:after are relative to the size of this div */ - position: relative; - /* allows this div (and with it the -element "#crate-search") to be shrunk */ + min-width: 0; + /* keep label text for switcher from moving down when this appears */ + margin-top: -1px; } #crate-search { - padding: 0 23px 0 4px; - /* prevents the from overflowing the containing div in case it's shrunk */ + max-width: 100%; + /* contents can overflow because of max-width limit, then show ellipsis */ + text-overflow: ellipsis; + border: 1px solid var(--border-color); + border-radius: 4px; + outline: none; + cursor: pointer; + -moz-appearance: none; + -webkit-appearance: none; + /* Removes default arrow from firefox */ + text-indent: 0.01px; + background-color: var(--main-background-color); + color: inherit; + line-height: 1.5; + font-weight: 500; +} +#crate-search:hover, +#crate-search:focus { + border-color: var(--crate-search-hover-border); } /* pseudo-element for holding the dropdown-arrow image; needs to be a separate thing so that we can apply CSS-filters to change the arrow color in themes */ #crate-search-div::after { - /* lets clicks through! */ - pointer-events: none; - /* completely covers the underlying div */ - width: 100%; - height: 100%; - position: absolute; - top: 0; - left: 0; - content: ""; - background-repeat: no-repeat; - background-size: 20px; - background-position: calc(100% - 2px) 56%; - /* down arrow (image is black color) */ - background-image: url('data:image/svg+xml, \ '); - /* changes the arrow image color */ - filter: var(--crate-search-div-filter); + /* changes the arrow image color */ + filter: var(--crate-search-div-filter); } -#crate-search-div:hover::after, #crate-search-div:focus-within::after { - filter: var(--crate-search-div-hover-filter); +#crate-search-div:hover::after, +#crate-search-div:focus-within::after { + filter: var(--crate-search-div-hover-filter); } #crate-search > option { - font-size: 1rem; + font-size: 1rem; } .search-input { - /* Override Normalize.css: it has a rule that sets + /* Override Normalize.css: it has a rule that sets -webkit-appearance: textfield for search inputs. That causes rounded corners and no border on iOS Safari. */ - -webkit-appearance: none; - outline: none; - border: 1px solid var(--border-color); - border-radius: 2px; - padding: 8px; - font-size: 1rem; - flex-grow: 1; - background-color: var(--button-background-color); - color: var(--search-color); - max-width: 100%; + -webkit-appearance: none; + outline: none; + border: 1px solid var(--border-color); + border-radius: 2px; + padding: 8px; + font-size: 1rem; + flex-grow: 1; + background-color: var(--button-background-color); + color: var(--search-color); + max-width: 100%; } .search-input:focus { - border-color: var(--search-input-focused-border-color); + border-color: var(--search-input-focused-border-color); } .search-results { - display: none; + display: none; } .search-results.active { - display: block; - margin: 0; - padding: 0; + display: block; + margin: 0; + padding: 0; } .search-results > a { - display: grid; - grid-template-areas: - "search-result-name search-result-desc" - "search-result-type-signature search-result-type-signature"; - grid-template-columns: .6fr .4fr; - /* A little margin ensures the browser's outlining of focused links has room to display. */ - margin-left: 2px; - margin-right: 2px; - border-bottom: 1px solid var(--search-result-border-color); - column-gap: 1em; + display: grid; + grid-template-areas: + "search-result-name search-result-desc" + "search-result-type-signature search-result-type-signature"; + grid-template-columns: 0.6fr 0.4fr; + /* A little margin ensures the browser's outlining of focused links has room to display. */ + margin-left: 2px; + margin-right: 2px; + border-bottom: 1px solid var(--search-result-border-color); + column-gap: 1em; } .search-results > a > div.desc { - white-space: nowrap; - text-overflow: ellipsis; - overflow: hidden; - grid-area: search-result-desc; + white-space: nowrap; + text-overflow: ellipsis; + overflow: hidden; + grid-area: search-result-desc; } .search-results a:hover, .search-results a:focus { - background-color: var(--search-result-link-focus-background-color); + background-color: var(--search-result-link-focus-background-color); } .search-results .result-name { - display: flex; - align-items: center; - justify-content: start; - grid-area: search-result-name; + display: flex; + align-items: center; + justify-content: start; + grid-area: search-result-name; } .search-results .result-name .alias { - color: var(--search-results-alias-color); + color: var(--search-results-alias-color); } .search-results .result-name .grey { - color: var(--search-results-grey-color); + color: var(--search-results-grey-color); } .search-results .result-name .typename { - color: var(--search-results-grey-color); - font-size: 0.875rem; - width: var(--search-typename-width); + color: var(--search-results-grey-color); + font-size: 0.875rem; + width: var(--search-typename-width); } .search-results .result-name .path { - word-break: break-all; - max-width: calc(100% - var(--search-typename-width)); - display: inline-block; + word-break: break-all; + max-width: calc(100% - var(--search-typename-width)); + display: inline-block; } .search-results .result-name .path > * { - display: inline; + display: inline; } .search-results .type-signature { - grid-area: search-result-type-signature; - white-space: pre-wrap; + grid-area: search-result-type-signature; + white-space: pre-wrap; } .popover { - position: absolute; - top: 100%; - right: 0; - z-index: calc(var(--desktop-sidebar-z-index) + 1); - margin-top: 7px; - border-radius: 3px; - border: 1px solid var(--border-color); - background-color: var(--main-background-color); - color: var(--main-color); - --popover-arrow-offset: 11px; + position: absolute; + top: 100%; + right: 0; + z-index: calc(var(--desktop-sidebar-z-index) + 1); + margin-top: 7px; + border-radius: 3px; + border: 1px solid var(--border-color); + background-color: var(--main-background-color); + color: var(--main-color); + --popover-arrow-offset: 11px; } /* This rule is to draw the little arrow connecting the settings menu to the gear icon. */ .popover::before { - content: ''; - position: absolute; - right: var(--popover-arrow-offset); - border: solid var(--border-color); - border-width: 1px 1px 0 0; - background-color: var(--main-background-color); - padding: 4px; - transform: rotate(-45deg); - top: -5px; + content: ""; + position: absolute; + right: var(--popover-arrow-offset); + border: solid var(--border-color); + border-width: 1px 1px 0 0; + background-color: var(--main-background-color); + padding: 4px; + transform: rotate(-45deg); + top: -5px; } .setting-line { - margin: 1.2em 0.6em; + margin: 1.2em 0.6em; } -.setting-radio input, .setting-check input { - margin-right: 0.3em; - height: 1.2rem; - width: 1.2rem; - border: 2px solid var(--settings-input-border-color); - outline: none; - -webkit-appearance: none; - cursor: pointer; +.setting-radio input, +.setting-check input { + margin-right: 0.3em; + height: 1.2rem; + width: 1.2rem; + border: 2px solid var(--settings-input-border-color); + outline: none; + -webkit-appearance: none; + cursor: pointer; } .setting-radio input { - border-radius: 50%; + border-radius: 50%; } -.setting-radio span, .setting-check span { - padding-bottom: 1px; +.setting-radio span, +.setting-check span { + padding-bottom: 1px; } .setting-radio { - margin-top: 0.1em; - margin-bottom: 0.1em; - min-width: 3.8em; - padding: 0.3em; - display: inline-flex; - align-items: center; - cursor: pointer; + margin-top: 0.1em; + margin-bottom: 0.1em; + min-width: 3.8em; + padding: 0.3em; + display: inline-flex; + align-items: center; + cursor: pointer; } .setting-radio + .setting-radio { - margin-left: 0.5em; + margin-left: 0.5em; } .setting-check { - margin-right: 20px; - display: flex; - align-items: center; - cursor: pointer; + margin-right: 20px; + display: flex; + align-items: center; + cursor: pointer; } .setting-check input { - flex-shrink: 0; + flex-shrink: 0; } .setting-radio input:checked { - box-shadow: inset 0 0 0 3px var(--main-background-color); - background-color: var(--settings-input-color); + box-shadow: inset 0 0 0 3px var(--main-background-color); + background-color: var(--settings-input-color); } .setting-check input:checked { - background-color: var(--settings-input-color); - border-width: 1px; - /* cross-mark image in the settings checkboxes */ - content: url('data:image/svg+xml,\ + background-color: var(--settings-input-color); + border-width: 1px; + /* cross-mark image in the settings checkboxes */ + content: url('data:image/svg+xml,\ \ '); } -.setting-radio input:focus, .setting-check input:focus { - box-shadow: 0 0 1px 1px var(--settings-input-color); +.setting-radio input:focus, +.setting-check input:focus { + box-shadow: 0 0 1px 1px var(--settings-input-color); } /* In here we combine both `:focus` and `:checked` properties. */ .setting-radio input:checked:focus { - box-shadow: inset 0 0 0 3px var(--main-background-color), - 0 0 2px 2px var(--settings-input-color); + box-shadow: + inset 0 0 0 3px var(--main-background-color), + 0 0 2px 2px var(--settings-input-color); } -.setting-radio input:hover, .setting-check input:hover { - border-color: var(--settings-input-color) !important; +.setting-radio input:hover, +.setting-check input:hover { + border-color: var(--settings-input-color) !important; } #settings.popover { - --popover-arrow-offset: 196px; - top: calc(100% - 16px); + --popover-arrow-offset: 196px; + top: calc(100% - 16px); } /* use larger max-width for help popover, but not for help.html */ #help.popover { - max-width: 600px; - --popover-arrow-offset: 115px; - top: calc(100% - 16px); + max-width: 600px; + --popover-arrow-offset: 115px; + top: calc(100% - 16px); } #help dt { - float: left; - clear: left; - margin-right: 0.5rem; + float: left; + clear: left; + margin-right: 0.5rem; } #help dd { - margin-bottom: 0.5rem; + margin-bottom: 0.5rem; } -#help span.top, #help span.bottom { - text-align: center; - display: block; - font-size: 1.125rem; - padding: 0 0.5rem; - text-wrap-style: balance; +#help span.top, +#help span.bottom { + text-align: center; + display: block; + font-size: 1.125rem; + padding: 0 0.5rem; + text-wrap-style: balance; } #help span.top { - margin: 10px 0; - border-bottom: 1px solid var(--border-color); - padding-bottom: 4px; - margin-bottom: 6px; + margin: 10px 0; + border-bottom: 1px solid var(--border-color); + padding-bottom: 4px; + margin-bottom: 6px; } #help span.bottom { - clear: both; - border-top: 1px solid var(--border-color); + clear: both; + border-top: 1px solid var(--border-color); } .side-by-side { - display: flex; - margin-bottom: 20px; + display: flex; + margin-bottom: 20px; } .side-by-side > div { - width: 50%; - padding: 0 20px 0 17px; + width: 50%; + padding: 0 20px 0 17px; } .item-info .stab { - display: block; - padding: 3px; - margin-bottom: 5px; + display: block; + padding: 3px; + margin-bottom: 5px; } .item-table dt .stab { - margin-left: 0.3125em; + margin-left: 0.3125em; } .stab { - padding: 0 2px; - font-size: 0.875rem; - font-weight: normal; - color: var(--main-color); - background-color: var(--stab-background-color); - width: fit-content; - white-space: pre-wrap; - border-radius: 3px; - display: inline; - vertical-align: baseline; + padding: 0 2px; + font-size: 0.875rem; + font-weight: normal; + color: var(--main-color); + background-color: var(--stab-background-color); + width: fit-content; + white-space: pre-wrap; + border-radius: 3px; + display: inline; + vertical-align: baseline; } .stab.portability > code { - background: none; - color: var(--stab-code-color); + background: none; + color: var(--stab-code-color); } -.stab .emoji, .item-info .stab::before { - font-size: 1.25rem; +.stab .emoji, +.item-info .stab::before { + font-size: 1.25rem; } .stab .emoji { - margin-right: 0.3rem; + margin-right: 0.3rem; } .item-info .stab::before { - /* ensure badges with emoji and without it have same height */ - content: "\0"; - width: 0; - display: inline-block; - color: transparent; + /* ensure badges with emoji and without it have same height */ + content: "\0"; + width: 0; + display: inline-block; + color: transparent; } /* Black one-pixel outline around emoji shapes */ .emoji { - text-shadow: - 1px 0 0 black, - -1px 0 0 black, - 0 1px 0 black, - 0 -1px 0 black; + text-shadow: + 1px 0 0 black, + -1px 0 0 black, + 0 1px 0 black, + 0 -1px 0 black; } .since { - font-weight: normal; - font-size: initial; + font-weight: normal; + font-size: initial; } .rightside { - padding-left: 12px; - float: right; + padding-left: 12px; + float: right; } .rightside:not(a), .out-of-band, .sub-heading, rustdoc-toolbar { - color: var(--right-side-color); + color: var(--right-side-color); } pre.rust { - tab-size: 4; - -moz-tab-size: 4; + tab-size: 4; + -moz-tab-size: 4; } /* Code highlighting */ pre.rust .kw { - color: var(--code-highlight-kw-color); + color: var(--code-highlight-kw-color); } pre.rust .kw-2 { - color: var(--code-highlight-kw-2-color); + color: var(--code-highlight-kw-2-color); } pre.rust .lifetime { - color: var(--code-highlight-lifetime-color); + color: var(--code-highlight-lifetime-color); } pre.rust .prelude-ty { - color: var(--code-highlight-prelude-color); + color: var(--code-highlight-prelude-color); } pre.rust .prelude-val { - color: var(--code-highlight-prelude-val-color); + color: var(--code-highlight-prelude-val-color); } pre.rust .string { - color: var(--code-highlight-string-color); + color: var(--code-highlight-string-color); } pre.rust .number { - color: var(--code-highlight-number-color); + color: var(--code-highlight-number-color); } pre.rust .bool-val { - color: var(--code-highlight-literal-color); + color: var(--code-highlight-literal-color); } pre.rust .self { - color: var(--code-highlight-self-color); + color: var(--code-highlight-self-color); } pre.rust .attr { - color: var(--code-highlight-attribute-color); + color: var(--code-highlight-attribute-color); } pre.rust .macro, pre.rust .macro-nonterminal { - color: var(--code-highlight-macro-color); + color: var(--code-highlight-macro-color); } pre.rust .question-mark { - font-weight: bold; - color: var(--code-highlight-question-mark-color); + font-weight: bold; + color: var(--code-highlight-question-mark-color); } pre.rust .comment { - color: var(--code-highlight-comment-color); + color: var(--code-highlight-comment-color); } pre.rust .doccomment { - color: var(--code-highlight-doc-comment-color); + color: var(--code-highlight-doc-comment-color); } .rustdoc.src .example-wrap pre.rust a:not([data-nosnippet]) { - background: var(--codeblock-link-background); + background: var(--codeblock-link-background); } .example-wrap.compile_fail, .example-wrap.should_panic { - border-left: 2px solid var(--codeblock-error-color); + border-left: 2px solid var(--codeblock-error-color); } .ignore.example-wrap { - border-left: 2px solid var(--codeblock-ignore-color); + border-left: 2px solid var(--codeblock-ignore-color); } .example-wrap.compile_fail:hover, .example-wrap.should_panic:hover { - border-left: 2px solid var(--codeblock-error-hover-color); + border-left: 2px solid var(--codeblock-error-hover-color); } .example-wrap.ignore:hover { - border-left: 2px solid var(--codeblock-ignore-hover-color); + border-left: 2px solid var(--codeblock-ignore-hover-color); } .example-wrap.compile_fail .tooltip, .example-wrap.should_panic .tooltip { - color: var(--codeblock-error-color); + color: var(--codeblock-error-color); } .example-wrap.ignore .tooltip { - color: var(--codeblock-ignore-color); + color: var(--codeblock-ignore-color); } .example-wrap.compile_fail:hover .tooltip, .example-wrap.should_panic:hover .tooltip { - color: var(--codeblock-error-hover-color); + color: var(--codeblock-error-hover-color); } .example-wrap.ignore:hover .tooltip { - color: var(--codeblock-ignore-hover-color); + color: var(--codeblock-ignore-hover-color); } .example-wrap .tooltip { - position: absolute; - display: block; - left: -25px; - top: 5px; - margin: 0; - line-height: 1; + position: absolute; + display: block; + left: -25px; + top: 5px; + margin: 0; + line-height: 1; } .example-wrap.compile_fail .tooltip, .example-wrap.should_panic .tooltip, .example-wrap.ignore .tooltip { - font-weight: bold; - font-size: 1.25rem; + font-weight: bold; + font-size: 1.25rem; } /* This class only exists for users who want to draw attention to a particular element in their documentation. */ .content .docblock .warning { - border-left: 2px solid var(--warning-border-color); - padding: 14px; - position: relative; - /* The "!important" part is required because the rule is otherwise overruled in this CSS + border-left: 2px solid var(--warning-border-color); + padding: 14px; + position: relative; + /* The "!important" part is required because the rule is otherwise overruled in this CSS selector: ".docblock > :not(.more-examples-toggle):not(.example-wrap)" */ - overflow-x: visible !important; + overflow-x: visible !important; } .content .docblock .warning::before { - color: var(--warning-border-color); - content: "ⓘ"; - position: absolute; - left: -25px; - top: 5px; - font-weight: bold; - font-size: 1.25rem; + color: var(--warning-border-color); + content: "ⓘ"; + position: absolute; + left: -25px; + top: 5px; + font-weight: bold; + font-size: 1.25rem; } -.top-doc > .docblock >.warning:first-child::before { - top: 20px; +.top-doc > .docblock > .warning:first-child::before { + top: 20px; } -.example-wrap > a.test-arrow, .example-wrap .button-holder { - visibility: hidden; - position: absolute; - top: 4px; - right: 4px; - z-index: 1; +.example-wrap > a.test-arrow, +.example-wrap .button-holder { + visibility: hidden; + position: absolute; + top: 4px; + right: 4px; + z-index: 1; } a.test-arrow { - height: var(--copy-path-height); - padding: 6px 4px 0 11px; + height: var(--copy-path-height); + padding: 6px 4px 0 11px; } a.test-arrow::before { - content: url('data:image/svg+xml,'); } .example-wrap .button-holder { - display: flex; + display: flex; } /* @@ -1786,233 +1909,235 @@ However, using `@media (hover: hover)` makes this rule never to be applied in GU instead, we check that it's not a "finger" cursor. */ @media not (pointer: coarse) { - .example-wrap:hover > a.test-arrow, .example-wrap:hover > .button-holder { - visibility: visible; - } + .example-wrap:hover > a.test-arrow, + .example-wrap:hover > .button-holder { + visibility: visible; + } } .example-wrap .button-holder.keep-visible { - visibility: visible; + visibility: visible; } .example-wrap .button-holder > * { - background: var(--main-background-color); - cursor: pointer; - border-radius: var(--button-border-radius); - height: var(--copy-path-height); - width: var(--copy-path-width); - border: 0; - color: var(--code-example-button-color); + background: var(--main-background-color); + cursor: pointer; + border-radius: var(--button-border-radius); + height: var(--copy-path-height); + width: var(--copy-path-width); + border: 0; + color: var(--code-example-button-color); } .example-wrap .button-holder > *:hover { - color: var(--code-example-button-hover-color); + color: var(--code-example-button-hover-color); } .example-wrap .button-holder > *:not(:first-child) { - margin-left: var(--button-left-margin); + margin-left: var(--button-left-margin); } .example-wrap .button-holder .copy-button { - padding: 2px 0 0 4px; + padding: 2px 0 0 4px; } .example-wrap .button-holder .copy-button::before, .example-wrap .test-arrow::before, .example-wrap .button-holder .prev::before, .example-wrap .button-holder .next::before, .example-wrap .button-holder .expand::before { - filter: var(--copy-path-img-filter); + filter: var(--copy-path-img-filter); } .example-wrap .button-holder .copy-button::before { - content: var(--clipboard-image); + content: var(--clipboard-image); } .example-wrap .button-holder .copy-button:hover::before, .example-wrap .test-arrow:hover::before { - filter: var(--copy-path-img-hover-filter); + filter: var(--copy-path-img-hover-filter); } .example-wrap .button-holder .copy-button.clicked::before { - content: var(--checkmark-image); - padding-right: 5px; + content: var(--checkmark-image); + padding-right: 5px; } .example-wrap .button-holder .prev, .example-wrap .button-holder .next, .example-wrap .button-holder .expand { - line-height: 0px; + line-height: 0px; } .example-wrap .button-holder .prev::before { - content: var(--prev-arrow-image); + content: var(--prev-arrow-image); } .example-wrap .button-holder .next::before { - content: var(--next-arrow-image); + content: var(--next-arrow-image); } .example-wrap .button-holder .expand::before { - content: var(--expand-arrow-image); + content: var(--expand-arrow-image); } .example-wrap .button-holder .expand.collapse::before { - content: var(--collapse-arrow-image); + content: var(--collapse-arrow-image); } .code-attribute { - font-weight: 300; - color: var(--code-attribute-color); + font-weight: 300; + color: var(--code-attribute-color); } .item-spacer { - width: 100%; - height: 12px; - display: block; + width: 100%; + height: 12px; + display: block; } .main-heading span.since::before { - content: "Since "; + content: "Since "; } .sub-variant h4 { - font-size: 1rem; - font-weight: 400; - margin-top: 0; - margin-bottom: 0; + font-size: 1rem; + font-weight: 400; + margin-top: 0; + margin-bottom: 0; } .sub-variant { - margin-left: 24px; - margin-bottom: 40px; + margin-left: 24px; + margin-bottom: 40px; } .sub-variant > .sub-variant-field { - margin-left: 24px; + margin-left: 24px; } @keyframes targetfadein { - from { - background-color: var(--main-background-color); - } - 10% { - background-color: var(--target-border-color); - } - to { - background-color: var(--target-background-color); - } + from { + background-color: var(--main-background-color); + } + 10% { + background-color: var(--target-border-color); + } + to { + background-color: var(--target-background-color); + } } :target:not([data-nosnippet]) { - background-color: var(--target-background-color); - border-right: 3px solid var(--target-border-color); + background-color: var(--target-background-color); + border-right: 3px solid var(--target-border-color); } a.tooltip { - font-family: var(--font-family); + font-family: var(--font-family); } .code-header a.tooltip { - color: inherit; - margin-right: 15px; - position: relative; + color: inherit; + margin-right: 15px; + position: relative; } .code-header a.tooltip:hover { - color: var(--link-color); + color: var(--link-color); } /* placeholder thunk so that the mouse can easily travel from "(i)" to popover the resulting "hover tunnel" is a stepped triangle, approximating https://bjk5.com/post/44698559168/breaking-down-amazons-mega-dropdown */ a.tooltip:hover::after { - position: absolute; - top: calc(100% - 10px); - left: -15px; - right: -15px; - height: 20px; - content: "\00a0"; + position: absolute; + top: calc(100% - 10px); + left: -15px; + right: -15px; + height: 20px; + content: "\00a0"; } @media not (prefers-reduced-motion) { - :target { - animation: 0.65s cubic-bezier(0, 0, 0.1, 1.0) 0.1s targetfadein; - } + :target { + animation: 0.65s cubic-bezier(0, 0, 0.1, 1) 0.1s targetfadein; + } - /* This animation is layered onto the mistake-proofing delay for dismissing + /* This animation is layered onto the mistake-proofing delay for dismissing a hovered tooltip, to ensure it feels responsive even with the delay. */ - .fade-out { - opacity: 0; - transition: opacity 0.45s cubic-bezier(0, 0, 0.1, 1.0); - } + .fade-out { + opacity: 0; + transition: opacity 0.45s cubic-bezier(0, 0, 0.1, 1); + } } .popover.tooltip .content { - margin: 0.25em 0.5em; + margin: 0.25em 0.5em; } -.popover.tooltip .content pre, .popover.tooltip .content code { - background: transparent; - margin: 0; - padding: 0; - font-size: 1.25rem; - white-space: pre-wrap; +.popover.tooltip .content pre, +.popover.tooltip .content code { + background: transparent; + margin: 0; + padding: 0; + font-size: 1.25rem; + white-space: pre-wrap; } .popover.tooltip .content > h3:first-child { - margin: 0 0 5px 0; + margin: 0 0 5px 0; } .search-failed { - text-align: center; - margin-top: 20px; - display: none; + text-align: center; + margin-top: 20px; + display: none; } .search-failed.active { - display: block; + display: block; } .search-failed > ul { - text-align: left; - max-width: 570px; - margin-left: auto; - margin-right: auto; + text-align: left; + max-width: 570px; + margin-left: auto; + margin-right: auto; } #search-tabs { - margin-top: 0.25rem; - display: flex; - flex-direction: row; - gap: 1px; - margin-bottom: 4px; + margin-top: 0.25rem; + display: flex; + flex-direction: row; + gap: 1px; + margin-bottom: 4px; } #search-tabs button { - text-align: center; - font-size: 1.125rem; - border: 0; - border-top: 2px solid; - flex: 1; - line-height: 1.5; - color: inherit; + text-align: center; + font-size: 1.125rem; + border: 0; + border-top: 2px solid; + flex: 1; + line-height: 1.5; + color: inherit; } #search-tabs button:not(.selected) { - background-color: var(--search-tab-button-not-selected-background); - border-top-color: var(--search-tab-button-not-selected-border-top-color); + background-color: var(--search-tab-button-not-selected-background); + border-top-color: var(--search-tab-button-not-selected-border-top-color); } -#search-tabs button:hover, #search-tabs button.selected { - background-color: var(--search-tab-button-selected-background); - border-top-color: var(--search-tab-button-selected-border-top-color); +#search-tabs button:hover, +#search-tabs button.selected { + background-color: var(--search-tab-button-selected-background); + border-top-color: var(--search-tab-button-selected-border-top-color); } #search-tabs .count { - font-size: 1rem; - font-variant-numeric: tabular-nums; - color: var(--search-tab-title-count-color); - position: relative; + font-size: 1rem; + font-variant-numeric: tabular-nums; + color: var(--search-tab-title-count-color); + position: relative; } #search-tabs .count.loading { - color: transparent; + color: transparent; } -.search-form.loading::after -{ - width: 18px; - height: 18px; - border-radius: 18px; - /* hourglass */ - content: url('data:image/svg+xml,\ +.search-form.loading::after { + width: 18px; + height: 18px; + border-radius: 18px; + /* hourglass */ + content: url('data:image/svg+xml,\ \ \ \ @@ -2023,139 +2148,155 @@ a.tooltip:hover::after { \ \ '); - position: absolute; - right: 8px; - top: 8px; - filter: var(--settings-menu-filter); + position: absolute; + right: 8px; + top: 8px; + filter: var(--settings-menu-filter); } #search .error code { - border-radius: 3px; - background-color: var(--search-error-code-background-color); + border-radius: 3px; + background-color: var(--search-error-code-background-color); } .search-corrections { - font-weight: normal; + font-weight: normal; } #src-sidebar { - width: 100%; - overflow: auto; + width: 100%; + overflow: auto; } -#src-sidebar div.files > a:hover, details.dir-entry summary:hover, -#src-sidebar div.files > a:focus, details.dir-entry summary:focus { - background-color: var(--src-sidebar-background-hover); +#src-sidebar div.files > a:hover, +details.dir-entry summary:hover, +#src-sidebar div.files > a:focus, +details.dir-entry summary:focus { + background-color: var(--src-sidebar-background-hover); } #src-sidebar div.files > a.selected { - background-color: var(--src-sidebar-background-selected); + background-color: var(--src-sidebar-background-selected); } .src-sidebar-title { - position: sticky; - top: 0; - display: flex; - padding: 8px 8px 0 48px; - margin-bottom: 7px; - background: var(--sidebar-background-color); - border-bottom: 1px solid var(--border-color); -} - -#search-button, .settings-menu, .help-menu, button#toggle-all-docs { - margin-left: var(--button-left-margin); - display: flex; - line-height: 1.25; - min-width: 14px; + position: sticky; + top: 0; + display: flex; + padding: 8px 8px 0 48px; + margin-bottom: 7px; + background: var(--sidebar-background-color); + border-bottom: 1px solid var(--border-color); +} + +#search-button, +.settings-menu, +.help-menu, +button#toggle-all-docs { + margin-left: var(--button-left-margin); + display: flex; + line-height: 1.25; + min-width: 14px; } #sidebar-button { - display: none; - line-height: 0; + display: none; + line-height: 0; } .hide-sidebar #sidebar-button, .src #sidebar-button { - display: flex; - margin-right: 4px; - position: fixed; - margin-top: 25px; - left: 6px; - height: 34px; - width: 34px; - z-index: calc(var(--desktop-sidebar-z-index) + 1); + display: flex; + margin-right: 4px; + position: fixed; + margin-top: 25px; + left: 6px; + height: 34px; + width: 34px; + z-index: calc(var(--desktop-sidebar-z-index) + 1); } .hide-sidebar #sidebar-button { - left: 6px; - background-color: var(--main-background-color); + left: 6px; + background-color: var(--main-background-color); } .src #sidebar-button { - margin-top: 0; - top: 8px; - left: 8px; - border-color: var(--border-color); + margin-top: 0; + top: 8px; + left: 8px; + border-color: var(--border-color); } .hide-sidebar .src #sidebar-button { - position: static; + position: static; } #search-button > a, .settings-menu > a, .help-menu > a, #sidebar-button > a, button#toggle-all-docs { - display: flex; - align-items: center; - justify-content: center; - flex-direction: column; + display: flex; + align-items: center; + justify-content: center; + flex-direction: column; } #search-button > a, .settings-menu > a, .help-menu > a, button#toggle-all-docs { - border: 1px solid transparent; - border-radius: var(--button-border-radius); - color: var(--main-color); + border: 1px solid transparent; + border-radius: var(--button-border-radius); + color: var(--main-color); } -#search-button > a, .settings-menu > a, .help-menu > a, button#toggle-all-docs { - width: 80px; - border-radius: var(--toolbar-button-border-radius); +#search-button > a, +.settings-menu > a, +.help-menu > a, +button#toggle-all-docs { + width: 80px; + border-radius: var(--toolbar-button-border-radius); } -#search-button > a, .settings-menu > a, .help-menu > a { - min-width: 0; +#search-button > a, +.settings-menu > a, +.help-menu > a { + min-width: 0; } #sidebar-button > a { - border: solid 1px transparent; - border-radius: var(--button-border-radius); - background-color: var(--button-background-color); - width: 33px; + border: solid 1px transparent; + border-radius: var(--button-border-radius); + background-color: var(--button-background-color); + width: 33px; } .src #sidebar-button > a { - background-color: var(--sidebar-background-color); - border-color: var(--border-color); -} - -#search-button > a:hover, #search-button > a:focus-visible, -.settings-menu > a:hover, .settings-menu > a:focus-visible, -.help-menu > a:hover, #help-menu > a:focus-visible, -#sidebar-button > a:hover, #sidebar-button > a:focus-visible, -#copy-path:hover, #copy-path:focus-visible, -button#toggle-all-docs:hover, button#toggle-all-docs:focus-visible { - border-color: var(--settings-button-border-focus); - text-decoration: none; + background-color: var(--sidebar-background-color); + border-color: var(--border-color); +} + +#search-button > a:hover, +#search-button > a:focus-visible, +.settings-menu > a:hover, +.settings-menu > a:focus-visible, +.help-menu > a:hover, +#help-menu > a:focus-visible, +#sidebar-button > a:hover, +#sidebar-button > a:focus-visible, +#copy-path:hover, +#copy-path:focus-visible, +button#toggle-all-docs:hover, +button#toggle-all-docs:focus-visible { + border-color: var(--settings-button-border-focus); + text-decoration: none; } #search-button > a::before { - /* Magnifying glass */ - content: url('data:image/svg+xml,\ \ Search\ '); - width: 18px; - height: 18px; - filter: var(--settings-menu-filter); + width: 18px; + height: 18px; + filter: var(--settings-menu-filter); } .settings-menu > a::before { - /* Wheel */ - content: url('data:image/svg+xml, */ + content: url('data:image/svg+xml,\ \ '); - width: 18px; - height: 18px; - filter: var(--settings-menu-filter); + width: 18px; + height: 18px; + filter: var(--settings-menu-filter); } button#toggle-all-docs::before { - /* Custom arrow icon */ - content: url('data:image/svg+xml,\ '); - width: 18px; - height: 18px; - filter: var(--settings-menu-filter); + width: 18px; + height: 18px; + filter: var(--settings-menu-filter); } .help-menu > a::before { - /* Question mark with "circle" */ - content: url('data:image/svg+xml,\ + /* Question mark with "circle" */ + content: url('data:image/svg+xml,\ \ \ '); - width: 18px; - height: 18px; - filter: var(--settings-menu-filter); + width: 18px; + height: 18px; + filter: var(--settings-menu-filter); } /* design hack to cope with "Help" being far shorter than "Settings" etc */ .help-menu > a { - width: 74px; + width: 74px; } .help-menu > a > .label { - padding-right: 1px; + padding-right: 1px; } #toggle-all-docs:not(.will-expand) > .label { - padding-left: 1px; + padding-left: 1px; } #search-button > a::before, button#toggle-all-docs::before, .help-menu > a::before, .settings-menu > a::before { - filter: var(--settings-menu-filter); - margin: 8px; + filter: var(--settings-menu-filter); + margin: 8px; } @media not (pointer: coarse) { - #search-button > a:hover::before, - button#toggle-all-docs:hover::before, - .help-menu > a:hover::before, - .settings-menu > a:hover::before { - filter: var(--settings-menu-hover-filter); - } + #search-button > a:hover::before, + button#toggle-all-docs:hover::before, + .help-menu > a:hover::before, + .settings-menu > a:hover::before { + filter: var(--settings-menu-hover-filter); + } } button[disabled]#toggle-all-docs { - opacity: 0.25; - border: solid 1px var(--main-background-color); - background-size: cover; + opacity: 0.25; + border: solid 1px var(--main-background-color); + background-size: cover; } button[disabled]#toggle-all-docs:hover { - border: solid 1px var(--main-background-color); - cursor: not-allowed; + border: solid 1px var(--main-background-color); + cursor: not-allowed; } rustdoc-toolbar span.label { - font-size: 1rem; - flex-grow: 1; - padding-bottom: 4px; + font-size: 1rem; + flex-grow: 1; + padding-bottom: 4px; } #sidebar-button > a::before { - /* sidebar resizer image */ - content: url('data:image/svg+xml,\ \ \ '); - width: 22px; - height: 22px; + width: 22px; + height: 22px; } #copy-path { - color: var(--copy-path-button-color); - background: var(--main-background-color); - height: var(--copy-path-height); - width: var(--copy-path-width); - margin-left: 10px; - padding: 0; - padding-left: 2px; - border: solid 1px transparent; - border-radius: var(--button-border-radius); - font-size: 0; + color: var(--copy-path-button-color); + background: var(--main-background-color); + height: var(--copy-path-height); + width: var(--copy-path-width); + margin-left: 10px; + padding: 0; + padding-left: 2px; + border: solid 1px transparent; + border-radius: var(--button-border-radius); + font-size: 0; } #copy-path::before { - filter: var(--copy-path-img-filter); - content: var(--clipboard-image); + filter: var(--copy-path-img-filter); + content: var(--clipboard-image); } #copy-path:hover::before { - filter: var(--copy-path-img-hover-filter); + filter: var(--copy-path-img-hover-filter); } #copy-path.clicked::before { - content: var(--checkmark-image); + content: var(--checkmark-image); } @keyframes rotating { - from { - transform: rotate(0deg); - } - to { - transform: rotate(360deg); - } + from { + transform: rotate(0deg); + } + to { + transform: rotate(360deg); + } } .settings-menu.rotate > a img { - animation: rotating 2s linear infinite; + animation: rotating 2s linear infinite; } kbd { - display: inline-block; - padding: 3px 5px; - font: 15px monospace; - line-height: 10px; - vertical-align: middle; - border: solid 1px var(--border-color); - border-radius: 3px; - color: var(--kbd-color); - background-color: var(--kbd-background); - box-shadow: inset 0 -1px 0 var(--kbd-box-shadow-color); + display: inline-block; + padding: 3px 5px; + font: 15px monospace; + line-height: 10px; + vertical-align: middle; + border: solid 1px var(--border-color); + border-radius: 3px; + color: var(--kbd-color); + background-color: var(--kbd-background); + box-shadow: inset 0 -1px 0 var(--kbd-box-shadow-color); } ul.all-items > li { - list-style: none; + list-style: none; } details.dir-entry { - padding-left: 4px; + padding-left: 4px; } details.dir-entry > summary { - margin: 0 0 0 -4px; - padding: 0 0 0 4px; - cursor: pointer; + margin: 0 0 0 -4px; + padding: 0 0 0 4px; + cursor: pointer; } -details.dir-entry div.folders, details.dir-entry div.files { - padding-left: 23px; +details.dir-entry div.folders, +details.dir-entry div.files { + padding-left: 23px; } details.dir-entry a { - display: block; + display: block; } /* We use CSS containment on the details elements because most sizeable elements @@ -2338,104 +2480,105 @@ details.dir-entry a { because the [-]/[+] toggles extend past the boundaries of the
https://developer.mozilla.org/en-US/docs/Web/CSS/contain */ details.toggle { - contain: layout; - position: relative; + contain: layout; + position: relative; } details.big-toggle { - /* This makes [-] on the same line as . */ - contain: inline-size; + /* This makes [-] on the same line as . */ + contain: inline-size; } /* The hideme class is used on summary tags that contain a span with placeholder text shown only when the toggle is closed. For instance, "Expand description" or "Show methods". */ details.toggle > summary.hideme { - cursor: pointer; - font-size: 1rem; + cursor: pointer; + font-size: 1rem; } details.toggle > summary { - list-style: none; - /* focus outline is shown on `::before` instead of this */ - outline: none; + list-style: none; + /* focus outline is shown on `::before` instead of this */ + outline: none; } details.toggle > summary::-webkit-details-marker, details.toggle > summary::marker { - display: none; + display: none; } details.toggle > summary.hideme > span { - margin-left: 9px; + margin-left: 9px; } details.toggle > summary::before { - /* arrow pointing left */ - background: url('data:image/svg+xml,\ '); - content: ""; - cursor: pointer; - width: 16px; - height: 16px; - display: inline-block; - vertical-align: middle; - opacity: .5; - filter: var(--toggle-filter); + content: ""; + cursor: pointer; + width: 16px; + height: 16px; + display: inline-block; + vertical-align: middle; + opacity: 0.5; + filter: var(--toggle-filter); } details.toggle > summary.hideme > span, -.more-examples-toggle summary, .more-examples-toggle .hide-more { - color: var(--toggles-color); +.more-examples-toggle summary, +.more-examples-toggle .hide-more { + color: var(--toggles-color); } /* Screen readers see the text version at the end the line. Visual readers see the icon at the start of the line, but small and transparent. */ details.toggle > summary::after { - content: "Expand"; - overflow: hidden; - width: 0; - height: 0; - position: absolute; + content: "Expand"; + overflow: hidden; + width: 0; + height: 0; + position: absolute; } details.toggle > summary.hideme::after { - /* "hideme" toggles already have a description when they're contracted */ - content: ""; + /* "hideme" toggles already have a description when they're contracted */ + content: ""; } details.toggle > summary:focus::before, details.toggle > summary:hover::before { - opacity: 1; + opacity: 1; } details.toggle > summary:focus-visible::before { - /* The SVG is black, and gets turned white using a filter in the dark themes. + /* The SVG is black, and gets turned white using a filter in the dark themes. Do the same with the outline. The dotted 1px style is copied from Firefox's focus ring style. */ - outline: 1px dotted #000; - outline-offset: 1px; + outline: 1px dotted #000; + outline-offset: 1px; } details.non-exhaustive { - margin-bottom: 8px; + margin-bottom: 8px; } details.toggle > summary.hideme::before { - position: relative; + position: relative; } details.toggle > summary:not(.hideme)::before { - position: absolute; - left: -24px; - top: 4px; + position: absolute; + left: -24px; + top: 4px; } .impl-items > details.toggle > summary:not(.hideme)::before, #main-content > .methods > details.toggle > summary:not(.hideme)::before { - position: absolute; - left: -24px; + position: absolute; + left: -24px; } /* We indent items of an impl block to have a visual marker that these items are part @@ -2449,12 +2592,12 @@ details.toggle > summary:not(.hideme)::before { .impl > .item-info, .impl > .docblock, .impl + .docblock { - margin-left: var(--impl-items-indent); + margin-left: var(--impl-items-indent); } details.big-toggle > summary:not(.hideme)::before { - left: -34px; - top: 9px; + left: -34px; + top: 9px; } /* When a "hideme" summary is open and the "Expand description" or "Show @@ -2463,60 +2606,63 @@ details.big-toggle > summary:not(.hideme)::before { absolute positioning. Note that we also set position: relative on the parent
to make this work properly. */ details.toggle[open] > summary.hideme { - position: absolute; + position: absolute; } details.toggle[open] > summary.hideme > span { - display: none; + display: none; } details.toggle[open] > summary::before { - /* arrow pointing down */ - background: url('data:image/svg+xml,\ '); } details.toggle[open] > summary::after { - content: "Collapse"; + content: "Collapse"; } details.toggle:not([open]) > summary .docblock { - max-height: calc(1.5em + 0.75em); - overflow-y: hidden; + max-height: calc(1.5em + 0.75em); + overflow-y: hidden; } details.toggle:not([open]) > summary .docblock > :first-child { - max-width: 100%; - overflow: hidden; - width: fit-content; - white-space: nowrap; - position: relative; - padding-right: 1em; + max-width: 100%; + overflow: hidden; + width: fit-content; + white-space: nowrap; + position: relative; + padding-right: 1em; } details.toggle:not([open]) > summary .docblock > :first-child::after { - content: "…"; - position: absolute; - right: 0; - top: 0; - bottom: 0; - z-index: 1; - background-color: var(--main-background-color); - font: 1rem/1.5 "Source Serif 4", NanumBarunGothic, serif; - /* To make it look a bit better and not have it stuck to the preceding element. */ - padding-left: 0.2em; + content: "…"; + position: absolute; + right: 0; + top: 0; + bottom: 0; + z-index: 1; + background-color: var(--main-background-color); + font: + 1rem/1.5 "Source Serif 4", + NanumBarunGothic, + serif; + /* To make it look a bit better and not have it stuck to the preceding element. */ + padding-left: 0.2em; } details.toggle:not([open]) > summary .docblock > div:first-child::after { - /* This is to make the "..." always appear at the bottom. */ - padding-top: calc(1.5em + 0.75em - 1.2rem); + /* This is to make the "..." always appear at the bottom. */ + padding-top: calc(1.5em + 0.75em - 1.2rem); } details.toggle > summary .docblock { - margin-top: 0.75em; + margin-top: 0.75em; } /* This is needed in docblocks to have the "▶" element to be on the same line. */ .docblock summary > * { - display: inline-block; + display: inline-block; } /* In case there is no documentation before a code block, we need to add some margin at the top @@ -2524,114 +2670,114 @@ to prevent an overlay between the "collapse toggle" and the information tooltip. However, it's not needed with smaller screen width because the doc/code block is always put "one line" below. */ .docblock > .example-wrap:first-child .tooltip { - margin-top: 16px; + margin-top: 16px; } /* sidebar button opens modal use hamburger button */ -.src #sidebar-button > a::before, .sidebar-menu-toggle::before { - /* hamburger button image */ - content: var(--hamburger-image); - opacity: 0.75; - filter: var(--mobile-sidebar-menu-filter); +.src #sidebar-button > a::before, +.sidebar-menu-toggle::before { + /* hamburger button image */ + content: var(--hamburger-image); + opacity: 0.75; + filter: var(--mobile-sidebar-menu-filter); } .src #sidebar-button > a:hover { - background: var(--main-background-color); + background: var(--main-background-color); } .sidebar-menu-toggle:hover::before, .sidebar-menu-toggle:active::before, .sidebar-menu-toggle:focus::before { - opacity: 1; + opacity: 1; } /* Media Queries */ @media (max-width: 850px) { - /* Make sure all the buttons line wrap at the same time */ - #search-tabs .count { - display: block; - } - .side-by-side { - flex-direction: column-reverse; - } - .side-by-side > div { - width: auto; - } - - /* Text label takes up too much space at this size. */ - .main-heading { - grid-template-areas: - "main-heading-breadcrumbs main-heading-toolbar" - "main-heading-h1 main-heading-toolbar" - "main-heading-sub-heading main-heading-toolbar"; - } - .search-results-main-heading { - display: grid; - grid-template-areas: - "main-heading-breadcrumbs main-heading-toolbar" - "main-heading-breadcrumbs main-heading-toolbar" - "main-heading-h1 main-heading-toolbar"; - } - rustdoc-toolbar { - margin-top: -10px; - display: grid; - grid-template-areas: - "x settings help" - "search summary summary"; - grid-template-rows: 35px 1fr; - } - .search-results-main-heading rustdoc-toolbar { - display: grid; - grid-template-areas: - "settings help" - "search search"; - } - .search-results-main-heading #toggle-all-docs { - display: none; - } - rustdoc-toolbar .settings-menu span.label, - rustdoc-toolbar .help-menu span.label - { - display: none; - } - rustdoc-toolbar .settings-menu { - grid-area: settings; - } - rustdoc-toolbar .help-menu { - grid-area: help; - } - rustdoc-toolbar .settings-menu { - grid-area: settings; - } - rustdoc-toolbar #search-button { - grid-area: search; - } - rustdoc-toolbar #toggle-all-docs { - grid-area: summary; - } - rustdoc-toolbar .settings-menu, - rustdoc-toolbar .help-menu { - height: 35px; - } - rustdoc-toolbar .settings-menu > a, - rustdoc-toolbar .help-menu > a { - border-radius: 2px; - text-align: center; - width: 34px; - padding: 5px 0; - } - rustdoc-toolbar .settings-menu > a:before, - rustdoc-toolbar .help-menu > a:before { - margin: 0 4px; - } - #settings.popover { - top: 16px; - --popover-arrow-offset: 58px; - } - #help.popover { - top: 16px; - --popover-arrow-offset: 16px; - } + /* Make sure all the buttons line wrap at the same time */ + #search-tabs .count { + display: block; + } + .side-by-side { + flex-direction: column-reverse; + } + .side-by-side > div { + width: auto; + } + + /* Text label takes up too much space at this size. */ + .main-heading { + grid-template-areas: + "main-heading-breadcrumbs main-heading-toolbar" + "main-heading-h1 main-heading-toolbar" + "main-heading-sub-heading main-heading-toolbar"; + } + .search-results-main-heading { + display: grid; + grid-template-areas: + "main-heading-breadcrumbs main-heading-toolbar" + "main-heading-breadcrumbs main-heading-toolbar" + "main-heading-h1 main-heading-toolbar"; + } + rustdoc-toolbar { + margin-top: -10px; + display: grid; + grid-template-areas: + "x settings help" + "search summary summary"; + grid-template-rows: 35px 1fr; + } + .search-results-main-heading rustdoc-toolbar { + display: grid; + grid-template-areas: + "settings help" + "search search"; + } + .search-results-main-heading #toggle-all-docs { + display: none; + } + rustdoc-toolbar .settings-menu span.label, + rustdoc-toolbar .help-menu span.label { + display: none; + } + rustdoc-toolbar .settings-menu { + grid-area: settings; + } + rustdoc-toolbar .help-menu { + grid-area: help; + } + rustdoc-toolbar .settings-menu { + grid-area: settings; + } + rustdoc-toolbar #search-button { + grid-area: search; + } + rustdoc-toolbar #toggle-all-docs { + grid-area: summary; + } + rustdoc-toolbar .settings-menu, + rustdoc-toolbar .help-menu { + height: 35px; + } + rustdoc-toolbar .settings-menu > a, + rustdoc-toolbar .help-menu > a { + border-radius: 2px; + text-align: center; + width: 34px; + padding: 5px 0; + } + rustdoc-toolbar .settings-menu > a:before, + rustdoc-toolbar .help-menu > a:before { + margin: 0 4px; + } + #settings.popover { + top: 16px; + --popover-arrow-offset: 58px; + } + #help.popover { + top: 16px; + --popover-arrow-offset: 16px; + } } /* @@ -2640,186 +2786,188 @@ If you update this line, then you also need to update the line with the same war in src-script.js and main.js */ @media (max-width: 700px) { - :root { - --impl-items-indent: 0.7em; - } + :root { + --impl-items-indent: 0.7em; + } - /* When linking to an item with an `id` (for instance, by clicking a link in the sidebar, + /* When linking to an item with an `id` (for instance, by clicking a link in the sidebar, or visiting a URL with a fragment like `#method.new`, we don't want the item to be obscured by the topbar. Anything with an `id` gets scroll-margin-top equal to rustdoc-topbar's size. */ - *[id] { - scroll-margin-top: 45px; - } + *[id] { + scroll-margin-top: 45px; + } - /* We don't display this button on mobile devices. */ - #copy-path { - /* display: none; avoided as a layout hack. + /* We don't display this button on mobile devices. */ + #copy-path { + /* display: none; avoided as a layout hack. When there's one line, we get an effective line-height of 34px, because that's how big the image is, but if the header wraps, they're packed more tightly than that. */ - width: 0; - visibility: hidden; - } - - - /* Pull settings and help up into the top bar. */ - rustdoc-topbar span.label, - html:not(.hide-sidebar) .rustdoc:not(.src) rustdoc-toolbar .settings-menu > a, - html:not(.hide-sidebar) .rustdoc:not(.src) rustdoc-toolbar .help-menu > a - { - display: none; - } - rustdoc-topbar .settings-menu > a, - rustdoc-topbar .help-menu > a { - width: 33px; - line-height: 0; - } - rustdoc-topbar .settings-menu > a:hover, - rustdoc-topbar .help-menu > a:hover { - border: none; - background: var(--main-background-color); - border-radius: 0; - } - #settings.popover { - top: 32px; - --popover-arrow-offset: 48px; - } - #help.popover { - top: 32px; - --popover-arrow-offset: 12px; - } - - .rustdoc { - /* Sidebar should overlay main content, rather than pushing main content to the right. + width: 0; + visibility: hidden; + } + + /* Pull settings and help up into the top bar. */ + rustdoc-topbar span.label, + html:not(.hide-sidebar) + .rustdoc:not(.src) + rustdoc-toolbar + .settings-menu + > a, + html:not(.hide-sidebar) .rustdoc:not(.src) rustdoc-toolbar .help-menu > a { + display: none; + } + rustdoc-topbar .settings-menu > a, + rustdoc-topbar .help-menu > a { + width: 33px; + line-height: 0; + } + rustdoc-topbar .settings-menu > a:hover, + rustdoc-topbar .help-menu > a:hover { + border: none; + background: var(--main-background-color); + border-radius: 0; + } + #settings.popover { + top: 32px; + --popover-arrow-offset: 48px; + } + #help.popover { + top: 32px; + --popover-arrow-offset: 12px; + } + + .rustdoc { + /* Sidebar should overlay main content, rather than pushing main content to the right. Turn off `display: flex` on the body element. */ - display: block; - } + display: block; + } - html:not(.hide-sidebar) main { - padding-left: 15px; - padding-top: 0px; - } + html:not(.hide-sidebar) main { + padding-left: 15px; + padding-top: 0px; + } - /* Hide the logo and item name from the sidebar. Those are displayed + /* Hide the logo and item name from the sidebar. Those are displayed in the rustdoc-topbar instead. */ - .sidebar .logo-container, - .sidebar .location, - .sidebar-resizer { - display: none; - } - - .sidebar { - position: fixed; - top: 45px; - /* Hide the sidebar offscreen while not in use. Doing this instead of display: none means + .sidebar .logo-container, + .sidebar .location, + .sidebar-resizer { + display: none; + } + + .sidebar { + position: fixed; + top: 45px; + /* Hide the sidebar offscreen while not in use. Doing this instead of display: none means the sidebar stays visible for screen readers, which is useful for navigation. */ - left: -1000px; - z-index: 11; - /* Reduce height slightly to account for mobile topbar. */ - height: calc(100vh - 45px); - /* resize indicator: hide this when on touch or mobile */ - border-right: none; - width: 100%; - } - .sidebar-elems .block li a { - white-space: wrap; - } - - /* The source view uses a different design for the sidebar toggle, and doesn't have a topbar, + left: -1000px; + z-index: 11; + /* Reduce height slightly to account for mobile topbar. */ + height: calc(100vh - 45px); + /* resize indicator: hide this when on touch or mobile */ + border-right: none; + width: 100%; + } + .sidebar-elems .block li a { + white-space: wrap; + } + + /* The source view uses a different design for the sidebar toggle, and doesn't have a topbar, so don't bump down the main content or the sidebar. */ - .src main, - .rustdoc.src .sidebar { - top: 0; - padding: 0; - height: 100vh; - border: 0; - } - html .src main { - padding: 18px 0; - } - .src .search-form { - margin-left: 40px; - } - .src .main-heading { - margin-left: 8px; - } - .hide-sidebar .search-form { - margin-left: 32px; - } - .hide-sidebar .src .search-form { - margin-left: 0; - } - - .sidebar.shown, - .src-sidebar-expanded .src .sidebar, - .rustdoc:not(.src) .sidebar:focus-within { - left: 0; - } - - rustdoc-topbar > h2 { - padding-bottom: 0; - margin: auto; - overflow: hidden; - /* Rare exception to specifying font sizes in rem. Since the topbar + .src main, + .rustdoc.src .sidebar { + top: 0; + padding: 0; + height: 100vh; + border: 0; + } + html .src main { + padding: 18px 0; + } + .src .search-form { + margin-left: 40px; + } + .src .main-heading { + margin-left: 8px; + } + .hide-sidebar .search-form { + margin-left: 32px; + } + .hide-sidebar .src .search-form { + margin-left: 0; + } + + .sidebar.shown, + .src-sidebar-expanded .src .sidebar, + .rustdoc:not(.src) .sidebar:focus-within { + left: 0; + } + + rustdoc-topbar > h2 { + padding-bottom: 0; + margin: auto; + overflow: hidden; + /* Rare exception to specifying font sizes in rem. Since the topbar height is specified in pixels, this also has to be specified in pixels to avoid overflowing the topbar when the user sets a bigger font size. */ - font-size: 24px; - white-space: nowrap; - text-overflow: ellipsis; - text-align: center; - } - - rustdoc-topbar .logo-container > img { - max-width: 35px; - max-height: 35px; - margin: 5px 0 5px 20px; - } - - rustdoc-topbar { - display: flex; - flex-direction: row; - position: sticky; - z-index: 10; - height: 45px; - width: 100%; - left: 0; - top: 0; - } - - .hide-sidebar rustdoc-topbar { - display: none; - } - - .sidebar-menu-toggle { - /* prevent flexbox shrinking */ - width: 41px; - min-width: 41px; - border: none; - line-height: 0; - } - - .hide-sidebar .sidebar-menu-toggle { - display: none; - } - - .sidebar-elems { - margin-top: 1em; - } - - .anchor { - display: none !important; - } - - #main-content > details.toggle > summary::before, - #main-content > div > details.toggle > summary::before { - left: -11px; - } - - /* sidebar button becomes topbar button */ - #sidebar-button > a::before { - content: url('data:image/svg+xml, img { + max-width: 35px; + max-height: 35px; + margin: 5px 0 5px 20px; + } + + rustdoc-topbar { + display: flex; + flex-direction: row; + position: sticky; + z-index: 10; + height: 45px; + width: 100%; + left: 0; + top: 0; + } + + .hide-sidebar rustdoc-topbar { + display: none; + } + + .sidebar-menu-toggle { + /* prevent flexbox shrinking */ + width: 41px; + min-width: 41px; + border: none; + line-height: 0; + } + + .hide-sidebar .sidebar-menu-toggle { + display: none; + } + + .sidebar-elems { + margin-top: 1em; + } + + .anchor { + display: none !important; + } + + #main-content > details.toggle > summary::before, + #main-content > div > details.toggle > summary::before { + left: -11px; + } + + /* sidebar button becomes topbar button */ + #sidebar-button > a::before { + content: url('data:image/svg+xml,\ \ \ @@ -2828,80 +2976,82 @@ in src-script.js and main.js \ \ '); - width: 22px; - height: 22px; - } - .sidebar-menu-toggle:hover { - background: var(--main-background-color); - } - - /* Display an alternating layout on tablets and phones */ - .search-results > a, .search-results > a > div { - display: block; - } - - /* Display an alternating layout on tablets and phones */ - .search-results > a { - padding: 5px 0px; - } - .search-results > a > div.desc, .item-table dd { - padding-left: 2em; - } - .search-results .result-name { - display: block; - } - .search-results .result-name .typename { - width: initial; - margin-right: 0; - } - .search-results .result-name .typename, .search-results .result-name .path { - display: inline; - } - - .src-sidebar-expanded .src .sidebar { - position: fixed; - max-width: 100vw; - width: 100vw; - } - .src .src-sidebar-title { - padding-top: 0; - } - - details.implementors-toggle:not(.top-doc) > summary { - margin-left: 10px; - } - - .impl-items > details.toggle > summary:not(.hideme)::before, - #main-content > .methods > details.toggle > summary:not(.hideme)::before { - left: -20px; - } - - /* Align summary-nested and unnested item-info gizmos. */ - summary > .item-info { - margin-left: 10px; - } - .impl-items > .item-info { - margin-left: calc(var(--impl-items-indent) + 10px); - } - - .src nav.sub { - margin: 0 0 -25px 0; - padding: var(--nav-sub-mobile-padding); - } - - html:not(.src-sidebar-expanded) .src #sidebar-button > a { - background-color: var(--main-background-color); - } - html:not(.src-sidebar-expanded) .src #sidebar-button > a:hover, - html:not(.src-sidebar-expanded) .src #sidebar-button > a:focus-visible { - background-color: var(--sidebar-background-color); - } + width: 22px; + height: 22px; + } + .sidebar-menu-toggle:hover { + background: var(--main-background-color); + } + + /* Display an alternating layout on tablets and phones */ + .search-results > a, + .search-results > a > div { + display: block; + } + + /* Display an alternating layout on tablets and phones */ + .search-results > a { + padding: 5px 0px; + } + .search-results > a > div.desc, + .item-table dd { + padding-left: 2em; + } + .search-results .result-name { + display: block; + } + .search-results .result-name .typename { + width: initial; + margin-right: 0; + } + .search-results .result-name .typename, + .search-results .result-name .path { + display: inline; + } + + .src-sidebar-expanded .src .sidebar { + position: fixed; + max-width: 100vw; + width: 100vw; + } + .src .src-sidebar-title { + padding-top: 0; + } + + details.implementors-toggle:not(.top-doc) > summary { + margin-left: 10px; + } + + .impl-items > details.toggle > summary:not(.hideme)::before, + #main-content > .methods > details.toggle > summary:not(.hideme)::before { + left: -20px; + } + + /* Align summary-nested and unnested item-info gizmos. */ + summary > .item-info { + margin-left: 10px; + } + .impl-items > .item-info { + margin-left: calc(var(--impl-items-indent) + 10px); + } + + .src nav.sub { + margin: 0 0 -25px 0; + padding: var(--nav-sub-mobile-padding); + } + + html:not(.src-sidebar-expanded) .src #sidebar-button > a { + background-color: var(--main-background-color); + } + html:not(.src-sidebar-expanded) .src #sidebar-button > a:hover, + html:not(.src-sidebar-expanded) .src #sidebar-button > a:focus-visible { + background-color: var(--sidebar-background-color); + } } - /* Should have min-width: (N + 1)px where N is the mobile breakpoint above. */ @media (min-width: 701px) { - /* Places file-link for a scraped example on top of the example to save space. + /* Places file-link for a scraped example on top of the example to save space. We only do this on large screens so the file-link doesn't overlap too much with the example's content. */ .scraped-example-title { @@ -2928,41 +3078,62 @@ in src-script.js and main.js .item-table > dd { grid-column-start: 2; } -} -@media print { - :root { - --docblock-indent: 0; - } + /* Hide deprecated items in module summaries (dt/dd pairs) when setting is off */ + .hide-depr dt:has(.depr-item), + .hide-depr dt:has(.depr-item) + dd { + display: none; + } - nav.sidebar, nav.sub, .out-of-band, a.src, #copy-path, - details.toggle[open] > summary::before, details.toggle > summary::before, - details.toggle.top-doc > summary { - display: none; - } + /* Hide deprecated items in the sidebar blocks */ + .hide-depr nav.sidebar li:has(.depr-item) { + display: none; + } - main { - padding: 10px; - } + /* Hide deprecated items in the all items page */ + .hide-depr ul.all-items li:has(.depr-item) { + display: none; + } } -@media (max-width: 464px) { - :root { - --docblock-indent: 12px; - } - - .docblock code { - overflow-wrap: break-word; - overflow-wrap: anywhere; - } - - nav.sub { - flex-direction: column; - } +@media print { + :root { + --docblock-indent: 0; + } + + nav.sidebar, + nav.sub, + .out-of-band, + a.src, + #copy-path, + details.toggle[open] > summary::before, + details.toggle > summary::before, + details.toggle.top-doc > summary { + display: none; + } + + main { + padding: 10px; + } +} - .search-form { - align-self: stretch; - } +@media (max-width: 464px) { + :root { + --docblock-indent: 12px; + } + + .docblock code { + overflow-wrap: break-word; + overflow-wrap: anywhere; + } + + nav.sub { + flex-direction: column; + } + + .search-form { + align-self: stretch; + } } .variant, diff --git a/src/librustdoc/html/static/js/settings.js b/src/librustdoc/html/static/js/settings.js index 347d3d0750ece..c7c596c9fbe5d 100644 --- a/src/librustdoc/html/static/js/settings.js +++ b/src/librustdoc/html/static/js/settings.js @@ -78,6 +78,13 @@ removeClass(document.documentElement, "word-wrap-source-code"); } break; + case "hide-deprecated-items": + if (value === true) { + addClass(document.documentElement, "hide-depr"); + } else { + removeClass(document.documentElement, "hide-depr"); + } + break; } } @@ -274,6 +281,11 @@ "js_name": "word-wrap-source-code", "default": false, }, + { + "name": "Hide deprecated items", + "js_name": "hide-deprecated-items", + "default": false, + }, ]; // Then we build the DOM. diff --git a/src/librustdoc/html/static/js/storage.js b/src/librustdoc/html/static/js/storage.js index 40ab8be03c93d..5be074f221480 100644 --- a/src/librustdoc/html/static/js/storage.js +++ b/src/librustdoc/html/static/js/storage.js @@ -334,6 +334,12 @@ if (getSettingValue("sans-serif-fonts") === "true") { if (getSettingValue("word-wrap-source-code") === "true") { addClass(document.documentElement, "word-wrap-source-code"); } +const hideDepr = getSettingValue("hide-deprecated-items"); +if (hideDepr === "true") { + addClass(document.documentElement, "hide-depr"); +} else { + removeClass(document.documentElement, "hide-depr"); +} function updateSidebarWidth() { const desktopSidebarWidth = getSettingValue("desktop-sidebar-width"); if (desktopSidebarWidth && desktopSidebarWidth !== "null") { From 1ed665bcbcddb8d0f2a6332617f48369a91042f9 Mon Sep 17 00:00:00 2001 From: Saphereye Date: Fri, 12 Dec 2025 00:52:04 +0530 Subject: [PATCH 13/14] checkpoint commit --- src/librustdoc/html/render/sidebar.rs | 222 ++++++++++++-- src/librustdoc/html/static/css/rustdoc.css | 22 +- src/librustdoc/html/static/js/main.js | 333 +++++++++++++++++++++ src/librustdoc/html/templates/sidebar.html | 4 +- 4 files changed, 535 insertions(+), 46 deletions(-) diff --git a/src/librustdoc/html/render/sidebar.rs b/src/librustdoc/html/render/sidebar.rs index ebbc8d8ef484e..ff441e235b276 100644 --- a/src/librustdoc/html/render/sidebar.rs +++ b/src/librustdoc/html/render/sidebar.rs @@ -91,6 +91,8 @@ pub(crate) struct Link<'a> { href: Cow<'a, str>, /// Nested list of links (used only in top-toc) children: Vec>, + /// Whether this link represents a deprecated item + deprecated: bool, } impl Ord for Link<'_> { @@ -115,7 +117,7 @@ impl PartialOrd for Link<'_> { impl<'a> Link<'a> { pub fn new(href: impl Into>, name: impl Into>) -> Self { - Self { href: href.into(), name: name.into(), children: vec![], name_html: None } + Self { href: href.into(), name: name.into(), children: vec![], name_html: None, deprecated: false } } pub fn empty() -> Link<'static> { Link::new("", "") @@ -153,7 +155,7 @@ pub(super) fn print_sidebar( clean::EnumItem(ref e) => sidebar_enum(cx, it, e, &mut blocks, &deref_id_map), clean::TypeAliasItem(ref t) => sidebar_type_alias(cx, it, t, &mut blocks, &deref_id_map), clean::ModuleItem(ref m) => { - blocks.push(sidebar_module(&m.items, &mut ids, ModuleLike::from(it))) + blocks.extend(sidebar_module(cx, &m.items, &mut ids, ModuleLike::from(it))); } clean::ForeignTypeItem => sidebar_foreign_type(cx, it, &mut blocks, &deref_id_map), _ => {} @@ -243,20 +245,24 @@ fn docblock_toc<'a>( .children .entries .into_iter() - .map(|entry| Link { - name_html: if entry.html == entry.name { - None - } else { - Some(entry.html.into()) - }, - name: entry.name.into(), - href: entry.id.into(), - // Only a single level of nesting is shown here. - // Going the full six could break the layout, - // so we have to cut it off somewhere. - children: vec![], + .map(|entry| { + Link { + name_html: if entry.html == entry.name { + None + } else { + Some(entry.html.into()) + }, + name: entry.name.into(), + href: entry.id.into(), + // Only a single level of nesting is shown here. + // Going the full six could break the layout, + // so we have to cut it off somewhere. + children: vec![], + deprecated: false, + } }) .collect(), + deprecated: false, } }) .collect(); @@ -439,8 +445,8 @@ fn sidebar_assoc_items<'a>( { let used_links_bor = &mut used_links; for impl_ in v.iter().map(|i| i.inner_impl()).filter(|i| i.trait_.is_none()) { - assoc_consts.extend(get_associated_constants(impl_, used_links_bor)); - assoc_types.extend(get_associated_types(impl_, used_links_bor)); + assoc_consts.extend(get_associated_constants(impl_, used_links_bor, cx.tcx())); + assoc_types.extend(get_associated_types(impl_, used_links_bor, cx.tcx())); methods.extend(get_methods(impl_, false, used_links_bor, false, cx.tcx())); } // We want links' order to be reproducible so we don't use unstable sort. @@ -655,10 +661,12 @@ pub(crate) fn sidebar_module_like( } fn sidebar_module( + cx: &Context<'_>, items: &[clean::Item], ids: &mut IdMap, module_like: ModuleLike, -) -> LinkBlock<'static> { +) -> Vec> { + // Header block linking to the module/crate items section let item_sections_in_use: FxHashSet<_> = items .iter() .filter(|it| { @@ -679,7 +687,122 @@ fn sidebar_module( .map(|it| item_ty_to_section(it.type_())) .collect(); - sidebar_module_like(item_sections_in_use, ids, module_like) + let mut blocks = vec![sidebar_module_like(item_sections_in_use, ids, module_like)]; + + // Collect per-item lists for module-scope entries + let mut structs: Vec> = Vec::new(); + let mut functions: Vec> = Vec::new(); + let mut enums: Vec> = Vec::new(); + let mut type_aliases: Vec> = Vec::new(); + let mut constants: Vec> = Vec::new(); + let mut modules: Vec> = Vec::new(); + + for it in items.iter() { + if it.is_stripped() { + continue; + } + let Some(name) = it.name.as_ref() else { continue }; + let name_str = name.as_str(); + match it.kind { + clean::StructItem(..) => { + let mut l = Link::new(format!("struct.{name_str}"), name_str.to_string()); + if it.deprecation(cx.tcx()).is_some_and(|d| d.is_in_effect()) { + l.deprecated = true; + l.name_html = Some(format!( + "{}
Deprecated", + name_str + ).into()); + } + structs.push(l); + } + clean::FunctionItem(..) => { + let mut l = Link::new(format!("fn.{name_str}"), name_str.to_string()); + if it.deprecation(cx.tcx()).is_some_and(|d| d.is_in_effect()) { + l.deprecated = true; + l.name_html = Some(format!( + "{} Deprecated", + name_str + ).into()); + } + functions.push(l); + } + clean::EnumItem(..) => { + let mut l = Link::new(format!("enum.{name_str}"), name_str.to_string()); + if it.deprecation(cx.tcx()).is_some_and(|d| d.is_in_effect()) { + l.deprecated = true; + l.name_html = Some(format!( + "{} Deprecated", + name_str + ).into()); + } + enums.push(l); + } + clean::TypeAliasItem(..) => { + let mut l = Link::new(format!("type.{name_str}"), name_str.to_string()); + if it.deprecation(cx.tcx()).is_some_and(|d| d.is_in_effect()) { + l.deprecated = true; + l.name_html = Some(format!( + "{} Deprecated", + name_str + ).into()); + } + type_aliases.push(l); + } + clean::ConstantItem(..) => { + let mut l = Link::new(format!("constant.{name_str}"), name_str.to_string()); + if it.deprecation(cx.tcx()).is_some_and(|d| d.is_in_effect()) { + l.deprecated = true; + l.name_html = Some(format!( + "{} Deprecated", + name_str + ).into()); + } + constants.push(l); + } + clean::ModuleItem(..) => { + let mut l = Link::new(format!("mod.{name_str}"), name_str.to_string()); + if it.deprecation(cx.tcx()).is_some_and(|d| d.is_in_effect()) { + l.deprecated = true; + l.name_html = Some(format!( + "{} Deprecated", + name_str + ).into()); + } + modules.push(l); + } + _ => {} + } + } + + // Sort lists + structs.sort(); + functions.sort(); + enums.sort(); + type_aliases.sort(); + constants.sort(); + modules.sort(); + + // Append blocks for each non-empty category with specific block classes + if !modules.is_empty() { + blocks.push(LinkBlock::new(Link::new("modules", "Modules"), "mod", modules)); + } + if !structs.is_empty() { + blocks.push(LinkBlock::new(Link::new("structs", "Structs"), "struct", structs)); + } + if !enums.is_empty() { + blocks.push(LinkBlock::new(Link::new("enums", "Enums"), "enum", enums)); + } + if !type_aliases.is_empty() { + blocks.push(LinkBlock::new(Link::new("types", "Type Aliases"), "type", type_aliases)); + } + if !constants.is_empty() { + blocks.push(LinkBlock::new(Link::new("constants", "Constants"), "constant", constants)); + } + if !functions.is_empty() { + blocks.push(LinkBlock::new(Link::new("functions", "Functions"), "fn", functions)); + } + + blocks } fn sidebar_foreign_type<'a>( @@ -768,10 +891,25 @@ fn get_methods<'a>( && item.is_method() && (!for_deref || super::should_render_item(item, deref_mut, tcx)) { - Some(Link::new( - get_next_url(used_links, format!("{typ}.{name}", typ = ItemType::Method)), - name.as_str(), - )) + { + let mut link = Link::new( + get_next_url(used_links, format!("{typ}.{name}", typ = ItemType::Method)), + name.as_str(), + ); + if item + .deprecation(tcx) + .is_some_and(|d| d.is_in_effect()) + { + // Mark as deprecated for template-based class insertion + link.deprecated = true; + // Also render the native deprecation tag in the link label + link.name_html = Some(format!( + "{} Deprecated", + name + ).into()); + } + Some(link) + } } else { None } @@ -782,6 +920,7 @@ fn get_methods<'a>( fn get_associated_constants<'a>( i: &'a clean::Impl, used_links: &mut FxHashSet, + tcx: TyCtxt<'_>, ) -> Vec> { i.items .iter() @@ -789,10 +928,25 @@ fn get_associated_constants<'a>( if let Some(ref name) = item.name && item.is_associated_const() { - Some(Link::new( - get_next_url(used_links, format!("{typ}.{name}", typ = ItemType::AssocConst)), - name.as_str(), - )) + { + let mut link = Link::new( + get_next_url(used_links, format!("{typ}.{name}", typ = ItemType::AssocConst)), + name.as_str(), + ); + if item + .deprecation(tcx) + .is_some_and(|d| d.is_in_effect()) + { + // Mark for template-based class insertion + link.deprecated = true; + // Also render the native deprecation tag in the link label + link.name_html = Some(format!( + "{} Deprecated", + name + ).into()); + } + Some(link) + } } else { None } @@ -803,6 +957,7 @@ fn get_associated_constants<'a>( fn get_associated_types<'a>( i: &'a clean::Impl, used_links: &mut FxHashSet, + tcx: TyCtxt<'_>, ) -> Vec> { i.items .iter() @@ -810,10 +965,21 @@ fn get_associated_types<'a>( if let Some(ref name) = item.name && item.is_associated_type() { - Some(Link::new( + let mut link = Link::new( get_next_url(used_links, format!("{typ}.{name}", typ = ItemType::AssocType)), name.as_str(), - )) + ); + if item + .deprecation(tcx) + .is_some_and(|d| d.is_in_effect()) + { + link.deprecated = true; + link.name_html = Some(format!( + "{} Deprecated", + name + ).into()); + } + Some(link) } else { None } diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index c684f6cf8fc3e..c668f061a526a 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -210,6 +210,12 @@ xmlns="http://www.w3.org/2000/svg" fill="black" height="18px">\ display: none; } +.hide-depr ul.block.struct li.depr-item { display: none; } +.hide-depr ul.block.fn li.depr-item { display: none; } +.hide-depr ul.block.enum li.depr-item { display: none; } +.hide-depr ul.block.type li.depr-item { display: none; } +.hide-depr ul.block.constant li.depr-item { display: none; } + body { /* Line spacing at least 1.5 per Web Content Accessibility Guidelines https://www.w3.org/WAI/WCAG21/Understanding/visual-presentation.html */ @@ -3078,22 +3084,6 @@ in src-script.js and main.js .item-table > dd { grid-column-start: 2; } - - /* Hide deprecated items in module summaries (dt/dd pairs) when setting is off */ - .hide-depr dt:has(.depr-item), - .hide-depr dt:has(.depr-item) + dd { - display: none; - } - - /* Hide deprecated items in the sidebar blocks */ - .hide-depr nav.sidebar li:has(.depr-item) { - display: none; - } - - /* Hide deprecated items in the all items page */ - .hide-depr ul.all-items li:has(.depr-item) { - display: none; - } } @media print { diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js index dff40485e9a90..7dc60a336b327 100644 --- a/src/librustdoc/html/static/js/main.js +++ b/src/librustdoc/html/static/js/main.js @@ -54,6 +54,339 @@ function showMain() { window.rootPath = getVar("root-path"); window.currentCrate = getVar("current-crate"); +// Tag deprecated entries in the current page and sidebar, and expose an updater +function rustdocTagDeprecated() { + // Mark any entry in the current page that contains the native deprecation tag + onEachLazy(document.querySelectorAll(".stab.deprecated"), el => { + let p = el.parentElement; + while (p && p !== document.body) { + if (p.tagName === "LI" || p.tagName === "TR" || p.tagName === "DD") { + addClass(p, "depr-item"); + break; + } + if (p.classList && + (p.classList.contains("item-row") || + p.classList.contains("module-item") || + p.classList.contains("item"))) { + addClass(p, "depr-item"); + break; + } + p = p.parentElement; + } + }); + + // Tag sidebar entries that link to deprecated items within this page + onEachLazy(document.querySelectorAll(".sidebar li a[href*='#']"), a => { + const href = a.getAttribute("href"); + if (!href) { + return; + } + const idx = href.indexOf("#"); + if (idx === -1) { + return; + } + const frag = href.slice(idx + 1); + + // Locate target element by id or name (anchors sometimes use name) + let target = document.getElementById(frag); + if (!target) { + target = document.querySelector(`[id="${frag}"], [name="${frag}"]`); + } + if (!target) { + return; + } + + // Search broadly around the target for a native deprecation tag + // - check the target subtree + // - walk up ancestors + // - check immediate siblings (common in summary/detail structures) + let found = false; + let scope = target; + + // 1) target subtree + if (scope.querySelector && scope.querySelector(".stab.deprecated")) { + found = true; + } + + // 2) ancestor walk (up to a reasonable depth) + for (let i = 0; !found && i < 8 && scope; i += 1) { + if (scope.classList && scope.classList.contains("stab") && + scope.classList.contains("deprecated")) { + found = true; + break; + } + if (scope.querySelector && scope.querySelector(".stab.deprecated")) { + found = true; + break; + } + scope = scope.parentElement; + } + + // 3) siblings near the anchor (covers dt/dd, li/ul, table row patterns) + if (!found) { + const parent = target.parentElement; + if (parent) { + const sibs = parent.children; + for (let i = 0; i < sibs.length; i += 1) { + const s = sibs[i]; + if (s === target) { + continue; + } + if (s.classList && s.classList.contains("stab") && + s.classList.contains("deprecated")) { + found = true; + break; + } + if (s.querySelector && s.querySelector(".stab.deprecated")) { + found = true; + break; + } + } + } + } + + if (!found) { + return; + } + + // Tag only the actual item entry in the sidebar (closest
  • that owns this link) + const li = a.closest("li"); + if (li && li.querySelector("a") === a) { + addClass(li, "depr-item"); + } + }); +} + +function rustdocApplyHideDeprecatedVisibility() { + const hide = document.documentElement.classList.contains("hide-depr"); + onEachLazy(document.querySelectorAll(".depr-item"), el => { + if (hide) { + addClass(el, "hidden"); + } else { + removeClass(el, "hidden"); + } + }); +} + +// Expose an updater so other code can re-run visibility application if needed. +window.rustdocUpdateDeprecatedVisibility = rustdocApplyHideDeprecatedVisibility; + +// Run once on load +rustdocTagDeprecated(); +rustdocApplyHideDeprecatedVisibility(); + +// Keep in sync with the setting toggle by watching class changes +new MutationObserver(mutations => { + for (const m of mutations) { + if (m.attributeName === "class") { + rustdocApplyHideDeprecatedVisibility(); + break; + } + } +}).observe(document.documentElement, { attributes: true, attributeFilter: ["class"] }); +window.rootPath = getVar("root-path"); +window.currentCrate = getVar("current-crate"); + +// Tag deprecated entries in the current page and sidebar, and expose an updater +function rustdocTagDeprecated() { + // Collect anchor fragments (id or name) for deprecated items by inspecting item headings + /** @type {Set} */ + const deprecatedFragments = new Set(); + + // Heuristic: item headings typically are anchors or have an id/name on the first child. + // We walk through elements that are potential anchors and look for a nearby .stab.deprecated. + onEachLazy(document.querySelectorAll("[id], [name]"), el => { + // Skip elements that are unlikely to be item anchors (like container sections without text) + const tag = el.tagName.toLowerCase(); + if (tag === "section" || tag === "div" || tag === "nav") { + return; + } + + // Determine fragment name + const frag = el.getAttribute("id") || el.getAttribute("name"); + if (!frag) { + return; + } + + // Search around this element to determine deprecation: + // 1) inside subtree, 2) up ancestors, 3) immediate siblings + let found = false; + + // 1) subtree + if (el.querySelector && el.querySelector(".stab.deprecated")) { + found = true; + } + + // 2) ancestors + let scope = el.parentElement; + for (let i = 0; !found && i < 8 && scope; i += 1) { + if (scope.classList && scope.classList.contains("stab") && + scope.classList.contains("deprecated")) { + found = true; + break; + } + if (scope.querySelector && scope.querySelector(".stab.deprecated")) { + found = true; + break; + } + scope = scope.parentElement; + } + + // 3) siblings + if (!found && el.parentElement) { + const sibs = el.parentElement.children; + for (let i = 0; i < sibs.length; i += 1) { + const s = sibs[i]; + if (s === el) { + continue; + } + if (s.classList && s.classList.contains("stab") && + s.classList.contains("deprecated")) { + found = true; + break; + } + if (s.querySelector && s.querySelector(".stab.deprecated")) { + found = true; + break; + } + } + } + + if (found) { + deprecatedFragments.add(frag); + } + }); + + // Also tag container elements in the main content that already show the native deprecation tag + onEachLazy(document.querySelectorAll(".stab.deprecated"), el => { + let p = el.parentElement; + while (p && p !== document.body) { + if (p.tagName === "LI" || p.tagName === "TR" || p.tagName === "DD") { + addClass(p, "depr-item"); + break; + } + if (p.classList && + (p.classList.contains("item-row") || + p.classList.contains("module-item") || + p.classList.contains("item"))) { + addClass(p, "depr-item"); + break; + } + p = p.parentElement; + } + }); + + // Tag only actual sidebar item entries (closest
  • owning the link) if they point to deprecated fragments + onEachLazy(document.querySelectorAll(".sidebar li a[href*='#']"), a => { + const href = a.getAttribute("href"); + if (!href) { + return; + } + const idx = href.indexOf("#"); + if (idx === -1) { + return; + } + const frag = href.slice(idx + 1); + + // If anchor matches a known deprecated fragment, mark its li + if (deprecatedFragments.has(frag)) { + const li = a.closest("li"); + if (li && li.querySelector("a") === a) { + addClass(li, "depr-item"); + } + return; + } + + // Fallback: resolve target by id or name and search locally for deprecation marker + let target = document.getElementById(frag); + if (!target) { + target = document.querySelector(`[id="${frag}"], [name="${frag}"]`); + } + if (!target) { + return; + } + + let found = false; + + // target subtree + if (target.querySelector && target.querySelector(".stab.deprecated")) { + found = true; + } + + // ancestor walk + let scope = target; + for (let i = 0; !found && i < 8 && scope; i += 1) { + if (scope.classList && scope.classList.contains("stab") && + scope.classList.contains("deprecated")) { + found = true; + break; + } + if (scope.querySelector && scope.querySelector(".stab.deprecated")) { + found = true; + break; + } + scope = scope.parentElement; + } + + // siblings near target + if (!found && target.parentElement) { + const sibs = target.parentElement.children; + for (let i = 0; i < sibs.length; i += 1) { + const s = sibs[i]; + if (s === target) { + continue; + } + if (s.classList && s.classList.contains("stab") && + s.classList.contains("deprecated")) { + found = true; + break; + } + if (s.querySelector && s.querySelector(".stab.deprecated")) { + found = true; + break; + } + } + } + + if (!found) { + return; + } + + const li = a.closest("li"); + if (li && li.querySelector("a") === a) { + addClass(li, "depr-item"); + } + }); +} + +function rustdocApplyHideDeprecatedVisibility() { + const hide = document.documentElement.classList.contains("hide-depr"); + onEachLazy(document.querySelectorAll(".depr-item"), el => { + if (hide) { + addClass(el, "hidden"); + } else { + removeClass(el, "hidden"); + } + }); +} + +// Expose an updater so other code can re-run visibility application if needed. +window.rustdocUpdateDeprecatedVisibility = rustdocApplyHideDeprecatedVisibility; + +// Run once on load +rustdocTagDeprecated(); +rustdocApplyHideDeprecatedVisibility(); + +// Keep in sync with the setting toggle by watching class changes +new MutationObserver(mutations => { + for (const m of mutations) { + if (m.attributeName === "class") { + rustdocApplyHideDeprecatedVisibility(); + break; + } + } +}).observe(document.documentElement, { attributes: true, attributeFilter: ["class"] }); + /** * Gets the human-readable string for the virtual-key code of the * given KeyboardEvent, ev. diff --git a/src/librustdoc/html/templates/sidebar.html b/src/librustdoc/html/templates/sidebar.html index 7f852b489fa24..d12299fd8f823 100644 --- a/src/librustdoc/html/templates/sidebar.html +++ b/src/librustdoc/html/templates/sidebar.html @@ -22,7 +22,7 @@

    {# #} {% if !block.links.is_empty() %}