diff --git a/mk/crates.mk b/mk/crates.mk index 1ecceb9280a7c..d8e0390504b97 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 8321f93c90f61..0d334219b4fe9 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 0000000000000..19293e80217e3 --- /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 or the MIT license +// , 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 fb0a840bfa22b..0a293579cf67d 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 937a234bec86d..51bf752e06d34 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 98d821b8b9023..058f27c33f607 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>, } +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 ba0095ce84980..720ba4fd2094d 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>) { + 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 6c700671f1111..35d22ee5d2658 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 fa3dee2f358f9..7d7930021498b 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 4e9d6da9157de..d403d76bb1400 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 0000000000000..8c618196113ba --- /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 or the MIT license +// , 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::>(); + 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 f2b92e6dec4dd..50350213074bf 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 800be13a243fb..1af05bfea19a2 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 d6495d02e1189..742433b99ac5f 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 5ab1a1d9c10f4..8d837d1a1a916 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 9ea1d21816191..9b243bc72ef71 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 9d78721ad3644..2106f32fafade 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 dc653b446da45..23e0af8113bf1 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 922e1b0fc5d6d..cef6edf68ee8d 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 1446d00b9ea6b..69a9899d82bc6 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 5789cd8edfc09..9798e323a6140 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 cae6520bdb286..02190d11b421f 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`]: ../vec/struct.Vec.html + /// [`&str`]: ../../std/primitive.str.html + /// [`u8`]: ../../std/primitive.u8.html + /// [`Vec`]: ../../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 cb9bf935cdb58..dfd2ba9154d53 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 0c3807d8ca0b5..a23b303f4bab1 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`]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 { /// 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 6cc3b4e01b865..7927b33804471 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(&mut self, padding: usize, default: Alignment, + fn with_padding(&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 fb8eda820f52c..06821ff94f712 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`]: ../option/enum.Option.html + /// [`Option`]: ../../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, E>`. See the examples /// below for more. /// - /// [`String`]: ../string/struct.String.html - /// [`Result`]: ../result/enum.Result.html - /// [`char`]: ../primitive.char.html + /// [`String`]: ../../std/string/struct.String.html + /// [`Result`]: ../../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` on the left-hand side. This is because /// we could collect into, for example, a [`VecDeque`] instead: /// - /// [`VecDeque`]: ../collections/struct.VecDeque.html + /// [`VecDeque`]: ../../std/collections/struct.VecDeque.html /// /// ``` /// use std::collections::VecDeque; diff --git a/src/libcore/macros.rs b/src/libcore/macros.rs index 154ca30c62dd1..f923668688b8c 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 ed370bb91648f..0b306c810b195 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(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 8acd0c8f2cf06..e59e8567d5b62 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 f5abdf65a5b4f..dee13bf3d3db1 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>); @@ -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, 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 e943f861e9d8c..07fae35b23be3 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 115002867555d..5bc5c78616093 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> Iterator for DecodeUtf16 { /// `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 c14e4af810310..061047cbd2f6d 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 { 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 5921093bcac1e..a4b8c9bf5f7db 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 { + match *self { + ResolvedPath { did, .. } => Some(did), + _ => None, + } + } } impl PrimitiveType { diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 5a6fe060eb80b..c30fd39616c44 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>>, pub external_typarams: RefCell>>, pub inlined: RefCell>>, - pub populated_crate_impls: RefCell>, + pub all_crate_impls: RefCell>>, pub deref_trait_did: Cell>, } @@ -179,7 +179,7 @@ pub fn run_core(search_paths: SearchPaths, cfgs: Vec, 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 6294b676651fe..d873c9ec340c0 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 7f57d6dc650ba..3705302592432 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 a39311f7d108d..446e22a20ad7d 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 24e35b87bf284..65ed879c4ada4 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 c684c474efa9e..0000000000000 --- 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 e4432720ab4f4..a271835164043 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", @@ -66,14 +65,6 @@ dependencies = [ "serialize 0.0.0", ] -[[package]] -name = "rustbook" -version = "0.0.0" -dependencies = [ - "rustc_back 0.0.0", - "rustdoc 0.0.0", -] - [[package]] name = "rustc" version = "0.0.0" diff --git a/src/rustc/Cargo.toml b/src/rustc/Cargo.toml index 9fcefd9d3a4dd..7431c35efba01 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 6f78f78bc55a6..0000000000000 --- 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 or the MIT license -// , 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 0000000000000..b7d2cfcaaa1a8 --- /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 0000000000000..5c5ca273e9ca3 --- /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 similarity index 88% rename from src/error_index_generator/main.rs rename to src/tools/error_index_generator/main.rs index db9dd006f3c86..4343aef00a908 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(err_map: &ErrorMetadataMap, output_path: &Pat formatter.footer(&mut output_file) } -fn main_with_result(format: OutputFormat) -> Result<(), Box> { +fn main_with_result(format: OutputFormat, dst: &Path) -> Result<(), Box> { 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(""), + } + }); + (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 0000000000000..8e94137d2139b --- /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 0000000000000..29fc78a65e916 --- /dev/null +++ b/src/tools/linkchecker/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "linkchecker" +version = "0.1.0" +authors = ["Alex Crichton "] + +[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 0000000000000..e5e88081bc43e --- /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 or the MIT license +// , 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 0000000000000..e541ce4b2b807 --- /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 0000000000000..956392ca540cd --- /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 similarity index 100% rename from src/rustbook/book.rs rename to src/tools/rustbook/book.rs diff --git a/src/rustbook/build.rs b/src/tools/rustbook/build.rs similarity index 99% rename from src/rustbook/build.rs rename to src/tools/rustbook/build.rs index 4b6d67d2d2620..70ed98519f972 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 similarity index 100% rename from src/rustbook/error.rs rename to src/tools/rustbook/error.rs diff --git a/src/rustbook/help.rs b/src/tools/rustbook/help.rs similarity index 100% rename from src/rustbook/help.rs rename to src/tools/rustbook/help.rs diff --git a/src/rustbook/main.rs b/src/tools/rustbook/main.rs similarity index 100% rename from src/rustbook/main.rs rename to src/tools/rustbook/main.rs diff --git a/src/rustbook/serve.rs b/src/tools/rustbook/serve.rs similarity index 100% rename from src/rustbook/serve.rs rename to src/tools/rustbook/serve.rs diff --git a/src/rustbook/static/rustbook.css b/src/tools/rustbook/static/rustbook.css similarity index 100% rename from src/rustbook/static/rustbook.css rename to src/tools/rustbook/static/rustbook.css diff --git a/src/rustbook/static/rustbook.js b/src/tools/rustbook/static/rustbook.js similarity index 100% rename from src/rustbook/static/rustbook.js rename to src/tools/rustbook/static/rustbook.js diff --git a/src/rustbook/subcommand.rs b/src/tools/rustbook/subcommand.rs similarity index 100% rename from src/rustbook/subcommand.rs rename to src/tools/rustbook/subcommand.rs diff --git a/src/rustbook/term.rs b/src/tools/rustbook/term.rs similarity index 100% rename from src/rustbook/term.rs rename to src/tools/rustbook/term.rs diff --git a/src/rustbook/test.rs b/src/tools/rustbook/test.rs similarity index 100% rename from src/rustbook/test.rs rename to src/tools/rustbook/test.rs