about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDirkjan Ochtman <dirkjan@ochtman.nl>2022-01-03 18:18:46 +0100
committerDirkjan Ochtman <dirkjan@ochtman.nl>2022-01-10 18:40:54 +0100
commit93a16cb7e2ee415f9b1a46165b297aa16b2a4fa0 (patch)
treea1deecaaf309dd19f532719aeba696e5281e7ce5
parent89b9f7b284aacc5f8613438b80e4dd7bdd10549e (diff)
downloadrust-93a16cb7e2ee415f9b1a46165b297aa16b2a4fa0.tar.gz
rust-93a16cb7e2ee415f9b1a46165b297aa16b2a4fa0.zip
Migrate rustdoc from Tera to Askama
See #84419.
-rw-r--r--Cargo.lock86
-rw-r--r--src/librustdoc/Cargo.toml2
-rw-r--r--src/librustdoc/html/layout.rs13
-rw-r--r--src/librustdoc/html/render/context.rs10
-rw-r--r--src/librustdoc/html/render/mod.rs1
-rw-r--r--src/librustdoc/html/render/print_item.rs15
-rw-r--r--src/librustdoc/html/render/templates.rs20
-rw-r--r--src/librustdoc/html/render/write_shared.rs9
-rw-r--r--src/librustdoc/html/sources.rs1
-rw-r--r--src/librustdoc/templates/STYLE.md (renamed from src/librustdoc/html/templates/STYLE.md)0
-rw-r--r--src/librustdoc/templates/page.html (renamed from src/librustdoc/html/templates/page.html)92
-rw-r--r--src/librustdoc/templates/print_item.html (renamed from src/librustdoc/html/templates/print_item.html)16
12 files changed, 130 insertions, 135 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 50a5d78731f..ef9f91fdb43 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -104,6 +104,47 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "5a2f58b0bb10c380af2b26e57212856b8c9a59e0925b4c20f4a174a49734eaf7"
 
 [[package]]
+name = "askama"
+version = "0.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4d8f355701c672c2ba3d718acbd213f740beea577cc4eae66accdffe15be1882"
+dependencies = [
+ "askama_derive",
+ "askama_escape",
+ "askama_shared",
+]
+
+[[package]]
+name = "askama_derive"
+version = "0.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "84704cab5b7ae0fd3a9f78ee5eb7b27f3749df445f04623db6633459ae283267"
+dependencies = [
+ "askama_shared",
+ "proc-macro2",
+ "syn",
+]
+
+[[package]]
+name = "askama_escape"
+version = "0.10.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9a1bb320f97e6edf9f756bf015900038e43c7700e059688e5724a928c8f3b8d5"
+
+[[package]]
+name = "askama_shared"
+version = "0.12.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dae03eebba55a2697a376e58b573a29fe36893157173ac8df312ad85f3c0e012"
+dependencies = [
+ "askama_escape",
+ "nom",
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
 name = "atty"
 version = "0.2.14"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1510,17 +1551,6 @@ dependencies = [
 ]
 
 [[package]]
-name = "globwalk"
-version = "0.8.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "93e3af942408868f6934a7b85134a3230832b9977cf66125df2f9edcfce4ddcc"
-dependencies = [
- "bitflags",
- "ignore",
- "walkdir",
-]
-
-[[package]]
 name = "gsgdt"
 version = "0.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2246,6 +2276,12 @@ dependencies = [
 ]
 
 [[package]]
+name = "minimal-lexical"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
+
+[[package]]
 name = "miniz_oxide"
 version = "0.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2305,6 +2341,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54"
 
 [[package]]
