diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 5cdddc76582b3..4c652f54009da 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -145,14 +145,19 @@ pub struct Implementor { /// Metadata about implementations for a type. #[derive(Clone)] pub struct Impl { - pub impl_: clean::Impl, - pub dox: Option, - pub stability: Option, + pub impl_item: clean::Item, } impl Impl { + fn inner_impl(&self) -> &clean::Impl { + match self.impl_item.inner { + clean::ImplItem(ref impl_) => impl_, + _ => panic!("non-impl item found in impl") + } + } + fn trait_did(&self) -> Option { - self.impl_.trait_.def_id() + self.inner_impl().trait_.def_id() } } @@ -1189,31 +1194,34 @@ impl DocFolder for Cache { // Once we've recursively found all the generics, then hoard off all the // implementations elsewhere let ret = self.fold_item_recur(item).and_then(|item| { - if let clean::Item { attrs, inner: clean::ImplItem(i), .. } = item { + if let clean::Item { inner: clean::ImplItem(_), .. } = item { // Figure out the id of this impl. This may map to a // primitive rather than always to a struct/enum. - let did = match i.for_ { - clean::ResolvedPath { did, .. } | - clean::BorrowedRef { - type_: box clean::ResolvedPath { did, .. }, .. - } => { - Some(did) - } - ref t => { - t.primitive_type().and_then(|t| { - self.primitive_locations.get(&t).map(|n| { - let id = t.to_def_index(); - DefId { krate: *n, index: id } + // Note: matching twice to restrict the lifetime of the `i` borrow. + let did = if let clean::Item { inner: clean::ImplItem(ref i), .. } = item { + match i.for_ { + clean::ResolvedPath { did, .. } | + clean::BorrowedRef { + type_: box clean::ResolvedPath { did, .. }, .. + } => { + Some(did) + } + ref t => { + t.primitive_type().and_then(|t| { + self.primitive_locations.get(&t).map(|n| { + let id = t.to_def_index(); + DefId { krate: *n, index: id } + }) }) - }) + } } + } else { + unreachable!() }; if !self.seen_mod { if let Some(did) = did { self.impls.entry(did).or_insert(vec![]).push(Impl { - impl_: i, - dox: attrs.value("doc").map(|s|s.to_owned()), - stability: item.stability.clone(), + impl_item: item, }); } } @@ -1510,11 +1518,15 @@ impl<'a> Item<'a> { // located, then we return `None`. } else { let cache = cache(); - let path = &cache.external_paths[&self.item.def_id]; - let root = match cache.extern_locations[&self.item.def_id.krate] { - (_, Remote(ref s)) => s.to_string(), - (_, Local) => self.cx.root_path.clone(), - (_, Unknown) => return None, + let path = match cache.external_paths.get(&self.item.def_id) { + Some(path) => path, + None => return None, + }; + let root = match cache.extern_locations.get(&self.item.def_id.krate) { + Some(&(_, Remote(ref s))) => s.to_string(), + Some(&(_, Local)) => self.cx.root_path.clone(), + Some(&(_, Unknown)) => return None, + None => return None, }; Some(format!("{root}{path}/{file}?gotosrc={goto}", root = root, @@ -2132,7 +2144,7 @@ fn render_stability_since_raw<'a>(w: &mut fmt::Formatter, containing_ver: Option<&'a str>) -> fmt::Result { if let Some(v) = ver { if containing_ver != ver && v.len() > 0 { - write!(w, "{}", + write!(w, "
{}
", v)? } } @@ -2449,7 +2461,7 @@ fn render_assoc_items(w: &mut fmt::Formatter, None => return Ok(()), }; let (non_trait, traits): (Vec<_>, _) = v.iter().partition(|i| { - i.impl_.trait_.is_none() + i.inner_impl().trait_.is_none() }); if !non_trait.is_empty() { let render_header = match what { @@ -2473,7 +2485,7 @@ fn render_assoc_items(w: &mut fmt::Formatter, } if !traits.is_empty() { let deref_impl = traits.iter().find(|t| { - t.impl_.trait_.def_id() == c.deref_trait_did + t.inner_impl().trait_.def_id() == c.deref_trait_did }); if let Some(impl_) = deref_impl { render_deref_methods(w, cx, impl_, containing_item)?; @@ -2481,11 +2493,11 @@ fn render_assoc_items(w: &mut fmt::Formatter, write!(w, "

Trait \ Implementations

")?; let (derived, manual): (Vec<_>, Vec<&Impl>) = traits.iter().partition(|i| { - i.impl_.derived + i.inner_impl().derived }); for i in &manual { let did = i.trait_did().unwrap(); - let assoc_link = AssocItemLink::GotoSource(did, &i.impl_.provided_trait_methods); + let assoc_link = AssocItemLink::GotoSource(did, &i.inner_impl().provided_trait_methods); render_impl(w, cx, i, assoc_link, true, containing_item.stable_since())?; } if !derived.is_empty() { @@ -2494,7 +2506,8 @@ fn render_assoc_items(w: &mut fmt::Formatter, ")?; for i in &derived { let did = i.trait_did().unwrap(); - let assoc_link = AssocItemLink::GotoSource(did, &i.impl_.provided_trait_methods); + let assoc_link = AssocItemLink::GotoSource(did, + &i.inner_impl().provided_trait_methods); render_impl(w, cx, i, assoc_link, true, containing_item.stable_since())?; } } @@ -2504,8 +2517,8 @@ fn render_assoc_items(w: &mut fmt::Formatter, fn render_deref_methods(w: &mut fmt::Formatter, cx: &Context, impl_: &Impl, container_item: &clean::Item) -> fmt::Result { - let deref_type = impl_.impl_.trait_.as_ref().unwrap(); - let target = impl_.impl_.items.iter().filter_map(|item| { + let deref_type = impl_.inner_impl().trait_.as_ref().unwrap(); + let target = impl_.inner_impl().items.iter().filter_map(|item| { match item.inner { clean::TypedefItem(ref t, true) => Some(&t.type_), _ => None, @@ -2531,11 +2544,21 @@ fn render_deref_methods(w: &mut fmt::Formatter, cx: &Context, impl_: &Impl, fn render_impl(w: &mut fmt::Formatter, cx: &Context, i: &Impl, link: AssocItemLink, render_header: bool, outer_version: Option<&str>) -> fmt::Result { if render_header { - write!(w, "

{}", i.impl_)?; - let since = i.stability.as_ref().map(|s| &s.since[..]); - render_stability_since_raw(w, since, outer_version)?; - write!(w, "

")?; - if let Some(ref dox) = i.dox { + write!(w, "

{}", i.inner_impl())?; + write!(w, "")?; + let since = i.impl_item.stability.as_ref().map(|s| &s.since[..]); + if let Some(l) = (Item { item: &i.impl_item, cx: cx }).href() { + write!(w, "
")?; + render_stability_since_raw(w, since, outer_version)?; + write!(w, "[src]", + i.impl_item.def_id.index.as_usize(), l, "goto source code")?; + } else { + render_stability_since_raw(w, since, outer_version)?; + } + write!(w, "
")?; + write!(w, "

\n")?; + if let Some(ref dox) = i.impl_item.attrs.value("doc") { write!(w, "
{}
", Markdown(dox))?; } } @@ -2601,7 +2624,7 @@ fn render_impl(w: &mut fmt::Formatter, cx: &Context, i: &Impl, link: AssocItemLi } write!(w, "
")?; - for trait_item in &i.impl_.items { + for trait_item in &i.inner_impl().items { doctraititem(w, cx, trait_item, link, render_header, false, outer_version)?; } @@ -2629,7 +2652,7 @@ fn render_impl(w: &mut fmt::Formatter, cx: &Context, i: &Impl, link: AssocItemLi // default items which weren't overridden in the implementation block. if let Some(did) = i.trait_did() { if let Some(t) = cache().traits.get(&did) { - render_default_items(w, cx, t, &i.impl_, render_header, outer_version)?; + render_default_items(w, cx, t, &i.inner_impl(), render_header, outer_version)?; } } write!(w, "
")?; diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css index c07871a4029ca..4d65b91ed421c 100644 --- a/src/librustdoc/html/static/rustdoc.css +++ b/src/librustdoc/html/static/rustdoc.css @@ -97,6 +97,7 @@ h1, h2, h3:not(.impl):not(.method):not(.type):not(.tymethod), h4:not(.method):no h1.fqn { border-bottom: 1px dashed; margin-top: 0; + position: relative; } h2, h3:not(.impl):not(.method):not(.type):not(.tymethod), h4:not(.method):not(.type):not(.tymethod) { border-bottom: 1px solid; @@ -105,6 +106,7 @@ h3.impl, h3.method, h4.method, h3.type, h4.type { font-weight: 600; margin-top: 10px; margin-bottom: 10px; + position: relative; } h3.impl, h3.method, h3.type { margin-top: 15px; @@ -265,20 +267,39 @@ nav.sub { .content .out-of-band { font-size: 23px; - width: 40%; margin: 0px; padding: 0px; text-align: right; display: inline-block; + font-weight: normal; + position: absolute; + right: 0; +} + +h3.impl > .out-of-band { + font-size: 21px; +} + +h4 > code, h3 > code { + position: inherit; +} + +.in-band, code { + z-index: 5; } .content .in-band { - width: 60%; margin: 0px; padding: 0px; display: inline-block; } +#main { position: relative; } +#main > .since { + top: inherit; + font-family: "Fira Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; +} + .content table { border-spacing: 0 5px; border-collapse: separate; @@ -498,11 +519,13 @@ em.stab p { opacity: 0.65; } -span.since { - float: right; +.since { font-weight: normal; font-size: initial; color: grey; + position: absolute; + right: 0; + top: 0; } .variants_table { @@ -597,7 +620,19 @@ a.test-arrow { color: #999; } +.ghost { + display: none; +} + +.ghost + .since { + position: initial; + display: table-cell; +} +.since + .srclink { + display: table-cell; + padding-left: 10px; +} /* Media Queries */ diff --git a/src/librustdoc/html/static/styles/main.css b/src/librustdoc/html/static/styles/main.css index 5c073860f08ca..59b2ff7e3d649 100644 --- a/src/librustdoc/html/static/styles/main.css +++ b/src/librustdoc/html/static/styles/main.css @@ -26,6 +26,9 @@ 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 { + background-color: white; +} .docblock code { background-color: #F5F5F5;