Rollup merge of #74370 - Manishearth:re-spotlight, r=GuillaumeGomez
Reintroduce spotlight / "important traits" feature (Reopened version of https://github.com/rust-lang/rust/pull/74111 because Github is broken, see discussion there) Fixes https://github.com/rust-lang/rust/issues/73785 This PR reintroduces the "spotlight" ("important traits") feature. A couple changes have been made: As there were concerns about its visibility, it has been moved to be next to the return type, as opposed to being on the side. It also no longer produces a modal, it shows the traits on hover, and it can be clicked on to pin the hover bubble. ![image](https://user-images.githubusercontent.com/1617736/86674555-a82d2600-bfad-11ea-9a4a-a1a9ffd66ae5.png) ![image](https://user-images.githubusercontent.com/1617736/86674533-a1061800-bfad-11ea-9e8a-c62ad86ed0d7.png) It also works fine on mobile: ![image](https://user-images.githubusercontent.com/1617736/86674638-bda25000-bfad-11ea-8d8d-1798b608923e.png)
This commit is contained in:
commit
fc098170ce
@ -150,6 +150,27 @@ Book][unstable-doc-cfg] and [its tracking issue][issue-doc-cfg].
|
||||
[unstable-doc-cfg]: ../unstable-book/language-features/doc-cfg.html
|
||||
[issue-doc-cfg]: https://github.com/rust-lang/rust/issues/43781
|
||||
|
||||
### Adding your trait to the "Important Traits" dialog
|
||||
|
||||
Rustdoc keeps a list of a few traits that are believed to be "fundamental" to a given type when
|
||||
implemented on it. These traits are intended to be the primary interface for their types, and are
|
||||
often the only thing available to be documented on their types. For this reason, Rustdoc will track
|
||||
when a given type implements one of these traits and call special attention to it when a function
|
||||
returns one of these types. This is the "Important Traits" dialog, visible as a circle-i button next
|
||||
to the function, which, when clicked, shows the dialog.
|
||||
|
||||
In the standard library, the traits that qualify for inclusion are `Iterator`, `io::Read`, and
|
||||
`io::Write`. However, rather than being implemented as a hard-coded list, these traits have a
|
||||
special marker attribute on them: `#[doc(spotlight)]`. This means that you could apply this
|
||||
attribute to your own trait to include it in the "Important Traits" dialog in documentation.
|
||||
|
||||
The `#[doc(spotlight)]` attribute currently requires the `#![feature(doc_spotlight)]` feature gate.
|
||||
For more information, see [its chapter in the Unstable Book][unstable-spotlight] and [its tracking
|
||||
issue][issue-spotlight].
|
||||
|
||||
[unstable-spotlight]: ../unstable-book/language-features/doc-spotlight.html
|
||||
[issue-spotlight]: https://github.com/rust-lang/rust/issues/45040
|
||||
|
||||
### Exclude certain dependencies from documentation
|
||||
|
||||
The standard library uses several dependencies which, in turn, use several types and traits from the
|
||||
|
30
src/doc/unstable-book/src/language-features/doc-spotlight.md
Normal file
30
src/doc/unstable-book/src/language-features/doc-spotlight.md
Normal file
@ -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
|
@ -24,6 +24,7 @@ use crate::task::{Context, Poll};
|
||||
/// `.await` the value.
|
||||
///
|
||||
/// [`Waker`]: ../task/struct.Waker.html
|
||||
#[doc(spotlight)]
|
||||
#[must_use = "futures do nothing unless you `.await` or poll them"]
|
||||
#[stable(feature = "futures_api", since = "1.36.0")]
|
||||
#[lang = "future_trait"]
|
||||
|
@ -92,6 +92,7 @@ fn _assert_is_object_safe(_: &dyn Iterator<Item = ()>) {}
|
||||
label = "`{Self}` is not an iterator",
|
||||
message = "`{Self}` is not an iterator"
|
||||
)]
|
||||
#[doc(spotlight)]
|
||||
#[must_use = "iterators are lazy and do nothing unless consumed"]
|
||||
pub trait Iterator {
|
||||
/// The type of the elements being iterated over.
|
||||
|
@ -96,6 +96,7 @@
|
||||
#![feature(custom_inner_attributes)]
|
||||
#![feature(decl_macro)]
|
||||
#![feature(doc_cfg)]
|
||||
#![cfg_attr(not(bootstrap), feature(doc_spotlight))]
|
||||
#![feature(duration_consts_2)]
|
||||
#![feature(extern_types)]
|
||||
#![feature(fundamental)]
|
||||
|
@ -253,6 +253,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
|
||||
include => external_doc
|
||||
cfg => doc_cfg
|
||||
masked => doc_masked
|
||||
spotlight => doc_spotlight
|
||||
alias => doc_alias
|
||||
keyword => doc_keyword
|
||||
);
|
||||
|
@ -368,6 +368,9 @@ declare_features! (
|
||||
/// Allows `#[doc(masked)]`.
|
||||
(active, doc_masked, "1.21.0", Some(44027), None),
|
||||
|
||||
/// Allows `#[doc(spotlight)]`.
|
||||
(active, doc_spotlight, "1.22.0", Some(45040), None),
|
||||
|
||||
/// Allows `#[doc(include = "some-file")]`.
|
||||
(active, external_doc, "1.22.0", Some(44732), None),
|
||||
|
||||
|
@ -400,6 +400,7 @@ symbols! {
|
||||
doc_cfg,
|
||||
doc_keyword,
|
||||
doc_masked,
|
||||
doc_spotlight,
|
||||
doctest,
|
||||
document_private_items,
|
||||
dotdot_in_tuple_patterns,
|
||||
@ -968,6 +969,7 @@ symbols! {
|
||||
soft,
|
||||
specialization,
|
||||
speed,
|
||||
spotlight,
|
||||
sqrtf32,
|
||||
sqrtf64,
|
||||
sse4a_target_feature,
|
||||
|
@ -12,7 +12,7 @@ use rustc_metadata::creader::LoadedMacro;
|
||||
use rustc_middle::ty;
|
||||
use rustc_mir::const_eval::is_min_const_fn;
|
||||
use rustc_span::hygiene::MacroKind;
|
||||
use rustc_span::symbol::Symbol;
|
||||
use rustc_span::symbol::{sym, Symbol};
|
||||
use rustc_span::Span;
|
||||
|
||||
use crate::clean::{self, GetDefId, ToSource, TypeKind};
|
||||
@ -194,6 +194,7 @@ 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).clean(cx).has_doc_flag(sym::spotlight);
|
||||
let is_auto = cx.tcx.trait_is_auto(did);
|
||||
clean::Trait {
|
||||
auto: auto_trait,
|
||||
@ -201,6 +202,7 @@ pub fn build_external_trait(cx: &DocContext<'_>, did: DefId) -> clean::Trait {
|
||||
generics,
|
||||
items: trait_items,
|
||||
bounds: supertrait_bounds,
|
||||
is_spotlight,
|
||||
is_auto,
|
||||
}
|
||||
}
|
||||
|
@ -1007,6 +1007,7 @@ impl Clean<FnRetTy> for hir::FnRetTy<'_> {
|
||||
impl Clean<Item> for doctree::Trait<'_> {
|
||||
fn clean(&self, cx: &DocContext<'_>) -> Item {
|
||||
let attrs = self.attrs.clean(cx);
|
||||
let is_spotlight = attrs.has_doc_flag(sym::spotlight);
|
||||
Item {
|
||||
name: Some(self.name.clean(cx)),
|
||||
attrs,
|
||||
@ -1021,6 +1022,7 @@ impl Clean<Item> for doctree::Trait<'_> {
|
||||
items: self.items.iter().map(|ti| ti.clean(cx)).collect(),
|
||||
generics: self.generics.clean(cx),
|
||||
bounds: self.bounds.clean(cx),
|
||||
is_spotlight,
|
||||
is_auto: self.is_auto.clean(cx),
|
||||
}),
|
||||
}
|
||||
|
@ -967,6 +967,7 @@ pub struct Trait {
|
||||
pub items: Vec<Item>,
|
||||
pub generics: Generics,
|
||||
pub bounds: Vec<GenericBound>,
|
||||
pub is_spotlight: bool,
|
||||
pub is_auto: bool,
|
||||
}
|
||||
|
||||
|
@ -63,10 +63,22 @@ impl Buffer {
|
||||
Buffer { for_html: false, buffer: String::new() }
|
||||
}
|
||||
|
||||
crate fn is_empty(&self) -> bool {
|
||||
self.buffer.is_empty()
|
||||
}
|
||||
|
||||
crate fn into_inner(self) -> String {
|
||||
self.buffer
|
||||
}
|
||||
|
||||
crate fn insert_str(&mut self, idx: usize, s: &str) {
|
||||
self.buffer.insert_str(idx, s);
|
||||
}
|
||||
|
||||
crate fn push_str(&mut self, s: &str) {
|
||||
self.buffer.push_str(s);
|
||||
}
|
||||
|
||||
// Intended for consumption by write! and writeln! (std::fmt) but without
|
||||
// the fmt::Result return type imposed by fmt::Write (and avoiding the trait
|
||||
// import).
|
||||
|
@ -2415,7 +2415,7 @@ fn item_function(w: &mut Buffer, cx: &Context, it: &clean::Item, f: &clean::Func
|
||||
write!(
|
||||
w,
|
||||
"{vis}{constness}{asyncness}{unsafety}{abi}fn \
|
||||
{name}{generics}{decl}{where_clause}</pre>",
|
||||
{name}{generics}{decl}{spotlight}{where_clause}</pre>",
|
||||
vis = it.visibility.print_with_space(),
|
||||
constness = f.header.constness.print_with_space(),
|
||||
asyncness = f.header.asyncness.print_with_space(),
|
||||
@ -2425,7 +2425,8 @@ fn item_function(w: &mut Buffer, cx: &Context, it: &clean::Item, f: &clean::Func
|
||||
generics = f.generics.print(),
|
||||
where_clause = WhereClause { gens: &f.generics, indent: 0, end_newline: true },
|
||||
decl = Function { decl: &f.decl, header_len, indent: 0, asyncness: f.header.asyncness }
|
||||
.print()
|
||||
.print(),
|
||||
spotlight = spotlight_decl(&f.decl),
|
||||
);
|
||||
document(w, cx, it)
|
||||
}
|
||||
@ -2612,7 +2613,7 @@ fn item_trait(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::Trait)
|
||||
let name = m.name.as_ref().unwrap();
|
||||
let item_type = m.type_();
|
||||
let id = cx.derive_id(format!("{}.{}", item_type, name));
|
||||
write!(w, "<h3 id='{id}' class='method'><code>", id = id);
|
||||
write!(w, "<h3 id='{id}' class='method'><code>", id = id,);
|
||||
render_assoc_item(w, m, AssocItemLink::Anchor(Some(&id)), ItemType::Impl);
|
||||
write!(w, "</code>");
|
||||
render_stability_since(w, m, t);
|
||||
@ -2926,7 +2927,7 @@ fn render_assoc_item(
|
||||
write!(
|
||||
w,
|
||||
"{}{}{}{}{}{}{}fn <a href='{href}' class='fnname'>{name}</a>\
|
||||
{generics}{decl}{where_clause}",
|
||||
{generics}{decl}{spotlight}{where_clause}",
|
||||
if parent == ItemType::Trait { " " } else { "" },
|
||||
meth.visibility.print_with_space(),
|
||||
header.constness.print_with_space(),
|
||||
@ -2938,6 +2939,7 @@ fn render_assoc_item(
|
||||
name = name,
|
||||
generics = g.print(),
|
||||
decl = Function { decl: d, header_len, indent, asyncness: header.asyncness }.print(),
|
||||
spotlight = spotlight_decl(&d),
|
||||
where_clause = WhereClause { gens: g, indent, end_newline }
|
||||
)
|
||||
}
|
||||
@ -3559,6 +3561,62 @@ fn should_render_item(item: &clean::Item, deref_mut_: bool) -> bool {
|
||||
}
|
||||
}
|
||||
|
||||
fn spotlight_decl(decl: &clean::FnDecl) -> String {
|
||||
let mut out = Buffer::html();
|
||||
let mut trait_ = String::new();
|
||||
|
||||
if let Some(did) = decl.output.def_id() {
|
||||
let c = cache();
|
||||
if let Some(impls) = c.impls.get(&did) {
|
||||
for i in impls {
|
||||
let impl_ = i.inner_impl();
|
||||
if impl_.trait_.def_id().map_or(false, |d| c.traits[&d].is_spotlight) {
|
||||
if out.is_empty() {
|
||||
out.push_str(&format!(
|
||||
"<h3 class=\"important\">Important traits for {}</h3>\
|
||||
<code class=\"content\">",
|
||||
impl_.for_.print()
|
||||
));
|
||||
trait_.push_str(&impl_.for_.print().to_string());
|
||||
}
|
||||
|
||||
//use the "where" class here to make it small
|
||||
out.push_str(&format!(
|
||||
"<span class=\"where fmt-newline\">{}</span>",
|
||||
impl_.print()
|
||||
));
|
||||
let t_did = impl_.trait_.def_id().unwrap();
|
||||
for it in &impl_.items {
|
||||
if let clean::TypedefItem(ref tydef, _) = it.inner {
|
||||
out.push_str("<span class=\"where fmt-newline\"> ");
|
||||
assoc_type(
|
||||
&mut out,
|
||||
it,
|
||||
&[],
|
||||
Some(&tydef.type_),
|
||||
AssocItemLink::GotoSource(t_did, &FxHashSet::default()),
|
||||
"",
|
||||
);
|
||||
out.push_str(";</span>");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !out.is_empty() {
|
||||
out.insert_str(
|
||||
0,
|
||||
"<span class=\"important-traits\"><span class=\"important-traits-tooltip\">ⓘ<div class='important-traits-tooltiptext'><span class=\"docblock\">"
|
||||
|
||||
);
|
||||
out.push_str("</code></span></div></span></span>");
|
||||
}
|
||||
|
||||
out.into_inner()
|
||||
}
|
||||
|
||||
fn render_impl(
|
||||
w: &mut Buffer,
|
||||
cx: &Context,
|
||||
@ -3670,7 +3728,8 @@ fn render_impl(
|
||||
// Only render when the method is not static or we allow static methods
|
||||
if render_method_item {
|
||||
let id = cx.derive_id(format!("{}.{}", item_type, name));
|
||||
write!(w, "<h4 id='{}' class=\"{}{}\"><code>", id, item_type, extra_class);
|
||||
write!(w, "<h4 id='{}' class=\"{}{}\">", id, item_type, extra_class);
|
||||
write!(w, "<code>");
|
||||
render_assoc_item(w, item, link.anchor(&id), ItemType::Impl);
|
||||
write!(w, "</code>");
|
||||
render_stability_since_raw(w, item.stable_since(), outer_version);
|
||||
|
@ -2636,6 +2636,13 @@ function defocusSearchBar() {
|
||||
});
|
||||
}());
|
||||
|
||||
onEachLazy(document.getElementsByClassName("important-traits"), function(e) {
|
||||
e.onclick = function() {
|
||||
this.getElementsByClassName('important-traits-tooltiptext')[0]
|
||||
.classList.toggle("force-tooltip");
|
||||
};
|
||||
});
|
||||
|
||||
// In the search display, allows to switch between tabs.
|
||||
function printTab(nb) {
|
||||
if (nb === 0 || nb === 1 || nb === 2) {
|
||||
|
@ -146,9 +146,12 @@ code, pre, a.test-arrow {
|
||||
border-radius: 3px;
|
||||
padding: 0 0.1em;
|
||||
}
|
||||
.docblock pre code, .docblock-short pre code {
|
||||
.docblock pre code, .docblock-short pre code, .docblock code.spotlight {
|
||||
padding: 0;
|
||||
}
|
||||
.docblock code.spotlight :last-child {
|
||||
padding-bottom: 0.6em;
|
||||
}
|
||||
pre {
|
||||
padding: 14px;
|
||||
}
|
||||
@ -523,7 +526,7 @@ h4 > code, h3 > code, .invisible > code {
|
||||
font-size: 0.8em;
|
||||
}
|
||||
|
||||
.content .methods > div {
|
||||
.content .methods > div:not(.important-traits) {
|
||||
margin-left: 40px;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
@ -1079,10 +1082,6 @@ h3 > .collapse-toggle, h4 > .collapse-toggle {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.tooltip:hover .tooltiptext {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.tooltip .tooltiptext::after {
|
||||
content: " ";
|
||||
position: absolute;
|
||||
@ -1098,13 +1097,52 @@ h3 > .collapse-toggle, h4 > .collapse-toggle {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.tooltip .tooltiptext {
|
||||
.important-traits-tooltip {
|
||||
display: inline-block;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.important-traits:hover .important-traits-tooltiptext,
|
||||
.important-traits .important-traits-tooltiptext.force-tooltip {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.important-traits .important-traits-tooltiptext {
|
||||
display: none;
|
||||
padding: 5px 3px 3px 3px;
|
||||
border-radius: 6px;
|
||||
margin-left: 5px;
|
||||
z-index: 10;
|
||||
font-size: 16px;
|
||||
cursor: default;
|
||||
position: absolute;
|
||||
border: 1px solid;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.important-traits-tooltip::after {
|
||||
/* The margin on the tooltip does not capture hover events,
|
||||
this extends the area of hover enough so that mouse hover is not
|
||||
lost when moving the mouse to the tooltip */
|
||||
content: "\00a0\00a0\00a0";
|
||||
}
|
||||
|
||||
.important-traits .important, .important-traits .docblock {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.important-traits .docblock code.content{
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
/* Example code has the "Run" button that
|
||||
needs to be positioned relative to the pre */
|
||||
pre.rust.rust-example-rendered {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
pre.rust {
|
||||
position: relative;
|
||||
tab-size: 4;
|
||||
-moz-tab-size: 4;
|
||||
}
|
||||
@ -1144,6 +1182,18 @@ pre.rust {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.important-traits {
|
||||
cursor: pointer;
|
||||
z-index: 2;
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
h4 > .important-traits {
|
||||
position: absolute;
|
||||
left: -44px;
|
||||
top: 2px;
|
||||
}
|
||||
|
||||
#all-types {
|
||||
text-align: center;
|
||||
border: 1px solid;
|
||||
@ -1370,6 +1420,12 @@ pre.rust {
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
h4 > .important-traits {
|
||||
position: absolute;
|
||||
left: -22px;
|
||||
top: 24px;
|
||||
}
|
||||
|
||||
#titles > div > div.count {
|
||||
float: left;
|
||||
width: 100%;
|
||||
|
@ -394,6 +394,11 @@ pre.ignore:hover, .information:hover + pre.ignore {
|
||||
border-color: transparent #314559 transparent transparent;
|
||||
}
|
||||
|
||||
.important-traits-tooltiptext {
|
||||
background-color: #314559;
|
||||
border-color: #5c6773;
|
||||
}
|
||||
|
||||
#titles > div.selected {
|
||||
background-color: #141920 !important;
|
||||
border-bottom: 1px solid #ffb44c !important;
|
||||
|
@ -337,6 +337,11 @@ pre.ignore:hover, .information:hover + pre.ignore {
|
||||
border-color: transparent black transparent transparent;
|
||||
}
|
||||
|
||||
.important-traits-tooltiptext {
|
||||
background-color: #111;
|
||||
border-color: #777;
|
||||
}
|
||||
|
||||
#titles > div:not(.selected) {
|
||||
background-color: #252525;
|
||||
border-top-color: #252525;
|
||||
|
@ -331,6 +331,11 @@ pre.ignore:hover, .information:hover + pre.ignore {
|
||||
border-color: transparent black transparent transparent;
|
||||
}
|
||||
|
||||
.important-traits-tooltiptext {
|
||||
background-color: #eee;
|
||||
border-color: #999;
|
||||
}
|
||||
|
||||
#titles > div:not(.selected) {
|
||||
background-color: #e6e6e6;
|
||||
border-top-color: #e6e6e6;
|
||||
|
@ -499,6 +499,7 @@ where
|
||||
/// [`&str`]: ../../std/primitive.str.html
|
||||
/// [slice]: ../../std/primitive.slice.html
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[doc(spotlight)]
|
||||
pub trait Read {
|
||||
/// Pull some bytes from this source into the specified buffer, returning
|
||||
/// how many bytes were read.
|
||||
@ -1261,6 +1262,7 @@ impl Initializer {
|
||||
///
|
||||
/// [`write_all`]: #method.write_all
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[doc(spotlight)]
|
||||
pub trait Write {
|
||||
/// Write a buffer into this writer, returning how many bytes were written.
|
||||
///
|
||||
|
@ -261,6 +261,7 @@
|
||||
#![feature(doc_cfg)]
|
||||
#![feature(doc_keyword)]
|
||||
#![feature(doc_masked)]
|
||||
#![cfg_attr(not(bootstrap), feature(doc_spotlight))]
|
||||
#![feature(dropck_eyepatch)]
|
||||
#![feature(duration_constants)]
|
||||
#![feature(exact_size_is_empty)]
|
||||
|
36
src/test/rustdoc/doc-spotlight.rs
Normal file
36
src/test/rustdoc/doc-spotlight.rs
Normal file
@ -0,0 +1,36 @@
|
||||
#![feature(doc_spotlight)]
|
||||
|
||||
pub struct Wrapper<T> {
|
||||
inner: T,
|
||||
}
|
||||
|
||||
impl<T: SomeTrait> SomeTrait for Wrapper<T> {}
|
||||
|
||||
#[doc(spotlight)]
|
||||
pub trait SomeTrait {
|
||||
// @has doc_spotlight/trait.SomeTrait.html
|
||||
// @has - '//code[@class="content"]' 'impl<T: SomeTrait> SomeTrait for Wrapper<T>'
|
||||
fn wrap_me(self) -> Wrapper<Self> where Self: Sized {
|
||||
Wrapper {
|
||||
inner: self,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct SomeStruct;
|
||||
impl SomeTrait for SomeStruct {}
|
||||
|
||||
impl SomeStruct {
|
||||
// @has doc_spotlight/struct.SomeStruct.html
|
||||
// @has - '//code[@class="content"]' 'impl SomeTrait for SomeStruct'
|
||||
// @has - '//code[@class="content"]' 'impl<T: SomeTrait> SomeTrait for Wrapper<T>'
|
||||
pub fn new() -> SomeStruct {
|
||||
SomeStruct
|
||||
}
|
||||
}
|
||||
|
||||
// @has doc_spotlight/fn.bare_fn.html
|
||||
// @has - '//code[@class="content"]' 'impl SomeTrait for SomeStruct'
|
||||
pub fn bare_fn() -> SomeStruct {
|
||||
SomeStruct
|
||||
}
|
4
src/test/ui/feature-gates/feature-gate-doc_spotlight.rs
Normal file
4
src/test/ui/feature-gates/feature-gate-doc_spotlight.rs
Normal file
@ -0,0 +1,4 @@
|
||||
#[doc(spotlight)] //~ ERROR: `#[doc(spotlight)]` is experimental
|
||||
trait SomeTrait {}
|
||||
|
||||
fn main() {}
|
12
src/test/ui/feature-gates/feature-gate-doc_spotlight.stderr
Normal file
12
src/test/ui/feature-gates/feature-gate-doc_spotlight.stderr
Normal file
@ -0,0 +1,12 @@
|
||||
error[E0658]: `#[doc(spotlight)]` is experimental
|
||||
--> $DIR/feature-gate-doc_spotlight.rs:1:1
|
||||
|
|
||||
LL | #[doc(spotlight)]
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #45040 <https://github.com/rust-lang/rust/issues/45040> for more information
|
||||
= help: add `#![feature(doc_spotlight)]` to the crate attributes to enable
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
Loading…
Reference in New Issue
Block a user