+name = "nom"
+version = "7.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1b1d11e1ef389c76fe5b81bcaf2ea32cf88b62bc494e19f493d0b30e7a930109"
+dependencies = [
+ "memchr",
+ "minimal-lexical",
+ "version_check",
+]
+
+[[package]]
 name = "ntapi"
 version = "0.3.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -4631,6 +4678,7 @@ name = "rustdoc"
 version = "0.0.0"
 dependencies = [
  "arrayvec",
+ "askama",
  "expect-test",
  "itertools 0.9.0",
  "minifier",
@@ -4642,7 +4690,6 @@ dependencies = [
  "serde_json",
  "smallvec",
  "tempfile",
- "tera",
  "tracing",
  "tracing-subscriber",
  "tracing-tree",
@@ -5188,21 +5235,6 @@ dependencies = [
 ]
 
 [[package]]
-name = "tera"
-version = "1.10.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "81060acb882480c8793782eb96bc86f5c83d2fc7175ad46c375c6956ef7afa62"
-dependencies = [
- "globwalk",
- "lazy_static",
- "pest",
- "pest_derive",
- "regex",
- "serde",
- "serde_json",
-]
-
-[[package]]
 name = "term"
 version = "0.6.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/src/librustdoc/Cargo.toml b/src/librustdoc/Cargo.toml
index a3cb982f277..5025342c1d6 100644
--- a/src/librustdoc/Cargo.toml
+++ b/src/librustdoc/Cargo.toml
@@ -8,6 +8,7 @@ path = "lib.rs"
 
 [dependencies]
 arrayvec = { version = "0.7", default-features = false }
+askama = { version = "0.11", default-features = false }
 pulldown-cmark = { version = "0.9", default-features = false }
 minifier = "0.0.41"
 rayon = "1.3.1"
@@ -20,7 +21,6 @@ regex = "1"
 rustdoc-json-types = { path = "../rustdoc-json-types" }
 tracing = "0.1"
 tracing-tree = "0.2.0"
-tera = { version = "1.10.0", default-features = false }
 
 [dependencies.tracing-subscriber]
 version = "0.3.3"
diff --git a/src/librustdoc/html/layout.rs b/src/librustdoc/html/layout.rs
index 3d3fa3aaeaa..1eba43d26b2 100644
--- a/src/librustdoc/html/layout.rs
+++ b/src/librustdoc/html/layout.rs
@@ -7,6 +7,7 @@ use crate::externalfiles::ExternalHtml;
 use crate::html::format::{Buffer, Print};
 use crate::html::render::{ensure_trailing_slash, StylePath};
 
+use askama::Template;
 use serde::Serialize;
 
 #[derive(Clone, Serialize)]
@@ -45,7 +46,8 @@ impl<'a> Page<'a> {
     }
 }
 
-#[derive(Serialize)]
+#[derive(Serialize, Template)]
+#[template(path = "page.html")]
 struct PageLayout<'a> {
     static_root_path: &'a str,
     page: &'a Page<'a>,
@@ -58,7 +60,6 @@ struct PageLayout<'a> {
 }
 
 crate fn render<T: Print, S: Print>(
-    templates: &tera::Tera,
     layout: &Layout,
     page: &Page<'_>,
     sidebar: S,
@@ -76,7 +77,7 @@ crate fn render<T: Print, S: Print>(
     let rustdoc_version = rustc_interface::util::version_str().unwrap_or("unknown version");
     let content = Buffer::html().to_display(t); // Note: This must happen before making the sidebar.
     let sidebar = Buffer::html().to_display(sidebar);
-    let teractx = tera::Context::from_serialize(PageLayout {
+    PageLayout {
         static_root_path,
         page,
         layout,
@@ -85,9 +86,9 @@ crate fn render<T: Print, S: Print>(
         content,
         krate_with_trailing_slash,
         rustdoc_version,
-    })
-    .unwrap();
-    templates.render("page.html", &teractx).unwrap()
+    }
+    .render()
+    .unwrap()
 }
 
 crate fn redirect(url: &str) -> String {
diff --git a/src/librustdoc/html/render/context.rs b/src/librustdoc/html/render/context.rs
index 2ae203e0d2f..9d7be783e85 100644
--- a/src/librustdoc/html/render/context.rs
+++ b/src/librustdoc/html/render/context.rs
@@ -15,7 +15,6 @@ use rustc_span::symbol::sym;
 
 use super::print_item::{full_path, item_path, print_item};
 use super::search_index::build_index;
-use super::templates;
 use super::write_shared::write_shared;
 use super::{
     collect_spans_and_sources, print_sidebar, settings, AllTypes, LinkFromSrc, NameDoc, StylePath,
@@ -118,8 +117,6 @@ crate struct SharedContext<'tcx> {
     /// the crate.
     redirections: Option<RefCell<FxHashMap<String, String>>>,
 
-    pub(crate) templates: tera::Tera,
-
     /// Correspondance map used to link types used in the source code pages to allow to click on
     /// links to jump to the type's definition.
     crate span_correspondance_map: FxHashMap<rustc_span::Span, LinkFromSrc>,
@@ -218,11 +215,10 @@ impl<'tcx> Context<'tcx> {
 
         if !self.render_redirect_pages {
             layout::render(
-                &self.shared.templates,
                 &self.shared.layout,
                 &page,
                 |buf: &mut _| print_sidebar(self, it, buf),
-                |buf: &mut _| print_item(self, &self.shared.templates, it, buf, &page),
+                |buf: &mut _| print_item(self, it, buf, &page),
                 &self.shared.style_files,
             )
         } else {
@@ -426,7 +422,6 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
         };
         let mut issue_tracker_base_url = None;
         let mut include_sources = true;
-        let templates = templates::load()?;
 
         // Crawl the crate attributes looking for attributes which control how we're
         // going to emit HTML
@@ -481,7 +476,6 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
             errors: receiver,
             redirections: if generate_redirect_map { Some(Default::default()) } else { None },
             show_type_layout,
-            templates,
             span_correspondance_map: matches,
             cache,
             call_locations,
@@ -577,7 +571,6 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
         };
         let all = self.shared.all.replace(AllTypes::new());
         let v = layout::render(
-            &self.shared.templates,
             &self.shared.layout,
             &page,
             sidebar,
@@ -599,7 +592,6 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
             .map(StylePath::basename)
             .collect::<Result<_, Error>>()?;
         let v = layout::render(
-            &self.shared.templates,
             &self.shared.layout,
             &page,
             sidebar,
diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs
index 2038e338186..fba8835e868 100644
--- a/src/librustdoc/html/render/mod.rs
+++ b/src/librustdoc/html/render/mod.rs
@@ -31,7 +31,6 @@ mod tests;
 mod context;
 mod print_item;
 mod span_map;
-mod templates;
 mod write_shared;
 
 crate use self::context::*;
diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs
index 9f2830ba542..29e03f7f65b 100644
--- a/src/librustdoc/html/render/print_item.rs
+++ b/src/librustdoc/html/render/print_item.rs
@@ -32,6 +32,7 @@ use crate::html::highlight;
 use crate::html::layout::Page;
 use crate::html::markdown::{HeadingOffset, MarkdownSummaryLine};
 
+use askama::Template;
 use serde::Serialize;
 
 const ITEM_TABLE_OPEN: &str = "<div class=\"item-table\">";
@@ -46,7 +47,8 @@ struct PathComponent<'a> {
     name: &'a str,
 }
 
-#[derive(Serialize)]
+#[derive(Serialize, Template)]
+#[template(path = "print_item.html")]
 struct ItemVars<'a> {
     page: &'a Page<'a>,
     static_root_path: &'a str,
@@ -58,13 +60,7 @@ struct ItemVars<'a> {
     src_href: Option<&'a str>,
 }
 
-pub(super) fn print_item(
-    cx: &Context<'_>,
-    templates: &tera::Tera,
-    item: &clean::Item,
-    buf: &mut Buffer,
-    page: &Page<'_>,
-) {
+pub(super) fn print_item(cx: &Context<'_>, item: &clean::Item, buf: &mut Buffer, page: &Page<'_>) {
     debug_assert!(!item.is_stripped());
     let typ = match *item.kind {
         clean::ModuleItem(_) => {
@@ -143,8 +139,7 @@ pub(super) fn print_item(
         src_href: src_href.as_deref(),
     };
 
-    let teractx = tera::Context::from_serialize(item_vars).unwrap();
-    let heading = templates.render("print_item.html", &teractx).unwrap();
+    let heading = item_vars.render().unwrap();
     buf.write_str(&heading);
 
     match *item.kind {
diff --git a/src/librustdoc/html/render/templates.rs b/src/librustdoc/html/render/templates.rs
deleted file mode 100644
index d1f18239447..00000000000
--- a/src/librustdoc/html/render/templates.rs
+++ /dev/null
@@ -1,20 +0,0 @@
-use std::error::Error as StdError;
-
-use crate::error::Error;
-
-pub(crate) fn load() -> Result<tera::Tera, Error> {
-    let mut templates = tera::Tera::default();
-
-    macro_rules! include_template {
-        ($file:literal, $fullpath:literal) => {
-            templates.add_raw_template($file, include_str!($fullpath)).map_err(|e| Error {
-                file: $file.into(),
-                error: format!("{}: {}", e, e.source().map(|e| e.to_string()).unwrap_or_default()),
-            })?
-        };
-    }
-
-    include_template!("page.html", "../templates/page.html");
-    include_template!("print_item.html", "../templates/print_item.html");
-    Ok(templates)
-}
diff --git a/src/librustdoc/html/render/write_shared.rs b/src/librustdoc/html/render/write_shared.rs
index 563f4ae7385..2e763dbd8fe 100644
--- a/src/librustdoc/html/render/write_shared.rs
+++ b/src/librustdoc/html/render/write_shared.rs
@@ -494,14 +494,7 @@ pub(super) fn write_shared(
                     })
                     .collect::<String>()
             );
-            let v = layout::render(
-                &cx.shared.templates,
-                &cx.shared.layout,
-                &page,
-                "",
-                content,
-                &cx.shared.style_files,
-            );
+            let v = layout::render(&cx.shared.layout, &page, "", content, &cx.shared.style_files);
             cx.shared.fs.write(dst, v)?;
         }
     }
diff --git a/src/librustdoc/html/sources.rs b/src/librustdoc/html/sources.rs
index 04c2b7a0c9a..bae04f2095a 100644
--- a/src/librustdoc/html/sources.rs
+++ b/src/librustdoc/html/sources.rs
@@ -203,7 +203,6 @@ impl SourceCollector<'_, '_> {
             static_extra_scripts: &[&format!("source-script{}", self.cx.shared.resource_suffix)],
         };
         let v = layout::render(
-            &self.cx.shared.templates,
             &self.cx.shared.layout,
             &page,
             "",
diff --git a/src/librustdoc/html/templates/STYLE.md b/src/librustdoc/templates/STYLE.md
index fff65e3b5ff..fff65e3b5ff 100644
--- a/src/librustdoc/html/templates/STYLE.md
+++ b/src/librustdoc/templates/STYLE.md
diff --git a/src/librustdoc/html/templates/page.html b/src/librustdoc/templates/page.html
index 5cade1b1a4c..e26d9856221 100644
--- a/src/librustdoc/html/templates/page.html
+++ b/src/librustdoc/templates/page.html
@@ -7,20 +7,20 @@
     <meta name="description" content="{{page.description}}"> {#- -#}
     <meta name="keywords" content="{{page.keywords}}"> {#- -#}
     <title>{{page.title}}</title> {#- -#}
-    <link rel="preload" as="font" type="font/woff2" crossorigin href="{{static_root_path | safe}}SourceSerif4-Regular.ttf.woff2"> {#- -#}
-    <link rel="preload" as="font" type="font/woff2" crossorigin href="{{static_root_path | safe}}FiraSans-Regular.woff2"> {#- -#}
-    <link rel="preload" as="font" type="font/woff2" crossorigin href="{{static_root_path | safe}}FiraSans-Medium.woff2"> {#- -#}
-    <link rel="preload" as="font" type="font/woff2" crossorigin href="{{static_root_path | safe}}SourceCodePro-Regular.ttf.woff2"> {#- -#}
-    <link rel="preload" as="font" type="font/woff2" crossorigin href="{{static_root_path | safe}}SourceSerif4-Bold.ttf.woff2"> {#- -#}
-    <link rel="preload" as="font" type="font/woff2" crossorigin href="{{static_root_path | safe}}SourceCodePro-Semibold.ttf.woff2"> {#- -#}
+    <link rel="preload" as="font" type="font/woff2" crossorigin href="{{static_root_path|safe}}SourceSerif4-Regular.ttf.woff2"> {#- -#}
+    <link rel="preload" as="font" type="font/woff2" crossorigin href="{{static_root_path|safe}}FiraSans-Regular.woff2"> {#- -#}
+    <link rel="preload" as="font" type="font/woff2" crossorigin href="{{static_root_path|safe}}FiraSans-Medium.woff2"> {#- -#}
+    <link rel="preload" as="font" type="font/woff2" crossorigin href="{{static_root_path|safe}}SourceCodePro-Regular.ttf.woff2"> {#- -#}
+    <link rel="preload" as="font" type="font/woff2" crossorigin href="{{static_root_path|safe}}SourceSerif4-Bold.ttf.woff2"> {#- -#}
+    <link rel="preload" as="font" type="font/woff2" crossorigin href="{{static_root_path|safe}}SourceCodePro-Semibold.ttf.woff2"> {#- -#}
     <link rel="stylesheet" type="text/css" {# -#}
-          href="{{static_root_path | safe}}normalize{{page.resource_suffix}}.css"> {#- -#}
+          href="{{static_root_path|safe}}normalize{{page.resource_suffix}}.css"> {#- -#}
     <link rel="stylesheet" type="text/css" {# -#}
-          href="{{static_root_path | safe}}rustdoc{{page.resource_suffix}}.css" {# -#}
+          href="{{static_root_path|safe}}rustdoc{{page.resource_suffix}}.css" {# -#}
           id="mainThemeStyle"> {#- -#}
     {%- for theme in themes -%}
         <link rel="stylesheet" type="text/css" {# -#}
-            href="{{static_root_path | safe}}{{theme}}{{page.resource_suffix}}.css" {# -#}
+            href="{{static_root_path|safe}}{{theme}}{{page.resource_suffix}}.css" {# -#}
         {%- if theme == "light" -%}
             id="themeStyle"
         {%- else -%}
@@ -29,41 +29,43 @@
         >
     {%- endfor -%}
     <script id="default-settings" {# -#}
-      {% for k, v in layout.default_settings %}
+      {% for (k, v) in layout.default_settings %}
         data-{{k}}="{{v}}"
       {%- endfor -%}
     ></script> {#- -#}
-    <script src="{{static_root_path | safe}}storage{{page.resource_suffix}}.js"></script> {#- -#}
-    <script src="{{page.root_path | safe}}crates{{page.resource_suffix}}.js"></script> {#- -#}
-    <script defer src="{{static_root_path | safe}}main{{page.resource_suffix}}.js"></script> {#- -#}
+    <script src="{{static_root_path|safe}}storage{{page.resource_suffix}}.js"></script> {#- -#}
+    <script src="{{page.root_path|safe}}crates{{page.resource_suffix}}.js"></script> {#- -#}
+    <script defer src="{{static_root_path|safe}}main{{page.resource_suffix}}.js"></script> {#- -#}
     {%- for script in page.static_extra_scripts -%}
-    <script defer src="{{static_root_path | safe}}{{script}}.js"></script> {#- -#}
+    <script defer src="{{static_root_path|safe}}{{script}}.js"></script> {#- -#}
     {% endfor %}
     {%- if layout.scrape_examples_extension -%}
-    <script defer src="{{page.root_path | safe}}scrape-examples{{page.resource_suffix}}.js"></script> {#- -#}
+    <script defer src="{{page.root_path|safe}}scrape-examples{{page.resource_suffix}}.js"></script> {#- -#}
     {%- endif -%}
     {%- for script in page.extra_scripts -%}
-    <script defer src="{{page.root_path | safe}}{{script}}.js"></script> {#- -#}
+    <script defer src="{{page.root_path|safe}}{{script}}.js"></script> {#- -#}
     {% endfor %}
     <noscript> {#- -#}
         <link rel="stylesheet" {# -#}
-           href="{{static_root_path | safe}}noscript{{page.resource_suffix}}.css"> {#- -#}
+           href="{{static_root_path|safe}}noscript{{page.resource_suffix}}.css"> {#- -#}
     </noscript> {#- -#}
-    {%- if layout.css_file_extension -%}
-        <link rel="stylesheet" type="text/css" {# -#}
-            href="{{static_root_path | safe}}theme{{page.resource_suffix}}.css"> {#- -#}
-    {%- endif -%}
-    {%- if layout.favicon -%}
+    {%- match layout.css_file_extension -%}
+        {%- when Some with (ext) -%}
+            <link rel="stylesheet" type="text/css" {# -#}
+                href="{{static_root_path|safe}}theme{{page.resource_suffix}}.css"> {#- -#}
+        {%- else -%}
+    {%- endmatch -%}
+    {%- if !layout.favicon.is_empty() -%}
         <link rel="shortcut icon" href="{{layout.favicon}}"> {#- -#}
     {%- else -%}
         <link rel="alternate icon" type="image/png" {# -#}
-            href="{{static_root_path | safe}}favicon-16x16{{page.resource_suffix}}.png"> {#- -#}
+            href="{{static_root_path|safe}}favicon-16x16{{page.resource_suffix}}.png"> {#- -#}
         <link rel="alternate icon" type="image/png" {# -#}
-            href="{{static_root_path | safe}}favicon-32x32{{page.resource_suffix}}.png"> {#- -#}
+            href="{{static_root_path|safe}}favicon-32x32{{page.resource_suffix}}.png"> {#- -#}
         <link rel="icon" type="image/svg+xml" {# -#}
-            href="{{static_root_path | safe}}favicon{{page.resource_suffix}}.svg"> {#- -#}
+            href="{{static_root_path|safe}}favicon{{page.resource_suffix}}.svg"> {#- -#}
     {%- endif -%}
-    {{- layout.external_html.in_header | safe -}}
+    {{- layout.external_html.in_header|safe -}}
 </head> {#- -#}
 <body class="rustdoc {{page.css_class}}"> {#- -#}
     <!--[if lte IE 11]> {#- -#}
@@ -71,35 +73,35 @@
         This old browser is unsupported and will most likely display funky things. {#- -#}
     </div> {#- -#}
     <![endif]--> {#- -#}
-    {{- layout.external_html.before_content | safe -}}
+    {{- layout.external_html.before_content|safe -}}
     <nav class="sidebar"> {#- -#}
         <div class="sidebar-menu" role="button">&#9776;</div> {#- -#}
-        <a class="sidebar-logo" href="{{page.root_path | safe}}{{krate_with_trailing_slash | safe}}index.html"> {#- -#}
+        <a class="sidebar-logo" href="{{page.root_path|safe}}{{krate_with_trailing_slash|safe}}index.html"> {#- -#}
             <div class="logo-container"> {#- -#}
-            {%- if layout.logo -%}
-                <img src="{{layout.logo}}" alt="logo"> {#- -#}
-            {%- else -%}
-                <img class="rust-logo" src="{{static_root_path | safe}}rust-logo{{page.resource_suffix}}.png" alt="logo"> {#- -#}
-            {%- endif -%}
+                {%- if !layout.logo.is_empty()  %}
+                    <img src="{{layout.logo}}" alt="logo"> {#- -#}
+                {%- else -%}
+                    <img class="rust-logo" src="{{static_root_path|safe}}rust-logo{{page.resource_suffix}}.png" alt="logo"> {#- -#}
+                {%- endif -%}
             </div>
         </a> {#- -#}
-        {{- sidebar | safe -}}
+        {{- sidebar|safe -}}
     </nav> {#- -#}
     <main> {#- -#}
         <div class="width-limiter"> {#- -#}
             <div class="sub-container"> {#- -#}
-                <a class="sub-logo-container" href="{{page.root_path | safe}}{{krate_with_trailing_slash | safe}}index.html"> {#- -#}
-                    {%- if layout.logo -%}
-                    <img src="{{layout.logo}}" alt="logo">
+                <a class="sub-logo-container" href="{{page.root_path|safe}}{{krate_with_trailing_slash|safe}}index.html"> {#- -#}
+                    {%- if !layout.logo.is_empty()  %}
+                        <img src="{{layout.logo}}" alt="logo"> {#- -#}
                     {%- else -%}
-                    <img class="rust-logo" src="{{static_root_path | safe}}rust-logo{{page.resource_suffix}}.png" alt="logo">
+                        <img class="rust-logo" src="{{static_root_path|safe}}rust-logo{{page.resource_suffix}}.png" alt="logo"> {#- -#}
                     {%- endif -%}
                 </a> {#- -#}
                 <nav class="sub"> {#- -#}
                     <div class="theme-picker"> {#- -#}
                         <button id="theme-picker" aria-label="Pick another theme!" aria-haspopup="menu" title="themes"> {#- -#}
                             <img width="18" height="18" alt="Pick another theme!" {# -#}
-                             src="{{static_root_path | safe}}brush{{page.resource_suffix}}.svg"> {#- -#}
+                             src="{{static_root_path|safe}}brush{{page.resource_suffix}}.svg"> {#- -#}
                         </button> {#- -#}
                         <div id="theme-choices" role="menu"></div> {#- -#}
                     </div> {#- -#}
@@ -115,23 +117,23 @@
                                     type="search"> {#- -#}
                             </div> {#- -#}
                             <button type="button" id="help-button" title="help">?</button> {#- -#}
-                            <a id="settings-menu" href="{{page.root_path | safe}}settings.html" title="settings"> {#- -#}
+                            <a id="settings-menu" href="{{page.root_path|safe}}settings.html" title="settings"> {#- -#}
                                 <img width="18" height="18" alt="Change settings" {# -#}
-                                     src="{{static_root_path | safe}}wheel{{page.resource_suffix}}.svg"> {#- -#}
+                                     src="{{static_root_path|safe}}wheel{{page.resource_suffix}}.svg"> {#- -#}
                             </a> {#- -#}
                         </div> {#- -#}
                     </form> {#- -#}
                 </nav> {#- -#}
             </div> {#- -#}
-            <section id="main-content" class="content">{{- content | safe -}}</section> {#- -#}
+            <section id="main-content" class="content">{{- content|safe -}}</section> {#- -#}
             <section id="search" class="content hidden"></section> {#- -#}
         </div> {#- -#}
     </main> {#- -#}
-    {{- layout.external_html.after_content | safe -}}
+    {{- layout.external_html.after_content|safe -}}
     <div id="rustdoc-vars" {# -#}
-         data-root-path="{{page.root_path | safe}}" {# -#}
+         data-root-path="{{page.root_path|safe}}" {# -#}
          data-current-crate="{{layout.krate}}" {# -#}
-         data-themes="{{themes | join(sep=",") }}" {# -#}
+         data-themes="{{themes|join(",") }}" {# -#}
          data-resource-suffix="{{page.resource_suffix}}" {# -#}
          data-rustdoc-version="{{rustdoc_version}}" {# -#}
     > {#- -#}
diff --git a/src/librustdoc/html/templates/print_item.html b/src/librustdoc/templates/print_item.html
index 09cd8513a64..c98c6db424a 100644
--- a/src/librustdoc/html/templates/print_item.html
+++ b/src/librustdoc/templates/print_item.html
@@ -4,23 +4,25 @@
             {{-typ-}}
             {#- The breadcrumbs of the item path, like std::string -#}
             {%- for component in path_components -%}
-            <a href="{{component.path | safe}}index.html">{{component.name}}</a>::<wbr>
+            <a href="{{component.path|safe}}index.html">{{component.name}}</a>::<wbr>
             {%- endfor -%}
             <a class="{{item_type}}" href="#">{{name}}</a> {#- -#}
             <button id="copy-path" onclick="copy_path(this)" title="Copy item path to clipboard"> {#- -#}
-                <img src="{{static_root_path | safe}}clipboard{{page.resource_suffix}}.svg" {# -#}
+                <img src="{{static_root_path|safe}}clipboard{{page.resource_suffix}}.svg" {# -#}
                     width="19" height="18" {# -#}
                     alt="Copy item path"> {#- -#}
             </button> {#- -#}
         </span> {#- -#}
     </h1> {#- -#}
     <span class="out-of-band"> {#- -#}
-        {% if stability_since_raw %}
-        {{- stability_since_raw | safe -}} · 
+        {% if !stability_since_raw.is_empty() %}
+        {{- stability_since_raw|safe -}} ·
         {% endif %}
-        {%- if src_href %}
-        <a class="srclink" href="{{src_href | safe}}" title="goto source code">source</a> ·
-        {% endif -%}
+        {%- match src_href -%}
+            {%- when Some with (href) -%}
+                <a class="srclink" href="{{href|safe}}" title="goto source code">source</a>
+            {%- else -%} ·
+        {%- endmatch -%}
         <a id="toggle-all-docs" href="javascript:void(0)" title="collapse all docs"> {#- -#}
             [<span class="inner">&#x2212;</span>] {#- -#}
         </a> {#- -#}