diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py index e15304a7e6e67..bfba1a0dede24 100644 --- a/src/bootstrap/bootstrap.py +++ b/src/bootstrap/bootstrap.py @@ -398,13 +398,14 @@ def run(self, args, env=None, cwd=None): sys.exit(ret) def output(self, args, env=None, cwd=None): + default_encoding = sys.getdefaultencoding() proc = subprocess.Popen(args, stdout=subprocess.PIPE, env=env, cwd=cwd) (out, err) = proc.communicate() ret = proc.wait() if ret != 0: print(out) sys.exit(ret) - return out + return out.decode(default_encoding) def build_triple(self): default_encoding = sys.getdefaultencoding() @@ -570,10 +571,10 @@ def update_submodules(self): for submod in submodules: path, status = submod - if path.endswith(b"llvm") and \ + if path.endswith('llvm') and \ (self.get_toml('llvm-config') or self.get_mk('CFG_LLVM_ROOT')): continue - if path.endswith(b"jemalloc") and \ + if path.endswith('jemalloc') and \ (self.get_toml('jemalloc') or self.get_mk('CFG_JEMALLOC_ROOT')): continue submod_path = os.path.join(self.rust_root, path) diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index 0fb597564e33d..abad216d89be4 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -94,6 +94,7 @@ pub struct Config { pub backtrace: bool, // support for RUST_BACKTRACE // misc + pub low_priority: bool, pub channel: String, pub quiet_tests: bool, // Fallback musl-root for all targets @@ -148,6 +149,7 @@ struct Build { target: Vec, cargo: Option, rustc: Option, + low_priority: Option, compiler_docs: Option, docs: Option, submodules: Option, @@ -306,6 +308,7 @@ impl Config { config.nodejs = build.nodejs.map(PathBuf::from); config.gdb = build.gdb.map(PathBuf::from); config.python = build.python.map(PathBuf::from); + set(&mut config.low_priority, build.low_priority); set(&mut config.compiler_docs, build.compiler_docs); set(&mut config.docs, build.docs); set(&mut config.submodules, build.submodules); diff --git a/src/bootstrap/config.toml.example b/src/bootstrap/config.toml.example index df180be4e27ab..95cca96f7fcc0 100644 --- a/src/bootstrap/config.toml.example +++ b/src/bootstrap/config.toml.example @@ -152,6 +152,10 @@ # known-good version of OpenSSL, compile it, and link it to Cargo. #openssl-static = false +# Run the build with low priority, by setting the process group's "nice" value +# to +10 on Unix platforms, and by using a "low priority" job object on Windows. +#low-priority = false + # ============================================================================= # General install configuration options # ============================================================================= diff --git a/src/bootstrap/install.rs b/src/bootstrap/install.rs index 386b001971bad..dce0b1670e181 100644 --- a/src/bootstrap/install.rs +++ b/src/bootstrap/install.rs @@ -21,83 +21,110 @@ use std::process::Command; use Build; use dist::{sanitize_sh, tmpdir}; -/// Installs everything. -pub fn install(build: &Build, stage: u32, host: &str) { - let prefix_default = PathBuf::from("/usr/local"); - let sysconfdir_default = PathBuf::from("/etc"); - let docdir_default = PathBuf::from("share/doc/rust"); - let bindir_default = PathBuf::from("bin"); - let libdir_default = PathBuf::from("lib"); - let mandir_default = PathBuf::from("share/man"); - let prefix = build.config.prefix.as_ref().unwrap_or(&prefix_default); - let sysconfdir = build.config.sysconfdir.as_ref().unwrap_or(&sysconfdir_default); - let docdir = build.config.docdir.as_ref().unwrap_or(&docdir_default); - let bindir = build.config.bindir.as_ref().unwrap_or(&bindir_default); - let libdir = build.config.libdir.as_ref().unwrap_or(&libdir_default); - let mandir = build.config.mandir.as_ref().unwrap_or(&mandir_default); - - let sysconfdir = prefix.join(sysconfdir); - let docdir = prefix.join(docdir); - let bindir = prefix.join(bindir); - let libdir = prefix.join(libdir); - let mandir = prefix.join(mandir); - - let destdir = env::var_os("DESTDIR").map(PathBuf::from); - - let prefix = add_destdir(&prefix, &destdir); - let sysconfdir = add_destdir(&sysconfdir, &destdir); - let docdir = add_destdir(&docdir, &destdir); - let bindir = add_destdir(&bindir, &destdir); - let libdir = add_destdir(&libdir, &destdir); - let mandir = add_destdir(&mandir, &destdir); - - let empty_dir = build.out.join("tmp/empty_dir"); - t!(fs::create_dir_all(&empty_dir)); - if build.config.docs { - install_sh(&build, "docs", "rust-docs", &build.rust_package_vers(), - stage, host, &prefix, &sysconfdir, &docdir, &bindir, &libdir, - &mandir, &empty_dir); - } +pub struct Installer<'a> { + build: &'a Build, + prefix: PathBuf, + sysconfdir: PathBuf, + docdir: PathBuf, + bindir: PathBuf, + libdir: PathBuf, + mandir: PathBuf, +} - for target in build.config.target.iter() { - install_sh(&build, "std", "rust-std", &build.rust_package_vers(), - stage, target, &prefix, &sysconfdir, &docdir, &bindir, &libdir, - &mandir, &empty_dir); - } +impl<'a> Installer<'a> { + pub fn new(build: &'a Build) -> Installer<'a> { + let prefix_default = PathBuf::from("/usr/local"); + let sysconfdir_default = PathBuf::from("/etc"); + let docdir_default = PathBuf::from("share/doc/rust"); + let bindir_default = PathBuf::from("bin"); + let libdir_default = PathBuf::from("lib"); + let mandir_default = PathBuf::from("share/man"); + let prefix = build.config.prefix.as_ref().unwrap_or(&prefix_default); + let sysconfdir = build.config.sysconfdir.as_ref().unwrap_or(&sysconfdir_default); + let docdir = build.config.docdir.as_ref().unwrap_or(&docdir_default); + let bindir = build.config.bindir.as_ref().unwrap_or(&bindir_default); + let libdir = build.config.libdir.as_ref().unwrap_or(&libdir_default); + let mandir = build.config.mandir.as_ref().unwrap_or(&mandir_default); + + let sysconfdir = prefix.join(sysconfdir); + let docdir = prefix.join(docdir); + let bindir = prefix.join(bindir); + let libdir = prefix.join(libdir); + let mandir = prefix.join(mandir); + + let destdir = env::var_os("DESTDIR").map(PathBuf::from); - if build.config.extended { - install_sh(&build, "cargo", "cargo", &build.cargo_package_vers(), - stage, host, &prefix, &sysconfdir, &docdir, &bindir, &libdir, - &mandir, &empty_dir); - install_sh(&build, "rls", "rls", &build.rls_package_vers(), - stage, host, &prefix, &sysconfdir, &docdir, &bindir, &libdir, - &mandir, &empty_dir); + let prefix = add_destdir(&prefix, &destdir); + let sysconfdir = add_destdir(&sysconfdir, &destdir); + let docdir = add_destdir(&docdir, &destdir); + let bindir = add_destdir(&bindir, &destdir); + let libdir = add_destdir(&libdir, &destdir); + let mandir = add_destdir(&mandir, &destdir); + + Installer { + build, + prefix, + sysconfdir, + docdir, + bindir, + libdir, + mandir, + } } - install_sh(&build, "rustc", "rustc", &build.rust_package_vers(), - stage, host, &prefix, &sysconfdir, &docdir, &bindir, &libdir, - &mandir, &empty_dir); + /// Installs everything. + pub fn install(&self, stage: u32, host: &str) { + let empty_dir = self.build.out.join("tmp/empty_dir"); + t!(fs::create_dir_all(&empty_dir)); - t!(fs::remove_dir_all(&empty_dir)); -} + if self.build.config.docs { + self.install_sh("docs", "rust-docs", &self.build.rust_package_vers(), + stage, Some(host), &empty_dir); + } -fn install_sh(build: &Build, package: &str, name: &str, version: &str, stage: u32, host: &str, - prefix: &Path, sysconfdir: &Path, docdir: &Path, bindir: &Path, libdir: &Path, - mandir: &Path, empty_dir: &Path) { - println!("Install {} stage{} ({})", package, stage, host); - let package_name = format!("{}-{}-{}", name, version, host); - - let mut cmd = Command::new("sh"); - cmd.current_dir(empty_dir) - .arg(sanitize_sh(&tmpdir(build).join(&package_name).join("install.sh"))) - .arg(format!("--prefix={}", sanitize_sh(prefix))) - .arg(format!("--sysconfdir={}", sanitize_sh(sysconfdir))) - .arg(format!("--docdir={}", sanitize_sh(docdir))) - .arg(format!("--bindir={}", sanitize_sh(bindir))) - .arg(format!("--libdir={}", sanitize_sh(libdir))) - .arg(format!("--mandir={}", sanitize_sh(mandir))) - .arg("--disable-ldconfig"); - build.run(&mut cmd); + for target in self.build.config.target.iter() { + self.install_sh("std", "rust-std", &self.build.rust_package_vers(), + stage, Some(target), &empty_dir); + } + + if self.build.config.extended { + self.install_sh("cargo", "cargo", &self.build.cargo_package_vers(), + stage, Some(host), &empty_dir); + self.install_sh("rls", "rls", &self.build.rls_package_vers(), + stage, Some(host), &empty_dir); + self.install_sh("analysis", "rust-analysis", &self.build.rust_package_vers(), + stage, Some(host), &empty_dir); + self.install_sh("src", "rust-src", &self.build.rust_package_vers(), + stage, None, &empty_dir); + } + + self.install_sh("rustc", "rustc", &self.build.rust_package_vers(), + stage, Some(host), &empty_dir); + + t!(fs::remove_dir_all(&empty_dir)); + } + + fn install_sh(&self, package: &str, name: &str, version: &str, + stage: u32, host: Option<&str>, empty_dir: &Path) { + println!("Install {} stage{} ({:?})", package, stage, host); + let package_name = if let Some(host) = host { + format!("{}-{}-{}", name, version, host) + } else { + format!("{}-{}", name, version) + }; + + let mut cmd = Command::new("sh"); + cmd.current_dir(empty_dir) + .arg(sanitize_sh(&tmpdir(self.build).join(&package_name).join("install.sh"))) + .arg(format!("--prefix={}", sanitize_sh(&self.prefix))) + .arg(format!("--sysconfdir={}", sanitize_sh(&self.sysconfdir))) + .arg(format!("--docdir={}", sanitize_sh(&self.docdir))) + .arg(format!("--bindir={}", sanitize_sh(&self.bindir))) + .arg(format!("--libdir={}", sanitize_sh(&self.libdir))) + .arg(format!("--mandir={}", sanitize_sh(&self.mandir))) + .arg("--disable-ldconfig"); + self.build.run(&mut cmd); + } } fn add_destdir(path: &Path, destdir: &Option) -> PathBuf { diff --git a/src/bootstrap/job.rs b/src/bootstrap/job.rs index c3859275e6fb4..72a5d1338b8d0 100644 --- a/src/bootstrap/job.rs +++ b/src/bootstrap/job.rs @@ -42,6 +42,7 @@ use std::env; use std::io; use std::mem; +use Build; type HANDLE = *mut u8; type BOOL = i32; @@ -60,8 +61,10 @@ const DUPLICATE_SAME_ACCESS: DWORD = 0x2; const PROCESS_DUP_HANDLE: DWORD = 0x40; const JobObjectExtendedLimitInformation: JOBOBJECTINFOCLASS = 9; const JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE: DWORD = 0x2000; +const JOB_OBJECT_LIMIT_PRIORITY_CLASS: DWORD = 0x00000020; const SEM_FAILCRITICALERRORS: UINT = 0x0001; const SEM_NOGPFAULTERRORBOX: UINT = 0x0002; +const BELOW_NORMAL_PRIORITY_CLASS: DWORD = 0x00004000; extern "system" { fn CreateJobObjectW(lpJobAttributes: *mut u8, lpName: *const u8) -> HANDLE; @@ -118,7 +121,7 @@ struct JOBOBJECT_BASIC_LIMIT_INFORMATION { SchedulingClass: DWORD, } -pub unsafe fn setup() { +pub unsafe fn setup(build: &mut Build) { // Tell Windows to not show any UI on errors (such as not finding a required dll // during startup or terminating abnormally). This is important for running tests, // since some of them use abnormal termination by design. @@ -136,6 +139,10 @@ pub unsafe fn setup() { // children will reside in the job by default. let mut info = mem::zeroed::(); info.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE; + if build.config.low_priority { + info.BasicLimitInformation.LimitFlags |= JOB_OBJECT_LIMIT_PRIORITY_CLASS; + info.BasicLimitInformation.PriorityClass = BELOW_NORMAL_PRIORITY_CLASS; + } let r = SetInformationJobObject(job, JobObjectExtendedLimitInformation, &mut info as *mut _ as LPVOID, diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index ca9de43f54219..6ba5196bbbb0f 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -76,6 +76,9 @@ extern crate num_cpus; extern crate rustc_serialize; extern crate toml; +#[cfg(unix)] +extern crate libc; + use std::cmp; use std::collections::HashMap; use std::env; @@ -108,9 +111,29 @@ pub mod util; #[cfg(windows)] mod job; -#[cfg(not(windows))] +#[cfg(unix)] mod job { - pub unsafe fn setup() {} + use libc; + + //apparently glibc defines their own enum for this parameter, in a different type + #[cfg(not(any(target_env = "musl", target_env = "musleabi", target_env = "musleabihf", + target_os = "emscripten", target_arch = "mips", target_arch = "mipsel")))] + const PRIO_PGRP: libc::c_uint = libc::PRIO_PGRP as libc::c_uint; + #[cfg(any(target_env = "musl", target_env = "musleabi", target_env = "musleabihf", + target_os = "emscripten", target_arch = "mips", target_arch = "mipsel"))] + const PRIO_PGRP: libc::c_int = libc::PRIO_PGRP; + + pub unsafe fn setup(build: &mut ::Build) { + if build.config.low_priority { + libc::setpriority(PRIO_PGRP, 0, 10); + } + } +} + +#[cfg(not(any(unix, windows)))] +mod job { + pub unsafe fn setup(_build: &mut ::Build) { + } } pub use config::Config; @@ -263,7 +286,7 @@ impl Build { /// Executes the entire build, as configured by the flags and configuration. pub fn build(&mut self) { unsafe { - job::setup(); + job::setup(self); } if let Subcommand::Clean = self.flags.cmd { diff --git a/src/bootstrap/step.rs b/src/bootstrap/step.rs index 92666e8e63907..57915446e1d1a 100644 --- a/src/bootstrap/step.rs +++ b/src/bootstrap/step.rs @@ -761,7 +761,7 @@ pub fn build_rules<'a>(build: &'a Build) -> Rules { .run(move |s| dist::rls(build, s.stage, s.target)); rules.dist("install", "path/to/nowhere") .dep(|s| s.name("default:dist")) - .run(move |s| install::install(build, s.stage, s.target)); + .run(move |s| install::Installer::new(build).install(s.stage, s.target)); rules.dist("dist-cargo", "cargo") .host(true) .only_host_build(true) diff --git a/src/librustc/hir/map/definitions.rs b/src/librustc/hir/map/definitions.rs index 6118df2ddfc89..9537b40b28a0b 100644 --- a/src/librustc/hir/map/definitions.rs +++ b/src/librustc/hir/map/definitions.rs @@ -16,6 +16,7 @@ use hir; use hir::def_id::{CrateNum, DefId, DefIndex, LOCAL_CRATE, DefIndexAddressSpace}; +use ich::Fingerprint; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::indexed_vec::IndexVec; use rustc_data_structures::stable_hasher::StableHasher; @@ -34,7 +35,7 @@ use util::nodemap::NodeMap; pub struct DefPathTable { index_to_key: [Vec; 2], key_to_index: FxHashMap, - def_path_hashes: [Vec; 2], + def_path_hashes: [Vec; 2], } // Unfortunately we have to provide a manual impl of Clone because of the @@ -55,7 +56,7 @@ impl DefPathTable { fn allocate(&mut self, key: DefKey, - def_path_hash: u64, + def_path_hash: Fingerprint, address_space: DefIndexAddressSpace) -> DefIndex { let index = { @@ -79,7 +80,7 @@ impl DefPathTable { } #[inline(always)] - pub fn def_path_hash(&self, index: DefIndex) -> u64 { + pub fn def_path_hash(&self, index: DefIndex) -> Fingerprint { self.def_path_hashes[index.address_space().index()] [index.as_array_index()] } @@ -146,8 +147,8 @@ impl Decodable for DefPathTable { let index_to_key_lo: Vec = Decodable::decode(d)?; let index_to_key_hi: Vec = Decodable::decode(d)?; - let def_path_hashes_lo: Vec = Decodable::decode(d)?; - let def_path_hashes_hi: Vec = Decodable::decode(d)?; + let def_path_hashes_lo: Vec = Decodable::decode(d)?; + let def_path_hashes_hi: Vec = Decodable::decode(d)?; let index_to_key = [index_to_key_lo, index_to_key_hi]; let def_path_hashes = [def_path_hashes_lo, def_path_hashes_hi]; @@ -210,7 +211,7 @@ pub struct DefKey { } impl DefKey { - fn compute_stable_hash(&self, parent_hash: u64) -> u64 { + fn compute_stable_hash(&self, parent_hash: Fingerprint) -> Fingerprint { let mut hasher = StableHasher::new(); // We hash a 0u8 here to disambiguate between regular DefPath hashes, @@ -221,7 +222,7 @@ impl DefKey { hasher.finish() } - fn root_parent_stable_hash(crate_name: &str, crate_disambiguator: &str) -> u64 { + fn root_parent_stable_hash(crate_name: &str, crate_disambiguator: &str) -> Fingerprint { let mut hasher = StableHasher::new(); // Disambiguate this from a regular DefPath hash, // see compute_stable_hash() above. @@ -396,7 +397,7 @@ impl Definitions { } #[inline(always)] - pub fn def_path_hash(&self, index: DefIndex) -> u64 { + pub fn def_path_hash(&self, index: DefIndex) -> Fingerprint { self.table.def_path_hash(index) } diff --git a/src/librustc/ich/fingerprint.rs b/src/librustc/ich/fingerprint.rs index ccdbab88b8b9c..a947f6aeff709 100644 --- a/src/librustc/ich/fingerprint.rs +++ b/src/librustc/ich/fingerprint.rs @@ -10,95 +10,75 @@ use rustc_serialize::{Encodable, Decodable, Encoder, Decoder}; use rustc_data_structures::stable_hasher; -use rustc_data_structures::ToHex; - -const FINGERPRINT_LENGTH: usize = 16; +use std::mem; +use std::slice; #[derive(Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Clone, Copy)] -pub struct Fingerprint(pub [u8; FINGERPRINT_LENGTH]); +pub struct Fingerprint(u64, u64); impl Fingerprint { #[inline] pub fn zero() -> Fingerprint { - Fingerprint([0; FINGERPRINT_LENGTH]) + Fingerprint(0, 0) } + #[inline] pub fn from_smaller_hash(hash: u64) -> Fingerprint { - let mut result = Fingerprint::zero(); - result.0[0] = (hash >> 0) as u8; - result.0[1] = (hash >> 8) as u8; - result.0[2] = (hash >> 16) as u8; - result.0[3] = (hash >> 24) as u8; - result.0[4] = (hash >> 32) as u8; - result.0[5] = (hash >> 40) as u8; - result.0[6] = (hash >> 48) as u8; - result.0[7] = (hash >> 56) as u8; - result + Fingerprint(hash, hash) } + #[inline] pub fn to_smaller_hash(&self) -> u64 { - ((self.0[0] as u64) << 0) | - ((self.0[1] as u64) << 8) | - ((self.0[2] as u64) << 16) | - ((self.0[3] as u64) << 24) | - ((self.0[4] as u64) << 32) | - ((self.0[5] as u64) << 40) | - ((self.0[6] as u64) << 48) | - ((self.0[7] as u64) << 56) + self.0 } pub fn to_hex(&self) -> String { - self.0.to_hex() + format!("{:x}{:x}", self.0, self.1) } } impl Encodable for Fingerprint { #[inline] fn encode(&self, s: &mut S) -> Result<(), S::Error> { - for &byte in &self.0 { - s.emit_u8(byte)?; - } - Ok(()) + s.emit_u64(self.0.to_le())?; + s.emit_u64(self.1.to_le()) } } impl Decodable for Fingerprint { #[inline] fn decode(d: &mut D) -> Result { - let mut result = Fingerprint([0u8; FINGERPRINT_LENGTH]); - for byte in &mut result.0 { - *byte = d.read_u8()?; - } - Ok(result) + let _0 = u64::from_le(d.read_u64()?); + let _1 = u64::from_le(d.read_u64()?); + Ok(Fingerprint(_0, _1)) } } impl ::std::fmt::Display for Fingerprint { fn fmt(&self, formatter: &mut ::std::fmt::Formatter) -> Result<(), ::std::fmt::Error> { - for i in 0 .. self.0.len() { - if i > 0 { - write!(formatter, "::")?; - } - - write!(formatter, "{}", self.0[i])?; - } - Ok(()) + write!(formatter, "{:x}-{:x}", self.0, self.1) } } - impl stable_hasher::StableHasherResult for Fingerprint { fn finish(mut hasher: stable_hasher::StableHasher) -> Self { - let mut fingerprint = Fingerprint::zero(); - fingerprint.0.copy_from_slice(hasher.finalize()); - fingerprint + let hash_bytes: &[u8] = hasher.finalize(); + + assert!(hash_bytes.len() >= mem::size_of::() * 2); + let hash_bytes: &[u64] = unsafe { + slice::from_raw_parts(hash_bytes.as_ptr() as *const u64, 2) + }; + + // The bytes returned bytes the Blake2B hasher are always little-endian. + Fingerprint(u64::from_le(hash_bytes[0]), u64::from_le(hash_bytes[1])) } } impl stable_hasher::HashStable for Fingerprint { + #[inline] fn hash_stable(&self, _: &mut CTX, hasher: &mut stable_hasher::StableHasher) { - ::std::hash::Hash::hash(&self.0, hasher); + ::std::hash::Hash::hash(self, hasher); } } diff --git a/src/librustc/ich/hcx.rs b/src/librustc/ich/hcx.rs index 786d1c5035d96..f25ec8ecd4d71 100644 --- a/src/librustc/ich/hcx.rs +++ b/src/librustc/ich/hcx.rs @@ -110,7 +110,7 @@ impl<'a, 'tcx: 'a> StableHashingContext<'a, 'tcx> { } #[inline] - pub fn def_path_hash(&mut self, def_id: DefId) -> u64 { + pub fn def_path_hash(&mut self, def_id: DefId) -> ich::Fingerprint { self.tcx.def_path_hash(def_id) } diff --git a/src/librustc/middle/cstore.rs b/src/librustc/middle/cstore.rs index a68aca4600054..8ad1db7859566 100644 --- a/src/librustc/middle/cstore.rs +++ b/src/librustc/middle/cstore.rs @@ -282,7 +282,7 @@ pub trait CrateStore { -> Option; fn def_key(&self, def: DefId) -> DefKey; fn def_path(&self, def: DefId) -> hir_map::DefPath; - fn def_path_hash(&self, def: DefId) -> u64; + fn def_path_hash(&self, def: DefId) -> ich::Fingerprint; fn struct_field_names(&self, def: DefId) -> Vec; fn item_children(&self, did: DefId) -> Vec; fn load_macro(&self, did: DefId, sess: &Session) -> LoadedMacro; @@ -414,7 +414,7 @@ impl CrateStore for DummyCrateStore { fn def_path(&self, def: DefId) -> hir_map::DefPath { bug!("relative_def_path") } - fn def_path_hash(&self, def: DefId) -> u64 { + fn def_path_hash(&self, def: DefId) -> ich::Fingerprint { bug!("wa") } fn struct_field_names(&self, def: DefId) -> Vec { bug!("struct_field_names") } diff --git a/src/librustc/session/filesearch.rs b/src/librustc/session/filesearch.rs index 82c2425aead73..47b988a21b4c1 100644 --- a/src/librustc/session/filesearch.rs +++ b/src/librustc/session/filesearch.rs @@ -159,9 +159,14 @@ pub fn get_or_default_sysroot() -> PathBuf { }) } - match canonicalize(env::current_exe().ok()) { - Some(mut p) => { p.pop(); p.pop(); p } - None => bug!("can't determine value for sysroot") + match env::current_exe() { + Ok(exe) => { + match canonicalize(Some(exe)) { + Some(mut p) => { p.pop(); p.pop(); return p; }, + None => bug!("can't determine value for sysroot") + } + } + Err(ref e) => panic!(format!("failed to get current_exe: {}", e)) } } diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index a86d7351ef472..359722ce96ec9 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -19,7 +19,7 @@ use dep_graph::DepNode; use hir::{map as hir_map, FreevarMap, TraitMap}; use hir::def::{Def, CtorKind, ExportMap}; use hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX, LOCAL_CRATE}; -use ich::StableHashingContext; +use ich::{self, StableHashingContext}; use middle::const_val::ConstVal; use middle::lang_items::{FnTraitLangItem, FnMutTraitLangItem, FnOnceTraitLangItem}; use middle::privacy::AccessLevels; @@ -2248,7 +2248,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { } #[inline] - pub fn def_path_hash(self, def_id: DefId) -> u64 { + pub fn def_path_hash(self, def_id: DefId) -> ich::Fingerprint { if def_id.is_local() { self.hir.definitions().def_path_hash(def_id.index) } else { diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index cfbf1244db3ad..348d164af4190 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -29,6 +29,7 @@ use util::nodemap::FxHashMap; use serialize; use hir; +use ich; use self::InferTy::*; use self::TypeVariants::*; @@ -849,7 +850,7 @@ impl<'a, 'tcx, 'gcx> ExistentialProjection<'tcx> { self.item_name // safe to skip the binder to access a name } - pub fn sort_key(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> (u64, InternedString) { + pub fn sort_key(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> (ich::Fingerprint, InternedString) { // We want something here that is stable across crate boundaries. // The DefId isn't but the `deterministic_hash` of the corresponding // DefPath is. @@ -884,7 +885,7 @@ impl<'a, 'tcx, 'gcx> PolyExistentialProjection<'tcx> { self.skip_binder().item_name() } - pub fn sort_key(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> (u64, InternedString) { + pub fn sort_key(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> (ich::Fingerprint, InternedString) { self.skip_binder().sort_key(tcx) } diff --git a/src/librustc/ty/trait_def.rs b/src/librustc/ty/trait_def.rs index 865297c7ecbfd..86774136bd6cb 100644 --- a/src/librustc/ty/trait_def.rs +++ b/src/librustc/ty/trait_def.rs @@ -9,6 +9,7 @@ // except according to those terms. use hir::def_id::DefId; +use ich::Fingerprint; use traits::specialization_graph; use ty::fast_reject; use ty::fold::TypeFoldable; @@ -32,7 +33,7 @@ pub struct TraitDef { /// The ICH of this trait's DefPath, cached here so it doesn't have to be /// recomputed all the time. - pub def_path_hash: u64, + pub def_path_hash: Fingerprint, } // We don't store the list of impls in a flat list because each cached list of @@ -94,7 +95,7 @@ impl<'a, 'gcx, 'tcx> TraitDef { unsafety: hir::Unsafety, paren_sugar: bool, has_default_impl: bool, - def_path_hash: u64) + def_path_hash: Fingerprint) -> TraitDef { TraitDef { def_id, diff --git a/src/librustc_incremental/calculate_svh/mod.rs b/src/librustc_incremental/calculate_svh/mod.rs index 8cdabc1d894e2..c9ed9ad3c7d2d 100644 --- a/src/librustc_incremental/calculate_svh/mod.rs +++ b/src/librustc_incremental/calculate_svh/mod.rs @@ -224,7 +224,7 @@ impl<'a, 'tcx: 'a> ComputeItemHashesVisitor<'a, 'tcx> { { let tcx = self.hcx.tcx(); - let mut impls: Vec<(u64, Fingerprint)> = krate + let mut impls: Vec<(Fingerprint, Fingerprint)> = krate .trait_impls .iter() .map(|(&trait_id, impls)| { diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs index 4b7083590d24a..7478f902e061a 100644 --- a/src/librustc_metadata/cstore_impl.rs +++ b/src/librustc_metadata/cstore_impl.rs @@ -17,6 +17,7 @@ use rustc::middle::cstore::{CrateStore, CrateSource, LibSource, DepKind, ExternCrate, NativeLibrary, MetadataLoader, LinkMeta, LinkagePreference, LoadedMacro, EncodedMetadata}; use rustc::hir::def; +use rustc::ich; use rustc::middle::lang_items; use rustc::session::Session; use rustc::ty::{self, TyCtxt}; @@ -337,7 +338,7 @@ impl CrateStore for cstore::CStore { self.get_crate_data(def.krate).def_path(def.index) } - fn def_path_hash(&self, def: DefId) -> u64 { + fn def_path_hash(&self, def: DefId) -> ich::Fingerprint { self.get_crate_data(def.krate).def_path_hash(def.index) } diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs index 754f27810c453..d8826d87d4d0f 100644 --- a/src/librustc_metadata/decoder.rs +++ b/src/librustc_metadata/decoder.rs @@ -16,6 +16,7 @@ use schema::*; use rustc::dep_graph::{DepGraph, DepNode, GlobalMetaDataKind}; use rustc::hir::map::{DefKey, DefPath, DefPathData}; use rustc::hir; +use rustc::ich; use rustc::middle::cstore::LinkagePreference; use rustc::hir::def::{self, Def, CtorKind}; @@ -1106,7 +1107,7 @@ impl<'a, 'tcx> CrateMetadata { } #[inline] - pub fn def_path_hash(&self, index: DefIndex) -> u64 { + pub fn def_path_hash(&self, index: DefIndex) -> ich::Fingerprint { self.def_path_table.def_path_hash(index) } diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index c115a6ccba609..f09ce1cc64849 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -215,14 +215,14 @@ } else if (ev.target.tagName === 'SPAN' && hasClass(ev.target.parentNode, 'line-numbers')) { var prev_id = 0; - function set_fragment(name) { + var set_fragment = function (name) { if (browserSupportsHistoryApi()) { history.replaceState(null, null, '#' + name); window.hashchange(); } else { location.replace('#' + name); } - } + }; var cur_id = parseInt(ev.target.id, 10); @@ -685,7 +685,7 @@ } function escape(content) { - let h1 = document.createElement('h1'); + var h1 = document.createElement('h1'); h1.textContent = content; return h1.innerHTML; } diff --git a/src/libstd/env.rs b/src/libstd/env.rs index 64eb52e28bc42..96c10c5d10d1a 100644 --- a/src/libstd/env.rs +++ b/src/libstd/env.rs @@ -43,16 +43,19 @@ use sys::os as os_imp; /// use std::env; /// /// // We assume that we are in a valid directory. -/// let p = env::current_dir().unwrap(); -/// println!("The current directory is {}", p.display()); +/// let path = env::current_dir().unwrap(); +/// println!("The current directory is {}", path.display()); /// ``` #[stable(feature = "env", since = "1.0.0")] pub fn current_dir() -> io::Result { os_imp::getcwd() } -/// Changes the current working directory to the specified path, returning -/// whether the change was completed successfully or not. +/// Changes the current working directory to the specified path. +/// +/// Returns an [`Err`] if the operation fails. +/// +/// [`Err`]: ../../std/result/enum.Result.html#method.err /// /// # Examples /// @@ -65,8 +68,8 @@ pub fn current_dir() -> io::Result { /// println!("Successfully changed working directory to {}!", root.display()); /// ``` #[stable(feature = "env", since = "1.0.0")] -pub fn set_current_dir>(p: P) -> io::Result<()> { - os_imp::chdir(p.as_ref()) +pub fn set_current_dir>(path: P) -> io::Result<()> { + os_imp::chdir(path.as_ref()) } /// An iterator over a snapshot of the environment variables of this process. @@ -175,10 +178,10 @@ impl fmt::Debug for VarsOs { /// /// The returned result is [`Ok(s)`] if the environment variable is present and is /// valid unicode. If the environment variable is not present, or it is not -/// valid unicode, then [`Err`] will be returned. +/// valid unicode, then [`VarError`] will be returned. /// /// [`Ok(s)`]: ../result/enum.Result.html#variant.Ok -/// [`Err`]: ../result/enum.Result.html#variant.Err +/// [`VarError`]: enum.VarError.html /// /// # Examples /// @@ -199,7 +202,7 @@ pub fn var>(key: K) -> Result { fn _var(key: &OsStr) -> Result { match var_os(key) { Some(s) => s.into_string().map_err(VarError::NotUnicode), - None => Err(VarError::NotPresent) + None => Err(VarError::NotPresent), } } diff --git a/src/libstd/process.rs b/src/libstd/process.rs index 3896fc20a2dde..d0e7defbbbb9a 100644 --- a/src/libstd/process.rs +++ b/src/libstd/process.rs @@ -754,6 +754,13 @@ impl fmt::Debug for Stdio { } /// Describes the result of a process after it has terminated. +/// +/// This `struct` is used to represent the exit status of a child process. +/// Child processes are created via the [`Command`] struct and their exit +/// status is exposed through the [`status`] method. +/// +/// [`Command`]: struct.Command.html +/// [`status`]: struct.Command.html#method.status #[derive(PartialEq, Eq, Clone, Copy, Debug)] #[stable(feature = "process", since = "1.0.0")] pub struct ExitStatus(imp::ExitStatus); @@ -788,6 +795,22 @@ impl ExitStatus { /// On Unix, this will return `None` if the process was terminated /// by a signal; `std::os::unix` provides an extension trait for /// extracting the signal and other details from the `ExitStatus`. + /// + /// # Examples + /// + /// ```no_run + /// use std::process::Command; + /// + /// let status = Command::new("mkdir") + /// .arg("projects") + /// .status() + /// .expect("failed to execute mkdir"); + /// + /// match status.code() { + /// Some(code) => println!("Exited with status code: {}", code), + /// None => println!("Process terminated by signal") + /// } + /// ``` #[stable(feature = "process", since = "1.0.0")] pub fn code(&self) -> Option { self.0.code() diff --git a/src/libstd/sync/mpsc/mod.rs b/src/libstd/sync/mpsc/mod.rs index 2cb649ce67b9c..284a5fbd9d506 100644 --- a/src/libstd/sync/mpsc/mod.rs +++ b/src/libstd/sync/mpsc/mod.rs @@ -1067,7 +1067,7 @@ impl Receiver { Receiver { inner: UnsafeCell::new(inner) } } - /// Attempts to return a pending value on this receiver without blocking + /// Attempts to return a pending value on this receiver without blocking. /// /// This method will never block the caller in order to wait for data to /// become available. Instead, this will always return immediately with a diff --git a/src/libstd/sys/unix/os.rs b/src/libstd/sys/unix/os.rs index 36928696c4059..8e41fd009be67 100644 --- a/src/libstd/sys/unix/os.rs +++ b/src/libstd/sys/unix/os.rs @@ -253,7 +253,12 @@ pub fn current_exe() -> io::Result { #[cfg(any(target_os = "linux", target_os = "android", target_os = "emscripten"))] pub fn current_exe() -> io::Result { - ::fs::read_link("/proc/self/exe") + let selfexe = PathBuf::from("/proc/self/exe"); + if selfexe.exists() { + ::fs::read_link(selfexe) + } else { + Err(io::Error::new(io::ErrorKind::Other, "no /proc/self/exe available. Is /proc mounted?")) + } } #[cfg(any(target_os = "macos", target_os = "ios"))] diff --git a/src/tools/cargo b/src/tools/cargo index 41e490480b01e..397359840ecad 160000 --- a/src/tools/cargo +++ b/src/tools/cargo @@ -1 +1 @@ -Subproject commit 41e490480b01ef8d15ef061b578fbf1e08d0faa9 +Subproject commit 397359840ecad02d5fe69b2a0cf328e98235ffea