From 5af8f1d8d7e78722eb7c89e3f0459ab81c3aebbc Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sun, 4 Nov 2018 21:35:09 +0100 Subject: [PATCH 1/2] Fixes primitive sidebar link generation --- src/librustdoc/html/render.rs | 87 +++++++++++++++++++++++------------ 1 file changed, 57 insertions(+), 30 deletions(-) diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index f560350d5105d..1ce7c9cfc8ac1 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -4234,13 +4234,30 @@ impl<'a> fmt::Display for Sidebar<'a> { } } -fn get_methods(i: &clean::Impl, for_deref: bool) -> Vec { +fn get_next_url(used_links: &mut FxHashSet, url: String) -> String { + if used_links.insert(url.clone()) { + return url; + } + let mut add = 1; + while used_links.insert(format!("{}-{}", url, add)) == false { + add += 1; + } + format!("{}-{}", url, add) +} + +fn get_methods( + i: &clean::Impl, + for_deref: bool, + used_links: &mut FxHashSet, +) -> Vec { i.items.iter().filter_map(|item| { match item.name { // Maybe check with clean::Visibility::Public as well? Some(ref name) if !name.is_empty() && item.visibility.is_some() && item.is_method() => { if !for_deref || should_render_item(item, false) { - Some(format!("{name}", name = name)) + Some(format!("{}", + get_next_url(used_links, format!("method.{}", name)), + name)) } else { None } @@ -4270,13 +4287,20 @@ fn sidebar_assoc_items(it: &clean::Item) -> String { let mut out = String::new(); let c = cache(); if let Some(v) = c.impls.get(&it.def_id) { - let ret = v.iter() - .filter(|i| i.inner_impl().trait_.is_none()) - .flat_map(|i| get_methods(i.inner_impl(), false)) - .collect::(); - if !ret.is_empty() { - out.push_str(&format!("Methods\ -
{}
", ret)); + let mut used_links = FxHashSet::default(); + + { + let used_links_bor = Rc::new(RefCell::new(&mut used_links)); + let ret = v.iter() + .filter(|i| i.inner_impl().trait_.is_none()) + .flat_map(move |i| get_methods(i.inner_impl(), + false, + &mut used_links_bor.borrow_mut())) + .collect::(); + if !ret.is_empty() { + out.push_str(&format!("Methods\ +
{}
", ret)); + } } if v.iter().any(|i| i.inner_impl().trait_.is_some()) { @@ -4301,7 +4325,9 @@ fn sidebar_assoc_items(it: &clean::Item) -> String { out.push_str(""); let ret = impls.iter() .filter(|i| i.inner_impl().trait_.is_none()) - .flat_map(|i| get_methods(i.inner_impl(), true)) + .flat_map(|i| get_methods(i.inner_impl(), + true, + &mut used_links)) .collect::(); out.push_str(&format!("
{}
", ret)); } @@ -4309,27 +4335,28 @@ fn sidebar_assoc_items(it: &clean::Item) -> String { } let format_impls = |impls: Vec<&Impl>| { let mut links = FxHashSet::default(); + impls.iter() - .filter_map(|i| { - let is_negative_impl = is_negative_impl(i.inner_impl()); - if let Some(ref i) = i.inner_impl().trait_ { - let i_display = format!("{:#}", i); - let out = Escape(&i_display); - let encoded = small_url_encode(&format!("{:#}", i)); - let generated = format!("{}{}", - encoded, - if is_negative_impl { "!" } else { "" }, - out); - if links.insert(generated.clone()) { - Some(generated) - } else { - None - } - } else { - None - } - }) - .collect::() + .filter_map(|i| { + let is_negative_impl = is_negative_impl(i.inner_impl()); + if let Some(ref i) = i.inner_impl().trait_ { + let i_display = format!("{:#}", i); + let out = Escape(&i_display); + let encoded = small_url_encode(&format!("{:#}", i)); + let generated = format!("{}{}", + encoded, + if is_negative_impl { "!" } else { "" }, + out); + if links.insert(generated.clone()) { + Some(generated) + } else { + None + } + } else { + None + } + }) + .collect::() }; let (synthetic, concrete): (Vec<&Impl>, Vec<&Impl>) = v From c746ecfa0190548f78afe62d4d8e4140ac4e4621 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 21 Nov 2018 23:21:50 +0100 Subject: [PATCH 2/2] Add test for sidebar link generation --- src/test/rustdoc/sidebar-link-generation.rs | 23 +++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 src/test/rustdoc/sidebar-link-generation.rs diff --git a/src/test/rustdoc/sidebar-link-generation.rs b/src/test/rustdoc/sidebar-link-generation.rs new file mode 100644 index 0000000000000..2482a7e82b9d7 --- /dev/null +++ b/src/test/rustdoc/sidebar-link-generation.rs @@ -0,0 +1,23 @@ +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![crate_name = "foo"] + +// @has foo/struct.SomeStruct.html '//*[@class="sidebar-links"]/a[@href="#method.some_fn-1"]' \ +// "some_fn" +pub struct SomeStruct { _inner: T } + +impl SomeStruct<()> { + pub fn some_fn(&self) {} +} + +impl SomeStruct { + pub fn some_fn(&self) {} +}