diff options
| author | bors <bors@rust-lang.org> | 2016-03-11 04:38:04 -0800 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2016-03-11 04:38:04 -0800 |
| commit | aeb85a953322df7773095186e9762f3fe73375e2 (patch) | |
| tree | 81ea15e110932e2a990351a9bea602599c23cb6c | |
| parent | 40c85cd8aec5de06140252610ad4bdc352324e2c (diff) | |
| parent | 3e6fed3a7a3f783bf967f6c73455743848f31167 (diff) | |
| download | rust-aeb85a953322df7773095186e9762f3fe73375e2.tar.gz rust-aeb85a953322df7773095186e9762f3fe73375e2.zip | |
Auto merge of #32133 - alexcrichton:linkchecker, r=brson
Add a link validator to rustbuild This commit was originally targeted at just adding a link checking script to the rustbuild system. This ended up snowballing a bit to extend rustbuild to be amenable to various tools we have as part of the build system in general. There's a new `src/tools` directory which has a number of scripts/programs that are purely intended to be used as part of the build system and CI of this repository. This is currently inhabited by rustbook, the error index generator, and a new linkchecker script added as part of this PR. I suspect that more tools like compiletest, tidy scripts, snapshot scripts, etc will migrate their way into this directory over time. The commit which adds the error index generator shows the steps necessary to add new tools to the build system, namely: 1. New steps are defined for building the tool and running the tool 2. The dependencies are configured 3. The steps are implemented In terms of the link checker, these commits do a few things: * A new `src/tools/linkchecker` script is added. This will read an entire documentation tree looking for broken relative links (HTTP links aren't followed yet). * A large number of broken links throughout the documentation were fixed. Many of these were just broken when viewed from core as opposed to std, but were easily fixed. * A few rustdoc bugs here and there were fixed
62 files changed, 813 insertions, 301 deletions
diff --git a/mk/crates.mk b/mk/crates.mk index 1ecceb9280a..d8e0390504b 100644 --- a/mk/crates.mk +++ b/mk/crates.mk @@ -126,8 +126,8 @@ TOOL_DEPS_error_index_generator := rustdoc syntax serialize TOOL_SOURCE_compiletest := $(S)src/compiletest/compiletest.rs TOOL_SOURCE_rustdoc := $(S)src/driver/driver.rs TOOL_SOURCE_rustc := $(S)src/driver/driver.rs -TOOL_SOURCE_rustbook := $(S)src/rustbook/main.rs -TOOL_SOURCE_error_index_generator := $(S)src/error_index_generator/main.rs +TOOL_SOURCE_rustbook := $(S)src/tools/rustbook/main.rs +TOOL_SOURCE_error_index_generator := $(S)src/tools/error_index_generator/main.rs ONLY_RLIB_core := 1 ONLY_RLIB_libc := 1 diff --git a/src/bootstrap/Cargo.toml b/src/bootstrap/Cargo.toml index 8321f93c90f..0d334219b4f 100644 --- a/src/bootstrap/Cargo.toml +++ b/src/bootstrap/Cargo.toml @@ -15,6 +15,10 @@ path = "main.rs" name = "rustc" path = "rustc.rs" +[[bin]] +name = "rustdoc" +path = "rustdoc.rs" + [dependencies] build_helper = { path = "../build_helper" } cmake = "0.1.10" diff --git a/src/bootstrap/build/check.rs b/src/bootstrap/build/check.rs new file mode 100644 index 00000000000..19293e80217 --- /dev/null +++ b/src/bootstrap/build/check.rs @@ -0,0 +1,21 @@ +// Copyright 2016 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. + +use std::process::Command; + +use build::{Build, Compiler}; + +pub fn linkcheck(build: &Build, stage: u32, host: &str) { + println!("Linkcheck stage{} ({})", stage, host); + let compiler = Compiler::new(stage, host); + let linkchecker = build.tool(&compiler, "linkchecker"); + build.run(Command::new(&linkchecker) + .arg(build.out.join(host).join("doc"))); +} diff --git a/src/bootstrap/build/compile.rs b/src/bootstrap/build/compile.rs index fb0a840bfa2..0a293579cf6 100644 --- a/src/bootstrap/build/compile.rs +++ b/src/bootstrap/build/compile.rs @@ -16,7 +16,7 @@ use std::process::Command; use build_helper::output; use build::util::{exe, staticlib, libdir, mtime, is_dylib}; -use build::{Build, Compiler}; +use build::{Build, Compiler, Mode}; /// Build the standard library. /// @@ -39,9 +39,10 @@ pub fn std<'a>(build: &'a Build, stage: u32, target: &str, build_startup_objects(build, target, &libdir); - let out_dir = build.cargo_out(stage, &host, true, target); + let out_dir = build.cargo_out(stage, &host, Mode::Libstd, target); build.clear_if_dirty(&out_dir, &build.compiler_path(compiler)); - let mut cargo = build.cargo(stage, compiler, true, target, "build"); + let mut cargo = build.cargo(stage, compiler, Mode::Libstd, Some(target), + "build"); cargo.arg("--features").arg(build.std_features()) .arg("--manifest-path") .arg(build.src.join("src/rustc/std_shim/Cargo.toml")); @@ -71,7 +72,7 @@ pub fn std_link(build: &Build, compiler: &Compiler, host: &str) { let libdir = build.sysroot_libdir(stage, host, target); - let out_dir = build.cargo_out(stage, compiler.host, true, target); + let out_dir = build.cargo_out(stage, compiler.host, Mode::Libstd, target); // If we're linking one compiler host's output into another, then we weren't // called from the `std` method above. In that case we clean out what's @@ -135,19 +136,15 @@ pub fn rustc<'a>(build: &'a Build, stage: u32, target: &str, println!("Building stage{} compiler artifacts ({} -> {})", stage, host, target); - let out_dir = build.cargo_out(stage, &host, false, target); + let out_dir = build.cargo_out(stage, &host, Mode::Librustc, target); build.clear_if_dirty(&out_dir, &libstd_shim(build, stage, &host, target)); - let mut cargo = build.cargo(stage, compiler, false, target, "build"); - cargo.arg("--features").arg(build.rustc_features(stage)) + let mut cargo = build.cargo(stage, compiler, Mode::Librustc, Some(target), + "build"); + cargo.arg("--features").arg(build.rustc_features()) .arg("--manifest-path") .arg(build.src.join("src/rustc/Cargo.toml")); - // In stage0 we may not need to build as many executables - if stage == 0 { - cargo.arg("--bin").arg("rustc"); - } - // Set some configuration variables picked up by build scripts and // the compiler alike cargo.env("CFG_RELEASE", &build.release) @@ -200,14 +197,14 @@ pub fn rustc_link(build: &Build, compiler: &Compiler, host: &str) { let libdir = build.sysroot_libdir(stage, host, target); - let out_dir = build.cargo_out(stage, compiler.host, false, target); + let out_dir = build.cargo_out(stage, compiler.host, Mode::Librustc, target); add_to_sysroot(&out_dir, &libdir); } /// Cargo's output path for the standard library in a given stage, compiled /// by a particular compiler for the specified target. fn libstd_shim(build: &Build, stage: u32, host: &str, target: &str) -> PathBuf { - build.cargo_out(stage, host, true, target).join("libstd_shim.rlib") + build.cargo_out(stage, host, Mode::Libstd, target).join("libstd_shim.rlib") } fn compiler_file(compiler: &Path, file: &str) -> String { @@ -239,7 +236,8 @@ pub fn assemble_rustc(build: &Build, stage: u32, host: &str) { } } - let out_dir = build.cargo_out(stage - 1, &build.config.build, false, host); + let out_dir = build.cargo_out(stage - 1, &build.config.build, + Mode::Librustc, host); // Link the compiler binary itself into place let rustc = out_dir.join(exe("rustc", host)); @@ -298,3 +296,27 @@ fn add_to_sysroot(out_dir: &Path, sysroot_dst: &Path) { sysroot_dst.join(path.file_name().unwrap()))); } } + +/// Build a tool in `src/tools` +/// +/// This will build the specified tool with the specified `host` compiler in +/// `stage` into the normal cargo output directory. +pub fn tool(build: &Build, stage: u32, host: &str, tool: &str) { + println!("Building stage{} tool {} ({})", stage, tool, host); + + let compiler = Compiler::new(stage, host); + + // FIXME: need to clear out previous tool and ideally deps, may require + // isolating output directories or require a pseudo shim step to + // clear out all the info. + // + // Maybe when libstd is compiled it should clear out the rustc of the + // corresponding stage? + // let out_dir = build.cargo_out(stage, &host, Mode::Librustc, target); + // build.clear_if_dirty(&out_dir, &libstd_shim(build, stage, &host, target)); + + let mut cargo = build.cargo(stage, &compiler, Mode::Tool, None, "build"); + cargo.arg("--manifest-path") + .arg(build.src.join(format!("src/tools/{}/Cargo.toml", tool))); + build.run(&mut cargo); +} diff --git a/src/bootstrap/build/doc.rs b/src/bootstrap/build/doc.rs index 937a234bec8..51bf752e06d 100644 --- a/src/bootstrap/build/doc.rs +++ b/src/bootstrap/build/doc.rs @@ -8,12 +8,13 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use std::path::Path; use std::fs::{self, File}; use std::io::prelude::*; +use std::path::Path; +use std::process::Command; -use build::{Build, Compiler}; -use build::util::up_to_date; +use build::{Build, Compiler, Mode}; +use build::util::{up_to_date, cp_r}; pub fn rustbook(build: &Build, stage: u32, host: &str, name: &str, out: &Path) { t!(fs::create_dir_all(out)); @@ -69,7 +70,7 @@ pub fn standalone(build: &Build, stage: u32, host: &str, out: &Path) { } let html = out.join(filename).with_extension("html"); - let rustdoc = build.tool(&compiler, "rustdoc"); + let rustdoc = build.rustdoc(&compiler); if up_to_date(&path, &html) && up_to_date(&footer, &html) && up_to_date(&favicon, &html) && @@ -79,7 +80,7 @@ pub fn standalone(build: &Build, stage: u32, host: &str, out: &Path) { continue } - let mut cmd = build.tool_cmd(&compiler, "rustdoc"); + let mut cmd = Command::new(&rustdoc); cmd.arg("--html-after-content").arg(&footer) .arg("--html-before-content").arg(&version_info) .arg("--html-in-header").arg(&favicon) @@ -102,3 +103,52 @@ pub fn standalone(build: &Build, stage: u32, host: &str, out: &Path) { build.run(&mut cmd); } } + +pub fn std(build: &Build, stage: u32, host: &str, out: &Path) { + println!("Documenting stage{} std ({})", stage, host); + let compiler = Compiler::new(stage, host); + let out_dir = build.stage_out(stage, host, Mode::Libstd) + .join(host).join("doc"); + let rustdoc = build.rustdoc(&compiler); + + build.clear_if_dirty(&out_dir, &rustdoc); + + let mut cargo = build.cargo(stage, &compiler, Mode::Libstd, Some(host), + "doc"); + cargo.arg("--manifest-path") + .arg(build.src.join("src/rustc/std_shim/Cargo.toml")) + .arg("--features").arg(build.std_features()); + build.run(&mut cargo); + cp_r(&out_dir, out) +} + +pub fn rustc(build: &Build, stage: u32, host: &str, out: &Path) { + println!("Documenting stage{} compiler ({})", stage, host); + let compiler = Compiler::new(stage, host); + let out_dir = build.stage_out(stage, host, Mode::Librustc) + .join(host).join("doc"); + let rustdoc = build.rustdoc(&compiler); + if !up_to_date(&rustdoc, &out_dir.join("rustc/index.html")) { + t!(fs::remove_dir_all(&out_dir)); + } + let mut cargo = build.cargo(stage, &compiler, Mode::Librustc, Some(host), + "doc"); + cargo.arg("--manifest-path") + .arg(build.src.join("src/rustc/Cargo.toml")) + .arg("--features").arg(build.rustc_features()); + build.run(&mut cargo); + cp_r(&out_dir, out) +} + +pub fn error_index(build: &Build, stage: u32, host: &str, out: &Path) { + println!("Documenting stage{} error index ({})", stage, host); + let compiler = Compiler::new(stage, host); + let mut index = Command::new(build.tool(&compiler, "error_index_generator")); + index.arg("html"); + index.arg(out.join("error-index.html")); + + // FIXME: shouldn't have to pass this env var + index.env("CFG_BUILD", &build.config.build); + + build.run(&mut index); +} diff --git a/src/bootstrap/build/mod.rs b/src/bootstrap/build/mod.rs index 98d821b8b90..058f27c33f6 100644 --- a/src/bootstrap/build/mod.rs +++ b/src/bootstrap/build/mod.rs @@ -30,6 +30,7 @@ macro_rules! t { mod cc; mod channel; +mod check; mod clean; mod compile; mod config; @@ -83,6 +84,12 @@ pub struct Build { compiler_rt_built: RefCell<HashMap<String, PathBuf>>, } +pub enum Mode { + Libstd, + Librustc, + Tool, +} + impl Build { pub fn new(flags: Flags, config: Config) -> Build { let cwd = t!(env::current_dir()); @@ -165,6 +172,16 @@ impl Build { Rustc { stage } => { compile::assemble_rustc(self, stage, target.target); } + ToolLinkchecker { stage } => { + compile::tool(self, stage, target.target, "linkchecker"); + } + ToolRustbook { stage } => { + compile::tool(self, stage, target.target, "rustbook"); + } + ToolErrorIndex { stage } => { + compile::tool(self, stage, target.target, + "error_index_generator"); + } DocBook { stage } => { doc::rustbook(self, stage, target.target, "book", &doc_out); } @@ -179,7 +196,22 @@ impl Build { DocStandalone { stage } => { doc::standalone(self, stage, target.target, &doc_out); } - Doc { .. } => {} // pseudo-step + DocStd { stage } => { + doc::std(self, stage, target.target, &doc_out); + } + DocRustc { stage } => { + doc::rustc(self, stage, target.target, &doc_out); + } + DocErrorIndex { stage } => { + doc::error_index(self, stage, target.target, &doc_out); + } + + CheckLinkcheck { stage } => { + check::linkcheck(self, stage, target.target); + } + + Doc { .. } | // pseudo-steps + Check { .. } => {} } } } @@ -230,14 +262,17 @@ impl Build { /// Cargo for the specified stage, whether or not the standard library is /// being built, and using the specified compiler targeting `target`. // FIXME: aren't stage/compiler duplicated? - fn cargo(&self, stage: u32, compiler: &Compiler, is_std: bool, - target: &str, cmd: &str) -> Command { + fn cargo(&self, + stage: u32, + compiler: &Compiler, + mode: Mode, + target: Option<&str>, + cmd: &str) -> Command { let mut cargo = Command::new(&self.cargo); let host = compiler.host; - let out_dir = self.stage_out(stage, host, is_std); + let out_dir = self.stage_out(stage, host, mode); cargo.env("CARGO_TARGET_DIR", out_dir) .arg(cmd) - .arg("--target").arg(target) .arg("-j").arg(self.jobs().to_string()); // Customize the compiler we're running. Specify the compiler to cargo @@ -254,24 +289,29 @@ impl Build { .env("RUSTC_SNAPSHOT", &self.rustc) .env("RUSTC_SYSROOT", self.sysroot(stage, host)) .env("RUSTC_SNAPSHOT_LIBDIR", self.rustc_snapshot_libdir()) - .env("RUSTC_FLAGS", self.rustc_flags(target).join(" ")) .env("RUSTC_RPATH", self.config.rust_rpath.to_string()) - .env("RUSTDOC", self.tool(compiler, "rustdoc")); - - // Specify some variuos options for build scripts used throughout the - // build. - // - // FIXME: the guard against msvc shouldn't need to be here - if !target.contains("msvc") { - cargo.env(format!("CC_{}", target), self.cc(target)) - .env(format!("AR_{}", target), self.ar(target)) - .env(format!("CFLAGS_{}", target), self.cflags(target)); - } + .env("RUSTDOC", self.out.join("bootstrap/debug/rustdoc")) + .env("RUSTDOC_REAL", self.rustdoc(compiler)); + + if let Some(target) = target { + cargo.env("RUSTC_FLAGS", self.rustc_flags(target).join(" ")); + cargo.arg("--target").arg(target); + + // Specify some various options for build scripts used throughout + // the build. + // + // FIXME: the guard against msvc shouldn't need to be here + if !target.contains("msvc") { + cargo.env(format!("CC_{}", target), self.cc(target)) + .env(format!("AR_{}", target), self.ar(target)) + .env(format!("CFLAGS_{}", target), self.cflags(target)); + } - // Environment variables *required* needed throughout the build - // - // FIXME: should update code to not require this env vars - cargo.env("CFG_COMPILER_HOST_TRIPLE", target); + // Environment variables *required* needed throughout the build + // + // FIXME: should update code to not require this env vars + cargo.env("CFG_COMPILER_HOST_TRIPLE", target); + } if self.config.verbose || self.flags.verbose { cargo.arg("-v"); @@ -293,17 +333,24 @@ impl Build { } } - /// Get the specified tool next to the specified compiler + /// Get the specified tool built by the specified compiler fn tool(&self, compiler: &Compiler, tool: &str) -> PathBuf { - if compiler.is_snapshot(self) { - assert!(tool == "rustdoc", "no tools other than rustdoc in stage0"); + self.stage_out(compiler.stage, compiler.host, Mode::Tool) + .join(self.cargo_dir()) + .join(exe(tool, compiler.host)) + } + + /// Get the `rustdoc` executable next to the specified compiler + fn rustdoc(&self, compiler: &Compiler) -> PathBuf { + let root = if compiler.is_snapshot(self) { let mut rustdoc = self.rustc.clone(); rustdoc.pop(); - rustdoc.push(exe("rustdoc", &self.config.build)); - return rustdoc - } - let (stage, host) = (compiler.stage, compiler.host); - self.cargo_out(stage - 1, host, false, host).join(exe(tool, host)) + rustdoc + } else { + let (stage, host) = (compiler.stage, compiler.host); + self.cargo_out(stage - 1, host, Mode::Librustc, host) + }; + root.join(exe("rustdoc", compiler.host)) } /// Get a `Command` which is ready to run `tool` in `stage` built for @@ -314,8 +361,8 @@ impl Build { let host = compiler.host; let stage = compiler.stage; let paths = vec![ - self.cargo_out(stage - 1, host, true, host).join("deps"), - self.cargo_out(stage - 1, host, false, host).join("deps"), + self.cargo_out(stage, host, Mode::Libstd, host).join("deps"), + self.cargo_out(stage, host, Mode::Librustc, host).join("deps"), ]; add_lib_path(paths, &mut cmd); return cmd @@ -339,15 +386,11 @@ impl Build { } /// Get the space-separated set of activated features for the compiler. - fn rustc_features(&self, stage: u32) -> String { + fn rustc_features(&self) -> String { let mut features = String::new(); if self.config.use_jemalloc { features.push_str(" jemalloc"); } - if stage > 0 { - features.push_str(" rustdoc"); - features.push_str(" rustbook"); - } return features } @@ -359,7 +402,7 @@ impl Build { fn sysroot(&self, stage: u32, host: &str) -> PathBuf { if stage == 0 { - self.stage_out(stage, host, false) + self.stage_out(stage, host, Mode::Librustc) } else { self.out.join(host).join(format!("stage{}", stage)) } @@ -373,19 +416,21 @@ impl Build { /// Returns the root directory for all output generated in a particular /// stage when running with a particular host compiler. /// - /// The `is_std` flag indicates whether the root directory is for the - /// bootstrap of the standard library or for the compiler. - fn stage_out(&self, stage: u32, host: &str, is_std: bool) -> PathBuf { - self.out.join(host) - .join(format!("stage{}{}", stage, if is_std {"-std"} else {"-rustc"})) + /// The mode indicates what the root directory is for. + fn stage_out(&self, stage: u32, host: &str, mode: Mode) -> PathBuf { + let suffix = match mode { + Mode::Libstd => "-std", + _ => "-rustc", + }; + self.out.join(host).join(format!("stage{}{}", stage, suffix)) } /// Returns the root output directory for all Cargo output in a given stage, /// running a particular comipler, wehther or not we're building the /// standard library, and targeting the specified architecture. - fn cargo_out(&self, stage: u32, host: &str, is_std: bool, + fn cargo_out(&self, stage: u32, host: &str, mode: Mode, target: &str) -> PathBuf { - self.stage_out(stage, host, is_std).join(target).join(self.cargo_dir()) + self.stage_out(stage, host, mode).join(target).join(self.cargo_dir()) } /// Root output directory for LLVM compiled for `target` diff --git a/src/bootstrap/build/step.rs b/src/bootstrap/build/step.rs index ba0095ce849..720ba4fd209 100644 --- a/src/bootstrap/build/step.rs +++ b/src/bootstrap/build/step.rs @@ -45,6 +45,11 @@ macro_rules! targets { host: &'a str }), + // Various tools that we can build as part of the build. + (tool_linkchecker, ToolLinkchecker { stage: u32 }), + (tool_rustbook, ToolRustbook { stage: u32 }), + (tool_error_index, ToolErrorIndex { stage: u32 }), + // Steps for long-running native builds. Ideally these wouldn't // actually exist and would be part of build scripts, but for now // these are here. @@ -53,11 +58,23 @@ macro_rules! targets { // with braces are unstable so we just pick something that works. (llvm, Llvm { _dummy: () }), (compiler_rt, CompilerRt { _dummy: () }), + + // Steps for various pieces of documentation that we can generate, + // the 'doc' step is just a pseudo target to depend on a bunch of + // others. (doc, Doc { stage: u32 }), (doc_book, DocBook { stage: u32 }), (doc_nomicon, DocNomicon { stage: u32 }), (doc_style, DocStyle { stage: u32 }), (doc_standalone, DocStandalone { stage: u32 }), + (doc_std, DocStd { stage: u32 }), + (doc_rustc, DocRustc { stage: u32 }), + (doc_error_index, DocErrorIndex { stage: u32 }), + + // Steps for running tests. The 'check' target is just a pseudo + // target to depend on a bunch of others. + (check, Check { stage: u32, compiler: Compiler<'a> }), + (check_linkcheck, CheckLinkcheck { stage: u32 }), } } } @@ -158,25 +175,37 @@ fn add_steps<'a>(build: &'a Build, host: &Step<'a>, target: &Step<'a>, targets: &mut Vec<Step<'a>>) { + struct Context<'a> { + stage: u32, + compiler: Compiler<'a>, + _dummy: (), + host: &'a str, + } for step in build.flags.step.iter() { - let compiler = host.target(&build.config.build).compiler(stage); - match &step[..] { - "libstd" => targets.push(target.libstd(stage, compiler)), - "librustc" => targets.push(target.librustc(stage, compiler)), - "libstd-link" => targets.push(target.libstd_link(stage, compiler, - host.target)), - "librustc-link" => targets.push(target.librustc_link(stage, compiler, - host.target)), - "rustc" => targets.push(host.rustc(stage)), - "llvm" => targets.push(target.llvm(())), - "compiler-rt" => targets.push(target.compiler_rt(())), - "doc-style" => targets.push(host.doc_style(stage)), - "doc-standalone" => targets.push(host.doc_standalone(stage)), - "doc-nomicon" => targets.push(host.doc_nomicon(stage)), - "doc-book" => targets.push(host.doc_book(stage)), - "doc" => targets.push(host.doc(stage)), - _ => panic!("unknown build target: `{}`", step), + + // The macro below insists on hygienic access to all local variables, so + // we shove them all in a struct and subvert hygiene by accessing struct + // fields instead, + let cx = Context { + stage: stage, + compiler: host.target(&build.config.build).compiler(stage), + _dummy: (), + host: host.target, + }; + macro_rules! add_step { + ($(($short:ident, $name:ident { $($arg:ident: $t:ty),* }),)*) => ({$( + let name = stringify!($short).replace("_", "-"); + if &step[..] == &name[..] { + targets.push(target.$short($(cx.$arg),*)); + continue + } + drop(name); + )*}) } + + targets!(add_step); + + panic!("unknown step: {}", step); } } @@ -230,15 +259,42 @@ impl<'a> Step<'a> { vec![self.llvm(()).target(&build.config.build)] } Source::Llvm { _dummy } => Vec::new(), + Source::DocStd { stage } => { + vec![self.libstd(stage, self.compiler(stage))] + } Source::DocBook { stage } | Source::DocNomicon { stage } | - Source::DocStyle { stage } | + Source::DocStyle { stage } => { + vec![self.tool_rustbook(stage)] + } + Source::DocErrorIndex { stage } => { + vec![self.tool_error_index(stage)] + } Source::DocStandalone { stage } => { vec![self.rustc(stage)] } + Source::DocRustc { stage } => { + vec![self.doc_std(stage)] + } Source::Doc { stage } => { vec![self.doc_book(stage), self.doc_nomicon(stage), - self.doc_style(stage), self.doc_standalone(stage)] + self.doc_style(stage), self.doc_standalone(stage), + self.doc_std(stage), + self.doc_error_index(stage)] + } + Source::Check { stage, compiler: _ } => { + vec![self.check_linkcheck(stage)] + } + Source::CheckLinkcheck { stage } => { + vec![self.tool_linkchecker(stage), self.doc(stage)] + } + + Source::ToolLinkchecker { stage } => { + vec![self.libstd(stage, self.compiler(stage))] + } + Source::ToolErrorIndex { stage } | + Source::ToolRustbook { stage } => { + vec![self.librustc(stage, self.compiler(stage))] } } } diff --git a/src/bootstrap/build/util.rs b/src/bootstrap/build/util.rs index 6c700671f11..35d22ee5d26 100644 --- a/src/bootstrap/build/util.rs +++ b/src/bootstrap/build/util.rs @@ -30,7 +30,6 @@ pub fn mtime(path: &Path) -> FileTime { }).unwrap_or(FileTime::zero()) } -#[allow(dead_code)] // this will be used soon pub fn cp_r(src: &Path, dst: &Path) { for f in t!(fs::read_dir(src)) { let f = t!(f); diff --git a/src/bootstrap/mk/Makefile.in b/src/bootstrap/mk/Makefile.in index fa3dee2f358..7d793002149 100644 --- a/src/bootstrap/mk/Makefile.in +++ b/src/bootstrap/mk/Makefile.in @@ -36,3 +36,5 @@ book: $(Q)$(BOOTSTRAP) --step doc-book standalone-docs: $(Q)$(BOOTSTRAP) --step doc-standalone +check: + $(Q)$(BOOTSTRAP) --step check diff --git a/src/bootstrap/rustc.rs b/src/bootstrap/rustc.rs index 4e9d6da9157..d403d76bb14 100644 --- a/src/bootstrap/rustc.rs +++ b/src/bootstrap/rustc.rs @@ -8,6 +8,23 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +//! Shim which is passed to Cargo as "rustc" when running the bootstrap. +//! +//! This shim will take care of some various tasks that our build process +//! requires that Cargo can't quite do through normal configuration: +//! +//! 1. When compiling build scripts and build dependencies, we need a guaranteed +//! full standard library available. The only compiler which actually has +//! this is the snapshot, so we detect this situation and always compile with +//! the snapshot compiler. +//! 2. We pass a bunch of `--cfg` and other flags based on what we're compiling +//! (and this slightly differs based on a whether we're using a snapshot or +//! not), so we do that all here. +//! +//! This may one day be replaced by RUSTFLAGS, but the dynamic nature of +//! switching compilers for the bootstrap and for build scripts will probably +//! never get replaced. + extern crate bootstrap; use std::env; diff --git a/src/bootstrap/rustdoc.rs b/src/bootstrap/rustdoc.rs new file mode 100644 index 00000000000..8c618196113 --- /dev/null +++ b/src/bootstrap/rustdoc.rs @@ -0,0 +1,31 @@ +// Copyright 2016 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. + +//! Shim which is passed to Cargo as "rustdoc" when running the bootstrap. +//! +//! See comments in `src/bootstrap/rustc.rs` for more information. + +use std::env; +use std::process::Command; + +fn main() { + let args = env::args_os().skip(1).collect::<Vec<_>>(); + let rustdoc = env::var_os("RUSTDOC_REAL").unwrap(); + + let mut cmd = Command::new(rustdoc); + cmd.args(&args) + .arg("--cfg").arg(format!("stage{}", env::var("RUSTC_STAGE").unwrap())) + .arg("--cfg").arg("dox"); + std::process::exit(match cmd.status() { + Ok(s) => s.code().unwrap_or(1), + Err(e) => panic!("\n\nfailed to run {:?}: {}\n\n", cmd, e), + }) +} + diff --git a/src/doc/book/choosing-your-guarantees.md b/src/doc/book/choosing-your-guarantees.md index f2b92e6dec4..50350213074 100644 --- a/src/doc/book/choosing-your-guarantees.md +++ b/src/doc/book/choosing-your-guarantees.md @@ -204,7 +204,7 @@ borrow checker. Generally we know that such mutations won't happen in a nested f to check. For large, complicated programs, it becomes useful to put some things in `RefCell`s to make things -simpler. For example, a lot of the maps in [the `ctxt` struct][ctxt] in the Rust compiler internals +simpler. For example, a lot of the maps in the `ctxt` struct in the Rust compiler internals are inside this wrapper. These are only modified once (during creation, which is not right after initialization) or a couple of times in well-separated places. However, since this struct is pervasively used everywhere, juggling mutable and immutable pointers would be hard (perhaps @@ -235,7 +235,6 @@ At runtime each borrow causes a modification/check of the refcount. [cell-mod]: ../std/cell/ [cell]: ../std/cell/struct.Cell.html [refcell]: ../std/cell/struct.RefCell.html -[ctxt]: ../rustc/middle/ty/struct.ctxt.html # Synchronous types diff --git a/src/doc/book/compiler-plugins.md b/src/doc/book/compiler-plugins.md index 800be13a243..1af05bfea19 100644 --- a/src/doc/book/compiler-plugins.md +++ b/src/doc/book/compiler-plugins.md @@ -8,12 +8,12 @@ extend the compiler's behavior with new syntax extensions, lint checks, etc. A plugin is a dynamic library crate with a designated *registrar* function that registers extensions with `rustc`. Other crates can load these extensions using the crate attribute `#![plugin(...)]`. See the -[`rustc_plugin`](../rustc_plugin/index.html) documentation for more about the +`rustc_plugin` documentation for more about the mechanics of defining and loading a plugin. If present, arguments passed as `#![plugin(foo(... args ...))]` are not interpreted by rustc itself. They are provided to the plugin through the -`Registry`'s [`args` method](../rustc_plugin/registry/struct.Registry.html#method.args). +`Registry`'s `args` method. In the vast majority of cases, a plugin should *only* be used through `#![plugin]` and not through an `extern crate` item. Linking a plugin would @@ -30,7 +30,7 @@ of a library. Plugins can extend Rust's syntax in various ways. One kind of syntax extension is the procedural macro. These are invoked the same way as [ordinary macros](macros.html), but the expansion is performed by arbitrary Rust -code that manipulates [syntax trees](../syntax/ast/index.html) at +code that manipulates syntax trees at compile time. Let's write a plugin @@ -120,11 +120,8 @@ The advantages over a simple `fn(&str) -> u32` are: In addition to procedural macros, you can define new [`derive`](../reference.html#derive)-like attributes and other kinds of -extensions. See -[`Registry::register_syntax_extension`](../rustc_plugin/registry/struct.Registry.html#method.register_syntax_extension) -and the [`SyntaxExtension` -enum](https://doc.rust-lang.org/syntax/ext/base/enum.SyntaxExtension.html). For -a more involved macro example, see +extensions. See `Registry::register_syntax_extension` and the `SyntaxExtension` +enum. For a more involved macro example, see [`regex_macros`](https://github.com/rust-lang/regex/blob/master/regex_macros/src/lib.rs). @@ -132,7 +129,7 @@ a more involved macro example, see Some of the [macro debugging tips](macros.html#debugging-macro-code) are applicable. -You can use [`syntax::parse`](../syntax/parse/index.html) to turn token trees into +You can use `syntax::parse` to turn token trees into higher-level syntax elements like expressions: ```ignore @@ -148,30 +145,21 @@ Looking through [`libsyntax` parser code](https://github.com/rust-lang/rust/blob/master/src/libsyntax/parse/parser.rs) will give you a feel for how the parsing infrastructure works. -Keep the [`Span`s](../syntax/codemap/struct.Span.html) of -everything you parse, for better error reporting. You can wrap -[`Spanned`](../syntax/codemap/struct.Spanned.html) around -your custom data structures. - -Calling -[`ExtCtxt::span_fatal`](../syntax/ext/base/struct.ExtCtxt.html#method.span_fatal) -will immediately abort compilation. It's better to instead call -[`ExtCtxt::span_err`](../syntax/ext/base/struct.ExtCtxt.html#method.span_err) -and return -[`DummyResult`](../syntax/ext/base/struct.DummyResult.html), -so that the compiler can continue and find further errors. - -To print syntax fragments for debugging, you can use -[`span_note`](../syntax/ext/base/struct.ExtCtxt.html#method.span_note) together -with -[`syntax::print::pprust::*_to_string`](https://doc.rust-lang.org/syntax/print/pprust/index.html#functions). - -The example above produced an integer literal using -[`AstBuilder::expr_usize`](../syntax/ext/build/trait.AstBuilder.html#tymethod.expr_usize). +Keep the `Span`s of everything you parse, for better error reporting. You can +wrap `Spanned` around your custom data structures. + +Calling `ExtCtxt::span_fatal` will immediately abort compilation. It's better to +instead call `ExtCtxt::span_err` and return `DummyResult` so that the compiler +can continue and find further errors. + +To print syntax fragments for debugging, you can use `span_note` together with +`syntax::print::pprust::*_to_string`. + +The example above produced an integer literal using `AstBuilder::expr_usize`. As an alternative to the `AstBuilder` trait, `libsyntax` provides a set of -[quasiquote macros](../syntax/ext/quote/index.html). They are undocumented and -very rough around the edges. However, the implementation may be a good -starting point for an improved quasiquote as an ordinary plugin library. +quasiquote macros. They are undocumented and very rough around the edges. +However, the implementation may be a good starting point for an improved +quasiquote as an ordinary plugin library. # Lint plugins @@ -239,12 +227,11 @@ foo.rs:4 fn lintme() { } The components of a lint plugin are: -* one or more `declare_lint!` invocations, which define static - [`Lint`](../rustc/lint/struct.Lint.html) structs; +* one or more `declare_lint!` invocations, which define static `Lint` structs; * a struct holding any state needed by the lint pass (here, none); -* a [`LintPass`](../rustc/lint/trait.LintPass.html) +* a `LintPass` implementation defining how to check each syntax element. A single `LintPass` may call `span_lint` for several different `Lint`s, but should register them all through the `get_lints` method. diff --git a/src/doc/guide-plugins.md b/src/doc/guide-plugins.md index d6495d02e11..742433b99ac 100644 --- a/src/doc/guide-plugins.md +++ b/src/doc/guide-plugins.md @@ -1,4 +1,4 @@ % The (old) Rust Compiler Plugins Guide This content has moved into -[the Rust Programming Language book](book/plugins.html). +[the Rust Programming Language book](book/compiler-plugins.html). diff --git a/src/doc/style/README.md b/src/doc/style/README.md index 5ab1a1d9c10..8d837d1a1a9 100644 --- a/src/doc/style/README.md +++ b/src/doc/style/README.md @@ -53,7 +53,7 @@ This document is broken into four parts: cross-cutting topic, starting with [Ownership and resources](ownership/README.md). -* **[APIs for a changing Rust](changing/README.md)** +* **APIs for a changing Rust** discusses the forward-compatibility hazards, especially those that interact with the pre-1.0 library stabilization process. diff --git a/src/doc/style/features/functions-and-methods/input.md b/src/doc/style/features/functions-and-methods/input.md index 9ea1d218161..9b243bc72ef 100644 --- a/src/doc/style/features/functions-and-methods/input.md +++ b/src/doc/style/features/functions-and-methods/input.md @@ -76,7 +76,7 @@ needs to make about its arguments. On the other hand, generics can make it more difficult to read and understand a function's signature. Aim for "natural" parameter types that a neither overly concrete nor overly abstract. See the discussion on -[traits](../../traits/README.md) for more guidance. +[traits](../traits/README.md) for more guidance. #### Minimizing ownership assumptions: diff --git a/src/doc/style/style/naming/README.md b/src/doc/style/style/naming/README.md index 9d78721ad36..2106f32fafa 100644 --- a/src/doc/style/style/naming/README.md +++ b/src/doc/style/style/naming/README.md @@ -101,7 +101,7 @@ The convention for a field `foo: T` is: here may take `&T` or some other type, depending on the context.) Note that this convention is about getters/setters on ordinary data types, *not* -on [builder objects](../ownership/builders.html). +on [builder objects](../../ownership/builders.html). ### Escape hatches [FIXME] diff --git a/src/libcollections/btree/set.rs b/src/libcollections/btree/set.rs index dc653b446da..23e0af8113b 100644 --- a/src/libcollections/btree/set.rs +++ b/src/libcollections/btree/set.rs @@ -34,8 +34,8 @@ use Bound; /// to any other item, as determined by the [`Ord`] trait, changes while it is in the set. This is /// normally only possible through [`Cell`], [`RefCell`], global state, I/O, or unsafe code. /// -/// [`BTreeMap`]: ../struct.BTreeMap.html -/// [`Ord`]: ../../core/cmp/trait.Ord.html +/// [`BTreeMap`]: struct.BTreeMap.html +/// [`Ord`]: ../../std/cmp/trait.Ord.html /// [`Cell`]: ../../std/cell/struct.Cell.html /// [`RefCell`]: ../../std/cell/struct.RefCell.html /// diff --git a/src/libcollections/lib.rs b/src/libcollections/lib.rs index 922e1b0fc5d..cef6edf68ee 100644 --- a/src/libcollections/lib.rs +++ b/src/libcollections/lib.rs @@ -71,13 +71,21 @@ extern crate std; #[cfg(test)] extern crate test; +#[doc(no_inline)] pub use binary_heap::BinaryHeap; +#[doc(no_inline)] pub use btree_map::BTreeMap; +#[doc(no_inline)] pub use btree_set::BTreeSet; +#[doc(no_inline)] pub use linked_list::LinkedList; +#[doc(no_inline)] pub use enum_set::EnumSet; +#[doc(no_inline)] pub use vec_deque::VecDeque; +#[doc(no_inline)] pub use string::String; +#[doc(no_inline)] pub use vec::Vec; // Needed for the vec! macro diff --git a/src/libcollections/slice.rs b/src/libcollections/slice.rs index 1446d00b9ea..69a9899d82b 100644 --- a/src/libcollections/slice.rs +++ b/src/libcollections/slice.rs @@ -78,7 +78,7 @@ //! * Further methods that return iterators are `.split()`, `.splitn()`, //! `.chunks()`, `.windows()` and more. //! -//! *[See also the slice primitive type](../primitive.slice.html).* +//! *[See also the slice primitive type](../../std/primitive.slice.html).* #![stable(feature = "rust1", since = "1.0.0")] // Many of the usings in this module are only used in the test configuration. diff --git a/src/libcollections/str.rs b/src/libcollections/str.rs index 5789cd8edfc..9798e323a61 100644 --- a/src/libcollections/str.rs +++ b/src/libcollections/str.rs @@ -10,7 +10,7 @@ //! Unicode string slices. //! -//! *[See also the `str` primitive type](../primitive.str.html).* +//! *[See also the `str` primitive type](../../std/primitive.str.html).* #![stable(feature = "rust1", since = "1.0.0")] diff --git a/src/libcollections/string.rs b/src/libcollections/string.rs index cae6520bdb2..02190d11b42 100644 --- a/src/libcollections/string.rs +++ b/src/libcollections/string.rs @@ -79,7 +79,7 @@ use boxed::Box; /// contents of the string. It has a close relationship with its borrowed /// counterpart, the primitive [`str`]. /// -/// [`str`]: ../primitive.str.html +/// [`str`]: ../../std/primitive.str.html /// /// # Examples /// @@ -99,7 +99,7 @@ use boxed::Box; /// hello.push_str("orld!"); /// ``` /// -/// [`char`]: ../primitive.char.html +/// [`char`]: ../../std/primitive.char.html /// [`push()`]: #method.push /// [`push_str()`]: #method.push_str /// @@ -131,7 +131,7 @@ use boxed::Box; /// println!("The first letter of s is {}", s[0]); // ERROR!!! /// ``` /// -/// [`OsString`]: ../ffi/struct.OsString.html +/// [`OsString`]: ../../std/ffi/struct.OsString.html /// /// Indexing is intended to be a constant-time operation, but UTF-8 encoding /// does not allow us to do this. Furtheremore, it's not clear what sort of @@ -156,8 +156,8 @@ use boxed::Box; /// takes_str(&s); /// ``` /// -/// [`&str`]: ../primitive.str.html -/// [`Deref`]: ../ops/trait.Deref.html +/// [`&str`]: ../../std/primitive.str.html +/// [`Deref`]: ../../std/ops/trait.Deref.html /// /// This will create a [`&str`] from the `String` and pass it in. This /// conversion is very inexpensive, and so generally, functions will accept @@ -280,10 +280,10 @@ pub struct String { /// an analogue to `FromUtf8Error`, and you can get one from a `FromUtf8Error` /// through the [`utf8_error()`] method. /// -/// [`Utf8Error`]: ../str/struct.Utf8Error.html -/// [`std::str`]: ../str/index.html -/// [`u8`]: ../primitive.u8.html -/// [`&str`]: ../primitive.str.html +/// [`Utf8Error`]: ../../std/str/struct.Utf8Error.html +/// [`std::str`]: ../../std/str/index.html +/// [`u8`]: ../../std/primitive.u8.html +/// [`&str`]: ../../std/primitive.str.html /// [`utf8_error()`]: #method.utf8_error /// /// # Examples @@ -414,9 +414,9 @@ impl String { /// requires that it is valid UTF-8. `from_utf8()` checks to ensure that /// the bytes are valid UTF-8, and then does the conversion. /// - /// [`&str`]: ../primitive.str.html - /// [`u8`]: ../primitive.u8.html - /// [`Vec<u8>`]: ../vec/struct.Vec.html + /// [`&str`]: ../../std/primitive.str.html + /// [`u8`]: ../../std/primitive.u8.html + /// [`Vec<u8>`]: ../../std/vec/struct.Vec.html /// /// If you are sure that the byte slice is valid UTF-8, and you don't want /// to incur the overhead of the validity check, there is an unsafe version @@ -431,7 +431,7 @@ impl String { /// If you need a `&str` instead of a `String`, consider /// [`str::from_utf8()`]. /// - /// [`str::from_utf8()`]: ../str/fn.from_utf8.html + /// [`str::from_utf8()`]: ../../std/str/fn.from_utf8.html /// /// # Errors /// @@ -488,8 +488,8 @@ impl String { /// `from_utf8_lossy()` will replace any invalid UTF-8 sequences with /// `U+FFFD REPLACEMENT CHARACTER`, which looks like this: � /// - /// [`u8`]: ../primitive.u8.html - /// [byteslice]: ../primitive.slice.html + /// [`u8`]: ../../std/primitive.u8.html + /// [byteslice]: ../../std/primitive.slice.html /// /// If you are sure that the byte slice is valid UTF-8, and you don't want /// to incur the overhead of the conversion, there is an unsafe version @@ -504,7 +504,7 @@ impl String { /// it's already valid UTF-8, we don't need a new allocation. This return /// type allows us to handle both cases. /// - /// [`Cow<'a, str>`]: ../borrow/enum.Cow.html + /// [`Cow<'a, str>`]: ../../std/borrow/enum.Cow.html /// /// # Examples /// @@ -1014,7 +1014,7 @@ impl String { /// Panics if `new_len` > current length, or if `new_len` does not lie on a /// [`char`] boundary. /// - /// [`char`]: ../primitive.char.html + /// [`char`]: ../../std/primitive.char.html /// /// # Examples /// @@ -1076,7 +1076,7 @@ impl String { /// Panics if `idx` is larger than or equal to the `String`'s length, /// or if it does not lie on a [`char`] boundary. /// - /// [`char`]: ../primitive.char.html + /// [`char`]: ../../std/primitive.char.html /// /// # Examples /// @@ -1116,7 +1116,7 @@ impl String { /// Panics if `idx` is larger than the `String`'s length, or if it does not /// lie on a [`char`] boundary. /// - /// [`char`]: ../primitive.char.html + /// [`char`]: ../../std/primitive.char.html /// /// # Examples /// @@ -1255,7 +1255,7 @@ impl String { /// Panics if the starting point or end point do not lie on a [`char`] /// boundary, or if they're out of bounds. /// - /// [`char`]: ../primitive.char.html + /// [`char`]: ../../std/primitive.char.html /// /// # Examples /// @@ -1353,10 +1353,10 @@ impl FromUtf8Error { /// an analogue to `FromUtf8Error`. See its documentation for more details /// on using it. /// - /// [`Utf8Error`]: ../str/struct.Utf8Error.html - /// [`std::str`]: ../str/index.html - /// [`u8`]: ../primitive.u8.html - /// [`&str`]: ../primitive.str.html + /// [`Utf8Error`]: ../../std/str/struct.Utf8Error.html + /// [`std::str`]: ../../std/str/index.html + /// [`u8`]: ../../std/primitive.u8.html + /// [`&str`]: ../../std/primitive.str.html /// /// # Examples /// @@ -1695,9 +1695,9 @@ impl ops::DerefMut for String { /// [`String`] without error, this type will never actually be returned. As /// such, it is only here to satisfy said signature, and is useless otherwise. /// -/// [`FromStr`]: ../str/trait.FromStr.html +/// [`FromStr`]: ../../std/str/trait.FromStr.html /// [`String`]: struct.String.html -/// [`from_str()`]: ../str/trait.FromStr.html#tymethod.from_str +/// [`from_str()`]: ../../std/str/trait.FromStr.html#tymethod.from_str #[stable(feature = "str_parse_error", since = "1.5.0")] #[derive(Copy)] pub enum ParseError {} @@ -1749,7 +1749,7 @@ impl Eq for ParseError {} /// [`Display`] should be implemented instead, and you get the `ToString` /// implementation for free. /// -/// [`Display`]: ../fmt/trait.Display.html +/// [`Display`]: ../../std/fmt/trait.Display.html #[stable(feature = "rust1", since = "1.0.0")] pub trait ToString { /// Converts the given value to a `String`. diff --git a/src/libcore/any.rs b/src/libcore/any.rs index cb9bf935cdb..dfd2ba9154d 100644 --- a/src/libcore/any.rs +++ b/src/libcore/any.rs @@ -22,7 +22,7 @@ //! Note that &Any is limited to testing whether a value is of a specified //! concrete type, and cannot be used to test whether a type implements a trait. //! -//! [`Box`]: ../boxed/struct.Box.html +//! [`Box`]: ../../std/boxed/struct.Box.html //! //! # Examples //! diff --git a/src/libcore/char.rs b/src/libcore/char.rs index 0c3807d8ca0..a23b303f4ba 100644 --- a/src/libcore/char.rs +++ b/src/libcore/char.rs @@ -69,7 +69,7 @@ const MAX_THREE_B: u32 = 0x10000; /// Point], but only ones within a certain range. `MAX` is the highest valid /// code point that's a valid [Unicode Scalar Value]. /// -/// [`char`]: ../primitive.char.html +/// [`char`]: ../../std/primitive.char.html /// [Unicode Scalar Value]: http://www.unicode.org/glossary/#unicode_scalar_value /// [Code Point]: http://www.unicode.org/glossary/#code_point #[stable(feature = "rust1", since = "1.0.0")] @@ -91,8 +91,8 @@ pub const MAX: char = '\u{10ffff}'; /// [`char`]s. `from_u32()` will return `None` if the input is not a valid value /// for a [`char`]. /// -/// [`char`]: ../primitive.char.html -/// [`u32`]: ../primitive.u32.html +/// [`char`]: ../../std/primitive.char.html +/// [`u32`]: ../../std/primitive.u32.html /// [`as`]: ../../book/casting-between-types.html#as /// /// For an unsafe version of this function which ignores these checks, see @@ -148,8 +148,8 @@ pub fn from_u32(i: u32) -> Option<char> { /// [`char`]s. `from_u32_unchecked()` will ignore this, and blindly cast to /// [`char`], possibly creating an invalid one. /// -/// [`char`]: ../primitive.char.html -/// [`u32`]: ../primitive.u32.html +/// [`char`]: ../../std/primitive.char.html +/// [`u32`]: ../../std/primitive.u32.html /// [`as`]: ../../book/casting-between-types.html#as /// /// # Safety @@ -414,8 +414,8 @@ pub fn encode_utf16_raw(mut ch: u32, dst: &mut [u16]) -> Option<usize> { /// This `struct` is created by the [`escape_unicode()`] method on [`char`]. See /// its documentation for more. /// -/// [`escape_unicode()`]: ../primitive.char.html#method.escape_unicode -/// [`char`]: ../primitive.char.html +/// [`escape_unicode()`]: ../../std/primitive.char.html#method.escape_unicode +/// [`char`]: ../../std/primitive.char.html #[derive(Clone)] #[stable(feature = "rust1", since = "1.0.0")] pub struct EscapeUnicode { @@ -494,8 +494,8 @@ impl Iterator for EscapeUnicode { /// This `struct` is created by the [`escape_default()`] method on [`char`]. See /// its documentation for more. /// -/// [`escape_default()`]: ../primitive.char.html#method.escape_default -/// [`char`]: ../primitive.char.html +/// [`escape_default()`]: ../../std/primitive.char.html#method.escape_default +/// [`char`]: ../../std/primitive.char.html #[derive(Clone)] #[stable(feature = "rust1", since = "1.0.0")] pub struct EscapeDefault { diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs index 6cc3b4e01b8..7927b338044 100644 --- a/src/libcore/fmt/mod.rs +++ b/src/libcore/fmt/mod.rs @@ -22,7 +22,19 @@ use ops::Deref; use result; use slice; use str; -use self::rt::v1::Alignment; + +#[unstable(feature = "fmt_flags_align", issue = "27726")] +/// Possible alignments returned by `Formatter::align` +pub enum Alignment { + /// Indication that contents should be left-aligned. + Left, + /// Indication that contents should be right-aligned. + Right, + /// Indication that contents should be center-aligned. + Center, + /// No alignment was requested. + Unknown, +} #[unstable(feature = "fmt_radix", issue = "27728")] #[rustc_deprecated(since = "1.7.0", reason = "not used enough to stabilize")] @@ -780,7 +792,7 @@ pub fn write(output: &mut Write, args: Arguments) -> Result { width: None, precision: None, buf: output, - align: Alignment::Unknown, + align: rt::v1::Alignment::Unknown, fill: ' ', args: args.args, curarg: args.args.iter(), @@ -920,13 +932,13 @@ impl<'a> Formatter<'a> { Some(min) if self.sign_aware_zero_pad() => { self.fill = '0'; try!(write_prefix(self)); - self.with_padding(min - width, Alignment::Right, |f| { + self.with_padding(min - width, rt::v1::Alignment::Right, |f| { f.buf.write_str(buf) }) } // Otherwise, the sign and prefix goes after the padding Some(min) => { - self.with_padding(min - width, Alignment::Right, |f| { + self.with_padding(min - width, rt::v1::Alignment::Right, |f| { try!(write_prefix(f)); f.buf.write_str(buf) }) } @@ -973,7 +985,8 @@ impl<'a> Formatter<'a> { // If we're under both the maximum and the minimum width, then fill // up the minimum width with the specified string + some alignment. Some(width) => { - self.with_padding(width - s.chars().count(), Alignment::Left, |me| { + let align = rt::v1::Alignment::Left; + self.with_padding(width - s.chars().count(), align, |me| { me.buf.write_str(s) }) } @@ -982,20 +995,21 @@ impl<'a> Formatter<'a> { /// Runs a callback, emitting the correct padding either before or /// afterwards depending on whether right or left alignment is requested. - fn with_padding<F>(&mut self, padding: usize, default: Alignment, + fn with_padding<F>(&mut self, padding: usize, default: rt::v1::Alignment, f: F) -> Result where F: FnOnce(&mut Formatter) -> Result, { use char::CharExt; let align = match self.align { - Alignment::Unknown => default, + rt::v1::Alignment::Unknown => default, _ => self.align }; let (pre_pad, post_pad) = match align { - Alignment::Left => (0, padding), - Alignment::Right | Alignment::Unknown => (padding, 0), - Alignment::Center => (padding / 2, (padding + 1) / 2), + rt::v1::Alignment::Left => (0, padding), + rt::v1::Alignment::Right | + rt::v1::Alignment::Unknown => (padding, 0), + rt::v1::Alignment::Center => (padding / 2, (padding + 1) / 2), }; let mut fill = [0; 4]; @@ -1033,7 +1047,7 @@ impl<'a> Formatter<'a> { // remove the sign from the formatted parts formatted.sign = b""; width = if width < sign.len() { 0 } else { width - sign.len() }; - align = Alignment::Right; + align = rt::v1::Alignment::Right; self.fill = '0'; } @@ -1116,7 +1130,14 @@ impl<'a> Formatter<'a> { /// Flag indicating what form of alignment was requested #[unstable(feature = "fmt_flags_align", reason = "method was just created", issue = "27726")] - pub fn align(&self) -> Alignment { self.align } + pub fn align(&self) -> Alignment { + match self.align { + rt::v1::Alignment::Left => Alignment::Left, + rt::v1::Alignment::Right => Alignment::Right, + rt::v1::Alignment::Center => Alignment::Center, + rt::v1::Alignment::Unknown => Alignment::Unknown, + } + } /// Optionally specified integer width that the output should be #[stable(feature = "fmt_flags", since = "1.5.0")] diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs index fb8eda820f5..06821ff94f7 100644 --- a/src/libcore/iter.rs +++ b/src/libcore/iter.rs @@ -65,7 +65,7 @@ //! //! [`Iterator`]: trait.Iterator.html //! [`next()`]: trait.Iterator.html#tymethod.next -//! [`Option`]: ../option/enum.Option.html +//! [`Option`]: ../../std/option/enum.Option.html //! //! # The three forms of iteration //! @@ -804,7 +804,7 @@ pub trait Iterator { /// closure returns `None`, it will try again, and call the closure on the /// next element, seeing if it will return `Some`. /// - /// [`Option<T>`]: ../option/enum.Option.html + /// [`Option<T>`]: ../../std/option/enum.Option.html /// /// Why `filter_map()` and not just [`filter()`].[`map()`]? The key is in this /// part: @@ -866,7 +866,7 @@ pub trait Iterator { /// different sized integer, the [`zip()`] function provides similar /// functionality. /// - /// [`usize`]: ../primitive.usize.html + /// [`usize`]: ../../std/primitive.usize.html /// [`zip()`]: #method.zip /// /// # Overflow Behavior @@ -875,7 +875,7 @@ pub trait Iterator { /// [`usize::MAX`] elements either produces the wrong result or panics. If /// debug assertions are enabled, a panic is guaranteed. /// - /// [`usize::MAX`]: ../usize/constant.MAX.html + /// [`usize::MAX`]: ../../std/usize/constant.MAX.html /// /// # Panics /// @@ -1151,7 +1151,7 @@ pub trait Iterator { /// iterator and the return value from the closure, an [`Option`], is /// yielded by the iterator. /// - /// [`Option`]: ../option/enum.Option.html + /// [`Option`]: ../../std/option/enum.Option.html /// /// # Examples /// @@ -1385,9 +1385,9 @@ pub trait Iterator { /// be thought of as single `Result<Collection<T>, E>`. See the examples /// below for more. /// - /// [`String`]: ../string/struct.String.html - /// [`Result<T, E>`]: ../result/enum.Result.html - /// [`char`]: ../primitive.char.html + /// [`String`]: ../../std/string/struct.String.html + /// [`Result<T, E>`]: ../../std/result/enum.Result.html + /// [`char`]: ../../std/primitive.char.html /// /// Because `collect()` is so general, it can cause problems with type /// inference. As such, `collect()` is one of the few times you'll see @@ -1412,7 +1412,7 @@ pub trait Iterator { /// Note that we needed the `: Vec<i32>` on the left-hand side. This is because /// we could collect into, for example, a [`VecDeque<T>`] instead: /// - /// [`VecDeque<T>`]: ../collections/struct.VecDeque.html + /// [`VecDeque<T>`]: ../../std/collections/struct.VecDeque.html /// /// ``` /// use std::collections::VecDeque; diff --git a/src/libcore/macros.rs b/src/libcore/macros.rs index 154ca30c62d..f923668688b 100644 --- a/src/libcore/macros.rs +++ b/src/libcore/macros.rs @@ -206,8 +206,8 @@ macro_rules! try { /// /// See [`std::fmt`][fmt] for more information on format syntax. /// -/// [fmt]: fmt/index.html -/// [write]: io/trait.Write.html +/// [fmt]: ../std/fmt/index.html +/// [write]: ../std/io/trait.Write.html /// /// # Examples /// @@ -232,8 +232,8 @@ macro_rules! write { /// /// See [`std::fmt`][fmt] for more information on format syntax. /// -/// [fmt]: fmt/index.html -/// [write]: io/trait.Write.html +/// [fmt]: ../std/fmt/index.html +/// [write]: ../std/io/trait.Write.html /// /// # Examples /// diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index ed370bb9164..0b306c810b1 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -2179,8 +2179,8 @@ impl usize { /// This `enum` is used as the return type for [`f32::classify()`] and [`f64::classify()`]. See /// their documentation for more. /// -/// [`f32::classify()`]: ../primitive.f32.html#method.classify -/// [`f64::classify()`]: ../primitive.f64.html#method.classify +/// [`f32::classify()`]: ../../std/primitive.f32.html#method.classify +/// [`f64::classify()`]: ../../std/primitive.f64.html#method.classify #[derive(Copy, Clone, PartialEq, Debug)] #[stable(feature = "rust1", since = "1.0.0")] pub enum FpCategory { @@ -2411,7 +2411,7 @@ fn from_str_radix<T: FromStrRadixHelper>(src: &str, radix: u32) /// This error is used as the error type for the `from_str_radix()` functions /// on the primitive integer types, such as [`i8::from_str_radix()`]. /// -/// [`i8::from_str_radix()`]: ../std/primitive.i8.html#method.from_str_radix +/// [`i8::from_str_radix()`]: ../../std/primitive.i8.html#method.from_str_radix #[derive(Debug, Clone, PartialEq)] #[stable(feature = "rust1", since = "1.0.0")] pub struct ParseIntError { kind: IntErrorKind } diff --git a/src/libcore/slice.rs b/src/libcore/slice.rs index 8acd0c8f2cf..e59e8567d5b 100644 --- a/src/libcore/slice.rs +++ b/src/libcore/slice.rs @@ -908,6 +908,7 @@ impl<'a, T> ExactSizeIterator for IterMut<'a, T> {} /// An internal abstraction over the splitting iterators, so that /// splitn, splitn_mut etc can be implemented once. +#[doc(hidden)] trait SplitIter: DoubleEndedIterator { /// Mark the underlying iterator as complete, extracting the remaining /// portion of the slice. diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index f5abdf65a5b..dee13bf3d3d 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -42,8 +42,8 @@ pub mod pattern; /// [`str`]'s [`parse()`] method. See [`parse()`]'s documentation for examples. /// /// [`from_str()`]: #tymethod.from_str -/// [`str`]: ../primitive.str.html -/// [`parse()`]: ../primitive.str.html#method.parse +/// [`str`]: ../../std/primitive.str.html +/// [`parse()`]: ../../std/primitive.str.html#method.parse #[stable(feature = "rust1", since = "1.0.0")] pub trait FromStr: Sized { /// The associated error which can be returned from parsing. @@ -60,7 +60,7 @@ pub trait FromStr: Sized { /// /// Basic usage with [`i32`][ithirtytwo], a type that implements `FromStr`: /// - /// [ithirtytwo]: ../primitive.i32.html + /// [ithirtytwo]: ../../std/primitive.i32.html /// /// ``` /// use std::str::FromStr; @@ -182,7 +182,7 @@ impl Utf8Error { /// If you need a `String` instead of a `&str`, consider /// [`String::from_utf8()`][string]. /// -/// [string]: ../string/struct.String.html#method.from_utf8 +/// [string]: ../../std/string/struct.String.html#method.from_utf8 /// /// Because you can stack-allocate a `[u8; N]`, and you can take a `&[u8]` of /// it, this function is one way to have a stack-allocated string. There is @@ -322,7 +322,7 @@ Section: Iterators /// /// Created with the method [`chars()`]. /// -/// [`chars()`]: ../primitive.str.html#method.chars +/// [`chars()`]: ../../std/primitive.str.html#method.chars #[derive(Clone)] #[stable(feature = "rust1", since = "1.0.0")] pub struct Chars<'a> { @@ -531,7 +531,7 @@ impl<'a> CharIndices<'a> { /// /// Created with the method [`bytes()`]. /// -/// [`bytes()`]: ../primitive.str.html#method.bytes +/// [`bytes()`]: ../../std/primitive.str.html#method.bytes #[stable(feature = "rust1", since = "1.0.0")] #[derive(Clone)] pub struct Bytes<'a>(Cloned<slice::Iter<'a, u8>>); @@ -816,12 +816,12 @@ generate_pattern_iterators! { forward: /// Created with the method [`split()`]. /// - /// [`split()`]: ../primitive.str.html#method.split + /// [`split()`]: ../../std/primitive.str.html#method.split struct Split; reverse: /// Created with the method [`rsplit()`]. /// - /// [`rsplit()`]: ../primitive.str.html#method.rsplit + /// [`rsplit()`]: ../../std/primitive.str.html#method.rsplit struct RSplit; stability: #[stable(feature = "rust1", since = "1.0.0")] @@ -834,12 +834,12 @@ generate_pattern_iterators! { forward: /// Created with the method [`split_terminator()`]. /// - /// [`split_terminator()`]: ../primitive.str.html#method.split_terminator + /// [`split_terminator()`]: ../../std/primitive.str.html#method.split_terminator struct SplitTerminator; reverse: /// Created with the method [`rsplit_terminator()`]. /// - /// [`rsplit_terminator()`]: ../primitive.str.html#method.rsplit_terminator + /// [`rsplit_terminator()`]: ../../std/primitive.str.html#method.rsplit_terminator struct RSplitTerminator; stability: #[stable(feature = "rust1", since = "1.0.0")] @@ -884,12 +884,12 @@ generate_pattern_iterators! { forward: /// Created with the method [`splitn()`]. /// - /// [`splitn()`]: ../primitive.str.html#method.splitn + /// [`splitn()`]: ../../std/primitive.str.html#method.splitn struct SplitN; reverse: /// Created with the method [`rsplitn()`]. /// - /// [`rsplitn()`]: ../primitive.str.html#method.rsplitn + /// [`rsplitn()`]: ../../std/primitive.str.html#method.rsplitn struct RSplitN; stability: #[stable(feature = "rust1", since = "1.0.0")] @@ -926,12 +926,12 @@ generate_pattern_iterators! { forward: /// Created with the method [`match_indices()`]. /// - /// [`match_indices()`]: ../primitive.str.html#method.match_indices + /// [`match_indices()`]: ../../std/primitive.str.html#method.match_indices struct MatchIndices; reverse: /// Created with the method [`rmatch_indices()`]. /// - /// [`rmatch_indices()`]: ../primitive.str.html#method.rmatch_indices + /// [`rmatch_indices()`]: ../../std/primitive.str.html#method.rmatch_indices struct RMatchIndices; stability: #[stable(feature = "str_match_indices", since = "1.5.0")] @@ -970,12 +970,12 @@ generate_pattern_iterators! { forward: /// Created with the method [`matches()`]. /// - /// [`matches()`]: ../primitive.str.html#method.matches + /// [`matches()`]: ../../std/primitive.str.html#method.matches struct Matches; reverse: /// Created with the method [`rmatches()`]. /// - /// [`rmatches()`]: ../primitive.str.html#method.rmatches + /// [`rmatches()`]: ../../std/primitive.str.html#method.rmatches struct RMatches; stability: #[stable(feature = "str_matches", since = "1.2.0")] @@ -986,7 +986,7 @@ generate_pattern_iterators! { /// Created with the method [`lines()`]. /// -/// [`lines()`]: ../primitive.str.html#method.lines +/// [`lines()`]: ../../std/primitive.str.html#method.lines #[stable(feature = "rust1", since = "1.0.0")] #[derive(Clone)] pub struct Lines<'a>(Map<SplitTerminator<'a, char>, LinesAnyMap>); @@ -1016,7 +1016,7 @@ impl<'a> DoubleEndedIterator for Lines<'a> { /// Created with the method [`lines_any()`]. /// -/// [`lines_any()`]: ../primitive.str.html#method.lines_any +/// [`lines_any()`]: ../../std/primitive.str.html#method.lines_any #[stable(feature = "rust1", since = "1.0.0")] #[rustc_deprecated(since = "1.4.0", reason = "use lines()/Lines instead now")] #[derive(Clone)] diff --git a/src/librand/lib.rs b/src/librand/lib.rs index e943f861e9d..07fae35b23b 100644 --- a/src/librand/lib.rs +++ b/src/librand/lib.rs @@ -67,6 +67,7 @@ mod rand_impls; // needed by librand; this is necessary because librand doesn't // depend on libstd. This will go away when librand is integrated // into libstd. +#[doc(hidden)] trait FloatMath : Sized { fn exp(self) -> Self; fn ln(self) -> Self; diff --git a/src/librustc_unicode/char.rs b/src/librustc_unicode/char.rs index 11500286755..5bc5c786160 100644 --- a/src/librustc_unicode/char.rs +++ b/src/librustc_unicode/char.rs @@ -19,7 +19,7 @@ //! [Unicode code point]: http://www.unicode.org/glossary/#code_point //! //! This module exists for technical reasons, the primary documentation for -//! `char` is directly on [the `char` primitive type](../primitive.char.html) +//! `char` is directly on [the `char` primitive type](../../std/primitive.char.html) //! itself. //! //! This module is the home of the iterator implementations for the iterators @@ -46,8 +46,8 @@ pub use tables::UNICODE_VERSION; /// This `struct` is created by the [`to_lowercase()`] method on [`char`]. See /// its documentation for more. /// -/// [`to_lowercase()`]: ../primitive.char.html#method.to_lowercase -/// [`char`]: ../primitive.char.html +/// [`to_lowercase()`]: ../../std/primitive.char.html#method.to_lowercase +/// [`char`]: ../../std/primitive.char.html #[stable(feature = "rust1", since = "1.0.0")] pub struct ToLowercase(CaseMappingIter); @@ -64,8 +64,8 @@ impl Iterator for ToLowercase { /// This `struct` is created by the [`to_uppercase()`] method on [`char`]. See /// its documentation for more. /// -/// [`to_uppercase()`]: ../primitive.char.html#method.to_uppercase -/// [`char`]: ../primitive.char.html +/// [`to_uppercase()`]: ../../std/primitive.char.html#method.to_uppercase +/// [`char`]: ../../std/primitive.char.html #[stable(feature = "rust1", since = "1.0.0")] pub struct ToUppercase(CaseMappingIter); @@ -968,6 +968,6 @@ impl<I: Iterator<Item=u16>> Iterator for DecodeUtf16<I> { /// `U+FFFD REPLACEMENT CHARACTER` (�) is used in Unicode to represent a decoding error. /// It can occur, for example, when giving ill-formed UTF-8 bytes to -/// [`String::from_utf8_lossy`](../string/struct.String.html#method.from_utf8_lossy). +/// [`String::from_utf8_lossy`](../../std/string/struct.String.html#method.from_utf8_lossy). #[unstable(feature = "decode_utf16", reason = "recently added", issue = "27830")] pub const REPLACEMENT_CHARACTER: char = '\u{FFFD}'; diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index c14e4af8103..061047cbd2f 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -222,7 +222,8 @@ fn build_type(cx: &DocContext, tcx: &TyCtxt, did: DefId) -> clean::ItemEnum { }, false) } -pub fn build_impls(cx: &DocContext, tcx: &TyCtxt, +pub fn build_impls(cx: &DocContext, + tcx: &TyCtxt, did: DefId) -> Vec<clean::Item> { tcx.populate_inherent_implementations_for_type_if_necessary(did); let mut impls = Vec::new(); @@ -241,10 +242,12 @@ pub fn build_impls(cx: &DocContext, tcx: &TyCtxt, // Primarily, the impls will be used to populate the documentation for this // type being inlined, but impls can also be used when generating // documentation for primitives (no way to find those specifically). - if cx.populated_crate_impls.borrow_mut().insert(did.krate) { + if !cx.all_crate_impls.borrow_mut().contains_key(&did.krate) { + let mut impls = Vec::new(); for item in tcx.sess.cstore.crate_top_level_items(did.krate) { populate_impls(cx, tcx, item.def, &mut impls); } + cx.all_crate_impls.borrow_mut().insert(did.krate, impls); fn populate_impls(cx: &DocContext, tcx: &TyCtxt, def: cstore::DefLike, @@ -266,6 +269,20 @@ pub fn build_impls(cx: &DocContext, tcx: &TyCtxt, } } + let mut candidates = cx.all_crate_impls.borrow_mut(); + let candidates = candidates.get_mut(&did.krate).unwrap(); + for i in (0..candidates.len()).rev() { + let remove = match candidates[i].inner { + clean::ImplItem(ref i) => { + i.for_.def_id() == Some(did) || i.for_.primitive_type().is_some() + } + _ => continue, + }; + if remove { + impls.push(candidates.swap_remove(i)); + } + } + return impls; } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 5921093bcac..a4b8c9bf5f7 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1499,6 +1499,13 @@ impl Type { _ => None, } } + + fn def_id(&self) -> Option<DefId> { + match *self { + ResolvedPath { did, .. } => Some(did), + _ => None, + } + } } impl PrimitiveType { diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 5a6fe060eb8..c30fd39616c 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -56,7 +56,7 @@ pub struct DocContext<'a, 'tcx: 'a> { pub external_traits: RefCell<Option<HashMap<DefId, clean::Trait>>>, pub external_typarams: RefCell<Option<HashMap<DefId, String>>>, pub inlined: RefCell<Option<HashSet<DefId>>>, - pub populated_crate_impls: RefCell<HashSet<ast::CrateNum>>, + pub all_crate_impls: RefCell<HashMap<ast::CrateNum, Vec<clean::Item>>>, pub deref_trait_did: Cell<Option<DefId>>, } @@ -179,7 +179,7 @@ pub fn run_core(search_paths: SearchPaths, cfgs: Vec<String>, externs: Externs, external_typarams: RefCell::new(Some(HashMap::new())), external_paths: RefCell::new(Some(HashMap::new())), inlined: RefCell::new(Some(HashSet::new())), - populated_crate_impls: RefCell::new(HashSet::new()), + all_crate_impls: RefCell::new(HashMap::new()), deref_trait_did: Cell::new(None), }; debug!("crate: {:?}", ctxt.map.krate()); diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index 6294b676651..d873c9ec340 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -11,7 +11,7 @@ #![allow(deprecated)] use std::cell::{RefCell, Cell}; -use std::collections::{HashSet, HashMap}; +use std::collections::HashMap; use std::dynamic_lib::DynamicLibrary; use std::env; use std::ffi::OsString; @@ -114,7 +114,7 @@ pub fn run(input: &str, external_traits: RefCell::new(None), external_typarams: RefCell::new(None), inlined: RefCell::new(None), - populated_crate_impls: RefCell::new(HashSet::new()), + all_crate_impls: RefCell::new(HashMap::new()), deref_trait_did: Cell::new(None), }; diff --git a/src/libstd/num/f32.rs b/src/libstd/num/f32.rs index 7f57d6dc650..37053025924 100644 --- a/src/libstd/num/f32.rs +++ b/src/libstd/num/f32.rs @@ -262,7 +262,7 @@ impl f32 { /// /// assert!(abs_difference <= f32::EPSILON); /// ``` - /// [floating-point]: ../../../../../reference.html#machine-types + /// [floating-point]: ../reference.html#machine-types #[unstable(feature = "float_extras", reason = "signature is undecided", issue = "27752")] #[inline] diff --git a/src/libstd/num/f64.rs b/src/libstd/num/f64.rs index a39311f7d10..446e22a20ad 100644 --- a/src/libstd/num/f64.rs +++ b/src/libstd/num/f64.rs @@ -206,7 +206,7 @@ impl f64 { /// /// assert!(abs_difference < 1e-10); /// ``` - /// [floating-point]: ../../../../../reference.html#machine-types + /// [floating-point]: ../reference.html#machine-types #[unstable(feature = "float_extras", reason = "signature is undecided", issue = "27752")] #[inline] diff --git a/src/libstd/primitive_docs.rs b/src/libstd/primitive_docs.rs index 24e35b87bf2..65ed879c4ad 100644 --- a/src/libstd/primitive_docs.rs +++ b/src/libstd/primitive_docs.rs @@ -27,11 +27,11 @@ /// assert!(!bool_val); /// ``` /// -/// [`assert!`]: std/macro.assert!.html -/// [`if` conditionals]: ../../book/if.html -/// [`BitAnd`]: ../ops/trait.BitAnd.html -/// [`BitOr`]: ../ops/trait.BitOr.html -/// [`Not`]: ../ops/trait.Not.html +/// [`assert!`]: macro.assert!.html +/// [`if` conditionals]: ../book/if.html +/// [`BitAnd`]: ops/trait.BitAnd.html +/// [`BitOr`]: ops/trait.BitOr.html +/// [`Not`]: ops/trait.Not.html /// /// # Examples /// @@ -54,7 +54,7 @@ /// } /// ``` /// -/// Also, since `bool` implements the [`Copy`](../marker/trait.Copy.html) trait, we don't +/// Also, since `bool` implements the [`Copy`](marker/trait.Copy.html) trait, we don't /// have to worry about the move semantics (just like the integer and float primitives). mod prim_bool { } @@ -421,7 +421,7 @@ mod prim_str { } /// assert_eq!(tuple.2, 'c'); /// ``` /// -/// For more about tuples, see [the book](../../book/primitive-types.html#tuples). +/// For more about tuples, see [the book](../book/primitive-types.html#tuples). /// /// # Trait implementations /// @@ -437,14 +437,14 @@ mod prim_str { } /// * [`Default`] /// * [`Hash`] /// -/// [`Clone`]: ../clone/trait.Clone.html -/// [`PartialEq`]: ../cmp/trait.PartialEq.html -/// [`Eq`]: ../cmp/trait.Eq.html -/// [`PartialOrd`]: ../cmp/trait.PartialOrd.html -/// [`Ord`]: ../cmp/trait.Ord.html -/// [`Debug`]: ../fmt/trait.Debug.html -/// [`Default`]: ../default/trait.Default.html -/// [`Hash`]: ../hash/trait.Hash.html +/// [`Clone`]: clone/trait.Clone.html +/// [`PartialEq`]: cmp/trait.PartialEq.html +/// [`Eq`]: cmp/trait.Eq.html +/// [`PartialOrd`]: cmp/trait.PartialOrd.html +/// [`Ord`]: cmp/trait.Ord.html +/// [`Debug`]: fmt/trait.Debug.html +/// [`Default`]: default/trait.Default.html +/// [`Hash`]: hash/trait.Hash.html /// /// Due to a temporary restriction in Rust's type system, these traits are only /// implemented on tuples of arity 32 or less. In the future, this may change. diff --git a/src/rustbook/Cargo.toml b/src/rustbook/Cargo.toml deleted file mode 100644 index c684c474efa..00000000000 --- a/src/rustbook/Cargo.toml +++ /dev/null @@ -1,13 +0,0 @@ -[package] -authors = ["The Rust Project Developers"] -name = "rustbook" -version = "0.0.0" - -[lib] -name = "rustbook" -path = "main.rs" -crate-type = ["dylib"] - -[dependencies] -rustc_back = { path = "../librustc_back" } -rustdoc = { path = "../librustdoc" } diff --git a/src/rustc/Cargo.lock b/src/rustc/Cargo.lock index e4432720ab4..a2718351640 100644 --- a/src/rustc/Cargo.lock +++ b/src/rustc/Cargo.lock @@ -2,7 +2,6 @@ name = "rustc-main" version = "0.0.0" dependencies = [ - "rustbook 0.0.0", "rustc_back 0.0.0", "rustc_driver 0.0.0", "rustdoc 0.0.0", @@ -67,14 +66,6 @@ dependencies = [ ] [[package]] -name = "rustbook" -version = "0.0.0" -dependencies = [ - "rustc_back 0.0.0", - "rustdoc 0.0.0", -] - -[[package]] name = "rustc" version = "0.0.0" dependencies = [ diff --git a/src/rustc/Cargo.toml b/src/rustc/Cargo.toml index 9fcefd9d3a4..7431c35efba 100644 --- a/src/rustc/Cargo.toml +++ b/src/rustc/Cargo.toml @@ -11,10 +11,6 @@ path = "rustc.rs" name = "rustdoc" path = "rustdoc.rs" -[[bin]] -name = "rustbook" -path = "rustbook.rs" - [profile.release] opt-level = 2 @@ -27,10 +23,9 @@ debug-assertions = false # All optional dependencies so the features passed to this Cargo.toml select # what should actually be built. [dependencies] -rustbook = { path = "../rustbook", optional = true } rustc_back = { path = "../librustc_back" } rustc_driver = { path = "../librustc_driver" } -rustdoc = { path = "../librustdoc", optional = true } +rustdoc = { path = "../librustdoc" } [features] jemalloc = ["rustc_back/jemalloc"] diff --git a/src/rustc/rustbook.rs b/src/rustc/rustbook.rs deleted file mode 100644 index 6f78f78bc55..00000000000 --- a/src/rustc/rustbook.rs +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright 2015 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. - -extern crate rustbook; - -fn main() { rustbook::main() } - diff --git a/src/tools/error_index_generator/Cargo.lock b/src/tools/error_index_generator/Cargo.lock new file mode 100644 index 00000000000..b7d2cfcaaa1 --- /dev/null +++ b/src/tools/error_index_generator/Cargo.lock @@ -0,0 +1,4 @@ +[root] +name = "error_index_generator" +version = "0.0.0" + diff --git a/src/tools/error_index_generator/Cargo.toml b/src/tools/error_index_generator/Cargo.toml new file mode 100644 index 00000000000..5c5ca273e9c --- /dev/null +++ b/src/tools/error_index_generator/Cargo.toml @@ -0,0 +1,8 @@ +[package] +authors = ["The Rust Project Developers"] +name = "error_index_generator" +version = "0.0.0" + +[[bin]] +name = "error_index_generator" +path = "main.rs" diff --git a/src/error_index_generator/main.rs b/src/tools/error_index_generator/main.rs index db9dd006f3c..4343aef00a9 100644 --- a/src/error_index_generator/main.rs +++ b/src/tools/error_index_generator/main.rs @@ -15,11 +15,12 @@ extern crate rustdoc; extern crate serialize as rustc_serialize; use std::collections::BTreeMap; +use std::env; +use std::error::Error; use std::fs::{read_dir, File}; use std::io::{Read, Write}; -use std::env; use std::path::Path; -use std::error::Error; +use std::path::PathBuf; use syntax::diagnostics::metadata::{get_metadata_dir, ErrorMetadataMap, ErrorMetadata}; @@ -173,31 +174,35 @@ fn render_error_page<T: Formatter>(err_map: &ErrorMetadataMap, output_path: &Pat formatter.footer(&mut output_file) } -fn main_with_result(format: OutputFormat) -> Result<(), Box<Error>> { +fn main_with_result(format: OutputFormat, dst: &Path) -> Result<(), Box<Error>> { let build_arch = try!(env::var("CFG_BUILD")); let metadata_dir = get_metadata_dir(&build_arch); let err_map = try!(load_all_errors(&metadata_dir)); match format { OutputFormat::Unknown(s) => panic!("Unknown output format: {}", s), - OutputFormat::HTML(h) => try!(render_error_page(&err_map, - Path::new("doc/error-index.html"), - h)), - OutputFormat::Markdown(m) => try!(render_error_page(&err_map, - Path::new("doc/error-index.md"), - m)), + OutputFormat::HTML(h) => try!(render_error_page(&err_map, dst, h)), + OutputFormat::Markdown(m) => try!(render_error_page(&err_map, dst, m)), } Ok(()) } -fn parse_args() -> OutputFormat { - for arg in env::args().skip(1) { - return OutputFormat::from(&arg); - } - OutputFormat::from("html") +fn parse_args() -> (OutputFormat, PathBuf) { + let mut args = env::args().skip(1); + let format = args.next().map(|a| OutputFormat::from(&a)) + .unwrap_or(OutputFormat::from("html")); + let dst = args.next().map(PathBuf::from).unwrap_or_else(|| { + match format { + OutputFormat::HTML(..) => PathBuf::from("doc/error-index.html"), + OutputFormat::Markdown(..) => PathBuf::from("doc/error-index.md"), + OutputFormat::Unknown(..) => PathBuf::from("<nul>"), + } + }); + (format, dst) } fn main() { - if let Err(e) = main_with_result(parse_args()) { + let (format, dst) = parse_args(); + if let Err(e) = main_with_result(format, &dst) { panic!("{}", e.description()); } } diff --git a/src/tools/linkchecker/Cargo.lock b/src/tools/linkchecker/Cargo.lock new file mode 100644 index 00000000000..8e94137d213 --- /dev/null +++ b/src/tools/linkchecker/Cargo.lock @@ -0,0 +1,64 @@ +[root] +name = "linkchecker" +version = "0.1.0" +dependencies = [ + "url 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "libc" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "matches" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "rand" +version = "0.3.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rustc-serialize" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "unicode-bidi" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "unicode-normalization" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "url" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-bidi 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-normalization 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "uuid 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "uuid" +version = "0.1.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)", +] + diff --git a/src/tools/linkchecker/Cargo.toml b/src/tools/linkchecker/Cargo.toml new file mode 100644 index 00000000000..29fc78a65e9 --- /dev/null +++ b/src/tools/linkchecker/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "linkchecker" +version = "0.1.0" +authors = ["Alex Crichton <alex@alexcrichton.com>"] + +[dependencies] +url = "0.5" + +[[bin]] +name = "linkchecker" +path = "main.rs" diff --git a/src/tools/linkchecker/main.rs b/src/tools/linkchecker/main.rs new file mode 100644 index 00000000000..e5e88081bc4 --- /dev/null +++ b/src/tools/linkchecker/main.rs @@ -0,0 +1,161 @@ +// Copyright 2016 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. + +//! Script to check the validity of `href` links in our HTML documentation. +//! +//! In the past we've been quite error prone to writing in broken links as most +//! of them are manually rather than automatically added. As files move over +//! time or apis change old links become stale or broken. The purpose of this +//! script is to check all relative links in our documentation to make sure they +//! actually point to a valid place. +//! +//! Currently this doesn't actually do any HTML parsing or anything fancy like +//! that, it just has a simple "regex" to search for `href` tags. These values +//! are then translated to file URLs if possible and then the destination is +//! asserted to exist. +//! +//! A few whitelisted exceptions are allowed as there's known bugs in rustdoc, +//! but this should catch the majority of "broken link" cases. + +extern crate url; + +use std::env; +use std::fs::File; +use std::io::prelude::*; +use std::path::Path; + +use url::{Url, UrlParser}; + +macro_rules! t { + ($e:expr) => (match $e { + Ok(e) => e, + Err(e) => panic!("{} failed with {}", stringify!($e), e), + }) +} + +fn main() { + let docs = env::args().nth(1).unwrap(); + let docs = env::current_dir().unwrap().join(docs); + let mut url = Url::from_file_path(&docs).unwrap(); + let mut errors = false; + walk(&docs, &docs, &mut url, &mut errors); + if errors { + panic!("found some broken links"); + } +} + +fn walk(root: &Path, dir: &Path, url: &mut Url, errors: &mut bool) { + for entry in t!(dir.read_dir()).map(|e| t!(e)) { + let path = entry.path(); + let kind = t!(entry.file_type()); + url.path_mut().unwrap().push(entry.file_name().into_string().unwrap()); + if kind.is_dir() { + walk(root, &path, url, errors); + } else { + check(root, &path, url, errors); + } + url.path_mut().unwrap().pop(); + } +} + +fn check(root: &Path, file: &Path, base: &Url, errors: &mut bool) { + // ignore js files as they are not prone to errors as the rest of the + // documentation is and they otherwise bring up false positives. + if file.extension().and_then(|s| s.to_str()) == Some("js") { + return + } + + let pretty_file = file.strip_prefix(root).unwrap_or(file); + + // Unfortunately we're not 100% full of valid links today to we need a few + // whitelists to get this past `make check` today. + if let Some(path) = pretty_file.to_str() { + // FIXME(#32129) + if path == "std/string/struct.String.html" { + return + } + // FIXME(#32130) + if path.contains("btree_set/struct.BTreeSet.html") || + path == "collections/struct.BTreeSet.html" { + return + } + // FIXME(#31948) + if path.contains("ParseFloatError") { + return + } + + // currently + if path == "std/sys/ext/index.html" { + return + } + + // weird reexports, but this module is on its way out, so chalk it up to + // "rustdoc weirdness" and move on from there + if path.contains("scoped_tls") { + return + } + } + + let mut parser = UrlParser::new(); + parser.base_url(base); + let mut contents = String::new(); + if t!(File::open(file)).read_to_string(&mut contents).is_err() { + return + } + + for (i, mut line) in contents.lines().enumerate() { + // Search for anything that's the regex 'href[ ]*=[ ]*".*?"' + while let Some(j) = line.find(" href") { + let rest = &line[j + 5..]; + line = rest; + let pos_equals = match rest.find("=") { + Some(i) => i, + None => continue, + }; + if rest[..pos_equals].trim_left_matches(" ") != "" { + continue + } + let rest = &rest[pos_equals + 1..]; + let pos_quote = match rest.find("\"").or_else(|| rest.find("'")) { + Some(i) => i, + None => continue, + }; + if rest[..pos_quote].trim_left_matches(" ") != "" { + continue + } + let rest = &rest[pos_quote + 1..]; + let url = match rest.find("\"").or_else(|| rest.find("'")) { + Some(i) => &rest[..i], + None => continue, + }; + + // Once we've plucked out the URL, parse it using our base url and + // then try to extract a file path. If either if these fail then we + // just keep going. + let parsed_url = match parser.parse(url) { + Ok(url) => url, + Err(..) => continue, + }; + let path = match parsed_url.to_file_path() { + Ok(path) => path, + Err(..) => continue, + }; + + // Alright, if we've found a file name then this file had better + // exist! If it doesn't then we register and print an error. + if !path.exists() { + *errors = true; + print!("{}:{}: broken link - ", pretty_file.display(), i + 1); + let pretty_path = path.strip_prefix(root).unwrap_or(&path); + println!("{}", pretty_path.display()); + } + } + } +} diff --git a/src/tools/rustbook/Cargo.lock b/src/tools/rustbook/Cargo.lock new file mode 100644 index 00000000000..e541ce4b2b8 --- /dev/null +++ b/src/tools/rustbook/Cargo.lock @@ -0,0 +1,4 @@ +[root] +name = "rustbook" +version = "0.0.0" + diff --git a/src/tools/rustbook/Cargo.toml b/src/tools/rustbook/Cargo.toml new file mode 100644 index 00000000000..956392ca540 --- /dev/null +++ b/src/tools/rustbook/Cargo.toml @@ -0,0 +1,8 @@ +[package] +authors = ["The Rust Project Developers"] +name = "rustbook" +version = "0.0.0" + +[[bin]] +name = "rustbook" +path = "main.rs" diff --git a/src/rustbook/book.rs b/src/tools/rustbook/book.rs index 36a37dba1fa..36a37dba1fa 100644 --- a/src/rustbook/book.rs +++ b/src/tools/rustbook/book.rs diff --git a/src/rustbook/build.rs b/src/tools/rustbook/build.rs index 4b6d67d2d26..70ed98519f9 100644 --- a/src/rustbook/build.rs +++ b/src/tools/rustbook/build.rs @@ -160,7 +160,7 @@ fn render(book: &Book, tgt: &Path) -> CliResult<()> { // Copy js for playpen let mut playpen = try!(File::create(tgt.join("playpen.js"))); - let js = include_bytes!("../librustdoc/html/static/playpen.js"); + let js = include_bytes!("../../librustdoc/html/static/playpen.js"); try!(playpen.write_all(js)); Ok(()) } diff --git a/src/rustbook/error.rs b/src/tools/rustbook/error.rs index e896dee2791..e896dee2791 100644 --- a/src/rustbook/error.rs +++ b/src/tools/rustbook/error.rs diff --git a/src/rustbook/help.rs b/src/tools/rustbook/help.rs index c90c2b93609..c90c2b93609 100644 --- a/src/rustbook/help.rs +++ b/src/tools/rustbook/help.rs diff --git a/src/rustbook/main.rs b/src/tools/rustbook/main.rs index bd4fc899293..bd4fc899293 100644 --- a/src/rustbook/main.rs +++ b/src/tools/rustbook/main.rs diff --git a/src/rustbook/serve.rs b/src/tools/rustbook/serve.rs index 2fa7b7eed7b..2fa7b7eed7b 100644 --- a/src/rustbook/serve.rs +++ b/src/tools/rustbook/serve.rs diff --git a/src/rustbook/static/rustbook.css b/src/tools/rustbook/static/rustbook.css index ba0151fa2ed..ba0151fa2ed 100644 --- a/src/rustbook/static/rustbook.css +++ b/src/tools/rustbook/static/rustbook.css diff --git a/src/rustbook/static/rustbook.js b/src/tools/rustbook/static/rustbook.js index d8ab15260ed..d8ab15260ed 100644 --- a/src/rustbook/static/rustbook.js +++ b/src/tools/rustbook/static/rustbook.js diff --git a/src/rustbook/subcommand.rs b/src/tools/rustbook/subcommand.rs index a66c2b4f302..a66c2b4f302 100644 --- a/src/rustbook/subcommand.rs +++ b/src/tools/rustbook/subcommand.rs diff --git a/src/rustbook/term.rs b/src/tools/rustbook/term.rs index cdd25e67c8f..cdd25e67c8f 100644 --- a/src/rustbook/term.rs +++ b/src/tools/rustbook/term.rs diff --git a/src/rustbook/test.rs b/src/tools/rustbook/test.rs index 72df0768e7b..72df0768e7b 100644 --- a/src/rustbook/test.rs +++ b/src/tools/rustbook/test.rs |
