about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/bootstrap/doc.rs4
-rw-r--r--src/librustdoc/config.rs4
-rw-r--r--src/librustdoc/html/render.rs27
-rw-r--r--src/librustdoc/lib.rs5
-rw-r--r--src/test/rustdoc/issue-19190.rs5
-rw-r--r--src/test/rustdoc/issue-35169-2.rs7
-rw-r--r--src/test/rustdoc/issue-35169.rs7
-rw-r--r--src/test/rustdoc/old-style-files.rs23
-rw-r--r--src/test/rustdoc/structfields.rs7
-rw-r--r--src/test/rustdoc/without-redirect.rs13
10 files changed, 77 insertions, 25 deletions
diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs
index eec193c21f5..0028997a7df 100644
--- a/src/bootstrap/doc.rs
+++ b/src/bootstrap/doc.rs
@@ -317,7 +317,8 @@ fn invoke_rustdoc(builder: &Builder, compiler: Compiler, target: Interned<String
         .arg("-o").arg(&out)
         .arg(&path)
         .arg("--markdown-css")
-        .arg("../rust.css");
+        .arg("../rust.css")
+        .arg("--generate-redirect-pages");
 
     builder.run(&mut cmd);
 }
@@ -491,6 +492,7 @@ impl Step for Std {
             cargo.arg("--")
                  .arg("--markdown-css").arg("rust.css")
                  .arg("--markdown-no-toc")
+                 .arg("--generate-redirect-pages")
                  .arg("--index-page").arg(&builder.src.join("src/doc/index.md"));
 
             builder.run(&mut cargo);
diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs
index 635d071b8e0..0ddf96695c4 100644
--- a/src/librustdoc/config.rs
+++ b/src/librustdoc/config.rs
@@ -192,6 +192,8 @@ pub struct RenderOptions {
     /// If false, the `select` element to have search filtering by crates on rendered docs
     /// won't be generated.
     pub generate_search_filter: bool,
+    /// Option (disabled by default) to generate files used by RLS and some other tools.
+    pub generate_redirect_pages: bool,
 }
 
 impl Options {
@@ -436,6 +438,7 @@ impl Options {
         let static_root_path = matches.opt_str("static-root-path");
         let generate_search_filter = !matches.opt_present("disable-per-crate-search");
         let persist_doctests = matches.opt_str("persist-doctests").map(PathBuf::from);
+        let generate_redirect_pages = matches.opt_present("generate-redirect-pages");
 
         let (lint_opts, describe_lints, lint_cap) = get_cmd_lint_options(matches, error_format);
 
@@ -480,6 +483,7 @@ impl Options {
                 markdown_css,
                 markdown_playground_url,
                 generate_search_filter,
+                generate_redirect_pages,
             }
         })
     }
diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index 4f237dc85a5..179ae56d9b6 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -33,7 +33,7 @@ use std::default::Default;
 use std::error;
 use std::fmt::{self, Display, Formatter, Write as FmtWrite};
 use std::ffi::OsStr;
-use std::fs::{self, File};
+use std::fs::{self, File, OpenOptions};
 use std::io::prelude::*;
 use std::io::{self, BufWriter, BufReader};
 use std::mem;
@@ -136,6 +136,8 @@ struct SharedContext {
     /// If false, the `select` element to have search filtering by crates on rendered docs
     /// won't be generated.
     pub generate_search_filter: bool,
+    /// Option disabled by default to generate files used by RLS and some other tools.
+    pub generate_redirect_pages: bool,
 }
 
 impl SharedContext {
@@ -504,6 +506,7 @@ pub fn run(mut krate: clean::Crate,
         resource_suffix,
         static_root_path,
         generate_search_filter,
+        generate_redirect_pages,
         ..
     } = options;
 
@@ -533,6 +536,7 @@ pub fn run(mut krate: clean::Crate,
         resource_suffix,
         static_root_path,
         generate_search_filter,
+        generate_redirect_pages,
     };
 
     // If user passed in `--playground-url` arg, we fill in crate name here
@@ -2229,6 +2233,27 @@ impl Context {
                 if !self.render_redirect_pages {
                     all.append(full_path(self, &item), &item_type);
                 }
+                if self.shared.generate_redirect_pages {
+                    // Redirect from a sane URL using the namespace to Rustdoc's
+                    // URL for the page.
+                    let redir_name = format!("{}.{}.html", name, item_type.name_space());
+                    let redir_dst = self.dst.join(redir_name);
+                    if let Ok(redirect_out) = OpenOptions::new().create_new(true)
+                                                                .write(true)
+                                                                .open(&redir_dst) {
+                        let mut redirect_out = BufWriter::new(redirect_out);
+                        try_err!(layout::redirect(&mut redirect_out, file_name), &redir_dst);
+                    }
+                     // If the item is a macro, redirect from the old macro URL (with !)
+                    // to the new one (without).
+                    if item_type == ItemType::Macro {
+                        let redir_name = format!("{}.{}!.html", item_type, name);
+                        let redir_dst = self.dst.join(redir_name);
+                        let redirect_out = try_err!(File::create(&redir_dst), &redir_dst);
+                        let mut redirect_out = BufWriter::new(redirect_out);
+                        try_err!(layout::redirect(&mut redirect_out, file_name), &redir_dst);
+                    }
+                }
             }
         }
         Ok(())
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index f4149b5f357..290f9586404 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -348,6 +348,11 @@ fn opts() -> Vec<RustcOptGroup> {
                        "Directory to persist doctest executables into",
                        "PATH")
         }),
