diff options
| author | Matthias Krüger <matthias.krueger@famsik.de> | 2022-07-26 16:57:46 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-07-26 16:57:46 +0200 |
| commit | 811b4b890ab2b9577abdd22e3f7e9957696bfd9e (patch) | |
| tree | dc735d957fc4381d45161aac1515c8da2f03e150 | |
| parent | 2614e437f54ebf98b8336d35af0a5821990eeac9 (diff) | |
| parent | ed8c2c28f0f0072dbb0ceae36b278d681d997fad (diff) | |
| download | rust-811b4b890ab2b9577abdd22e3f7e9957696bfd9e.tar.gz rust-811b4b890ab2b9577abdd22e3f7e9957696bfd9e.zip | |
Rollup merge of #99235 - WaffleLapkin:rustdoc_implement_support_for_must_implement, r=GuillaumeGomez
rustdoc: Add support for `#[rustc_must_implement_one_of]`
This PR adds support for `#[rustc_must_implement_one_of]` attribute added in #92164. There is a desire to eventually use this attribute of `Read`, so making it show up in docs is a good thing.
I "stole" the styling from cfg notes, not sure what would be a proper styling. Currently it looks like this:

<details><summary>Code to reproduce</summary>
<p>
```rust
#![feature(rustc_attrs)]
#[rustc_must_implement_one_of(a, b)]
pub trait Trait {
fn req();
fn a(){ Self::b() }
fn b(){ Self::a() }
}
```
</p>
</details>
| -rw-r--r-- | src/librustdoc/clean/mod.rs | 1 | ||||
| -rw-r--r-- | src/librustdoc/html/render/print_item.rs | 21 | ||||
| -rw-r--r-- | src/librustdoc/html/static/css/themes/ayu.css | 4 | ||||
| -rw-r--r-- | src/librustdoc/html/static/css/themes/dark.css | 1 | ||||
| -rw-r--r-- | src/librustdoc/html/static/css/themes/light.css | 1 | ||||
| -rw-r--r-- | src/test/rustdoc/must_implement_one_of.rs | 10 |
6 files changed, 32 insertions, 6 deletions
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index c9ef4748a48..07237438a0d 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1993,6 +1993,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 81cc12c9d55..dcd2eaac7ea 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 = "<div class=\"item-table\">"; const ITEM_TABLE_CLOSE: &str = "</div>"; @@ -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", "<div class=\"methods\">", ); + + if let Some(list) = must_implement_one_of_functions.as_deref() { + write!( + w, + "<div class=\"stab must_implement\">At least one of the `{}` methods is required.</div>", + list.iter().join("`, `") + ); + } + for m in required_methods { trait_item(w, cx, m, it); } diff --git a/src/librustdoc/html/static/css/themes/ayu.css b/src/librustdoc/html/static/css/themes/ayu.css index 7ff8063904a..c42cac59bd6 100644 --- a/src/librustdoc/html/static/css/themes/ayu.css +++ b/src/librustdoc/html/static/css/themes/ayu.css @@ -205,11 +205,13 @@ details.rustdoc-toggle > summary::before { /* Created this empty rule to satisfy the theme checks. */ .stab.empty-impl {} +.stab.must_implement {} .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 8e753f57682..62d9eaa02e6 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 40d965c39c3..b751acff152 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; } 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 00000000000..1f1dd5d5796 --- /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 the `a`, `b` methods is required.$' +pub trait Trait { + fn a() {} + fn b() {} +} |
