diff --git a/src/librustdoc/html/layout.rs b/src/librustdoc/html/layout.rs
index c34dcbbb672e9..b444993c1b5ec 100644
--- a/src/librustdoc/html/layout.rs
+++ b/src/librustdoc/html/layout.rs
@@ -4,6 +4,8 @@ use std::path::PathBuf;
use externalfiles::ExternalHtml;
+use html::render::SlashChecker;
+
#[derive(Clone)]
pub struct Layout {
pub logo: String,
@@ -176,16 +178,22 @@ pub fn render(
static_root_path = static_root_path,
root_path = page.root_path,
css_class = page.css_class,
- logo = if layout.logo.is_empty() {
- format!("\
- ",
- static_root_path=static_root_path,
- suffix=page.resource_suffix)
- } else {
- format!("\
- ",
- page.root_path, layout.krate,
- layout.logo)
+ logo = {
+ let p = format!("{}{}", page.root_path, layout.krate);
+ let p = SlashChecker(&p);
+ if layout.logo.is_empty() {
+ format!("\
+ ",
+ path=p,
+ static_root_path=static_root_path,
+ suffix=page.resource_suffix)
+ } else {
+ format!("\
+ ",
+ p,
+ layout.logo)
+ }
},
title = page.title,
description = page.description,
diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index c928edea75a2f..1014766dd905e 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -73,6 +73,18 @@ use minifier;
/// A pair of name and its optional document.
pub type NameDoc = (String, Option);
+pub struct SlashChecker<'a>(pub &'a str);
+
+impl<'a> Display for SlashChecker<'a> {
+ fn fmt(&self, f: &mut Formatter) -> fmt::Result {
+ if !self.0.ends_with("/") && !self.0.is_empty() {
+ write!(f, "{}/", self.0)
+ } else {
+ write!(f, "{}", self.0)
+ }
+ }
+}
+
/// Major driving force in all rustdoc rendering. This contains information
/// about where in the tree-like hierarchy rendering is occurring and controls
/// how the current page is being rendered.
@@ -1140,7 +1152,8 @@ themePicker.onblur = handleThemeButtonsBlur;
krates
.iter()
.map(|s| {
- format!("{}", s, s)
+ format!("{}",
+ SlashChecker(s), s)
})
.collect::());
try_err!(layout::render(&mut w, &cx.shared.layout,
@@ -2075,8 +2088,7 @@ impl Context {
let mut themes = self.shared.themes.clone();
let sidebar = "Settings
";
themes.push(PathBuf::from("settings.css"));
- let mut layout = self.shared.layout.clone();
- layout.krate = String::new();
+ let layout = self.shared.layout.clone();
try_err!(layout::render(&mut w, &layout,
&page, &sidebar, &settings,
self.shared.css_file_extension.is_some(),
@@ -2455,7 +2467,7 @@ impl<'a> fmt::Display for Item<'a> {
fn item_path(ty: ItemType, name: &str) -> String {
match ty {
- ItemType::Module => format!("{}/index.html", name),
+ ItemType::Module => format!("{}index.html", SlashChecker(name)),
_ => format!("{}.{}.html", ty.css_class(), name),
}
}
diff --git a/src/test/rustdoc/keyword.rs b/src/test/rustdoc/keyword.rs
index d3327ae7ae117..c721c024468dd 100644
--- a/src/test/rustdoc/keyword.rs
+++ b/src/test/rustdoc/keyword.rs
@@ -7,7 +7,7 @@
// @has foo/keyword.match.html '//a[@class="keyword"]' 'match'
// @has foo/keyword.match.html '//span[@class="in-band"]' 'Keyword match'
// @has foo/keyword.match.html '//section[@id="main"]//div[@class="docblock"]//p' 'this is a test!'
-// @!has foo/index.html '//a/@href' 'foo/index.html'
+// @has foo/index.html '//a/@href' '../foo/index.html'
// @!has foo/foo/index.html
// @!has-dir foo/foo
#[doc(keyword = "match")]