+        stable("generate-redirect-pages", |o| {
+            o.optflag("",
+                      "generate-redirect-pages",
+                      "Generate extra pages to support legacy URLs and tool links")
+        }),
     ]
 }
 
diff --git a/src/test/rustdoc/issue-19190.rs b/src/test/rustdoc/issue-19190.rs
index 4d3b7622970..e023e79fcde 100644
--- a/src/test/rustdoc/issue-19190.rs
+++ b/src/test/rustdoc/issue-19190.rs
@@ -1,3 +1,5 @@
+// compile-flags:--generate-redirect-pages
+
 use std::ops::Deref;
 
 pub struct Foo;
@@ -13,6 +15,9 @@ impl Deref for Bar {
     fn deref(&self) -> &Foo { loop {} }
 }
 
+// @has issue_19190/Bar.t.html
 // @has issue_19190/struct.Bar.html
+// @has - '//*[@id="foo.v"]' 'fn foo(&self)'
 // @has - '//*[@id="method.foo"]' 'fn foo(&self)'
+// @!has - '//*[@id="static_foo.v"]' 'fn static_foo()'
 // @!has - '//*[@id="method.static_foo"]' 'fn static_foo()'
diff --git a/src/test/rustdoc/issue-35169-2.rs b/src/test/rustdoc/issue-35169-2.rs
index 7dea268ec02..33f7646ced6 100644
--- a/src/test/rustdoc/issue-35169-2.rs
+++ b/src/test/rustdoc/issue-35169-2.rs
@@ -24,10 +24,17 @@ impl DerefMut for Bar {
 }
 
 // @has issue_35169_2/struct.Bar.html
+// @has - '//*[@id="by_ref.v"]' 'fn by_ref(&self)'
 // @has - '//*[@id="method.by_ref"]' 'fn by_ref(&self)'
+// @has - '//*[@id="by_explicit_ref.v"]' 'fn by_explicit_ref(self: &Foo)'
 // @has - '//*[@id="method.by_explicit_ref"]' 'fn by_explicit_ref(self: &Foo)'
+// @has - '//*[@id="by_mut_ref.v"]' 'fn by_mut_ref(&mut self)'
 // @has - '//*[@id="method.by_mut_ref"]' 'fn by_mut_ref(&mut self)'
+// @has - '//*[@id="by_explicit_mut_ref.v"]' 'fn by_explicit_mut_ref(self: &mut Foo)'
 // @has - '//*[@id="method.by_explicit_mut_ref"]' 'fn by_explicit_mut_ref(self: &mut Foo)'
+// @!has - '//*[@id="by_explicit_box.v"]' 'fn by_explicit_box(self: Box<Foo>)'
 // @!has - '//*[@id="method.by_explicit_box"]' 'fn by_explicit_box(self: Box<Foo>)'
+// @!has - '//*[@id="by_explicit_self_box.v"]' 'fn by_explicit_self_box(self: Box<Self>)'
 // @!has - '//*[@id="method.by_explicit_self_box"]' 'fn by_explicit_self_box(self: Box<Self>)'
+// @!has - '//*[@id="static_foo.v"]' 'fn static_foo()'
 // @!has - '//*[@id="method.static_foo"]' 'fn static_foo()'
