diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 2f03b235e9f67..f8b852074dd2b 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -326,7 +326,7 @@ pub fn href(did: DefId) -> Option<(String, ItemType, Vec)> { url.push_str("/index.html"); } _ => { - url.push_str(shortty.to_static_str()); + url.push_str(shortty.css_class()); url.push_str("."); url.push_str(fqp.last().unwrap()); url.push_str(".html"); diff --git a/src/librustdoc/html/item_type.rs b/src/librustdoc/html/item_type.rs index 74f7b099044f1..6b462a76f04ed 100644 --- a/src/librustdoc/html/item_type.rs +++ b/src/librustdoc/html/item_type.rs @@ -42,6 +42,14 @@ pub enum ItemType { AssociatedConst = 18, } + +#[derive(Copy, Eq, PartialEq, Clone)] +pub enum NameSpace { + Type, + Value, + Macro, +} + impl ItemType { pub fn from_item(item: &clean::Item) -> ItemType { let inner = match item.inner { @@ -90,7 +98,7 @@ impl ItemType { } } - pub fn to_static_str(&self) -> &'static str { + pub fn css_class(&self) -> &'static str { match *self { ItemType::Module => "mod", ItemType::ExternCrate => "externcrate", @@ -113,9 +121,55 @@ impl ItemType { ItemType::AssociatedConst => "associatedconstant", } } + + pub fn name_space(&self) -> NameSpace { + match *self { + ItemType::Struct | + ItemType::Enum | + ItemType::Module | + ItemType::Typedef | + ItemType::Trait | + ItemType::Primitive | + ItemType::AssociatedType => NameSpace::Type, + + ItemType::ExternCrate | + ItemType::Import | + ItemType::Function | + ItemType::Static | + ItemType::Impl | + ItemType::TyMethod | + ItemType::Method | + ItemType::StructField | + ItemType::Variant | + ItemType::Constant | + ItemType::AssociatedConst => NameSpace::Value, + + ItemType::Macro => NameSpace::Macro, + } + } } impl fmt::Display for ItemType { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + self.css_class().fmt(f) + } +} + +pub const NAMESPACE_TYPE: &'static str = "t"; +pub const NAMESPACE_VALUE: &'static str = "v"; +pub const NAMESPACE_MACRO: &'static str = "m"; + +impl NameSpace { + pub fn to_static_str(&self) -> &'static str { + match *self { + NameSpace::Type => NAMESPACE_TYPE, + NameSpace::Value => NAMESPACE_VALUE, + NameSpace::Macro => NAMESPACE_MACRO, + } + } +} + +impl fmt::Display for NameSpace { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { self.to_static_str().fmt(f) } diff --git a/src/librustdoc/html/layout.rs b/src/librustdoc/html/layout.rs index 265ed6be1552d..151e138efefbf 100644 --- a/src/librustdoc/html/layout.rs +++ b/src/librustdoc/html/layout.rs @@ -24,7 +24,7 @@ pub struct Layout { pub struct Page<'a> { pub title: &'a str, - pub ty: &'a str, + pub css_class: &'a str, pub root_path: &'a str, pub description: &'a str, pub keywords: &'a str, @@ -80,7 +80,7 @@ r##" -
{content}
+
{content}
@@ -152,7 +152,7 @@ r##" }, content = *t, root_path = page.root_path, - ty = page.ty, + css_class = page.css_class, logo = if layout.logo.is_empty() { "".to_string() } else { diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index e4e886c853347..d654429146d83 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -41,7 +41,7 @@ use std::collections::{BTreeMap, HashMap, HashSet}; use std::default::Default; use std::error; use std::fmt::{self, Display, Formatter}; -use std::fs::{self, File}; +use std::fs::{self, File, OpenOptions}; use std::io::prelude::*; use std::io::{self, BufWriter, BufReader}; use std::iter::repeat; @@ -587,7 +587,7 @@ fn build_index(krate: &clean::Crate, cache: &mut Cache) -> String { for &(did, ref item) in orphan_methods { if let Some(&(ref fqp, _)) = paths.get(&did) { search_index.push(IndexItem { - ty: shortty(item), + ty: item_type(item), name: item.name.clone().unwrap(), path: fqp[..fqp.len() - 1].join("::"), desc: Escape(&shorter(item.doc_value())).to_string(), @@ -714,10 +714,10 @@ fn write_shared(cx: &Context, for line in BufReader::new(File::open(path)?).lines() { let line = line?; if !line.starts_with(key) { - continue + continue; } if line.starts_with(&format!(r#"{}["{}"]"#, key, krate)) { - continue + continue; } ret.push(line.to_string()); } @@ -761,7 +761,7 @@ fn write_shared(cx: &Context, try_err!(mkdir(&mydst), &mydst); } mydst.push(&format!("{}.{}.js", - remote_item_type.to_static_str(), + remote_item_type.css_class(), remote_path[remote_path.len() - 1])); let all_implementors = try_err!(collect(&mydst, &krate.name, "implementors"), @@ -832,7 +832,7 @@ fn mkdir(path: &Path) -> io::Result<()> { } /// Returns a documentation-level item type from the item. -fn shortty(item: &clean::Item) -> ItemType { +fn item_type(item: &clean::Item) -> ItemType { ItemType::from_item(item) } @@ -952,7 +952,7 @@ impl<'a> SourceCollector<'a> { let mut fname = p.file_name().expect("source has no filename") .to_os_string(); fname.push(".html"); - cur.push(&fname[..]); + cur.push(&fname); href.push_str(&fname.to_string_lossy()); let mut w = BufWriter::new(File::create(&cur)?); @@ -961,7 +961,7 @@ impl<'a> SourceCollector<'a> { let desc = format!("Source to the Rust file `{}`.", filename); let page = layout::Page { title: &title, - ty: "source", + css_class: "source", root_path: &root_path, description: &desc, keywords: BASIC_KEYWORDS, @@ -1080,7 +1080,7 @@ impl DocFolder for Cache { // inserted later on when serializing the search-index. if item.def_id.index != CRATE_DEF_INDEX { self.search_index.push(IndexItem { - ty: shortty(&item), + ty: item_type(&item), name: s.to_string(), path: path.join("::").to_string(), desc: Escape(&shorter(item.doc_value())).to_string(), @@ -1126,7 +1126,7 @@ impl DocFolder for Cache { self.access_levels.is_public(item.def_id) { self.paths.insert(item.def_id, - (self.stack.clone(), shortty(&item))); + (self.stack.clone(), item_type(&item))); } } // link variants to their parent enum because pages aren't emitted @@ -1139,7 +1139,7 @@ impl DocFolder for Cache { clean::PrimitiveItem(..) if item.visibility.is_some() => { self.paths.insert(item.def_id, (self.stack.clone(), - shortty(&item))); + item_type(&item))); } _ => {} @@ -1283,74 +1283,77 @@ impl Context { Ok(()) } - /// Non-parallelized version of rendering an item. This will take the input - /// item, render its contents, and then invoke the specified closure with - /// all sub-items which need to be rendered. - /// - /// The rendering driver uses this closure to queue up more work. - fn item(&mut self, item: clean::Item, mut f: F) -> Result<(), Error> where - F: FnMut(&mut Context, clean::Item), - { - fn render(writer: &mut io::Write, cx: &Context, it: &clean::Item, - pushname: bool) -> io::Result<()> { - // A little unfortunate that this is done like this, but it sure - // does make formatting *a lot* nicer. - CURRENT_LOCATION_KEY.with(|slot| { - *slot.borrow_mut() = cx.current.clone(); - }); + fn render_item(&self, + writer: &mut io::Write, + it: &clean::Item, + pushname: bool) + -> io::Result<()> { + // A little unfortunate that this is done like this, but it sure + // does make formatting *a lot* nicer. + CURRENT_LOCATION_KEY.with(|slot| { + *slot.borrow_mut() = self.current.clone(); + }); - let mut title = if it.is_primitive() { - // No need to include the namespace for primitive types - String::new() - } else { - cx.current.join("::") - }; - if pushname { - if !title.is_empty() { - title.push_str("::"); - } - title.push_str(it.name.as_ref().unwrap()); + let mut title = if it.is_primitive() { + // No need to include the namespace for primitive types + String::new() + } else { + self.current.join("::") + }; + if pushname { + if !title.is_empty() { + title.push_str("::"); } - title.push_str(" - Rust"); - let tyname = shortty(it).to_static_str(); - let desc = if it.is_crate() { - format!("API documentation for the Rust `{}` crate.", - cx.shared.layout.krate) - } else { - format!("API documentation for the Rust `{}` {} in crate `{}`.", - it.name.as_ref().unwrap(), tyname, cx.shared.layout.krate) - }; - let keywords = make_item_keywords(it); - let page = layout::Page { - ty: tyname, - root_path: &cx.root_path, - title: &title, - description: &desc, - keywords: &keywords, - }; + title.push_str(it.name.as_ref().unwrap()); + } + title.push_str(" - Rust"); + let tyname = item_type(it).css_class(); + let desc = if it.is_crate() { + format!("API documentation for the Rust `{}` crate.", + self.shared.layout.krate) + } else { + format!("API documentation for the Rust `{}` {} in crate `{}`.", + it.name.as_ref().unwrap(), tyname, self.shared.layout.krate) + }; + let keywords = make_item_keywords(it); + let page = layout::Page { + css_class: tyname, + root_path: &self.root_path, + title: &title, + description: &desc, + keywords: &keywords, + }; - reset_ids(true); + reset_ids(true); - if !cx.render_redirect_pages { - layout::render(writer, &cx.shared.layout, &page, - &Sidebar{ cx: cx, item: it }, - &Item{ cx: cx, item: it }, - cx.shared.css_file_extension.is_some())?; - } else { - let mut url = repeat("../").take(cx.current.len()) - .collect::(); - if let Some(&(ref names, ty)) = cache().paths.get(&it.def_id) { - for name in &names[..names.len() - 1] { - url.push_str(name); - url.push_str("/"); - } - url.push_str(&item_path(ty, names.last().unwrap())); - layout::redirect(writer, &url)?; + if !self.render_redirect_pages { + layout::render(writer, &self.shared.layout, &page, + &Sidebar{ cx: self, item: it }, + &Item{ cx: self, item: it }, + self.shared.css_file_extension.is_some())?; + } else { + let mut url = repeat("../").take(self.current.len()) + .collect::(); + if let Some(&(ref names, ty)) = cache().paths.get(&it.def_id) { + for name in &names[..names.len() - 1] { + url.push_str(name); + url.push_str("/"); } + url.push_str(&item_path(ty, names.last().unwrap())); + layout::redirect(writer, &url)?; } - Ok(()) } + Ok(()) + } + /// Non-parallelized version of rendering an item. This will take the input + /// item, render its contents, and then invoke the specified closure with + /// all sub-items which need to be rendered. + /// + /// The rendering driver uses this closure to queue up more work. + fn item(&mut self, item: clean::Item, mut f: F) -> Result<(), Error> where + F: FnMut(&mut Context, clean::Item), + { // Stripped modules survive the rustdoc passes (i.e. `strip-private`) // if they contain impls for public types. These modules can also // contain items such as publicly reexported structures. @@ -1371,7 +1374,7 @@ impl Context { let item = item.take().unwrap(); let mut buf = Vec::new(); - render(&mut buf, this, &item, false).unwrap(); + this.render_item(&mut buf, &item, false).unwrap(); // buf will be empty if the module is stripped and there is no redirect for it if !buf.is_empty() { let joint_dst = this.dst.join("index.html"); @@ -1386,7 +1389,7 @@ impl Context { _ => unreachable!() }; - // render sidebar-items.js used throughout this module + // Render sidebar-items.js used throughout this module. if !this.render_redirect_pages { let items = this.build_sidebar_items(&m); let js_dst = this.dst.join("sidebar-items.js"); @@ -1398,23 +1401,34 @@ impl Context { for item in m.items { f(this,item); } + Ok(()) - }) + })?; } else if item.name.is_some() { let mut buf = Vec::new(); - render(&mut buf, self, &item, true).unwrap(); + self.render_item(&mut buf, &item, true).unwrap(); // buf will be empty if the item is stripped and there is no redirect for it if !buf.is_empty() { - let joint_dst = self.dst.join(&item_path(shortty(&item), - item.name.as_ref().unwrap())); + let name = item.name.as_ref().unwrap(); + let item_type = item_type(&item); + let file_name = &item_path(item_type, name); + let joint_dst = self.dst.join(file_name); try_err!(fs::create_dir_all(&self.dst), &self.dst); let mut dst = try_err!(File::create(&joint_dst), &joint_dst); try_err!(dst.write_all(&buf), &joint_dst); + + // Redirect from a sane URL using the namespace to Rustdoc's + // URL for the page. + let redir_name = format!("{}.{}.html", name, item_type.name_space()); + let redir_dst = self.dst.join(redir_name); + if let Ok(mut redirect_out) = OpenOptions::new().create_new(true) + .write(true) + .open(&redir_dst) { + try_err!(layout::redirect(&mut redirect_out, file_name), &redir_dst); + } } - Ok(()) - } else { - Ok(()) } + Ok(()) } fn build_sidebar_items(&self, m: &clean::Module) -> BTreeMap> { @@ -1423,7 +1437,7 @@ impl Context { for item in &m.items { if self.maybe_ignore_item(item) { continue } - let short = shortty(item).to_static_str(); + let short = item_type(item).css_class(); let myname = match item.name { None => continue, Some(ref s) => s.to_string(), @@ -1531,7 +1545,7 @@ impl<'a> Item<'a> { } Some(format!("{path}{file}?gotosrc={goto}", path = path, - file = item_path(shortty(self.item), external_path.last().unwrap()), + file = item_path(item_type(self.item), external_path.last().unwrap()), goto = self.item.def_id.index.as_usize())) } } @@ -1566,7 +1580,7 @@ impl<'a> fmt::Display for Item<'a> { } } write!(fmt, "{}", - shortty(self.item), self.item.name.as_ref().unwrap())?; + item_type(self.item), self.item.name.as_ref().unwrap())?; write!(fmt, "")?; // in-band write!(fmt, "")?; @@ -1622,7 +1636,7 @@ impl<'a> fmt::Display for Item<'a> { fn item_path(ty: ItemType, name: &str) -> String { match ty { ItemType::Module => format!("{}/index.html", name), - _ => format!("{}.{}.html", ty.to_static_str(), name), + _ => format!("{}.{}.html", ty.css_class(), name), } } @@ -1714,8 +1728,8 @@ fn item_module(w: &mut fmt::Formatter, cx: &Context, } fn cmp(i1: &clean::Item, i2: &clean::Item, idx1: usize, idx2: usize) -> Ordering { - let ty1 = shortty(i1); - let ty2 = shortty(i2); + let ty1 = item_type(i1); + let ty2 = item_type(i2); if ty1 != ty2 { return (reorder(ty1), idx1).cmp(&(reorder(ty2), idx2)) } @@ -1739,7 +1753,7 @@ fn item_module(w: &mut fmt::Formatter, cx: &Context, continue; } - let myty = Some(shortty(myitem)); + let myty = Some(item_type(myitem)); if curty == Some(ItemType::ExternCrate) && myty == Some(ItemType::Import) { // Put `extern crate` and `use` re-exports in the same section. curty = myty; @@ -1825,9 +1839,9 @@ fn item_module(w: &mut fmt::Formatter, cx: &Context, name = *myitem.name.as_ref().unwrap(), stab_docs = stab_docs, docs = shorter(Some(&Markdown(doc_value).to_string())), - class = shortty(myitem), + class = item_type(myitem), stab = myitem.stability_class(), - href = item_path(shortty(myitem), myitem.name.as_ref().unwrap()), + href = item_path(item_type(myitem), myitem.name.as_ref().unwrap()), title = full_path(cx, myitem))?; } } @@ -2022,14 +2036,18 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item, fn trait_item(w: &mut fmt::Formatter, cx: &Context, m: &clean::Item, t: &clean::Item) -> fmt::Result { let name = m.name.as_ref().unwrap(); - let id = derive_id(format!("{}.{}", shortty(m), name)); - write!(w, "

", + let item_type = item_type(m); + let id = derive_id(format!("{}.{}", item_type, name)); + let ns_id = derive_id(format!("{}.{}", name, item_type.name_space())); + write!(w, "

\ +

")?; + write!(w, "

")?; document(w, cx, m)?; Ok(()) } @@ -2104,7 +2122,7 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item, let (ref path, _) = cache.external_paths[&it.def_id]; path[..path.len() - 1].join("/") }, - ty = shortty(it).to_static_str(), + ty = item_type(it).css_class(), name = *it.name.as_ref().unwrap())?; Ok(()) } @@ -2113,7 +2131,7 @@ fn naive_assoc_href(it: &clean::Item, link: AssocItemLink) -> String { use html::item_type::ItemType::*; let name = it.name.as_ref().unwrap(); - let ty = match shortty(it) { + let ty = match item_type(it) { Typedef | AssociatedType => AssociatedType, s@_ => s, }; @@ -2191,7 +2209,7 @@ fn render_assoc_item(w: &mut fmt::Formatter, link: AssocItemLink) -> fmt::Result { let name = meth.name.as_ref().unwrap(); - let anchor = format!("#{}.{}", shortty(meth), name); + let anchor = format!("#{}.{}", item_type(meth), name); let href = match link { AssocItemLink::Anchor(Some(ref id)) => format!("#{}", id), AssocItemLink::Anchor(None) => anchor, @@ -2268,9 +2286,19 @@ fn item_struct(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item, if fields.peek().is_some() { write!(w, "

Fields

")?; for (field, ty) in fields { - write!(w, "{name}: {ty} - ", - shortty = ItemType::StructField, + let id = derive_id(format!("{}.{}", + ItemType::StructField, + field.name.as_ref().unwrap())); + let ns_id = derive_id(format!("{}.{}", + field.name.as_ref().unwrap(), + ItemType::StructField.name_space())); + write!(w, " + ", + item_type = ItemType::StructField, + id = id, + ns_id = ns_id, stab = field.stability_class(), name = field.name.as_ref().unwrap(), ty = ty)?; @@ -2339,8 +2367,16 @@ fn item_enum(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item, if !e.variants.is_empty() { write!(w, "

Variants

\n")?; for variant in &e.variants { - write!(w, "{name}", - shortty = ItemType::Variant, + let id = derive_id(format!("{}.{}", + ItemType::Variant, + variant.name.as_ref().unwrap())); + let ns_id = derive_id(format!("{}.{}", + variant.name.as_ref().unwrap(), + ItemType::Variant.name_space())); + write!(w, "\ + ")?; + write!(w, "
")?; document(w, cx, variant)?; use clean::{Variant, StructVariant}; @@ -2364,10 +2400,20 @@ fn item_enum(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item, for field in &s.fields { use clean::StructFieldItem; if let StructFieldItem(ref ty) = field.inner { + let id = derive_id(format!("variant.{}.field.{}", + variant.name.as_ref().unwrap(), + field.name.as_ref().unwrap())); + let ns_id = derive_id(format!("{}.{}.{}.{}", + variant.name.as_ref().unwrap(), + ItemType::Variant.name_space(), + field.name.as_ref().unwrap(), + ItemType::StructField.name_space())); write!(w, "\ - {f}: {t}", - v = variant.name.as_ref().unwrap(), + id='{id}'>\ + ", + id = id, + ns_id = ns_id, f = field.name.as_ref().unwrap(), t = *ty)?; document(w, cx, field)?; @@ -2584,11 +2630,11 @@ fn render_impl(w: &mut fmt::Formatter, cx: &Context, i: &Impl, link: AssocItemLi } } - fn doctraititem(w: &mut fmt::Formatter, cx: &Context, item: &clean::Item, - link: AssocItemLink, render_static: bool, - is_default_item: bool, outer_version: Option<&str>, - trait_: Option<&clean::Trait>) -> fmt::Result { - let shortty = shortty(item); + fn doc_impl_item(w: &mut fmt::Formatter, cx: &Context, item: &clean::Item, + link: AssocItemLink, render_static: bool, + is_default_item: bool, outer_version: Option<&str>, + trait_: Option<&clean::Trait>) -> fmt::Result { + let item_type = item_type(item); let name = item.name.as_ref().unwrap(); let is_static = match item.inner { @@ -2601,38 +2647,48 @@ fn render_impl(w: &mut fmt::Formatter, cx: &Context, i: &Impl, link: AssocItemLi clean::MethodItem(..) | clean::TyMethodItem(..) => { // Only render when the method is not static or we allow static methods if !is_static || render_static { - let id = derive_id(format!("{}.{}", shortty, name)); - write!(w, "

", id, shortty)?; + let id = derive_id(format!("{}.{}", item_type, name)); + let ns_id = derive_id(format!("{}.{}", name, item_type.name_space())); + write!(w, "

", id, item_type)?; + write!(w, "

\n")?; + write!(w, "\n")?; } } clean::TypedefItem(ref tydef, _) => { let id = derive_id(format!("{}.{}", ItemType::AssociatedType, name)); - write!(w, "

", id, shortty)?; + let ns_id = derive_id(format!("{}.{}", name, item_type.name_space())); + write!(w, "

", id, item_type)?; + write!(w, "

\n")?; + write!(w, "

\n")?; } clean::AssociatedConstItem(ref ty, ref default) => { - let id = derive_id(format!("{}.{}", shortty, name)); - write!(w, "

", id, shortty)?; + let id = derive_id(format!("{}.{}", item_type, name)); + let ns_id = derive_id(format!("{}.{}", name, item_type.name_space())); + write!(w, "

", id, item_type)?; + write!(w, "

\n")?; + write!(w, "

\n")?; } clean::ConstantItem(ref c) => { - let id = derive_id(format!("{}.{}", shortty, name)); - write!(w, "

", id, shortty)?; + let id = derive_id(format!("{}.{}", item_type, name)); + let ns_id = derive_id(format!("{}.{}", name, item_type.name_space())); + write!(w, "

", id, item_type)?; + write!(w, "

\n")?; + write!(w, "

\n")?; } clean::AssociatedTypeItem(ref bounds, ref default) => { - let id = derive_id(format!("{}.{}", shortty, name)); - write!(w, "

", id, shortty)?; + let id = derive_id(format!("{}.{}", item_type, name)); + let ns_id = derive_id(format!("{}.{}", name, item_type.name_space())); + write!(w, "

", id, item_type)?; + write!(w, "

\n")?; + write!(w, "

\n")?; } clean::StrippedItem(..) => return Ok(()), _ => panic!("can't make docs for trait item with name {:?}", item.name) @@ -2671,8 +2727,8 @@ fn render_impl(w: &mut fmt::Formatter, cx: &Context, i: &Impl, link: AssocItemLi write!(w, "
")?; for trait_item in &i.inner_impl().items { - doctraititem(w, cx, trait_item, link, render_header, - false, outer_version, trait_)?; + doc_impl_item(w, cx, trait_item, link, render_header, + false, outer_version, trait_)?; } fn render_default_items(w: &mut fmt::Formatter, @@ -2689,8 +2745,8 @@ fn render_impl(w: &mut fmt::Formatter, cx: &Context, i: &Impl, link: AssocItemLi let did = i.trait_.as_ref().unwrap().def_id().unwrap(); let assoc_link = AssocItemLink::GotoSource(did, &i.provided_trait_methods); - doctraititem(w, cx, trait_item, assoc_link, render_static, true, - outer_version, None)?; + doc_impl_item(w, cx, trait_item, assoc_link, render_static, true, + outer_version, None)?; } Ok(()) } @@ -2749,7 +2805,7 @@ impl<'a> fmt::Display for Sidebar<'a> { relpath: '{path}'\ }};", name = it.name.as_ref().map(|x| &x[..]).unwrap_or(""), - ty = shortty(it).to_static_str(), + ty = item_type(it).css_class(), path = relpath)?; if parentlen == 0 { // there is no sidebar-items.js beyond the crate root path diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css index de0457592fc88..c97cacd10c381 100644 --- a/src/librustdoc/html/static/rustdoc.css +++ b/src/librustdoc/html/static/rustdoc.css @@ -284,7 +284,7 @@ h3.impl > .out-of-band { font-size: 21px; } -h4 > code, h3 > code { +h4 > code, h3 > code, invisible > code { position: inherit; } @@ -292,6 +292,12 @@ h4 > code, h3 > code { z-index: 5; } +.invisible { + background: rgba(0, 0, 0, 0); + width: 100%; + display: inline-block; +} + .content .in-band { margin: 0px; padding: 0px; @@ -660,6 +666,7 @@ span.since { :target > code { background: #FDFFD3; + opacity: 1; } /* Media Queries */ diff --git a/src/librustdoc/html/static/styles/main.css b/src/librustdoc/html/static/styles/main.css index aee6d15b7ca37..c64fb1b67f3d7 100644 --- a/src/librustdoc/html/static/styles/main.css +++ b/src/librustdoc/html/static/styles/main.css @@ -26,7 +26,7 @@ h1.fqn { h2, h3:not(.impl):not(.method):not(.type):not(.tymethod), h4:not(.method):not(.type):not(.tymethod) { border-bottom-color: #DDDDDD; } -.in-band, code { +.in-band { background-color: white; } diff --git a/src/test/rustdoc/assoc-types.rs b/src/test/rustdoc/assoc-types.rs index d5047ade062dc..e5485c356c292 100644 --- a/src/test/rustdoc/assoc-types.rs +++ b/src/test/rustdoc/assoc-types.rs @@ -13,7 +13,9 @@ // @has assoc_types/trait.Index.html pub trait Index { // @has - '//*[@id="associatedtype.Output"]//code' 'type Output: ?Sized' + // @has - '//*[@id="Output.t"]//code' 'type Output: ?Sized' type Output: ?Sized; + // @has - '//*[@id="index.v"]//code' 'fn index' // @has - '//*[@id="tymethod.index"]//code' \ // "fn index<'a>(&'a self, index: I) -> &'a Self::Output" fn index<'a>(&'a self, index: I) -> &'a Self::Output; diff --git a/src/test/rustdoc/issue-19190.rs b/src/test/rustdoc/issue-19190.rs index 6289fcc6fe526..15f7528b4ba21 100644 --- a/src/test/rustdoc/issue-19190.rs +++ b/src/test/rustdoc/issue-19190.rs @@ -23,6 +23,9 @@ impl Deref for Bar { fn deref(&self) -> &Foo { loop {} } } +// @has issue_19190/Bar.t.html // @has issue_19190/struct.Bar.html +// @has - '//*[@id="foo.v"]' 'fn foo(&self)' // @has - '//*[@id="method.foo"]' 'fn foo(&self)' +// @!has - '//*[@id="static_foo.v"]' 'fn static_foo()' // @!has - '//*[@id="method.static_foo"]' 'fn static_foo()' diff --git a/src/test/rustdoc/issue-21092.rs b/src/test/rustdoc/issue-21092.rs index ff48c70fc58dc..8c5bda7584c9f 100644 --- a/src/test/rustdoc/issue-21092.rs +++ b/src/test/rustdoc/issue-21092.rs @@ -13,6 +13,7 @@ extern crate issue_21092; +// @has issue_21092/Bar.t.html // @has issue_21092/struct.Bar.html // @has - '//*[@id="associatedtype.Bar"]' 'type Bar = i32' pub use issue_21092::{Foo, Bar}; diff --git a/src/test/rustdoc/issue-25001.rs b/src/test/rustdoc/issue-25001.rs index 25c97ee2c76a9..0b6a8104661af 100644 --- a/src/test/rustdoc/issue-25001.rs +++ b/src/test/rustdoc/issue-25001.rs @@ -19,14 +19,17 @@ pub trait Bar { impl Foo { // @has - '//*[@id="method.pass"]//code' 'fn pass()' + // @has - '//*[@id="pass.v"]//code' 'fn pass()' pub fn pass() {} } impl Foo { // @has - '//*[@id="method.pass-1"]//code' 'fn pass() -> usize' + // @has - '//*[@id="pass.v-1"]//code' 'fn pass() -> usize' pub fn pass() -> usize { 42 } } impl Foo { // @has - '//*[@id="method.pass-2"]//code' 'fn pass() -> isize' + // @has - '//*[@id="pass.v-2"]//code' 'fn pass() -> isize' pub fn pass() -> isize { 42 } } diff --git a/src/test/rustdoc/src-links.rs b/src/test/rustdoc/src-links.rs index 4d7dad64b47ae..e946e2423167a 100644 --- a/src/test/rustdoc/src-links.rs +++ b/src/test/rustdoc/src-links.rs @@ -24,11 +24,13 @@ pub mod bar { // @has foo/bar/baz/index.html '//a/@href' '../../../src/foo/src-links.rs.html' pub mod baz { /// Dox + // @has foo/bar/baz/baz.v.html // @has foo/bar/baz/fn.baz.html '//a/@href' '../../../src/foo/src-links.rs.html' pub fn baz() { } } /// Dox + // @has foo/bar/Foobar.t.html // @has foo/bar/trait.Foobar.html '//a/@href' '../../src/foo/src-links.rs.html' pub trait Foobar { fn dummy(&self) { } } diff --git a/src/test/rustdoc/structfields.rs b/src/test/rustdoc/structfields.rs index c4327f70728cb..c0bfe3ffe3cf9 100644 --- a/src/test/rustdoc/structfields.rs +++ b/src/test/rustdoc/structfields.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// @has structfields/Foo.t.html +// @has - struct.Foo.html // @has structfields/struct.Foo.html pub struct Foo { // @has - //pre "pub a: ()" @@ -22,6 +24,8 @@ pub struct Foo { pub d: usize, } +// @has structfields/Bar.t.html +// @has - struct.Bar.html // @has structfields/struct.Bar.html pub struct Bar { // @has - //pre "pub a: ()" @@ -29,6 +33,8 @@ pub struct Bar { // @!has - //pre "// some fields omitted" } +// @has structfields/Qux.t.html +// @has - enum.Qux.html // @has structfields/enum.Qux.html pub enum Qux { Quz {