diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index b6cb0fbc76a..342c15855d2 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -503,28 +503,6 @@ crate enum HrefError { NotInExternalCache, } -// This mostly works with sequences of symbols, but sometimes the first item -// comes from a string, and in that case we want to trim any trailing `/`. -// `syms` can be empty. -crate fn join_with_slash(first: Option<&str>, syms: &[Symbol]) -> String { - // 64 bytes covers 99.9%+ of cases. - let mut s = String::with_capacity(64); - if let Some(first) = first { - s.push_str(first.trim_end_matches('/')); - if !syms.is_empty() { - s.push('/'); - } - } - if !syms.is_empty() { - s.push_str(&syms[0].as_str()); - for sym in &syms[1..] { - s.push('/'); - s.push_str(&sym.as_str()); - } - } - s -} - // Panics if `syms` is empty. crate fn join_with_double_colon(syms: &[Symbol]) -> String { // 64 bytes covers 99.9%+ of cases. diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index dacaeac78f2..eda637acfc5 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -26,12 +26,13 @@ use crate::formats::item_type::ItemType; use crate::formats::{AssocItemRender, Impl, RenderMode}; use crate::html::escape::Escape; use crate::html::format::{ - join_with_double_colon, join_with_slash, print_abi_with_space, print_constness_with_space, - print_where_clause, Buffer, PrintWithSpace, + join_with_double_colon, print_abi_with_space, print_constness_with_space, print_where_clause, + Buffer, PrintWithSpace, }; use crate::html::highlight; use crate::html::layout::Page; use crate::html::markdown::{HeadingOffset, MarkdownSummaryLine}; +use crate::html::url_parts_builder::UrlPartsBuilder; use askama::Template; @@ -854,20 +855,21 @@ fn item_trait(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Tra } } + let mut js_src_path: UrlPartsBuilder = std::iter::repeat("..") + .take(cx.current.len()) + .chain(std::iter::once("implementors")) + .collect(); + if it.def_id.is_local() { + js_src_path.extend(cx.current.iter().copied()); + } else { + let (ref path, _) = cache.external_paths[&it.def_id.expect_def_id()]; + js_src_path.extend(path[..path.len() - 1].iter().copied()); + } + js_src_path.push_fmt(format_args!("{}.{}.js", it.type_(), it.name.unwrap())); write!( w, - "", - root_path = vec![".."; cx.current.len()].join("/"), - path = if it.def_id.is_local() { - join_with_slash(None, &cx.current) - } else { - let (ref path, _) = cache.external_paths[&it.def_id.expect_def_id()]; - join_with_slash(None, &path[..path.len() - 1]) - }, - ty = it.type_(), - name = it.name.unwrap() + "", + src = js_src_path.finish(), ); }