diff --git a/src/test/rustdoc/issue-35169.rs b/src/test/rustdoc/issue-35169.rs
index 883d5d0158d..04fffc40572 100644
--- a/src/test/rustdoc/issue-35169.rs
+++ b/src/test/rustdoc/issue-35169.rs
@@ -19,10 +19,17 @@ impl Deref for Bar {
 }
 
 // @has issue_35169/struct.Bar.html
+// @has - '//*[@id="by_ref.v"]' 'fn by_ref(&self)'
 // @has - '//*[@id="method.by_ref"]' 'fn by_ref(&self)'
+// @has - '//*[@id="by_explicit_ref.v"]' 'fn by_explicit_ref(self: &Foo)'
 // @has - '//*[@id="method.by_explicit_ref"]' 'fn by_explicit_ref(self: &Foo)'
+// @!has - '//*[@id="by_mut_ref.v"]' 'fn by_mut_ref(&mut self)'
 // @!has - '//*[@id="method.by_mut_ref"]' 'fn by_mut_ref(&mut self)'
+// @!has - '//*[@id="by_explicit_mut_ref.v"]' 'fn by_explicit_mut_ref(self: &mut Foo)'
 // @!has - '//*[@id="method.by_explicit_mut_ref"]' 'fn by_explicit_mut_ref(self: &mut Foo)'
+// @!has - '//*[@id="by_explicit_box.v"]' 'fn by_explicit_box(self: Box<Foo>)'
 // @!has - '//*[@id="method.by_explicit_box"]' 'fn by_explicit_box(self: Box<Foo>)'
+// @!has - '//*[@id="by_explicit_self_box.v"]' 'fn by_explicit_self_box(self: Box<Self>)'
 // @!has - '//*[@id="method.by_explicit_self_box"]' 'fn by_explicit_self_box(self: Box<Self>)'
+// @!has - '//*[@id="static_foo.v"]' 'fn static_foo()'
 // @!has - '//*[@id="method.static_foo"]' 'fn static_foo()'
diff --git a/src/test/rustdoc/old-style-files.rs b/src/test/rustdoc/old-style-files.rs
deleted file mode 100644
index fb6697e18fb..00000000000
--- a/src/test/rustdoc/old-style-files.rs
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2018 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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#![crate_name = "foo"]
-
-// @has foo/macro.bar.html
-// @!has foo/macro.bar!.html
-// @!has foo/bar.m.html
-#[macro_export]
-macro_rules! bar {
-    () => {}
-}
-
-// @has foo/struct.Bar.html
-// @!has foo/Bar.t.html
-pub struct Bar;
diff --git a/src/test/rustdoc/structfields.rs b/src/test/rustdoc/structfields.rs
index cd8957aa2ec..bfe116acffc 100644
--- a/src/test/rustdoc/structfields.rs
+++ b/src/test/rustdoc/structfields.rs
@@ -1,5 +1,8 @@
+// compile-flags:--generate-redirect-pages
+
 // @has structfields/Foo.t.html
 // @has - struct.Foo.html
+// @has structfields/struct.Foo.html
 pub struct Foo {
     // @has - //pre "pub a: ()"
     pub a: (),
@@ -13,6 +16,8 @@ pub struct Foo {
     pub d: usize,
 }
 
+// @has structfields/Bar.t.html
+// @has - struct.Bar.html
 // @has structfields/struct.Bar.html
 pub struct Bar {
     // @has - //pre "pub a: ()"
@@ -20,6 +25,8 @@ pub struct Bar {
     // @!has - //pre "// some fields omitted"
 }
 
+// @has structfields/Qux.t.html
+// @has - enum.Qux.html
 // @has structfields/enum.Qux.html
 pub enum Qux {
     Quz {
diff --git a/src/test/rustdoc/without-redirect.rs b/src/test/rustdoc/without-redirect.rs
new file mode 100644
index 00000000000..d473dd8f428
--- /dev/null
+++ b/src/test/rustdoc/without-redirect.rs
@@ -0,0 +1,13 @@
+#![crate_name = "foo"]
+
+// @has foo/macro.bar.html
+// @!has foo/macro.bar!.html
+// @!has foo/bar.m.html
+#[macro_export]
+macro_rules! bar {
+    () => {}
+}
+
+// @has foo/struct.Bar.html
+// @!has foo/Bar.t.html
+pub struct Bar;