{
+ let mut has_notable_trait = false;
+
+ let did = ty.def_id(cx.cache())?;
- if let Some((did, ty)) = decl.output.as_return().and_then(|t| Some((t.def_id(cx.cache())?, t)))
+ // Box has pass-through impls for Read, Write, Iterator, and Future when the
+ // boxed type implements one of those. We don't want to treat every Box return
+ // as being notably an Iterator (etc), though, so we exempt it. Pin has the same
+ // issue, with a pass-through impl for Future.
+ if Some(did) == cx.tcx().lang_items().owned_box()
+ || Some(did) == cx.tcx().lang_items().pin_type()
{
- // Box has pass-through impls for Read, Write, Iterator, and Future when the
- // boxed type implements one of those. We don't want to treat every Box return
- // as being notably an Iterator (etc), though, so we exempt it. Pin has the same
- // issue, with a pass-through impl for Future.
- if Some(did) == cx.tcx().lang_items().owned_box()
- || Some(did) == cx.tcx().lang_items().pin_type()
- {
- return "".to_string();
- }
- if let Some(impls) = cx.cache().impls.get(&did) {
- for i in impls {
- let impl_ = i.inner_impl();
- if !impl_.for_.without_borrowed_ref().is_same(ty.without_borrowed_ref(), cx.cache())
+ return None;
+ }
+
+ if let Some(impls) = cx.cache().impls.get(&did) {
+ for i in impls {
+ let impl_ = i.inner_impl();
+ if !impl_.for_.without_borrowed_ref().is_same(ty.without_borrowed_ref(), cx.cache()) {
+ // Two different types might have the same did,
+ // without actually being the same.
+ continue;
+ }
+ if let Some(trait_) = &impl_.trait_ {
+ let trait_did = trait_.def_id();
+
+ if cx.cache().traits.get(&trait_did).map_or(false, |t| t.is_notable_trait(cx.tcx()))
{
- // Two different types might have the same did,
- // without actually being the same.
- continue;
+ has_notable_trait = true;
+ }
+ }
+ }
+ }
+
+ if has_notable_trait {
+ cx.types_with_notable_traits.insert(ty.clone());
+ Some(format!(
+ "\
+ ⓘ\
+ ",
+ ty = ty.print(cx),
+ ))
+ } else {
+ None
+ }
+}
+
+fn notable_traits_decl(ty: &clean::Type, cx: &Context<'_>) -> (String, String) {
+ let mut out = Buffer::html();
+
+ let did = ty.def_id(cx.cache()).expect("notable_traits_button already checked this");
+
+ let impls = cx.cache().impls.get(&did).expect("notable_traits_button already checked this");
+
+ for i in impls {
+ let impl_ = i.inner_impl();
+ if !impl_.for_.without_borrowed_ref().is_same(ty.without_borrowed_ref(), cx.cache()) {
+ // Two different types might have the same did,
+ // without actually being the same.
+ continue;
+ }
+ if let Some(trait_) = &impl_.trait_ {
+ let trait_did = trait_.def_id();
+
+ if cx.cache().traits.get(&trait_did).map_or(false, |t| t.is_notable_trait(cx.tcx())) {
+ if out.is_empty() {
+ write!(
+ &mut out,
+ "Notable traits for {}
\
+ ",
+ impl_.for_.print(cx)
+ );
}
- if let Some(trait_) = &impl_.trait_ {
- let trait_did = trait_.def_id();
-
- if cx
- .cache()
- .traits
- .get(&trait_did)
- .map_or(false, |t| t.is_notable_trait(cx.tcx()))
- {
- if out.is_empty() {
- write!(
- &mut out,
- "Notable traits for {}\
- ",
- impl_.for_.print(cx)
- );
- }
- //use the "where" class here to make it small
- write!(
+ //use the "where" class here to make it small
+ write!(
+ &mut out,
+ "{}",
+ impl_.print(false, cx)
+ );
+ for it in &impl_.items {
+ if let clean::AssocTypeItem(ref tydef, ref _bounds) = *it.kind {
+ out.push_str(" ");
+ let empty_set = FxHashSet::default();
+ let src_link = AssocItemLink::GotoSource(trait_did.into(), &empty_set);
+ assoc_type(
&mut out,
- "{}",
- impl_.print(false, cx)
+ it,
+ &tydef.generics,
+ &[], // intentionally leaving out bounds
+ Some(&tydef.type_),
+ src_link,
+ 0,
+ cx,
);
- for it in &impl_.items {
- if let clean::AssocTypeItem(ref tydef, ref _bounds) = *it.kind {
- out.push_str(" ");
- let empty_set = FxHashSet::default();
- let src_link =
- AssocItemLink::GotoSource(trait_did.into(), &empty_set);
- assoc_type(
- &mut out,
- it,
- &tydef.generics,
- &[], // intentionally leaving out bounds
- Some(&tydef.type_),
- src_link,
- 0,
- cx,
- );
- out.push_str(";");
- }
- }
+ out.push_str(";");
}
}
}
}
}
-
- if !out.is_empty() {
- out.insert_str(
- 0,
- "ⓘ\
- ",
- );
- out.push_str("
");
+ if out.is_empty() {
+ write!(&mut out, "
",);
}
- out.into_inner()
+ (format!("{:#}", ty.print(cx)), out.into_inner())
+}
+
+pub(crate) fn notable_traits_json<'a>(
+ tys: impl Iterator- ,
+ cx: &Context<'_>,
+) -> String {
+ let mp: Vec<(String, String)> = tys.map(|ty| notable_traits_decl(ty, cx)).collect();
+ struct NotableTraitsMap(Vec<(String, String)>);
+ impl Serialize for NotableTraitsMap {
+ fn serialize
(&self, serializer: S) -> Result
+ where
+ S: Serializer,
+ {
+ let mut map = serializer.serialize_map(Some(self.0.len()))?;
+ for item in &self.0 {
+ map.serialize_entry(&item.0, &item.1)?;
+ }
+ map.end()
+ }
+ }
+ serde_json::to_string(&NotableTraitsMap(mp))
+ .expect("serialize (string, string) -> json object cannot fail")
}
#[derive(Clone, Copy, Debug)]
diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs
index ce4fc4d68fac2..ac11a860a4f0b 100644
--- a/src/librustdoc/html/render/print_item.rs
+++ b/src/librustdoc/html/render/print_item.rs
@@ -17,9 +17,10 @@ use std::rc::Rc;
use super::{
collect_paths_for_type, document, ensure_trailing_slash, get_filtered_impls_for_reference,
- item_ty_to_section, notable_traits_decl, render_all_impls, render_assoc_item,
- render_assoc_items, render_attributes_in_code, render_attributes_in_pre, render_impl,
- render_rightside, render_stability_since_raw, AssocItemLink, Context, ImplRenderingParameters,
+ item_ty_to_section, notable_traits_button, notable_traits_json, render_all_impls,
+ render_assoc_item, render_assoc_items, render_attributes_in_code, render_attributes_in_pre,
+ render_impl, render_rightside, render_stability_since_raw, AssocItemLink, Context,
+ ImplRenderingParameters,
};
use crate::clean;
use crate::config::ModuleSorting;
@@ -183,6 +184,16 @@ pub(super) fn print_item(
unreachable!();
}
}
+
+ // Render notable-traits.js used for all methods in this module.
+ if !cx.types_with_notable_traits.is_empty() {
+ write!(
+ buf,
+ r#""#,
+ notable_traits_json(cx.types_with_notable_traits.iter(), cx)
+ );
+ cx.types_with_notable_traits.clear();
+ }
}
/// For large structs, enums, unions, etc, determine whether to hide their fields
@@ -516,6 +527,9 @@ fn item_function(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, f: &cle
+ name.as_str().len()
+ generics_len;
+ let notable_traits =
+ f.decl.output.as_return().and_then(|output| notable_traits_button(output, cx));
+
wrap_into_item_decl(w, |w| {
wrap_item(w, "fn", |w| {
render_attributes_in_pre(w, it, "");
@@ -533,11 +547,11 @@ fn item_function(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, f: &cle
generics = f.generics.print(cx),
where_clause = print_where_clause(&f.generics, cx, 0, Ending::Newline),
decl = f.decl.full_print(header_len, 0, cx),
- notable_traits = notable_traits_decl(&f.decl, cx),
+ notable_traits = notable_traits.unwrap_or_default(),
);
});
});
- document(w, cx, it, None, HeadingOffset::H2)
+ document(w, cx, it, None, HeadingOffset::H2);
}
fn item_trait(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean::Trait) {
diff --git a/src/librustdoc/html/static/css/noscript.css b/src/librustdoc/html/static/css/noscript.css
index 301f03a16427a..54e8b6561f34f 100644
--- a/src/librustdoc/html/static/css/noscript.css
+++ b/src/librustdoc/html/static/css/noscript.css
@@ -22,3 +22,9 @@ nav.sub {
.source .sidebar {
display: none;
}
+
+.notable-traits {
+ /* layout requires javascript
+ https://github.com/rust-lang/rust/issues/102576 */
+ display: none;
+}
diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css
index a38c0e42ab455..44e4cc0c7acd5 100644
--- a/src/librustdoc/html/static/css/rustdoc.css
+++ b/src/librustdoc/html/static/css/rustdoc.css
@@ -183,6 +183,8 @@ h4.code-header {
font-weight: 600;
margin: 0;
padding: 0;
+ /* position notable traits in mobile mode within the header */
+ position: relative;
}
#crate-search,
@@ -1268,13 +1270,12 @@ h3.variant {
cursor: pointer;
}
-.notable-traits:hover .notable-traits-tooltiptext,
-.notable-traits .notable-traits-tooltiptext.force-tooltip {
+.notable-traits .notable-traits-tooltiptext {
display: inline-block;
+ visibility: hidden;
}
-.notable-traits .notable-traits-tooltiptext {
- display: none;
+.notable-traits-tooltiptext {
padding: 5px 3px 3px 3px;
border-radius: 6px;
margin-left: 5px;
@@ -1292,22 +1293,26 @@ h3.variant {
content: "\00a0\00a0\00a0";
}
-.notable-traits .docblock {
+.notable-traits-tooltiptext .docblock {
margin: 0;
}
-.notable-traits .notable {
- margin: 0;
- margin-bottom: 13px;
+.notable-traits-tooltiptext .notable {
font-size: 1.1875rem;
font-weight: 600;
display: block;
}
-.notable-traits .docblock code.content {
+.notable-traits-tooltiptext pre, .notable-traits-tooltiptext code {
+ background: transparent;
+}
+
+.notable-traits-tooltiptext .docblock pre.content {
margin: 0;
padding: 0;
font-size: 1.25rem;
+ white-space: pre-wrap;
+ overflow: hidden;
}
.search-failed {
diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js
index 1c84393cb4e6f..0426774e80d46 100644
--- a/src/librustdoc/html/static/js/main.js
+++ b/src/librustdoc/html/static/js/main.js
@@ -790,6 +790,19 @@ function loadCss(cssUrl) {
// we need to switch away from mobile mode and make the main content area scrollable.
hideSidebar();
}
+ if (window.CURRENT_NOTABLE_ELEMENT) {
+ // As a workaround to the behavior of `contains: layout` used in doc togglers, the
+ // notable traits popup is positioned using javascript.
+ //
+ // This means when the window is resized, we need to redo the layout.
+ const base = window.CURRENT_NOTABLE_ELEMENT.NOTABLE_BASE;
+ const force_visible = base.NOTABLE_FORCE_VISIBLE;
+ hideNotable();
+ if (force_visible) {
+ showNotable(base);
+ base.NOTABLE_FORCE_VISIBLE = true;
+ }
+ }
});
function handleClick(id, f) {
@@ -822,10 +835,80 @@ function loadCss(cssUrl) {
});
});
+ function showNotable(e) {
+ if (!window.NOTABLE_TRAITS) {
+ const data = document.getElementById("notable-traits-data");
+ if (data) {
+ window.NOTABLE_TRAITS = JSON.parse(data.innerText);
+ } else {
+ throw new Error("showNotable() called on page without any notable traits!");
+ }
+ }
+ if (window.CURRENT_NOTABLE_ELEMENT && window.CURRENT_NOTABLE_ELEMENT.NOTABLE_BASE === e) {
+ // Make this function idempotent.
+ return;
+ }
+ hideNotable();
+ const ty = e.getAttribute("data-ty");
+ const tooltip = e.getElementsByClassName("notable-traits-tooltip")[0];
+ const wrapper = document.createElement("div");
+ wrapper.innerHTML = "" + window.NOTABLE_TRAITS[ty] + "
";
+ wrapper.className = "notable-traits-tooltiptext";
+ tooltip.appendChild(wrapper);
+ const pos = wrapper.getBoundingClientRect();
+ tooltip.removeChild(wrapper);
+ wrapper.style.top = (pos.top + window.scrollY) + "px";
+ wrapper.style.left = (pos.left + window.scrollX) + "px";
+ wrapper.style.width = pos.width + "px";
+ const body = document.getElementsByTagName("body")[0];
+ body.appendChild(wrapper);
+ window.CURRENT_NOTABLE_ELEMENT = wrapper;
+ window.CURRENT_NOTABLE_ELEMENT.NOTABLE_BASE = e;
+ wrapper.onpointerleave = function(ev) {
+ // If this is a synthetic touch event, ignore it. A click event will be along shortly.
+ if (ev.pointerType !== "mouse") {
+ return;
+ }
+ if (!e.NOTABLE_FORCE_VISIBLE && !elemIsInParent(event.relatedTarget, e)) {
+ hideNotable();
+ }
+ };
+ }
+
+ function hideNotable() {
+ if (window.CURRENT_NOTABLE_ELEMENT) {
+ window.CURRENT_NOTABLE_ELEMENT.NOTABLE_BASE.NOTABLE_FORCE_VISIBLE = false;
+ const body = document.getElementsByTagName("body")[0];
+ body.removeChild(window.CURRENT_NOTABLE_ELEMENT);
+ window.CURRENT_NOTABLE_ELEMENT = null;
+ }
+ }
+
onEachLazy(document.getElementsByClassName("notable-traits"), e => {
e.onclick = function() {
- this.getElementsByClassName("notable-traits-tooltiptext")[0]
- .classList.toggle("force-tooltip");
+ this.NOTABLE_FORCE_VISIBLE = this.NOTABLE_FORCE_VISIBLE ? false : true;
+ if (window.CURRENT_NOTABLE_ELEMENT && !this.NOTABLE_FORCE_VISIBLE) {
+ hideNotable();
+ } else {
+ showNotable(this);
+ }
+ };
+ e.onpointerenter = function(ev) {
+ // If this is a synthetic touch event, ignore it. A click event will be along shortly.
+ if (ev.pointerType !== "mouse") {
+ return;
+ }
+ showNotable(this);
+ };
+ e.onpointerleave = function(ev) {
+ // If this is a synthetic touch event, ignore it. A click event will be along shortly.
+ if (ev.pointerType !== "mouse") {
+ return;
+ }
+ if (!this.NOTABLE_FORCE_VISIBLE &&
+ !elemIsInParent(event.relatedTarget, window.CURRENT_NOTABLE_ELEMENT)) {
+ hideNotable();
+ }
};
});
diff --git a/src/test/rustdoc-gui/notable-trait.goml b/src/test/rustdoc-gui/notable-trait.goml
index efe0cb15f08a0..d8261d8dc902c 100644
--- a/src/test/rustdoc-gui/notable-trait.goml
+++ b/src/test/rustdoc-gui/notable-trait.goml
@@ -25,22 +25,28 @@ assert-position: (
{"x": 951},
)
// The tooltip should be beside the `i`
+// Also, clicking the tooltip should bring its text into the DOM
+assert-count: ("//*[@class='notable-traits-tooltiptext']", 0)
click: "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']"
+assert-count: ("//*[@class='notable-traits-tooltiptext']", 1)
compare-elements-position-near: (
"//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']",
- "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits-tooltiptext force-tooltip']",
+ "//*[@class='notable-traits-tooltiptext']",
{"y": 2}
)
compare-elements-position-false: (
"//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']",
- "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits-tooltiptext force-tooltip']",
+ "//*[@class='notable-traits-tooltiptext']",
("x")
)
// The docblock should be flush with the border.
assert-css: (
- "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits-tooltiptext force-tooltip']/*[@class='docblock']",
+ "//*[@class='notable-traits-tooltiptext']/*[@class='docblock']",
{"margin-left": "0px"}
)
+click: "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']"
+move-cursor-to: "//h1"
+assert-count: ("//*[@class='notable-traits-tooltiptext']", 0)
// Now only the `i` should be on the next line.
size: (1055, 600)
@@ -98,26 +104,31 @@ assert-position: (
{"x": 289},
)
// The tooltip should be below `i`
+click: "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']"
+assert-count: ("//*[@class='notable-traits-tooltiptext']", 1)
compare-elements-position-near-false: (
"//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']",
- "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits-tooltiptext force-tooltip']",
+ "//*[@class='notable-traits-tooltiptext']",
{"y": 2}
)
compare-elements-position-false: (
"//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']",
- "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits-tooltiptext force-tooltip']",
+ "//*[@class='notable-traits-tooltiptext']",
("x")
)
compare-elements-position-near: (
- "//*[@id='method.create_an_iterator_from_read']/parent::*",
- "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits-tooltiptext force-tooltip']",
- {"x": 5}
+ "//*[@id='method.create_an_iterator_from_read']",
+ "//*[@class='notable-traits-tooltiptext']",
+ {"x": 10}
)
// The docblock should be flush with the border.
assert-css: (
- "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits-tooltiptext force-tooltip']/*[@class='docblock']",
+ "//*[@class='notable-traits-tooltiptext']/*[@class='docblock']",
{"margin-left": "0px"}
)
+click: "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']"
+move-cursor-to: "//h1"
+assert-count: ("//*[@class='notable-traits-tooltiptext']", 0)
// Checking on very small mobile. The `i` should be on its own line.
size: (365, 600)
@@ -126,3 +137,76 @@ compare-elements-position-false: (
"//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']",
("y", "x"),
)
+
+// Now check the colors.
+define-function: (
+ "check-colors",
+ (theme, header_color, content_color, type_color, trait_color),
+ [
+ ("goto", "file://" + |DOC_PATH| + "/test_docs/struct.NotableStructWithLongName.html"),
+ // This is needed to ensure that the text color is computed.
+ ("show-text", true),
+
+ // Setting the theme.
+ ("local-storage", {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}),
+ // We reload the page so the local storage settings are being used.
+ ("reload"),
+
+ ("move-cursor-to", "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']"),
+ ("assert-count", (".notable-traits-tooltiptext", 1)),
+
+ ("assert-css", (
+ ".notable-traits-tooltiptext h3.notable",
+ {"color": |header_color|},
+ ALL,
+ )),
+ ("assert-css", (
+ ".notable-traits-tooltiptext pre.content",
+ {"color": |content_color|},
+ ALL,
+ )),
+ ("assert-css", (
+ ".notable-traits-tooltiptext pre.content a.struct",
+ {"color": |type_color|},
+ ALL,
+ )),
+ ("assert-css", (
+ ".notable-traits-tooltiptext pre.content a.trait",
+ {"color": |trait_color|},
+ ALL,
+ )),
+ ]
+)
+
+call-function: (
+ "check-colors",
+ {
+ "theme": "ayu",
+ "content_color": "rgb(230, 225, 207)",
+ "header_color": "rgb(255, 255, 255)",
+ "type_color": "rgb(255, 160, 165)",
+ "trait_color": "rgb(57, 175, 215)",
+ },
+)
+
+call-function: (
+ "check-colors",
+ {
+ "theme": "dark",
+ "content_color": "rgb(221, 221, 221)",
+ "header_color": "rgb(221, 221, 221)",
+ "type_color": "rgb(45, 191, 184)",
+ "trait_color": "rgb(183, 140, 242)",
+ },
+)
+
+call-function: (
+ "check-colors",
+ {
+ "theme": "light",
+ "content_color": "rgb(0, 0, 0)",
+ "header_color": "rgb(0, 0, 0)",
+ "type_color": "rgb(173, 55, 138)",
+ "trait_color": "rgb(110, 79, 201)",
+ },
+)
diff --git a/src/test/rustdoc/doc-notable_trait-slice.bare_fn_matches.html b/src/test/rustdoc/doc-notable_trait-slice.bare_fn_matches.html
new file mode 100644
index 0000000000000..6b58be7e6853e
--- /dev/null
+++ b/src/test/rustdoc/doc-notable_trait-slice.bare_fn_matches.html
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/test/rustdoc/doc-notable_trait-slice.rs b/src/test/rustdoc/doc-notable_trait-slice.rs
index b0d414027216a..2411da8cd4549 100644
--- a/src/test/rustdoc/doc-notable_trait-slice.rs
+++ b/src/test/rustdoc/doc-notable_trait-slice.rs
@@ -8,13 +8,13 @@ pub struct OtherStruct;
impl SomeTrait for &[SomeStruct] {}
// @has doc_notable_trait_slice/fn.bare_fn_matches.html
-// @has - '//code[@class="content"]' 'impl SomeTrait for &[SomeStruct]'
+// @snapshot bare_fn_matches - '//script[@id="notable-traits-data"]'
pub fn bare_fn_matches() -> &'static [SomeStruct] {
&[]
}
// @has doc_notable_trait_slice/fn.bare_fn_no_matches.html
-// @!has - '//code[@class="content"]' 'impl SomeTrait for &[SomeStruct]'
+// @count - '//script[@id="notable-traits-data"]' 0
pub fn bare_fn_no_matches() -> &'static [OtherStruct] {
&[]
}
diff --git a/src/test/rustdoc/doc-notable_trait.bare-fn.html b/src/test/rustdoc/doc-notable_trait.bare-fn.html
new file mode 100644
index 0000000000000..4e4a3f18f2498
--- /dev/null
+++ b/src/test/rustdoc/doc-notable_trait.bare-fn.html
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/test/rustdoc/doc-notable_trait.rs b/src/test/rustdoc/doc-notable_trait.rs
index 58a24b855d6e2..1f2cd7181c3d4 100644
--- a/src/test/rustdoc/doc-notable_trait.rs
+++ b/src/test/rustdoc/doc-notable_trait.rs
@@ -9,7 +9,8 @@ impl SomeTrait for Wrapper {}
#[doc(notable_trait)]
pub trait SomeTrait {
// @has doc_notable_trait/trait.SomeTrait.html
- // @has - '//code[@class="content"]' 'impl SomeTrait for Wrapper'
+ // @has - '//span[@class="notable-traits"]/@data-ty' 'Wrapper'
+ // @snapshot wrap-me - '//script[@id="notable-traits-data"]'
fn wrap_me(self) -> Wrapper where Self: Sized {
Wrapper {
inner: self,
@@ -22,15 +23,16 @@ impl SomeTrait for SomeStruct {}
impl SomeStruct {
// @has doc_notable_trait/struct.SomeStruct.html
- // @has - '//code[@class="content"]' 'impl SomeTrait for SomeStruct'
- // @has - '//code[@class="content"]' 'impl SomeTrait for Wrapper'
+ // @has - '//span[@class="notable-traits"]/@data-ty' 'SomeStruct'
+ // @snapshot some-struct-new - '//script[@id="notable-traits-data"]'
pub fn new() -> SomeStruct {
SomeStruct
}
}
// @has doc_notable_trait/fn.bare_fn.html
-// @has - '//code[@class="content"]' 'impl SomeTrait for SomeStruct'
+// @has - '//span[@class="notable-traits"]/@data-ty' 'SomeStruct'
+// @snapshot bare-fn - '//script[@id="notable-traits-data"]'
pub fn bare_fn() -> SomeStruct {
SomeStruct
}
diff --git a/src/test/rustdoc/doc-notable_trait.some-struct-new.html b/src/test/rustdoc/doc-notable_trait.some-struct-new.html
new file mode 100644
index 0000000000000..a61e7c752e66d
--- /dev/null
+++ b/src/test/rustdoc/doc-notable_trait.some-struct-new.html
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/test/rustdoc/doc-notable_trait.wrap-me.html b/src/test/rustdoc/doc-notable_trait.wrap-me.html
new file mode 100644
index 0000000000000..9a59d5edd12a8
--- /dev/null
+++ b/src/test/rustdoc/doc-notable_trait.wrap-me.html
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/test/rustdoc/spotlight-from-dependency.odd.html b/src/test/rustdoc/spotlight-from-dependency.odd.html
new file mode 100644
index 0000000000000..987a949af44b1
--- /dev/null
+++ b/src/test/rustdoc/spotlight-from-dependency.odd.html
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/test/rustdoc/spotlight-from-dependency.rs b/src/test/rustdoc/spotlight-from-dependency.rs
index 5245789212d8c..156aedca62b4e 100644
--- a/src/test/rustdoc/spotlight-from-dependency.rs
+++ b/src/test/rustdoc/spotlight-from-dependency.rs
@@ -3,7 +3,8 @@
use std::iter::Iterator;
// @has foo/struct.Odd.html
-// @has - '//*[@id="method.new"]//span[@class="notable-traits"]//code/span' 'impl Iterator for Odd'
+// @has - '//*[@id="method.new"]//span[@class="notable-traits"]/@data-ty' 'Odd'
+// @snapshot odd - '//script[@id="notable-traits-data"]'
pub struct Odd {
current: usize,
}