diff --git a/src/doc/unstable-book/src/language-features/doc-spotlight.md b/src/doc/unstable-book/src/language-features/doc-spotlight.md new file mode 100644 index 0000000000000..8117755fef1c8 --- /dev/null +++ b/src/doc/unstable-book/src/language-features/doc-spotlight.md @@ -0,0 +1,30 @@ +# `doc_spotlight` + +The tracking issue for this feature is: [#45040] + +The `doc_spotlight` feature allows the use of the `spotlight` parameter to the `#[doc]` attribute, +to "spotlight" a specific trait on the return values of functions. Adding a `#[doc(spotlight)]` +attribute to a trait definition will make rustdoc print extra information for functions which return +a type that implements that trait. This attribute is applied to the `Iterator`, `io::Read`, and +`io::Write` traits in the standard library. + +You can do this on your own traits, like this: + +``` +#![feature(doc_spotlight)] + +#[doc(spotlight)] +pub trait MyTrait {} + +pub struct MyStruct; +impl MyTrait for MyStruct {} + +/// The docs for this function will have an extra line about `MyStruct` implementing `MyTrait`, +/// without having to write that yourself! +pub fn my_fn() -> MyStruct { MyStruct } +``` + +This feature was originally implemented in PR [#45039]. + +[#45040]: https://github.com/rust-lang/rust/issues/45040 +[#45039]: https://github.com/rust-lang/rust/pull/45039 diff --git a/src/libcore/iter/iterator.rs b/src/libcore/iter/iterator.rs index 40298389c1ac7..7f6d627536da3 100644 --- a/src/libcore/iter/iterator.rs +++ b/src/libcore/iter/iterator.rs @@ -30,6 +30,7 @@ fn _assert_is_object_safe(_: &Iterator) {} #[stable(feature = "rust1", since = "1.0.0")] #[rustc_on_unimplemented = "`{Self}` is not an iterator; maybe try calling \ `.iter()` or a similar method"] +#[doc(spotlight)] pub trait Iterator { /// The type of the elements being iterated over. #[stable(feature = "rust1", since = "1.0.0")] diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index 4a57417e86a1c..631b9f98589f6 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -107,6 +107,24 @@ #![feature(const_unsafe_cell_new)] #![feature(const_cell_new)] #![feature(const_nonzero_new)] +#![cfg_attr(not(stage0), feature(doc_spotlight))] + +#![cfg_attr(not(stage0), feature(const_min_value))] +#![cfg_attr(not(stage0), feature(const_max_value))] +#![cfg_attr(not(stage0), feature(const_atomic_bool_new))] +#![cfg_attr(not(stage0), feature(const_atomic_isize_new))] +#![cfg_attr(not(stage0), feature(const_atomic_usize_new))] +#![cfg_attr(not(stage0), feature(const_atomic_i8_new))] +#![cfg_attr(not(stage0), feature(const_atomic_u8_new))] +#![cfg_attr(not(stage0), feature(const_atomic_i16_new))] +#![cfg_attr(not(stage0), feature(const_atomic_u16_new))] +#![cfg_attr(not(stage0), feature(const_atomic_i32_new))] +#![cfg_attr(not(stage0), feature(const_atomic_u32_new))] +#![cfg_attr(not(stage0), feature(const_atomic_i64_new))] +#![cfg_attr(not(stage0), feature(const_atomic_u64_new))] +#![cfg_attr(not(stage0), feature(const_unsafe_cell_new))] +#![cfg_attr(not(stage0), feature(const_cell_new))] +#![cfg_attr(not(stage0), feature(const_nonzero_new))] #[prelude_import] #[allow(unused)] diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index 4c518167e088d..820c3e856dbb1 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -145,11 +145,13 @@ pub fn build_external_trait(cx: &DocContext, did: DefId) -> clean::Trait { let generics = (cx.tcx.generics_of(did), &predicates).clean(cx); let generics = filter_non_trait_generics(did, generics); let (generics, supertrait_bounds) = separate_supertrait_bounds(generics); + let is_spotlight = load_attrs(cx, did).has_doc_flag("spotlight"); clean::Trait { unsafety: cx.tcx.trait_def(did).unsafety, generics, items: trait_items, bounds: supertrait_bounds, + is_spotlight, } } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 1d107c169b046..69226239c96e8 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -151,7 +151,7 @@ impl<'a, 'tcx> Clean for visit_ast::RustdocVisitor<'a, 'tcx> { match module.inner { ModuleItem(ref module) => { for it in &module.items { - if it.is_extern_crate() && it.attrs.has_doc_masked() { + if it.is_extern_crate() && it.attrs.has_doc_flag("masked") { masked_crates.insert(it.def_id.krate); } } @@ -596,12 +596,12 @@ impl Attributes { None } - pub fn has_doc_masked(&self) -> bool { + pub fn has_doc_flag(&self, flag: &str) -> bool { for attr in &self.other_attrs { if !attr.check_name("doc") { continue; } if let Some(items) = attr.meta_item_list() { - if items.iter().filter_map(|i| i.meta_item()).any(|it| it.check_name("masked")) { + if items.iter().filter_map(|i| i.meta_item()).any(|it| it.check_name(flag)) { return true; } } @@ -1331,19 +1331,31 @@ impl Clean for hir::FunctionRetTy { } } +impl GetDefId for FunctionRetTy { + fn def_id(&self) -> Option { + match *self { + Return(ref ty) => ty.def_id(), + DefaultReturn => None, + } + } +} + #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] pub struct Trait { pub unsafety: hir::Unsafety, pub items: Vec, pub generics: Generics, pub bounds: Vec, + pub is_spotlight: bool, } impl Clean for doctree::Trait { fn clean(&self, cx: &DocContext) -> Item { + let attrs = self.attrs.clean(cx); + let is_spotlight = attrs.has_doc_flag("spotlight"); Item { name: Some(self.name.clean(cx)), - attrs: self.attrs.clean(cx), + attrs: attrs, source: self.whence.clean(cx), def_id: cx.tcx.hir.local_def_id(self.id), visibility: self.vis.clean(cx), @@ -1354,6 +1366,7 @@ impl Clean for doctree::Trait { items: self.items.clean(cx), generics: self.generics.clean(cx), bounds: self.bounds.clean(cx), + is_spotlight: is_spotlight, }), } } diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index e79a63fb8d86f..8370f80582861 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -2268,7 +2268,7 @@ fn item_function(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item, AbiSpace(f.abi), it.name.as_ref().unwrap(), f.generics).len(); - write!(w, "
")?;
+    write!(w, "{}
", render_spotlight_traits(it)?)?;
     render_attributes(w, it)?;
     write!(w, "{vis}{constness}{unsafety}{abi}fn \
                {name}{generics}{decl}{where_clause}
", @@ -2402,8 +2402,9 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item, let item_type = m.type_(); let id = derive_id(format!("{}.{}", item_type, name)); let ns_id = derive_id(format!("{}.{}", name, item_type.name_space())); - write!(w, "

\ + write!(w, "{extra}

\