From 3da2553f2f0a9691b8577bfb79a74a655beac6f2 Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Thu, 14 Jul 2022 14:51:38 +0400 Subject: [PATCH 1/6] Add support for `#[rustc_must_implement_one_of]` to rustdoc --- src/librustdoc/clean/mod.rs | 1 + src/librustdoc/html/render/print_item.rs | 21 ++++++++++++++----- src/librustdoc/html/static/css/rustdoc.css | 2 +- src/librustdoc/html/static/css/themes/ayu.css | 3 ++- .../html/static/css/themes/dark.css | 1 + .../html/static/css/themes/light.css | 1 + 6 files changed, 22 insertions(+), 7 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 6160783f652f1..2c63f381851f4 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1991,6 +1991,7 @@ fn clean_maybe_renamed_item<'tcx>( ItemKind::Trait(_, _, generics, bounds, item_ids) => { let items = item_ids.iter().map(|ti| cx.tcx.hir().trait_item(ti.id).clean(cx)).collect(); + TraitItem(Trait { def_id, items, diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index 81cc12c9d5596..82b06ae02bdca 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -1,9 +1,5 @@ use clean::AttributesExt; -use std::cmp::Ordering; -use std::fmt; -use std::rc::Rc; - use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_hir as hir; use rustc_hir::def::CtorKind; @@ -15,6 +11,9 @@ use rustc_middle::ty::{Adt, TyCtxt}; use rustc_span::hygiene::MacroKind; use rustc_span::symbol::{kw, sym, Symbol}; use rustc_target::abi::{Layout, Primitive, TagEncoding, Variants}; +use std::cmp::Ordering; +use std::fmt; +use std::rc::Rc; use super::{ collect_paths_for_type, document, ensure_trailing_slash, item_ty_to_section, @@ -37,6 +36,7 @@ use crate::html::markdown::{HeadingOffset, MarkdownSummaryLine}; use crate::html::url_parts_builder::UrlPartsBuilder; use askama::Template; +use itertools::Itertools; const ITEM_TABLE_OPEN: &str = "
"; const ITEM_TABLE_CLOSE: &str = "
"; @@ -539,6 +539,8 @@ fn item_trait(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean: let count_types = required_types.len() + provided_types.len(); let count_consts = required_consts.len() + provided_consts.len(); let count_methods = required_methods.len() + provided_methods.len(); + let must_implement_one_of_functions = + cx.tcx().trait_def(t.def_id).must_implement_one_of.clone(); // Output the trait definition wrap_into_docblock(w, |w| { @@ -784,13 +786,22 @@ fn item_trait(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean: } // Output the documentation for each function individually - if !required_methods.is_empty() { + if !required_methods.is_empty() || must_implement_one_of_functions.is_some() { write_small_section_header( w, "required-methods", "Required Methods", "
", ); + + if let Some(list) = must_implement_one_of_functions.as_deref() { + write!( + w, + "
At least one of {} methods is required.
", + list.iter().join(", ") + ); + } + for m in required_methods { trait_item(w, cx, m, it); } diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index 70b7a47bcd58b..0329c7c4b7480 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -1110,7 +1110,7 @@ table, padding: 0 20px 20px 17px; } -.item-info .stab { +.item-info,.methods .stab { display: inline-block; } .stab { diff --git a/src/librustdoc/html/static/css/themes/ayu.css b/src/librustdoc/html/static/css/themes/ayu.css index 7ff8063904ace..11e68a155f8bd 100644 --- a/src/librustdoc/html/static/css/themes/ayu.css +++ b/src/librustdoc/html/static/css/themes/ayu.css @@ -209,7 +209,8 @@ details.rustdoc-toggle > summary::before { .stab.unstable, .stab.deprecated, .stab.portability, -.stab.empty-impl { +.stab.empty-impl, +.stab.must_implement { color: #c5c5c5; background: #314559 !important; border-style: none !important; diff --git a/src/librustdoc/html/static/css/themes/dark.css b/src/librustdoc/html/static/css/themes/dark.css index 8e753f5768206..62d9eaa02e6a7 100644 --- a/src/librustdoc/html/static/css/themes/dark.css +++ b/src/librustdoc/html/static/css/themes/dark.css @@ -180,6 +180,7 @@ details.rustdoc-toggle > summary::before { .stab.empty-impl { background: #FFF5D6; border-color: #FFC600; color: #2f2f2f; } .stab.unstable { background: #FFF5D6; border-color: #FFC600; color: #2f2f2f; } .stab.deprecated { background: #ffc4c4; border-color: #db7b7b; color: #2f2f2f; } +.stab.must_implement { background: #F3DFFF; border-color: #b07bdb; color: #2f2f2f; } .stab.portability { background: #F3DFFF; border-color: #b07bdb; color: #2f2f2f; } .stab.portability > code { background: none; } diff --git a/src/librustdoc/html/static/css/themes/light.css b/src/librustdoc/html/static/css/themes/light.css index 40d965c39c390..b751acff152cb 100644 --- a/src/librustdoc/html/static/css/themes/light.css +++ b/src/librustdoc/html/static/css/themes/light.css @@ -163,6 +163,7 @@ details.rustdoc-toggle > summary::before { .stab.empty-impl { background: #FFF5D6; border-color: #FFC600; } .stab.unstable { background: #FFF5D6; border-color: #FFC600; } .stab.deprecated { background: #ffc4c4; border-color: #db7b7b; } +.stab.must_implement { background: #F3DFFF; border-color: #b07bdb; } .stab.portability { background: #F3DFFF; border-color: #b07bdb; } .stab.portability > code { background: none; } From 9b9693c11b808447d683c458315d53e20105b445 Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Sun, 17 Jul 2022 20:51:39 +0400 Subject: [PATCH 2/6] Add rustdoc test for `#[rustc_must_implement_one_of]` --- src/test/rustdoc/must_implement_one_of.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 src/test/rustdoc/must_implement_one_of.rs diff --git a/src/test/rustdoc/must_implement_one_of.rs b/src/test/rustdoc/must_implement_one_of.rs new file mode 100644 index 0000000000000..9a89a5815b461 --- /dev/null +++ b/src/test/rustdoc/must_implement_one_of.rs @@ -0,0 +1,10 @@ +#![crate_name = "c"] +#![feature(rustc_attrs)] + +#[rustc_must_implement_one_of(a, b)] +// @matches c/trait.Trait.html '//*[@class="stab must_implement"]' \ +// 'At least one of a, b methods is required.$' +pub trait Trait { + fn a() {} + fn b() {} +} From d566334a940df8ca66d778c5aa8bebaad9b32d81 Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Tue, 19 Jul 2022 20:28:53 +0400 Subject: [PATCH 3/6] add backticks --- src/librustdoc/html/render/print_item.rs | 4 ++-- src/test/rustdoc/must_implement_one_of.rs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index 82b06ae02bdca..c12b3ca6c600f 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -797,8 +797,8 @@ fn item_trait(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean: if let Some(list) = must_implement_one_of_functions.as_deref() { write!( w, - "
At least one of {} methods is required.
", - list.iter().join(", ") + "
At least one of `{}` methods is required.
", + list.iter().join("`, `") ); } diff --git a/src/test/rustdoc/must_implement_one_of.rs b/src/test/rustdoc/must_implement_one_of.rs index 9a89a5815b461..112c8b25e7e50 100644 --- a/src/test/rustdoc/must_implement_one_of.rs +++ b/src/test/rustdoc/must_implement_one_of.rs @@ -3,7 +3,7 @@ #[rustc_must_implement_one_of(a, b)] // @matches c/trait.Trait.html '//*[@class="stab must_implement"]' \ -// 'At least one of a, b methods is required.$' +// 'At least one of `a`, `b` methods is required.$' pub trait Trait { fn a() {} fn b() {} From 7f1af4219082b2a17f7bd647b7f19487d9cc9f2d Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Sun, 24 Jul 2022 16:48:35 +0400 Subject: [PATCH 4/6] Satisfy theme check --- src/librustdoc/html/static/css/themes/ayu.css | 1 + 1 file changed, 1 insertion(+) diff --git a/src/librustdoc/html/static/css/themes/ayu.css b/src/librustdoc/html/static/css/themes/ayu.css index 11e68a155f8bd..c42cac59bd6fa 100644 --- a/src/librustdoc/html/static/css/themes/ayu.css +++ b/src/librustdoc/html/static/css/themes/ayu.css @@ -205,6 +205,7 @@ details.rustdoc-toggle > summary::before { /* Created this empty rule to satisfy the theme checks. */ .stab.empty-impl {} +.stab.must_implement {} .stab.unstable, .stab.deprecated, From 1c4c39885b95e61256599c423114758f29cf3c32 Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Mon, 25 Jul 2022 01:41:25 +0400 Subject: [PATCH 5/6] fix rustdoc-gui tests --- src/librustdoc/html/static/css/rustdoc.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index 0329c7c4b7480..70b7a47bcd58b 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -1110,7 +1110,7 @@ table, padding: 0 20px 20px 17px; } -.item-info,.methods .stab { +.item-info .stab { display: inline-block; } .stab { From ed8c2c28f0f0072dbb0ceae36b278d681d997fad Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Mon, 25 Jul 2022 21:12:56 +0400 Subject: [PATCH 6/6] apply review suggestions --- src/librustdoc/html/render/print_item.rs | 2 +- src/test/rustdoc/must_implement_one_of.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index c12b3ca6c600f..dcd2eaac7ea60 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -797,7 +797,7 @@ fn item_trait(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean: if let Some(list) = must_implement_one_of_functions.as_deref() { write!( w, - "
At least one of `{}` methods is required.
", + "
At least one of the `{}` methods is required.
", list.iter().join("`, `") ); } diff --git a/src/test/rustdoc/must_implement_one_of.rs b/src/test/rustdoc/must_implement_one_of.rs index 112c8b25e7e50..1f1dd5d5796ee 100644 --- a/src/test/rustdoc/must_implement_one_of.rs +++ b/src/test/rustdoc/must_implement_one_of.rs @@ -3,7 +3,7 @@ #[rustc_must_implement_one_of(a, b)] // @matches c/trait.Trait.html '//*[@class="stab must_implement"]' \ -// 'At least one of `a`, `b` methods is required.$' +// 'At least one of the `a`, `b` methods is required.$' pub trait Trait { fn a() {} fn b() {}