From a42c0257c7ed05558f685a77db0de08379feeef8 Mon Sep 17 00:00:00 2001 From: Marco A L Barbosa Date: Tue, 18 Apr 2017 13:40:00 -0300 Subject: [PATCH 01/25] Add bootstrap support for android --- src/bootstrap/bootstrap.py | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py index 2e33b4511949d..e27f4091b1914 100644 --- a/src/bootstrap/bootstrap.py +++ b/src/bootstrap/bootstrap.py @@ -415,7 +415,11 @@ def build_triple(self): # The goal here is to come up with the same triple as LLVM would, # at least for the subset of platforms we're willing to target. if ostype == 'Linux': - ostype = 'unknown-linux-gnu' + os = subprocess.check_output(['uname', '-o']).strip().decode(default_encoding) + if os == 'Android': + ostype = 'linux-android' + else: + ostype = 'unknown-linux-gnu' elif ostype == 'FreeBSD': ostype = 'unknown-freebsd' elif ostype == 'DragonFly': @@ -472,15 +476,21 @@ def build_triple(self): cputype = 'i686' elif cputype in {'xscale', 'arm'}: cputype = 'arm' + if ostype == 'linux-android': + ostype = 'linux-androideabi' elif cputype == 'armv6l': cputype = 'arm' - ostype += 'eabihf' + if ostype == 'linux-android': + ostype = 'linux-androideabi' + else: + ostype += 'eabihf' elif cputype in {'armv7l', 'armv8l'}: cputype = 'armv7' - ostype += 'eabihf' - elif cputype == 'aarch64': - cputype = 'aarch64' - elif cputype == 'arm64': + if ostype == 'linux-android': + ostype = 'linux-androideabi' + else: + ostype += 'eabihf' + elif cputype in {'aarch64', 'arm64'}: cputype = 'aarch64' elif cputype == 'mips': if sys.byteorder == 'big': From c49d0906da09972f447013834dcf891ec887151b Mon Sep 17 00:00:00 2001 From: Tobias Bucher Date: Fri, 21 Apr 2017 10:32:13 +0200 Subject: [PATCH 02/25] Specify behavior of `write_all` for `ErrorKind::Interrupted` errors Also spell out that read and write operations should be retried on `ErrorKind::Interrupted` errors. Fixes #38494. --- src/libstd/io/mod.rs | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs index cd096c115ba5a..39a0602eab826 100644 --- a/src/libstd/io/mod.rs +++ b/src/libstd/io/mod.rs @@ -466,6 +466,9 @@ pub trait Read { /// variant will be returned. If an error is returned then it must be /// guaranteed that no bytes were read. /// + /// An error of the `ErrorKind::Interrupted` kind is non-fatal and the read + /// operation should be retried if there is nothing else to do. + /// /// # Examples /// /// [`File`][file]s implement `Read`: @@ -481,7 +484,7 @@ pub trait Read { /// let mut f = File::open("foo.txt")?; /// let mut buffer = [0; 10]; /// - /// // read 10 bytes + /// // read up to 10 bytes /// f.read(&mut buffer[..])?; /// # Ok(()) /// # } @@ -885,6 +888,9 @@ pub trait Write { /// It is **not** considered an error if the entire buffer could not be /// written to this writer. /// + /// An error of the `ErrorKind::Interrupted` kind is non-fatal and the + /// write operation should be retried if there is nothing else to do. + /// /// # Examples /// /// ``` @@ -894,6 +900,7 @@ pub trait Write { /// # fn foo() -> std::io::Result<()> { /// let mut buffer = File::create("foo.txt")?; /// + /// // Writes some prefix of the byte string, not necessarily all of it. /// buffer.write(b"some bytes")?; /// # Ok(()) /// # } @@ -929,14 +936,17 @@ pub trait Write { /// Attempts to write an entire buffer into this write. /// - /// This method will continuously call `write` while there is more data to - /// write. This method will not return until the entire buffer has been - /// successfully written or an error occurs. The first error generated from - /// this method will be returned. + /// This method will continuously call `write` until there is no more data + /// to be written or an error of non-`ErrorKind::Interrupted` kind is + /// returned. This method will not return until the entire buffer has been + /// successfully written or such an error occurs. The first error that is + /// not of `ErrorKind::Interrupted` kind generated from this method will be + /// returned. /// /// # Errors /// - /// This function will return the first error that `write` returns. + /// This function will return the first error of + /// non-`ErrorKind::Interrupted` kind that `write` returns. /// /// # Examples /// From e1afddc29c7a056f855c0523e598c3bda42f4aea Mon Sep 17 00:00:00 2001 From: Jessica Hamilton Date: Sat, 22 Apr 2017 13:47:36 +1200 Subject: [PATCH 03/25] Haiku: fix initial platform support --- src/librustc_back/target/haiku_base.rs | 3 ++- src/librustc_data_structures/flock.rs | 1 + src/libunwind/build.rs | 2 ++ 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/librustc_back/target/haiku_base.rs b/src/librustc_back/target/haiku_base.rs index bfdc9faaa8a73..8e7f463563c38 100644 --- a/src/librustc_back/target/haiku_base.rs +++ b/src/librustc_back/target/haiku_base.rs @@ -16,9 +16,10 @@ pub fn opts() -> TargetOptions { linker: "cc".to_string(), dynamic_linking: true, executables: true, - has_rpath: true, + has_rpath: false, target_family: Some("unix".to_string()), linker_is_gnu: true, + no_integrated_as: true, .. Default::default() } } diff --git a/src/librustc_data_structures/flock.rs b/src/librustc_data_structures/flock.rs index 26417e3ba7cd1..32f0fd4199776 100644 --- a/src/librustc_data_structures/flock.rs +++ b/src/librustc_data_structures/flock.rs @@ -113,6 +113,7 @@ mod imp { pub l_sysid: libc::c_int, } + pub const F_RDLCK: libc::c_short = 0x0040; pub const F_UNLCK: libc::c_short = 0x0200; pub const F_WRLCK: libc::c_short = 0x0400; pub const F_SETLK: libc::c_int = 0x0080; diff --git a/src/libunwind/build.rs b/src/libunwind/build.rs index 9b8099d55a024..be9aa6c5d40ba 100644 --- a/src/libunwind/build.rs +++ b/src/libunwind/build.rs @@ -39,5 +39,7 @@ fn main() { println!("cargo:rustc-link-lib=static-nobundle=pthread"); } else if target.contains("fuchsia") { println!("cargo:rustc-link-lib=unwind"); + } else if target.contains("haiku") { + println!("cargo:rustc-link-lib=gcc_s"); } } From f8c6436173f9ccbe79eaf021161f26b601eef026 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Sun, 23 Apr 2017 21:47:09 -0700 Subject: [PATCH 04/25] Step::replace_one should put a one, not a zero (Issue #41492) Turns out all six of these impls are incorrect. --- src/libcore/iter/range.rs | 12 ++++++------ src/libcore/tests/iter.rs | 38 ++++++++++++++++++++++++++++++++++++++ src/libcore/tests/lib.rs | 2 ++ 3 files changed, 46 insertions(+), 6 deletions(-) diff --git a/src/libcore/iter/range.rs b/src/libcore/iter/range.rs index 687c477f19e4c..bd831d638c0c4 100644 --- a/src/libcore/iter/range.rs +++ b/src/libcore/iter/range.rs @@ -86,12 +86,12 @@ macro_rules! step_impl_unsigned { #[inline] fn replace_one(&mut self) -> Self { - mem::replace(self, 0) + mem::replace(self, 1) } #[inline] fn replace_zero(&mut self) -> Self { - mem::replace(self, 1) + mem::replace(self, 0) } #[inline] @@ -157,12 +157,12 @@ macro_rules! step_impl_signed { #[inline] fn replace_one(&mut self) -> Self { - mem::replace(self, 0) + mem::replace(self, 1) } #[inline] fn replace_zero(&mut self) -> Self { - mem::replace(self, 1) + mem::replace(self, 0) } #[inline] @@ -206,12 +206,12 @@ macro_rules! step_impl_no_between { #[inline] fn replace_one(&mut self) -> Self { - mem::replace(self, 0) + mem::replace(self, 1) } #[inline] fn replace_zero(&mut self) -> Self { - mem::replace(self, 1) + mem::replace(self, 0) } #[inline] diff --git a/src/libcore/tests/iter.rs b/src/libcore/tests/iter.rs index 08442f9bcbff5..001fa304cd08f 100644 --- a/src/libcore/tests/iter.rs +++ b/src/libcore/tests/iter.rs @@ -1082,3 +1082,41 @@ fn test_chain_fold() { assert_eq!(&[2, 3, 1, 2, 0], &result[..]); } +#[test] +fn test_step_replace_unsigned() { + let mut x = 4u32; + let y = x.replace_zero(); + assert_eq!(x, 0); + assert_eq!(y, 4); + + x = 5; + let y = x.replace_one(); + assert_eq!(x, 1); + assert_eq!(y, 5); +} + +#[test] +fn test_step_replace_signed() { + let mut x = 4i32; + let y = x.replace_zero(); + assert_eq!(x, 0); + assert_eq!(y, 4); + + x = 5; + let y = x.replace_one(); + assert_eq!(x, 1); + assert_eq!(y, 5); +} + +#[test] +fn test_step_replace_no_between() { + let mut x = 4u128; + let y = x.replace_zero(); + assert_eq!(x, 0); + assert_eq!(y, 4); + + x = 5; + let y = x.replace_one(); + assert_eq!(x, 1); + assert_eq!(y, 5); +} \ No newline at end of file diff --git a/src/libcore/tests/lib.rs b/src/libcore/tests/lib.rs index 528ab3bc84523..f0c46a6f194d5 100644 --- a/src/libcore/tests/lib.rs +++ b/src/libcore/tests/lib.rs @@ -20,6 +20,7 @@ #![feature(fixed_size_array)] #![feature(flt2dec)] #![feature(fmt_internals)] +#![feature(i128_type)] #![feature(iter_rfind)] #![feature(libc)] #![feature(nonzero)] @@ -30,6 +31,7 @@ #![feature(sort_internals)] #![feature(sort_unstable)] #![feature(step_by)] +#![feature(step_trait)] #![feature(test)] #![feature(try_from)] #![feature(unicode)] From f852e3fcbcdbcc42d7eb215b08bb3539f76b8ca1 Mon Sep 17 00:00:00 2001 From: steveklabnik Date: Mon, 24 Apr 2017 07:47:00 -0400 Subject: [PATCH 05/25] use the word 'length' in Vec::len's docs Fixes #37866 --- src/libcollections/vec.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs index 6deb87ae77204..1d443b19d80a7 100644 --- a/src/libcollections/vec.rs +++ b/src/libcollections/vec.rs @@ -1147,7 +1147,8 @@ impl Vec { self.truncate(0) } - /// Returns the number of elements in the vector. + /// Returns the number of elements in the vector, also referred to + /// as its 'length'. /// /// # Examples /// From e4825290223f39647bf2782b9d4ef5f00554c7ee Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 8 Dec 2016 16:12:38 -0800 Subject: [PATCH 06/25] Fix invalid module suggestion --- src/libsyntax/parse/parser.rs | 33 ++++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 1baf0d1b54ce1..dd32b40554b5d 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -5363,26 +5363,33 @@ impl<'a> Parser<'a> { } let mut err = self.diagnostic().struct_span_err(id_sp, "cannot declare a new module at this location"); - let this_module = match self.directory.path.file_name() { - Some(file_name) => file_name.to_str().unwrap().to_owned(), - None => self.root_module_name.as_ref().unwrap().clone(), - }; - err.span_note(id_sp, - &format!("maybe move this module `{0}` to its own directory \ - via `{0}{1}mod.rs`", - this_module, - path::MAIN_SEPARATOR)); + if id_sp != syntax_pos::DUMMY_SP { + let full_path = self.sess.codemap().span_to_filename(id_sp); + let path = Path::new(&full_path); + let filename = path.file_stem().unwrap(); + let parent = path.parent().unwrap_or(Path::new("")) + .to_str().unwrap_or("").to_owned(); + let path = format!("{}/{}", + if parent.len() == 0 { "." } else { &parent }, + filename.to_str().unwrap_or("")); + err.span_note(id_sp, + &format!("maybe move this module `{0}` to its own directory \ + via `{0}{1}mod.rs`", + path, + path::MAIN_SEPARATOR)); + } if paths.path_exists { err.span_note(id_sp, &format!("... or maybe `use` the module `{}` instead \ of possibly redeclaring it", paths.name)); - Err(err) - } else { - Err(err) } + Err(err) } else { - paths.result.map_err(|err| self.span_fatal_err(id_sp, err)) + match paths.result { + Ok(succ) => Ok(succ), + Err(err) => Err(self.span_fatal_err(id_sp, &err.err_msg, &err.help_msg)), + } } } From bd880bc6bf62a223664467d4df2b056a9122b7e7 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 3 Jan 2017 12:19:13 +0100 Subject: [PATCH 07/25] Add tests for module suggestions --- src/libsyntax/parse/parser.rs | 43 ++++++++++++------- src/test/compile-fail/auxiliary/foo/bar.rs | 11 +++++ src/test/compile-fail/auxiliary/foo/mod.rs | 11 +++++ .../invalid-module-declaration.rs | 20 +++++++++ 4 files changed, 70 insertions(+), 15 deletions(-) create mode 100644 src/test/compile-fail/auxiliary/foo/bar.rs create mode 100644 src/test/compile-fail/auxiliary/foo/mod.rs create mode 100644 src/test/compile-fail/invalid-module-declaration.rs diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index dd32b40554b5d..ac72d21ec4271 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -58,8 +58,11 @@ use symbol::{Symbol, keywords}; use util::ThinVec; use std::collections::HashSet; -use std::{cmp, mem, slice}; -use std::path::{self, Path, PathBuf}; +use std::env; +use std::mem; +use std::path::{Path, PathBuf}; +use std::rc::Rc; +use std::slice; bitflags! { flags Restrictions: u8 { @@ -5364,19 +5367,29 @@ impl<'a> Parser<'a> { let mut err = self.diagnostic().struct_span_err(id_sp, "cannot declare a new module at this location"); if id_sp != syntax_pos::DUMMY_SP { - let full_path = self.sess.codemap().span_to_filename(id_sp); - let path = Path::new(&full_path); - let filename = path.file_stem().unwrap(); - let parent = path.parent().unwrap_or(Path::new("")) - .to_str().unwrap_or("").to_owned(); - let path = format!("{}/{}", - if parent.len() == 0 { "." } else { &parent }, - filename.to_str().unwrap_or("")); - err.span_note(id_sp, - &format!("maybe move this module `{0}` to its own directory \ - via `{0}{1}mod.rs`", - path, - path::MAIN_SEPARATOR)); + let mut src_path = PathBuf::from(self.sess.codemap().span_to_filename(id_sp)); + if let Some(stem) = src_path.clone().file_stem() { + let mut dest_path = src_path.clone(); + dest_path.set_file_name(stem); + dest_path.push("mod.rs"); + if let Ok(cur_dir) = env::current_dir() { + let tmp = if let (Ok(src_path), Ok(dest_path)) = + (Path::new(&src_path).strip_prefix(&cur_dir), + Path::new(&dest_path).strip_prefix(&cur_dir)) { + Some((src_path.to_path_buf(), dest_path.to_path_buf())) + } else { + None + }; + if let Some(tmp) = tmp { + src_path = tmp.0; + dest_path = tmp.1; + } + } + err.span_note(id_sp, + &format!("maybe move this module `{}` to its own \ + directory via `{}`", src_path.to_string_lossy(), + dest_path.to_string_lossy())); + } } if paths.path_exists { err.span_note(id_sp, diff --git a/src/test/compile-fail/auxiliary/foo/bar.rs b/src/test/compile-fail/auxiliary/foo/bar.rs new file mode 100644 index 0000000000000..4b6b4f5ebf82f --- /dev/null +++ b/src/test/compile-fail/auxiliary/foo/bar.rs @@ -0,0 +1,11 @@ +// Copyright 2017 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. + +pub mod baz; diff --git a/src/test/compile-fail/auxiliary/foo/mod.rs b/src/test/compile-fail/auxiliary/foo/mod.rs new file mode 100644 index 0000000000000..6d77fb60a35de --- /dev/null +++ b/src/test/compile-fail/auxiliary/foo/mod.rs @@ -0,0 +1,11 @@ +// Copyright 2017 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. + +pub mod bar; diff --git a/src/test/compile-fail/invalid-module-declaration.rs b/src/test/compile-fail/invalid-module-declaration.rs new file mode 100644 index 0000000000000..658fa0a65c47f --- /dev/null +++ b/src/test/compile-fail/invalid-module-declaration.rs @@ -0,0 +1,20 @@ +// 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. + +// ignore-tidy-linelength + +// error-pattern: cannot declare a new module at this location +// error-pattern: maybe move this module `src/test/compile-fail/auxiliary/foo/bar.rs` to its own directory via `src/test/compile-fail/auxiliary/foo/bar/mod.rs` + +mod auxiliary { + mod foo; +} + +fn main() {} From b10c04472bf0969d123aa4461a7f0a1a255ac660 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 25 Feb 2017 17:08:46 +0100 Subject: [PATCH 08/25] Remove strip prefix --- src/libsyntax/parse/parser.rs | 18 ++---------------- .../compile-fail/invalid-module-declaration.rs | 2 +- 2 files changed, 3 insertions(+), 17 deletions(-) diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index ac72d21ec4271..9df791c1c124e 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -58,7 +58,6 @@ use symbol::{Symbol, keywords}; use util::ThinVec; use std::collections::HashSet; -use std::env; use std::mem; use std::path::{Path, PathBuf}; use std::rc::Rc; @@ -5367,24 +5366,11 @@ impl<'a> Parser<'a> { let mut err = self.diagnostic().struct_span_err(id_sp, "cannot declare a new module at this location"); if id_sp != syntax_pos::DUMMY_SP { - let mut src_path = PathBuf::from(self.sess.codemap().span_to_filename(id_sp)); + let src_path = PathBuf::from(self.sess.codemap().span_to_filename(id_sp)); if let Some(stem) = src_path.clone().file_stem() { let mut dest_path = src_path.clone(); dest_path.set_file_name(stem); dest_path.push("mod.rs"); - if let Ok(cur_dir) = env::current_dir() { - let tmp = if let (Ok(src_path), Ok(dest_path)) = - (Path::new(&src_path).strip_prefix(&cur_dir), - Path::new(&dest_path).strip_prefix(&cur_dir)) { - Some((src_path.to_path_buf(), dest_path.to_path_buf())) - } else { - None - }; - if let Some(tmp) = tmp { - src_path = tmp.0; - dest_path = tmp.1; - } - } err.span_note(id_sp, &format!("maybe move this module `{}` to its own \ directory via `{}`", src_path.to_string_lossy(), @@ -5401,7 +5387,7 @@ impl<'a> Parser<'a> { } else { match paths.result { Ok(succ) => Ok(succ), - Err(err) => Err(self.span_fatal_err(id_sp, &err.err_msg, &err.help_msg)), + Err(err) => Err(self.span_fatal_err(id_sp, err)), } } } diff --git a/src/test/compile-fail/invalid-module-declaration.rs b/src/test/compile-fail/invalid-module-declaration.rs index 658fa0a65c47f..c15cfb8cc8e22 100644 --- a/src/test/compile-fail/invalid-module-declaration.rs +++ b/src/test/compile-fail/invalid-module-declaration.rs @@ -11,7 +11,7 @@ // ignore-tidy-linelength // error-pattern: cannot declare a new module at this location -// error-pattern: maybe move this module `src/test/compile-fail/auxiliary/foo/bar.rs` to its own directory via `src/test/compile-fail/auxiliary/foo/bar/mod.rs` +// error-pattern: maybe move this module mod auxiliary { mod foo; From 0d63f13378f8d8625a439ecbb36b3f97d0d2263d Mon Sep 17 00:00:00 2001 From: Jessica Hamilton Date: Mon, 24 Apr 2017 14:21:36 +0000 Subject: [PATCH 09/25] Haiku: add missing cases of using LIBRARY_PATH --- src/bootstrap/bootstrap.py | 3 +++ src/bootstrap/util.rs | 2 ++ src/librustc_back/dynamic_lib.rs | 2 ++ src/tools/compiletest/src/procsrv.rs | 2 ++ 4 files changed, 9 insertions(+) diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py index 3233a73b007cc..55622c6b81b27 100644 --- a/src/bootstrap/bootstrap.py +++ b/src/bootstrap/bootstrap.py @@ -367,6 +367,9 @@ def build_bootstrap(self): env["DYLD_LIBRARY_PATH"] = os.path.join(self.bin_root(), "lib") + \ (os.pathsep + env["DYLD_LIBRARY_PATH"]) \ if "DYLD_LIBRARY_PATH" in env else "" + env["LIBRARY_PATH"] = os.path.join(self.bin_root(), "lib") + \ + (os.pathsep + env["LIBRARY_PATH"]) \ + if "LIBRARY_PATH" in env else "" env["PATH"] = os.path.join(self.bin_root(), "bin") + \ os.pathsep + env["PATH"] if not os.path.isfile(self.cargo()): diff --git a/src/bootstrap/util.rs b/src/bootstrap/util.rs index dab20f44bc361..e01c06b10fcd6 100644 --- a/src/bootstrap/util.rs +++ b/src/bootstrap/util.rs @@ -139,6 +139,8 @@ pub fn dylib_path_var() -> &'static str { "PATH" } else if cfg!(target_os = "macos") { "DYLD_LIBRARY_PATH" + } else if cfg!(target_os = "haiku") { + "LIBRARY_PATH" } else { "LD_LIBRARY_PATH" } diff --git a/src/librustc_back/dynamic_lib.rs b/src/librustc_back/dynamic_lib.rs index 38e60060925e6..e6f305c22b2d4 100644 --- a/src/librustc_back/dynamic_lib.rs +++ b/src/librustc_back/dynamic_lib.rs @@ -68,6 +68,8 @@ impl DynamicLibrary { "PATH" } else if cfg!(target_os = "macos") { "DYLD_LIBRARY_PATH" + } else if cfg!(target_os = "haiku") { + "LIBRARY_PATH" } else { "LD_LIBRARY_PATH" } diff --git a/src/tools/compiletest/src/procsrv.rs b/src/tools/compiletest/src/procsrv.rs index 3d8f2296236a2..dbda8f4d802c0 100644 --- a/src/tools/compiletest/src/procsrv.rs +++ b/src/tools/compiletest/src/procsrv.rs @@ -20,6 +20,8 @@ pub fn dylib_env_var() -> &'static str { "PATH" } else if cfg!(target_os = "macos") { "DYLD_LIBRARY_PATH" + } else if cfg!(target_os = "haiku") { + "LIBRARY_PATH" } else { "LD_LIBRARY_PATH" } From 957d51aecb3eb4960129b38b147cff0b8d0fae5c Mon Sep 17 00:00:00 2001 From: Tobias Bucher Date: Tue, 25 Apr 2017 01:02:59 +0200 Subject: [PATCH 10/25] Fix a copy-paste error in `Instant::sub_duration` Fixes #41514. --- src/libstd/sys/unix/time.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libstd/sys/unix/time.rs b/src/libstd/sys/unix/time.rs index a08cec38f732d..a1ad94872de5c 100644 --- a/src/libstd/sys/unix/time.rs +++ b/src/libstd/sys/unix/time.rs @@ -157,7 +157,7 @@ mod inner { pub fn sub_duration(&self, other: &Duration) -> Instant { Instant { t: self.t.checked_sub(dur2intervals(other)) - .expect("overflow when adding duration to instant"), + .expect("overflow when subtracting duration from instant"), } } } From 70e673952ee7544576e2912efe9735bc4617e447 Mon Sep 17 00:00:00 2001 From: Andrew Gaspar Date: Mon, 20 Feb 2017 11:10:32 -0800 Subject: [PATCH 11/25] Adds rust-windbg.cmd script --- src/bootstrap/dist.rs | 7 ++++++- src/etc/rust-windbg.cmd | 18 ++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 src/etc/rust-windbg.cmd diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index 4328c4e3f1d4c..ada8d4df604e3 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -254,7 +254,12 @@ pub fn debugger_scripts(build: &Build, install(&build.src.join("src/etc/").join(file), &dst, 0o644); }; if host.contains("windows-msvc") { - // no debugger scripts + // windbg debugger scripts + install(&build.src.join("src/etc/rust-windbg.cmd"), &sysroot.join("bin"), + 0o755); + + cp_debugger_script("natvis/libcore.natvis"); + cp_debugger_script("natvis/libcollections.natvis"); } else { cp_debugger_script("debugger_pretty_printers_common.py"); diff --git a/src/etc/rust-windbg.cmd b/src/etc/rust-windbg.cmd new file mode 100644 index 0000000000000..4cdd6b9860996 --- /dev/null +++ b/src/etc/rust-windbg.cmd @@ -0,0 +1,18 @@ +@echo off +setlocal + +REM Copyright 2014 The Rust Project Developers. See the COPYRIGHT +REM file at the top-level directory of this distribution and at +REM http://rust-lang.org/COPYRIGHT. +REM +REM Licensed under the Apache License, Version 2.0 or the MIT license +REM , at your +REM option. This file may not be copied, modified, or distributed +REM except according to those terms. + +for /f "delims=" %%i in ('rustc --print=sysroot') do set rustc_sysroot=%%i + +set rust_etc=%rustc_sysroot%\lib\rustlib\etc + +windbg -c ".nvload %rust_etc%\libcore.natvis;.nvload %rust_etc%\libcollections.natvis;" %* \ No newline at end of file From a765dcaf5378cbd6cfa71f3fdeede82eeca4fc26 Mon Sep 17 00:00:00 2001 From: Sergio Benitez Date: Sat, 22 Apr 2017 01:14:18 -0700 Subject: [PATCH 12/25] Add internal accessor methods to io::{Chain, Take}. Resolves #29067. --- src/libstd/io/mod.rs | 131 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 131 insertions(+) diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs index cd096c115ba5a..cf548346b176c 100644 --- a/src/libstd/io/mod.rs +++ b/src/libstd/io/mod.rs @@ -1494,6 +1494,83 @@ pub struct Chain { done_first: bool, } +impl Chain { + /// Consumes the `Chain`, returning the wrapped readers. + /// + /// # Examples + /// + /// ``` + /// #![feature(more_io_inner_methods)] + /// + /// # use std::io; + /// use std::io::prelude::*; + /// use std::fs::File; + /// + /// # fn foo() -> io::Result<()> { + /// let mut foo_file = File::open("foo.txt")?; + /// let mut bar_file = File::open("bar.txt")?; + /// + /// let chain = foo_file.chain(bar_file); + /// let (foo_file, bar_file) = chain.into_inner(); + /// # Ok(()) + /// # } + /// ``` + #[unstable(feature = "more_io_inner_methods", issue="0")] + pub fn into_inner(self) -> (T, U) { + (self.first, self.second) + } + + /// Gets references to the underlying readers in this `Chain`. + /// + /// # Examples + /// + /// ``` + /// #![feature(more_io_inner_methods)] + /// + /// # use std::io; + /// use std::io::prelude::*; + /// use std::fs::File; + /// + /// # fn foo() -> io::Result<()> { + /// let mut foo_file = File::open("foo.txt")?; + /// let mut bar_file = File::open("bar.txt")?; + /// + /// let chain = foo_file.chain(bar_file); + /// let (foo_file, bar_file) = chain.get_ref(); + /// # Ok(()) + /// # } + /// ``` + #[unstable(feature = "more_io_inner_methods", issue="0")] + pub fn get_ref(&self) -> (&T, &U) { + (&self.first, &self.second) + } + + /// Gets mutable references to the underlying readers in this `Chain`. + /// + /// # Examples + /// + /// ``` + /// #![feature(more_io_inner_methods)] + /// + /// # use std::io; + /// use std::io::prelude::*; + /// use std::fs::File; + /// + /// # fn foo() -> io::Result<()> { + /// let mut foo_file = File::open("foo.txt")?; + /// let mut bar_file = File::open("bar.txt")?; + /// + /// let mut chain = foo_file.chain(bar_file); + /// let (foo_file, bar_file) = chain.get_mut(); + /// # Ok(()) + /// # } + /// ``` + #[unstable(feature = "more_io_inner_methods", issue="0")] + pub fn get_mut(&mut self) -> (&mut T, &mut U) { + (&mut self.first, &mut self.second) + } +} + #[stable(feature = "std_debug", since = "1.16.0")] impl fmt::Debug for Chain { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { @@ -1606,6 +1683,60 @@ impl Take { pub fn into_inner(self) -> T { self.inner } + + /// Gets a reference to the underlying reader. + /// + /// # Examples + /// + /// ``` + /// #![feature(more_io_inner_methods)] + /// + /// use std::io; + /// use std::io::prelude::*; + /// use std::fs::File; + /// + /// # fn foo() -> io::Result<()> { + /// let mut file = File::open("foo.txt")?; + /// + /// let mut buffer = [0; 5]; + /// let mut handle = file.take(5); + /// handle.read(&mut buffer)?; + /// + /// let file = handle.get_ref(); + /// # Ok(()) + /// # } + /// ``` + #[unstable(feature = "more_io_inner_methods", issue="0")] + pub fn get_ref(&self) -> &T { + &self.inner + } + + /// Gets a mutable reference to the underlying reader. + /// + /// # Examples + /// + /// ``` + /// #![feature(more_io_inner_methods)] + /// + /// use std::io; + /// use std::io::prelude::*; + /// use std::fs::File; + /// + /// # fn foo() -> io::Result<()> { + /// let mut file = File::open("foo.txt")?; + /// + /// let mut buffer = [0; 5]; + /// let mut handle = file.take(5); + /// handle.read(&mut buffer)?; + /// + /// let file = handle.get_mut(); + /// # Ok(()) + /// # } + /// ``` + #[unstable(feature = "more_io_inner_methods", issue="0")] + pub fn get_mut(&mut self) -> &mut T { + &mut self.inner + } } #[stable(feature = "rust1", since = "1.0.0")] From aab87e3e9e71696d475a0b2c57f0dee7f702fc27 Mon Sep 17 00:00:00 2001 From: Sergio Benitez Date: Sat, 22 Apr 2017 03:35:53 -0700 Subject: [PATCH 13/25] Add more_io_inner_methods feature to unstable book. --- src/doc/unstable-book/src/SUMMARY.md | 1 + .../src/library-features/more-io-inner-methods.md | 9 +++++++++ 2 files changed, 10 insertions(+) create mode 100644 src/doc/unstable-book/src/library-features/more-io-inner-methods.md diff --git a/src/doc/unstable-book/src/SUMMARY.md b/src/doc/unstable-book/src/SUMMARY.md index 6134757304170..9b77d99403fdb 100644 --- a/src/doc/unstable-book/src/SUMMARY.md +++ b/src/doc/unstable-book/src/SUMMARY.md @@ -160,6 +160,7 @@ - [linked_list_extras](library-features/linked-list-extras.md) - [lookup_host](library-features/lookup-host.md) - [manually_drop](library-features/manually-drop.md) + - [more_io_inner_methods](library-features/more-io-inner-methods.md) - [mpsc_select](library-features/mpsc-select.md) - [n16](library-features/n16.md) - [never_type_impls](library-features/never-type-impls.md) diff --git a/src/doc/unstable-book/src/library-features/more-io-inner-methods.md b/src/doc/unstable-book/src/library-features/more-io-inner-methods.md new file mode 100644 index 0000000000000..1b56a8b395c69 --- /dev/null +++ b/src/doc/unstable-book/src/library-features/more-io-inner-methods.md @@ -0,0 +1,9 @@ +# `more_io_inner_methods` + +The tracking issue for this feature is: None. + +------------------------ + +This feature enables several internal accessor methods on structures in +`std::io` including `Take::{get_ref, get_mut}` and `Chain::{into_inner, get_ref, +get_mut}`. From 76397aea50a506ac177b74d352a0ebbe99d4cdc6 Mon Sep 17 00:00:00 2001 From: Sergio Benitez Date: Mon, 24 Apr 2017 16:46:05 -0700 Subject: [PATCH 14/25] Reference tracking issue for more_io_inner_methods. --- .../src/library-features/more-io-inner-methods.md | 4 +++- src/libstd/io/mod.rs | 10 +++++----- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/doc/unstable-book/src/library-features/more-io-inner-methods.md b/src/doc/unstable-book/src/library-features/more-io-inner-methods.md index 1b56a8b395c69..c84f40e7ee551 100644 --- a/src/doc/unstable-book/src/library-features/more-io-inner-methods.md +++ b/src/doc/unstable-book/src/library-features/more-io-inner-methods.md @@ -1,6 +1,8 @@ # `more_io_inner_methods` -The tracking issue for this feature is: None. +The tracking issue for this feature is: [#41519] + +[#41519]: https://github.com/rust-lang/rust/issues/41519 ------------------------ diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs index cf548346b176c..a30246ae88b6c 100644 --- a/src/libstd/io/mod.rs +++ b/src/libstd/io/mod.rs @@ -1515,7 +1515,7 @@ impl Chain { /// # Ok(()) /// # } /// ``` - #[unstable(feature = "more_io_inner_methods", issue="0")] + #[unstable(feature = "more_io_inner_methods", issue="41519")] pub fn into_inner(self) -> (T, U) { (self.first, self.second) } @@ -1540,7 +1540,7 @@ impl Chain { /// # Ok(()) /// # } /// ``` - #[unstable(feature = "more_io_inner_methods", issue="0")] + #[unstable(feature = "more_io_inner_methods", issue="41519")] pub fn get_ref(&self) -> (&T, &U) { (&self.first, &self.second) } @@ -1565,7 +1565,7 @@ impl Chain { /// # Ok(()) /// # } /// ``` - #[unstable(feature = "more_io_inner_methods", issue="0")] + #[unstable(feature = "more_io_inner_methods", issue="41519")] pub fn get_mut(&mut self) -> (&mut T, &mut U) { (&mut self.first, &mut self.second) } @@ -1706,7 +1706,7 @@ impl Take { /// # Ok(()) /// # } /// ``` - #[unstable(feature = "more_io_inner_methods", issue="0")] + #[unstable(feature = "more_io_inner_methods", issue="41519")] pub fn get_ref(&self) -> &T { &self.inner } @@ -1733,7 +1733,7 @@ impl Take { /// # Ok(()) /// # } /// ``` - #[unstable(feature = "more_io_inner_methods", issue="0")] + #[unstable(feature = "more_io_inner_methods", issue="41519")] pub fn get_mut(&mut self) -> &mut T { &mut self.inner } From c168d8bb07392ca6c5e30c2cde1458c9e32bf03b Mon Sep 17 00:00:00 2001 From: Sergio Benitez Date: Mon, 24 Apr 2017 16:46:21 -0700 Subject: [PATCH 15/25] Add cautions to io::get_mut method documentation. --- src/libstd/io/mod.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs index a30246ae88b6c..d08ba591de018 100644 --- a/src/libstd/io/mod.rs +++ b/src/libstd/io/mod.rs @@ -1547,6 +1547,10 @@ impl Chain { /// Gets mutable references to the underlying readers in this `Chain`. /// + /// Care should be taken to avoid modifying the internal I/O state of the + /// underlying readers as doing so may corrupt the internal state of this + /// `Chain`. + /// /// # Examples /// /// ``` @@ -1713,6 +1717,10 @@ impl Take { /// Gets a mutable reference to the underlying reader. /// + /// Care should be taken to avoid modifying the internal I/O state of the + /// underlying reader as doing so may corrupt the internal limit of this + /// `Take`. + /// /// # Examples /// /// ``` From 93d57d64b86d574efa35e2fb354d8dc92153b8a7 Mon Sep 17 00:00:00 2001 From: kennytm Date: Tue, 18 Apr 2017 00:07:36 +0800 Subject: [PATCH 16/25] Pass `--format-version 1` to `cargo metadata`. Suppress warning introduced by rust-lang/cargo#3841. --- src/bootstrap/metadata.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/bootstrap/metadata.rs b/src/bootstrap/metadata.rs index 5918fe41e7c8b..7b6b01655df58 100644 --- a/src/bootstrap/metadata.rs +++ b/src/bootstrap/metadata.rs @@ -58,6 +58,7 @@ fn build_krate(build: &mut Build, krate: &str) { // the dependency graph and what `-p` arguments there are. let mut cargo = Command::new(&build.cargo); cargo.arg("metadata") + .arg("--format-version").arg("1") .arg("--manifest-path").arg(build.src.join(krate).join("Cargo.toml")); let output = output(&mut cargo); let output: Output = json::decode(&output).unwrap(); From 00dff0aa59ce2d71957ca16a4444c303910686a3 Mon Sep 17 00:00:00 2001 From: kennytm Date: Tue, 18 Apr 2017 04:22:16 +0800 Subject: [PATCH 17/25] Support AddressSanitizer and ThreadSanitizer on x86_64-apple-darwin. ASan and TSan are supported on macOS, and this commit enables their support. The sanitizers are always built as *.dylib on Apple platforms, so they cannot be statically linked into the corresponding `rustc_?san.rlib`. The dylibs are directly copied to `lib/rustlib/x86_64-apple-darwin/lib/` instead. Note, although Xcode also ships with their own copies of ASan/TSan dylibs, we cannot use them due to version mismatch. There is a caveat: the sanitizer libraries are linked as @rpath, so the user needs to additionally pass `-C rpath`: rustc -Z sanitizer=address -C rpath file.rs ^~~~~~~~ Otherwise there will be a runtime error: dyld: Library not loaded: @rpath/libclang_rt.asan_osx_dynamic.dylib Referenced from: /path/to/executable Reason: image not found Abort trap: 6 The next commit includes a temporary change in compiler to force the linker to emit a usable @rpath. --- .travis.yml | 4 +-- src/bootstrap/compile.rs | 19 ++++++++++++++ src/build_helper/lib.rs | 21 +++++++++++++++- src/librustc/session/config.rs | 2 +- src/librustc_asan/build.rs | 5 ++-- src/librustc_lsan/build.rs | 5 ++-- src/librustc_metadata/creader.rs | 25 +++++++++++++++---- src/librustc_msan/build.rs | 5 ++-- src/librustc_tsan/build.rs | 5 ++-- src/libstd/Cargo.toml | 4 +++ src/test/run-make/sanitizer-address/Makefile | 20 ++++++++++----- .../sanitizer-invalid-target/Makefile | 2 +- src/test/run-make/sanitizer-leak/Makefile | 8 +++--- src/test/run-make/sanitizer-memory/Makefile | 8 +++--- 14 files changed, 97 insertions(+), 36 deletions(-) diff --git a/.travis.yml b/.travis.yml index 5d56379dccebf..c5372609e9bc6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -54,7 +54,7 @@ matrix: # version that we're using, 8.2, cannot compile LLVM for OSX 10.7. - env: > RUST_CHECK_TARGET=check - RUST_CONFIGURE_ARGS=--build=x86_64-apple-darwin + RUST_CONFIGURE_ARGS="--build=x86_64-apple-darwin --enable-sanitizers" SRC=. RUSTC_RETRY_LINKER_ON_SEGFAULT=1 SCCACHE_ERROR_LOG=/tmp/sccache.log @@ -98,7 +98,7 @@ matrix: install: *osx_install_sccache - env: > RUST_CHECK_TARGET=dist - RUST_CONFIGURE_ARGS="--target=aarch64-apple-ios,armv7-apple-ios,armv7s-apple-ios,i386-apple-ios,x86_64-apple-ios --enable-extended" + RUST_CONFIGURE_ARGS="--target=aarch64-apple-ios,armv7-apple-ios,armv7s-apple-ios,i386-apple-ios,x86_64-apple-ios --enable-extended --enable-sanitizers" SRC=. DEPLOY=1 RUSTC_RETRY_LINKER_ON_SEGFAULT=1 diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index cd87b27d4f1aa..6f1de62d07ee3 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -115,6 +115,13 @@ pub fn std_link(build: &Build, if target.contains("musl") && !target.contains("mips") { copy_musl_third_party_objects(build, target, &libdir); } + + if build.config.sanitizers && compiler.stage != 0 && target == "x86_64-apple-darwin" { + // The sanitizers are only built in stage1 or above, so the dylibs will + // be missing in stage0 and causes panic. See the `std()` function above + // for reason why the sanitizers are not built in stage0. + copy_apple_sanitizer_dylibs(&build.native_dir(target), "osx", &libdir); + } } /// Copies the crt(1,i,n).o startup objects @@ -126,6 +133,18 @@ fn copy_musl_third_party_objects(build: &Build, target: &str, into: &Path) { } } +fn copy_apple_sanitizer_dylibs(native_dir: &Path, platform: &str, into: &Path) { + for &sanitizer in &["asan", "tsan"] { + let filename = format!("libclang_rt.{}_{}_dynamic.dylib", sanitizer, platform); + let mut src_path = native_dir.join(sanitizer); + src_path.push("build"); + src_path.push("lib"); + src_path.push("darwin"); + src_path.push(&filename); + copy(&src_path, &into.join(filename)); + } +} + /// Build and prepare startup objects like rsbegin.o and rsend.o /// /// These are primarily used on Windows right now for linking executables/dlls. diff --git a/src/build_helper/lib.rs b/src/build_helper/lib.rs index cb58a916fb797..da00b970da977 100644 --- a/src/build_helper/lib.rs +++ b/src/build_helper/lib.rs @@ -198,7 +198,11 @@ pub fn native_lib_boilerplate(src_name: &str, let out_dir = env::var_os("RUSTBUILD_NATIVE_DIR").unwrap_or(env::var_os("OUT_DIR").unwrap()); let out_dir = PathBuf::from(out_dir).join(out_name); t!(create_dir_racy(&out_dir)); - println!("cargo:rustc-link-lib=static={}", link_name); + if link_name.contains('=') { + println!("cargo:rustc-link-lib={}", link_name); + } else { + println!("cargo:rustc-link-lib=static={}", link_name); + } println!("cargo:rustc-link-search=native={}", out_dir.join(search_subdir).display()); let timestamp = out_dir.join("rustbuild.timestamp"); @@ -209,6 +213,21 @@ pub fn native_lib_boilerplate(src_name: &str, } } +pub fn sanitizer_lib_boilerplate(sanitizer_name: &str) -> Result { + let (link_name, search_path) = match &*env::var("TARGET").unwrap() { + "x86_64-unknown-linux-gnu" => ( + format!("clang_rt.{}-x86_64", sanitizer_name), + "build/lib/linux", + ), + "x86_64-apple-darwin" => ( + format!("dylib=clang_rt.{}_osx_dynamic", sanitizer_name), + "build/lib/darwin", + ), + _ => return Err(()), + }; + native_lib_boilerplate("compiler-rt", sanitizer_name, &link_name, search_path) +} + fn dir_up_to_date(src: &Path, threshold: &FileTime) -> bool { t!(fs::read_dir(src)).map(|e| t!(e)).all(|e| { let meta = t!(e.metadata()); diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index fadb1844008c0..462fd57cbf17f 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -51,7 +51,7 @@ pub struct Config { pub uint_type: UintTy, } -#[derive(Clone, Hash)] +#[derive(Clone, Hash, Debug)] pub enum Sanitizer { Address, Leak, diff --git a/src/librustc_asan/build.rs b/src/librustc_asan/build.rs index 2df2e001e6ff2..3a80baa0485f5 100644 --- a/src/librustc_asan/build.rs +++ b/src/librustc_asan/build.rs @@ -12,14 +12,13 @@ extern crate build_helper; extern crate cmake; use std::env; -use build_helper::native_lib_boilerplate; +use build_helper::sanitizer_lib_boilerplate; use cmake::Config; fn main() { if let Some(llvm_config) = env::var_os("LLVM_CONFIG") { - let native = match native_lib_boilerplate("compiler-rt", "asan", "clang_rt.asan-x86_64", - "build/lib/linux") { + let native = match sanitizer_lib_boilerplate("asan") { Ok(native) => native, _ => return, }; diff --git a/src/librustc_lsan/build.rs b/src/librustc_lsan/build.rs index 005163f41026c..da53571a24390 100644 --- a/src/librustc_lsan/build.rs +++ b/src/librustc_lsan/build.rs @@ -12,14 +12,13 @@ extern crate build_helper; extern crate cmake; use std::env; -use build_helper::native_lib_boilerplate; +use build_helper::sanitizer_lib_boilerplate; use cmake::Config; fn main() { if let Some(llvm_config) = env::var_os("LLVM_CONFIG") { - let native = match native_lib_boilerplate("compiler-rt", "lsan", "clang_rt.lsan-x86_64", - "build/lib/linux") { + let native = match sanitizer_lib_boilerplate("lsan") { Ok(native) => native, _ => return, }; diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index 7bc0e8a512be0..966e814e33790 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -799,11 +799,26 @@ impl<'a> CrateLoader<'a> { fn inject_sanitizer_runtime(&mut self) { if let Some(ref sanitizer) = self.sess.opts.debugging_opts.sanitizer { - // Sanitizers can only be used with x86_64 Linux executables linked - // to `std` - if self.sess.target.target.llvm_target != "x86_64-unknown-linux-gnu" { - self.sess.err(&format!("Sanitizers only work with the \ - `x86_64-unknown-linux-gnu` target.")); + // Sanitizers can only be used on some tested platforms with + // executables linked to `std` + const ASAN_SUPPORTED_TARGETS: &[&str] = &["x86_64-unknown-linux-gnu", + "x86_64-apple-darwin"]; + const TSAN_SUPPORTED_TARGETS: &[&str] = &["x86_64-unknown-linux-gnu", + "x86_64-apple-darwin"]; + const LSAN_SUPPORTED_TARGETS: &[&str] = &["x86_64-unknown-linux-gnu"]; + const MSAN_SUPPORTED_TARGETS: &[&str] = &["x86_64-unknown-linux-gnu"]; + + let supported_targets = match *sanitizer { + Sanitizer::Address => ASAN_SUPPORTED_TARGETS, + Sanitizer::Thread => TSAN_SUPPORTED_TARGETS, + Sanitizer::Leak => LSAN_SUPPORTED_TARGETS, + Sanitizer::Memory => MSAN_SUPPORTED_TARGETS, + }; + if !supported_targets.contains(&&*self.sess.target.target.llvm_target) { + self.sess.err(&format!("{:?}Sanitizer only works with the `{}` target", + sanitizer, + supported_targets.join("` or `") + )); return } diff --git a/src/librustc_msan/build.rs b/src/librustc_msan/build.rs index c438b5250463b..dcadbe86966e7 100644 --- a/src/librustc_msan/build.rs +++ b/src/librustc_msan/build.rs @@ -12,14 +12,13 @@ extern crate build_helper; extern crate cmake; use std::env; -use build_helper::native_lib_boilerplate; +use build_helper::sanitizer_lib_boilerplate; use cmake::Config; fn main() { if let Some(llvm_config) = env::var_os("LLVM_CONFIG") { - let native = match native_lib_boilerplate("compiler-rt", "msan", "clang_rt.msan-x86_64", - "build/lib/linux") { + let native = match sanitizer_lib_boilerplate("msan") { Ok(native) => native, _ => return, }; diff --git a/src/librustc_tsan/build.rs b/src/librustc_tsan/build.rs index 055b344d2e947..5ea52f17a0fde 100644 --- a/src/librustc_tsan/build.rs +++ b/src/librustc_tsan/build.rs @@ -12,14 +12,13 @@ extern crate build_helper; extern crate cmake; use std::env; -use build_helper::native_lib_boilerplate; +use build_helper::sanitizer_lib_boilerplate; use cmake::Config; fn main() { if let Some(llvm_config) = env::var_os("LLVM_CONFIG") { - let native = match native_lib_boilerplate("compiler-rt", "tsan", "clang_rt.tsan-x86_64", - "build/lib/linux") { + let native = match sanitizer_lib_boilerplate("tsan") { Ok(native) => native, _ => return, }; diff --git a/src/libstd/Cargo.toml b/src/libstd/Cargo.toml index 46511452a7237..717892be2abad 100644 --- a/src/libstd/Cargo.toml +++ b/src/libstd/Cargo.toml @@ -23,6 +23,10 @@ compiler_builtins = { path = "../libcompiler_builtins" } std_unicode = { path = "../libstd_unicode" } unwind = { path = "../libunwind" } +[target.x86_64-apple-darwin.dependencies] +rustc_asan = { path = "../librustc_asan" } +rustc_tsan = { path = "../librustc_tsan" } + [target.x86_64-unknown-linux-gnu.dependencies] rustc_asan = { path = "../librustc_asan" } rustc_lsan = { path = "../librustc_lsan" } diff --git a/src/test/run-make/sanitizer-address/Makefile b/src/test/run-make/sanitizer-address/Makefile index 5931145f3a47d..61b25df1451b3 100644 --- a/src/test/run-make/sanitizer-address/Makefile +++ b/src/test/run-make/sanitizer-address/Makefile @@ -1,11 +1,19 @@ -include ../tools.mk -# NOTE the address sanitizer only supports x86_64 linux -ifdef SANITIZER_SUPPORT -all: - $(RUSTC) -g -Z sanitizer=address -Z print-link-args overflow.rs | grep -q librustc_asan - $(TMPDIR)/overflow 2>&1 | grep -q stack-buffer-overflow +# NOTE the address sanitizer only supports x86_64 linux and macOS + +ifeq ($(TARGET),x86_64-apple-darwin) +ASAN_SUPPORT=$(SANITIZER_SUPPORT) +EXTRA_RUSTFLAG=-C rpath else -all: +ifeq ($(TARGET),x86_64-unknown-linux-gnu) +ASAN_SUPPORT=$(SANITIZER_SUPPORT) +EXTRA_RUSTFLAG= +endif +endif +all: +ifeq ($(ASAN_SUPPORT),1) + $(RUSTC) -g -Z sanitizer=address -Z print-link-args $(EXTRA_RUSTFLAG) overflow.rs | grep -q librustc_asan + $(TMPDIR)/overflow 2>&1 | grep -q stack-buffer-overflow endif diff --git a/src/test/run-make/sanitizer-invalid-target/Makefile b/src/test/run-make/sanitizer-invalid-target/Makefile index 6a1ce8bab2fb6..82e32f0995202 100644 --- a/src/test/run-make/sanitizer-invalid-target/Makefile +++ b/src/test/run-make/sanitizer-invalid-target/Makefile @@ -1,4 +1,4 @@ -include ../tools.mk all: - $(RUSTC) -Z sanitizer=leak --target i686-unknown-linux-gnu hello.rs 2>&1 | grep -q 'Sanitizers only work with the `x86_64-unknown-linux-gnu` target' + $(RUSTC) -Z sanitizer=leak --target i686-unknown-linux-gnu hello.rs 2>&1 | grep -q 'LeakSanitizer only works with the `x86_64-unknown-linux-gnu` target' diff --git a/src/test/run-make/sanitizer-leak/Makefile b/src/test/run-make/sanitizer-leak/Makefile index f02d948fdc84f..b18dd1d45eda4 100644 --- a/src/test/run-make/sanitizer-leak/Makefile +++ b/src/test/run-make/sanitizer-leak/Makefile @@ -1,10 +1,10 @@ -include ../tools.mk -ifdef SANITIZER_SUPPORT all: +ifeq ($(TARGET),x86_64-unknown-linux-gnu) +ifdef SANITIZER_SUPPORT $(RUSTC) -C opt-level=1 -g -Z sanitizer=leak -Z print-link-args leak.rs | grep -q librustc_lsan $(TMPDIR)/leak 2>&1 | grep -q 'detected memory leaks' -else -all: - endif +endif + diff --git a/src/test/run-make/sanitizer-memory/Makefile b/src/test/run-make/sanitizer-memory/Makefile index 08682e5975e51..7502ef0e7a7b7 100644 --- a/src/test/run-make/sanitizer-memory/Makefile +++ b/src/test/run-make/sanitizer-memory/Makefile @@ -1,10 +1,10 @@ -include ../tools.mk -ifdef SANITIZER_SUPPORT all: +ifeq ($(TARGET),x86_64-unknown-linux-gnu) +ifdef SANITIZER_SUPPORT $(RUSTC) -g -Z sanitizer=memory -Z print-link-args uninit.rs | grep -q librustc_msan $(TMPDIR)/uninit 2>&1 | grep -q use-of-uninitialized-value -else -all: - endif +endif + From 86747a9952d9d112f64dd2671cfa8694a7822158 Mon Sep 17 00:00:00 2001 From: kennytm Date: Thu, 20 Apr 2017 08:31:43 +0800 Subject: [PATCH 18/25] Force link with an absolute rpath when using sanitizer on macOS. --- src/librustc_trans/back/link.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/librustc_trans/back/link.rs b/src/librustc_trans/back/link.rs index 7c0522a9c8cf8..e42e69d2a76e2 100644 --- a/src/librustc_trans/back/link.rs +++ b/src/librustc_trans/back/link.rs @@ -1122,6 +1122,19 @@ fn add_upstream_rust_crates(cmd: &mut Linker, cnum: CrateNum) { let src = sess.cstore.used_crate_source(cnum); let cratepath = &src.rlib.unwrap().0; + + if sess.target.target.options.is_like_osx { + // On Apple platforms, the sanitizer is always built as a dylib, and + // LLVM will link to `@rpath/*.dylib`, so we need to specify an + // rpath to the library as well (the rpath should be absolute, see + // PR #41352 for details). + // + // FIXME: Remove this logic into librustc_*san once Cargo supports it + let rpath = cratepath.parent().unwrap(); + let rpath = rpath.to_str().expect("non-utf8 component in path"); + cmd.args(&["-Wl,-rpath".into(), "-Xlinker".into(), rpath.into()]); + } + let dst = tmpdir.join(cratepath.file_name().unwrap()); let cfg = archive_config(sess, &dst, Some(cratepath)); let mut archive = ArchiveBuilder::new(cfg); From 3b33913cfbf165d95f5688c232b663bf979c75df Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Thu, 20 Apr 2017 08:35:03 -0700 Subject: [PATCH 19/25] appveyor: Upgrade to gcc for mingw 6.3.0 This commit sort of brings back #40777 by upgrading back to 6.3.0. While investigating #40546 it was discovered that 6.3.0 appears to not spurious fail in the same way that 6.2.0 does (which we're currently using). The workaround for #40184 contained in #40777 did not work so this commit also contains a different workaround for the gdb issue. We will not download the 6.2.0 version of gdb and use that instead of the default version that comes with 6.3.0. I'm going to optimistically say... Closes #40546 --- appveyor.yml | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index f0589b0e64561..ab973a82b7ade 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -35,13 +35,13 @@ environment: RUST_CONFIGURE_ARGS: --build=i686-pc-windows-gnu --enable-ninja SCRIPT: python x.py test MINGW_URL: https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror - MINGW_ARCHIVE: i686-6.2.0-release-posix-dwarf-rt_v5-rev1.7z + MINGW_ARCHIVE: i686-6.3.0-release-posix-dwarf-rt_v5-rev1.7z MINGW_DIR: mingw32 - MSYS_BITS: 64 SCRIPT: python x.py test RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-gnu --enable-ninja MINGW_URL: https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror - MINGW_ARCHIVE: x86_64-6.2.0-release-posix-seh-rt_v5-rev1.7z + MINGW_ARCHIVE: x86_64-6.3.0-release-posix-seh-rt_v5-rev1.7z MINGW_DIR: mingw64 # 32/64 bit MSVC and GNU deployment @@ -60,14 +60,14 @@ environment: RUST_CONFIGURE_ARGS: --build=i686-pc-windows-gnu --enable-extended --enable-ninja SCRIPT: python x.py dist MINGW_URL: https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror - MINGW_ARCHIVE: i686-6.2.0-release-posix-dwarf-rt_v5-rev1.7z + MINGW_ARCHIVE: i686-6.3.0-release-posix-dwarf-rt_v5-rev1.7z MINGW_DIR: mingw32 DEPLOY: 1 - MSYS_BITS: 64 SCRIPT: python x.py dist RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-gnu --enable-extended --enable-ninja MINGW_URL: https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror - MINGW_ARCHIVE: x86_64-6.2.0-release-posix-seh-rt_v5-rev1.7z + MINGW_ARCHIVE: x86_64-6.3.0-release-posix-seh-rt_v5-rev1.7z MINGW_DIR: mingw64 DEPLOY: 1 @@ -96,6 +96,26 @@ install: - if defined MINGW_URL 7z x -y %MINGW_ARCHIVE% > nul - if defined MINGW_URL set PATH=%CD%\%MINGW_DIR%\bin;C:\msys64\usr\bin;%PATH% + # Here we do a pretty heinous thing which is to mangle the MinGW installation + # we just had above. Currently, as of this writing, we're using MinGW-w64 + # builds of gcc, and that's currently at 6.3.0. We use 6.3.0 as it appears to + # be the first version which contains a fix for #40546, builds randomly + # failing during LLVM due to ar.exe/ranlib.exe failures. + # + # Unfortunately, though, 6.3.0 *also* is the first version of MinGW-w64 builds + # to contain a regression in gdb (#40184). As a result if we were to use the + # gdb provided (7.11.1) then we would fail all debuginfo tests. + # + # In order to fix spurious failures (pretty high priority) we use 6.3.0. To + # avoid disabling gdb tests we download an *old* version of gdb, specifically + # that found inside the 6.2.0 distribution. We then overwrite the 6.3.0 gdb + # with the 6.2.0 gdb to get tests passing. + # + # Note that we don't literally overwrite the gdb.exe binary because it appears + # to just use gdborig.exe, so that's the binary we deal with instead. + - if defined MINGW_URL appveyor-retry appveyor DownloadFile %MINGW_URL%/2017-04-20-%MSYS_BITS%bits-gdborig.exe + - if defined MINGW_URL mv 2017-04-20-%MSYS_BITS%bits-gdborig.exe %MINGW_DIR%\bin\gdborig.exe + # Otherwise pull in the MinGW installed on appveyor - if NOT defined MINGW_URL set PATH=C:\msys64\mingw%MSYS_BITS%\bin;C:\msys64\usr\bin;%PATH% From ca96892ebb2dfcf302c98a2869fe41f14adb4f39 Mon Sep 17 00:00:00 2001 From: steveklabnik Date: Tue, 25 Apr 2017 04:10:06 -0400 Subject: [PATCH 20/25] Clean up TcpStream example Fixes #35950 --- src/libstd/net/tcp.rs | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/libstd/net/tcp.rs b/src/libstd/net/tcp.rs index bc315d54100e4..bc4e8598bbaec 100644 --- a/src/libstd/net/tcp.rs +++ b/src/libstd/net/tcp.rs @@ -73,6 +73,7 @@ pub struct TcpStream(net_imp::TcpStream); /// # Examples /// /// ```no_run +/// # use std::io; /// use std::net::{TcpListener, TcpStream}; /// /// let listener = TcpListener::bind("127.0.0.1:80").unwrap(); @@ -81,15 +82,13 @@ pub struct TcpStream(net_imp::TcpStream); /// // ... /// } /// +/// # fn process() -> io::Result<()> { /// // accept connections and process them serially /// for stream in listener.incoming() { -/// match stream { -/// Ok(stream) => { -/// handle_client(stream); -/// } -/// Err(e) => { /* connection failed */ } -/// } +/// handle_client(stream?); /// } +/// # Ok(()) +/// # } /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub struct TcpListener(net_imp::TcpListener); From dce33e96bc2f904fbc5bfb96b5fb92433dc18ba8 Mon Sep 17 00:00:00 2001 From: steveklabnik Date: Tue, 25 Apr 2017 05:35:51 -0400 Subject: [PATCH 21/25] Clarify the doc index With regards to the unstable book, the reference, and the processes involved. Also, fix up a link by pointing to the new tracking issue rather than the older one. Fixes #41285 --- src/doc/index.md | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/doc/index.md b/src/doc/index.md index 1294c1a8c59e7..fd5b120e81fae 100644 --- a/src/doc/index.md +++ b/src/doc/index.md @@ -32,16 +32,21 @@ nicknamed 'The Rust Bookshelf.' * [The Rustonomicon][nomicon] is your guidebook to the dark arts of unsafe Rust. * [The Reference][ref] is not a formal spec, but is more detailed and comprehensive than the book. +Initially, documentation lands in the Unstable Book, and then, as part of the +stabilization process, is moved into the Book, Nomicon, or Reference. + Another few words about the reference: it is guaranteed to be accurate, but not -complete. We now have a policy that all new features must be included in the -reference before stabilization; however, we are still back-filling things that -landed before then. That work is being tracked [here][38643]. +complete. We have a policy that features must have documentation to be stabilized, +but we did not always have this policy, and so there are some stable things that +are not yet in the reference. We're working on back-filling things that landed +before this policy was put into place. That work is being tracked +[here][refchecklist]. [Rust Learning]: https://github.com/ctjhoa/rust-learning [Docs.rs]: https://docs.rs/ [api]: std/index.html [ref]: reference/index.html -[38643]: https://github.com/rust-lang/rust/issues/38643 +[refchecklist]: https://github.com/rust-lang-nursery/reference/issues/9 [err]: error-index.html [book]: book/index.html [nomicon]: nomicon/index.html From 696df71d0c442dba82f52f2b985feb0e1431bd60 Mon Sep 17 00:00:00 2001 From: steveklabnik Date: Tue, 25 Apr 2017 05:38:26 -0400 Subject: [PATCH 22/25] Clarify "side effect" in peek's docs Fixes #33269 --- src/libcore/iter/iterator.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/libcore/iter/iterator.rs b/src/libcore/iter/iterator.rs index 3ad91ef15ea7b..b3f4d75c4da61 100644 --- a/src/libcore/iter/iterator.rs +++ b/src/libcore/iter/iterator.rs @@ -629,8 +629,9 @@ pub trait Iterator { /// /// Note that the underlying iterator is still advanced when [`peek`] is /// called for the first time: In order to retrieve the next element, - /// [`next`] is called on the underlying iterator, hence any side effects of - /// the [`next`] method will occur. + /// [`next`] is called on the underlying iterator, hence any side effects (i.e. + /// anything other than fetching the next value) of the [`next`] method + /// will occur. /// /// [`peek`]: struct.Peekable.html#method.peek /// [`next`]: ../../std/iter/trait.Iterator.html#tymethod.next From 3f97b2a65c31a1c53c29d233d6b37b0258e4a6b2 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 24 Apr 2017 16:26:04 +0200 Subject: [PATCH 23/25] Add ui tests --- src/libsyntax/parse/parser.rs | 11 ++++------- .../auxiliary/foo/bar.rs | 0 .../auxiliary/foo/mod.rs | 0 .../invalid-module-declaration.rs | 0 .../invalid-module-declaration.stderr | 14 ++++++++++++++ 5 files changed, 18 insertions(+), 7 deletions(-) rename src/test/{compile-fail => ui/invalid-module-declaration}/auxiliary/foo/bar.rs (100%) rename src/test/{compile-fail => ui/invalid-module-declaration}/auxiliary/foo/mod.rs (100%) rename src/test/{compile-fail => ui/invalid-module-declaration}/invalid-module-declaration.rs (100%) create mode 100644 src/test/ui/invalid-module-declaration/invalid-module-declaration.stderr diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 9df791c1c124e..afdb0cc4fdb79 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -57,10 +57,10 @@ use tokenstream::{self, Delimited, ThinTokenStream, TokenTree, TokenStream}; use symbol::{Symbol, keywords}; use util::ThinVec; +use std::cmp; use std::collections::HashSet; use std::mem; -use std::path::{Path, PathBuf}; -use std::rc::Rc; +use std::path::{self, Path, PathBuf}; use std::slice; bitflags! { @@ -5367,7 +5367,7 @@ impl<'a> Parser<'a> { "cannot declare a new module at this location"); if id_sp != syntax_pos::DUMMY_SP { let src_path = PathBuf::from(self.sess.codemap().span_to_filename(id_sp)); - if let Some(stem) = src_path.clone().file_stem() { + if let Some(stem) = src_path.file_stem() { let mut dest_path = src_path.clone(); dest_path.set_file_name(stem); dest_path.push("mod.rs"); @@ -5385,10 +5385,7 @@ impl<'a> Parser<'a> { } Err(err) } else { - match paths.result { - Ok(succ) => Ok(succ), - Err(err) => Err(self.span_fatal_err(id_sp, err)), - } + paths.result.map_err(|err| self.span_fatal_err(id_sp, err)) } } diff --git a/src/test/compile-fail/auxiliary/foo/bar.rs b/src/test/ui/invalid-module-declaration/auxiliary/foo/bar.rs similarity index 100% rename from src/test/compile-fail/auxiliary/foo/bar.rs rename to src/test/ui/invalid-module-declaration/auxiliary/foo/bar.rs diff --git a/src/test/compile-fail/auxiliary/foo/mod.rs b/src/test/ui/invalid-module-declaration/auxiliary/foo/mod.rs similarity index 100% rename from src/test/compile-fail/auxiliary/foo/mod.rs rename to src/test/ui/invalid-module-declaration/auxiliary/foo/mod.rs diff --git a/src/test/compile-fail/invalid-module-declaration.rs b/src/test/ui/invalid-module-declaration/invalid-module-declaration.rs similarity index 100% rename from src/test/compile-fail/invalid-module-declaration.rs rename to src/test/ui/invalid-module-declaration/invalid-module-declaration.rs diff --git a/src/test/ui/invalid-module-declaration/invalid-module-declaration.stderr b/src/test/ui/invalid-module-declaration/invalid-module-declaration.stderr new file mode 100644 index 0000000000000..3e9b21cdb740f --- /dev/null +++ b/src/test/ui/invalid-module-declaration/invalid-module-declaration.stderr @@ -0,0 +1,14 @@ +error: cannot declare a new module at this location + --> $DIR/auxiliary/foo/bar.rs:11:9 + | +11 | pub mod baz; + | ^^^ + | +note: maybe move this module `$DIR/auxiliary/foo/bar.rs` to its own directory via `$DIR/auxiliary/foo/bar/mod.rs` + --> $DIR/auxiliary/foo/bar.rs:11:9 + | +11 | pub mod baz; + | ^^^ + +error: aborting due to previous error + From 164fd696bf9db696148018f395ad703a5825246e Mon Sep 17 00:00:00 2001 From: kennytm Date: Tue, 25 Apr 2017 18:34:21 +0800 Subject: [PATCH 24/25] Do not check if libclang_rt.?san_*_dynamic.dylib is an unstable crate. These are not even crates... --- src/test/run-make/sysroot-crates-are-unstable/Makefile | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/test/run-make/sysroot-crates-are-unstable/Makefile b/src/test/run-make/sysroot-crates-are-unstable/Makefile index 2bdc76e01db1a..4b7052f9b9493 100644 --- a/src/test/run-make/sysroot-crates-are-unstable/Makefile +++ b/src/test/run-make/sysroot-crates-are-unstable/Makefile @@ -1,7 +1,7 @@ -include ../tools.mk -# This is a whitelist of crates which are stable, we don't check for the -# instability of these crates as they're all stable! +# This is a whitelist of files which are stable crates or simply are not crates, +# we don't check for the instability of these crates as they're all stable! STABLE_CRATES := \ std \ core \ @@ -9,7 +9,8 @@ STABLE_CRATES := \ rsbegin.o \ rsend.o \ dllcrt2.o \ - crt2.o + crt2.o \ + clang_rt.%_dynamic.dylib # Generate a list of all crates in the sysroot. To do this we list all files in # rustc's sysroot, look at the filename, strip everything after the `-`, and From 19b7272dbcd9a35acfed7c8aa5e8d3e23b2a67f9 Mon Sep 17 00:00:00 2001 From: steveklabnik Date: Tue, 25 Apr 2017 10:41:17 -0400 Subject: [PATCH 25/25] Fix up vec guarnatee around capacity Fixes #37746 --- src/libcollections/vec.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs index 6deb87ae77204..fcebc22bb455a 100644 --- a/src/libcollections/vec.rs +++ b/src/libcollections/vec.rs @@ -275,7 +275,9 @@ use Bound::{Excluded, Included, Unbounded}; /// removed data to be erased for security purposes. Even if you drop a `Vec`, its /// buffer may simply be reused by another `Vec`. Even if you zero a `Vec`'s memory /// first, that may not actually happen because the optimizer does not consider -/// this a side-effect that must be preserved. +/// this a side-effect that must be preserved. There is one case which we will +/// not break, however: using `unsafe` code to write to the excess capacity, +/// and then increasing the length to match, is always valid. /// /// `Vec` does not currently guarantee the order in which elements are dropped /// (the order has changed in the past, and may change again).