diff --git a/configure b/configure index e5333b45525fc..af500a056f1dd 100755 --- a/configure +++ b/configure @@ -697,15 +697,17 @@ probe CFG_ADB adb if [ ! -z "$CFG_PANDOC" ] then - PV_MAJOR_MINOR=$(pandoc --version | grep '^pandoc\(.exe\)\? ' | - # extract the first 2 version fields, ignore everything else - sed 's/pandoc\(.exe\)\? \([0-9]*\)\.\([0-9]*\).*/\2 \3/') + PV_MAJOR_MINOR=$(pandoc --version | grep '^pandoc' | + # Extract "MAJOR MINOR" from Pandoc's version number + sed -E 's/pandoc(.exe)? ([0-9]+)\.([0-9]+).*/\2 \3/') MIN_PV_MAJOR="1" MIN_PV_MINOR="9" + # these patterns are shell globs, *not* regexps PV_MAJOR=${PV_MAJOR_MINOR% *} PV_MINOR=${PV_MAJOR_MINOR#* } + if [ "$PV_MAJOR" -lt "$MIN_PV_MAJOR" ] || [ "$PV_MINOR" -lt "$MIN_PV_MINOR" ] then step_msg "pandoc $PV_MAJOR.$PV_MINOR is too old. Need at least $MIN_PV_MAJOR.$MIN_PV_MINOR. Disabling" diff --git a/mk/main.mk b/mk/main.mk index 9752ee233b6e3..c00494be47cb7 100644 --- a/mk/main.mk +++ b/mk/main.mk @@ -18,7 +18,7 @@ CFG_RELEASE_NUM=1.0.0 # An optional number to put after the label, e.g. '.2' -> '-beta.2' # NB Make sure it starts with a dot to conform to semver pre-release # versions (section 9) -CFG_PRERELEASE_VERSION=.2 +CFG_PRERELEASE_VERSION= CFG_FILENAME_EXTRA=4e7c5e5c @@ -30,8 +30,8 @@ CFG_PACKAGE_VERS=$(CFG_RELEASE_NUM) CFG_DISABLE_UNSTABLE_FEATURES=1 endif ifeq ($(CFG_RELEASE_CHANNEL),beta) -CFG_RELEASE=$(CFG_RELEASE_NUM)-alpha$(CFG_PRERELEASE_VERSION) -CFG_PACKAGE_VERS=$(CFG_RELEASE_NUM)-alpha$(CFG_PRERELEASE_VERSION) +CFG_RELEASE=$(CFG_RELEASE_NUM)-beta(CFG_PRERELEASE_VERSION) +CFG_PACKAGE_VERS=$(CFG_RELEASE_NUM)-beta(CFG_PRERELEASE_VERSION) CFG_DISABLE_UNSTABLE_FEATURES=1 endif ifeq ($(CFG_RELEASE_CHANNEL),nightly) diff --git a/mk/tests.mk b/mk/tests.mk index 838ed0dccfcbb..ef38abcab6518 100644 --- a/mk/tests.mk +++ b/mk/tests.mk @@ -590,7 +590,7 @@ TEST_SREQ$(1)_T_$(2)_H_$(3) = \ # The tests select when to use debug configuration on their own; # remove directive, if present, from CFG_RUSTC_FLAGS (issue #7898). -CTEST_RUSTC_FLAGS := $$(subst --cfg ndebug,,$$(CFG_RUSTC_FLAGS)) +CTEST_RUSTC_FLAGS := $$(subst -C debug-assertions,,$$(CFG_RUSTC_FLAGS)) # The tests cannot be optimized while the rest of the compiler is optimized, so # filter out the optimization (if any) from rustc and then figure out if we need diff --git a/src/compiletest/compiletest.rs b/src/compiletest/compiletest.rs index b9e6f1842eeab..073f16e354d3a 100644 --- a/src/compiletest/compiletest.rs +++ b/src/compiletest/compiletest.rs @@ -22,10 +22,9 @@ #![feature(unicode)] #![feature(core)] #![feature(path)] -#![feature(os)] #![feature(io)] -#![feature(fs)] #![feature(net)] +#![feature(path_ext)] #![deny(warnings)] diff --git a/src/compiletest/runtest.rs b/src/compiletest/runtest.rs index 7fb1a436ba385..04714b50fc027 100644 --- a/src/compiletest/runtest.rs +++ b/src/compiletest/runtest.rs @@ -20,7 +20,6 @@ use procsrv; use util::logv; use std::env; -use std::ffi::OsStr; use std::fmt; use std::fs::{self, File}; use std::io::BufReader; @@ -1323,7 +1322,7 @@ fn make_exe_name(config: &Config, testfile: &Path) -> PathBuf { let mut f = output_base_name(config, testfile); if !env::consts::EXE_SUFFIX.is_empty() { let mut fname = f.file_name().unwrap().to_os_string(); - fname.push_os_str(OsStr::from_str(env::consts::EXE_SUFFIX)); + fname.push(env::consts::EXE_SUFFIX); f.set_file_name(&fname); } f @@ -1433,7 +1432,7 @@ fn make_out_name(config: &Config, testfile: &Path, extension: &str) -> PathBuf { fn aux_output_dir_name(config: &Config, testfile: &Path) -> PathBuf { let f = output_base_name(config, testfile); let mut fname = f.file_name().unwrap().to_os_string(); - fname.push_os_str(OsStr::from_str("libaux")); + fname.push("libaux"); f.with_file_name(&fname) } @@ -1647,8 +1646,8 @@ fn append_suffix_to_stem(p: &Path, suffix: &str) -> PathBuf { p.to_path_buf() } else { let mut stem = p.file_stem().unwrap().to_os_string(); - stem.push_os_str(OsStr::from_str("-")); - stem.push_os_str(OsStr::from_str(suffix)); + stem.push("-"); + stem.push(suffix); p.with_file_name(&stem) } } diff --git a/src/doc/guide-tasks.md b/src/doc/guide-tasks.md index 197559bef0408..21217bf54d769 100644 --- a/src/doc/guide-tasks.md +++ b/src/doc/guide-tasks.md @@ -1,4 +1,4 @@ % The (old) Rust Threads and Communication Guide This content has moved into -[the Rust Programming Language book](book/tasks.html). +[the Rust Programming Language book](book/concurrency.html). diff --git a/src/doc/trpl/arrays-vectors-and-slices.md b/src/doc/trpl/arrays-vectors-and-slices.md index d4e2ad5cd5f66..f1b5ecf4ff031 100644 --- a/src/doc/trpl/arrays-vectors-and-slices.md +++ b/src/doc/trpl/arrays-vectors-and-slices.md @@ -60,6 +60,12 @@ let v = vec![1, 2, 3]; // v: Vec brackets `[]` with `vec!`. Rust allows you to use either in either situation, this is just convention.) +There's an alternate form of `vec!` for repeating an initial value: + +``` +let v = vec![0; 10]; // ten zeroes +``` + You can get the length of, iterate over, and subscript vectors just like arrays. In addition, (mutable) vectors can grow automatically: diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index b1fdf139b0c51..5c9a42a8a7174 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -56,6 +56,8 @@ //! The [`heap`](heap/index.html) module defines the low-level interface to the //! default global allocator. It is not compatible with the libc allocator API. +// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364) +#![cfg_attr(stage0, feature(custom_attribute))] #![crate_name = "alloc"] #![unstable(feature = "alloc")] #![feature(staged_api)] diff --git a/src/libarena/lib.rs b/src/libarena/lib.rs index 4678fe15c8b7b..01fb8e3587240 100644 --- a/src/libarena/lib.rs +++ b/src/libarena/lib.rs @@ -19,6 +19,8 @@ //! arena but can only hold objects of a single type, and `Arena`, which is a //! more complex, slower arena which can hold objects of any type. +// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364) +#![cfg_attr(stage0, feature(custom_attribute))] #![crate_name = "arena"] #![unstable(feature = "rustc_private")] #![staged_api] diff --git a/src/libcollections/lib.rs b/src/libcollections/lib.rs index 7b66bfee34f21..9c1c2cc5906eb 100644 --- a/src/libcollections/lib.rs +++ b/src/libcollections/lib.rs @@ -12,7 +12,8 @@ //! //! See [std::collections](../std/collections) for a detailed discussion of collections in Rust. - +// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364) +#![cfg_attr(stage0, feature(custom_attribute))] #![crate_name = "collections"] #![unstable(feature = "collections")] #![staged_api] diff --git a/src/libcollections/str.rs b/src/libcollections/str.rs index 19c085df2c43d..99547b9c60a89 100644 --- a/src/libcollections/str.rs +++ b/src/libcollections/str.rs @@ -1086,7 +1086,7 @@ pub trait StrExt: Index { /// /// let s = "中华Việt Nam"; /// let mut i = s.len(); - /// while i < 0 { + /// while i > 0 { /// let CharRange {ch, next} = s.char_range_at_reverse(i); /// println!("{}: {}", i, ch); /// i = next; diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs index 16e652fcc9a8a..32225b90f6b14 100644 --- a/src/libcore/iter.rs +++ b/src/libcore/iter.rs @@ -1279,14 +1279,14 @@ pub struct Cloned { } #[stable(feature = "rust1", since = "1.0.0")] -impl Iterator for Cloned where - T: Clone, - D: Deref, - I: Iterator, +impl Iterator for Cloned where + I: Iterator, + I::Item: Deref, + ::Target: Clone { - type Item = T; + type Item = ::Target; - fn next(&mut self) -> Option { + fn next(&mut self) -> Option<::Item> { self.it.next().cloned() } @@ -1296,28 +1296,28 @@ impl Iterator for Cloned where } #[stable(feature = "rust1", since = "1.0.0")] -impl DoubleEndedIterator for Cloned where - T: Clone, - D: Deref, - I: DoubleEndedIterator, +impl DoubleEndedIterator for Cloned where + I: DoubleEndedIterator, + I::Item: Deref, + ::Target: Clone { - fn next_back(&mut self) -> Option { + fn next_back(&mut self) -> Option<::Item> { self.it.next_back().cloned() } } #[stable(feature = "rust1", since = "1.0.0")] -impl ExactSizeIterator for Cloned where - T: Clone, - D: Deref, - I: ExactSizeIterator, +impl ExactSizeIterator for Cloned where + I: ExactSizeIterator, + I::Item: Deref, + ::Target: Clone {} #[unstable(feature = "core", reason = "trait is experimental")] -impl RandomAccessIterator for Cloned where - T: Clone, - D: Deref, - I: RandomAccessIterator +impl RandomAccessIterator for Cloned where + I: RandomAccessIterator, + I::Item: Deref, + ::Target: Clone { #[inline] fn indexable(&self) -> usize { @@ -1325,7 +1325,7 @@ impl RandomAccessIterator for Cloned where } #[inline] - fn idx(&mut self, index: usize) -> Option { + fn idx(&mut self, index: usize) -> Option<::Item> { self.it.idx(index).cloned() } } @@ -1400,11 +1400,14 @@ pub struct Chain { } #[stable(feature = "rust1", since = "1.0.0")] -impl Iterator for Chain where A: Iterator, B: Iterator { - type Item = T; +impl Iterator for Chain where + A: Iterator, + B: Iterator +{ + type Item = A::Item; #[inline] - fn next(&mut self) -> Option { + fn next(&mut self) -> Option { if self.flag { self.b.next() } else { @@ -1434,12 +1437,12 @@ impl Iterator for Chain where A: Iterator, B: Iterator DoubleEndedIterator for Chain where - A: DoubleEndedIterator, - B: DoubleEndedIterator, +impl DoubleEndedIterator for Chain where + A: DoubleEndedIterator, + B: DoubleEndedIterator, { #[inline] - fn next_back(&mut self) -> Option { + fn next_back(&mut self) -> Option { match self.b.next_back() { Some(x) => Some(x), None => self.a.next_back() @@ -1448,9 +1451,9 @@ impl DoubleEndedIterator for Chain where } #[unstable(feature = "core", reason = "trait is experimental")] -impl RandomAccessIterator for Chain where - A: RandomAccessIterator, - B: RandomAccessIterator, +impl RandomAccessIterator for Chain where + A: RandomAccessIterator, + B: RandomAccessIterator, { #[inline] fn indexable(&self) -> usize { @@ -1459,7 +1462,7 @@ impl RandomAccessIterator for Chain where } #[inline] - fn idx(&mut self, index: usize) -> Option { + fn idx(&mut self, index: usize) -> Option { let len = self.a.indexable(); if index < len { self.a.idx(index) @@ -1479,14 +1482,12 @@ pub struct Zip { } #[stable(feature = "rust1", since = "1.0.0")] -impl Iterator for Zip where - A: Iterator, - B: Iterator, +impl Iterator for Zip where A: Iterator, B: Iterator { - type Item = (T, U); + type Item = (A::Item, B::Item); #[inline] - fn next(&mut self) -> Option<(T, U)> { + fn next(&mut self) -> Option<(A::Item, B::Item)> { match self.a.next() { None => None, Some(x) => match self.b.next() { @@ -1515,12 +1516,12 @@ impl Iterator for Zip where } #[stable(feature = "rust1", since = "1.0.0")] -impl DoubleEndedIterator for Zip where - A: DoubleEndedIterator + ExactSizeIterator, - B: DoubleEndedIterator + ExactSizeIterator, +impl DoubleEndedIterator for Zip where + A: DoubleEndedIterator + ExactSizeIterator, + B: DoubleEndedIterator + ExactSizeIterator, { #[inline] - fn next_back(&mut self) -> Option<(T, U)> { + fn next_back(&mut self) -> Option<(A::Item, B::Item)> { let a_sz = self.a.len(); let b_sz = self.b.len(); if a_sz != b_sz { @@ -1540,9 +1541,9 @@ impl DoubleEndedIterator for Zip where } #[unstable(feature = "core", reason = "trait is experimental")] -impl RandomAccessIterator for Zip where - A: RandomAccessIterator, - B: RandomAccessIterator, +impl RandomAccessIterator for Zip where + A: RandomAccessIterator, + B: RandomAccessIterator { #[inline] fn indexable(&self) -> usize { @@ -1550,7 +1551,7 @@ impl RandomAccessIterator for Zip where } #[inline] - fn idx(&mut self, index: usize) -> Option<(T, U)> { + fn idx(&mut self, index: usize) -> Option<(A::Item, B::Item)> { match self.a.idx(index) { None => None, Some(x) => match self.b.idx(index) { @@ -2058,8 +2059,9 @@ pub struct Scan { } #[stable(feature = "rust1", since = "1.0.0")] -impl, St, F> Iterator for Scan where - F: FnMut(&mut St, A) -> Option, +impl Iterator for Scan where + I: Iterator, + F: FnMut(&mut St, I::Item) -> Option, { type Item = B; diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index 94d37cee5b37d..45a5563ceeb17 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -35,8 +35,7 @@ //! often generated by LLVM. Additionally, this library can make explicit //! calls to these functions. Their signatures are the same as found in C. //! These functions are often provided by the system libc, but can also be -//! provided by `librlibc` which is distributed with the standard rust -//! distribution. +//! provided by the [rlibc crate](https://crates.io/crates/rlibc). //! //! * `rust_begin_unwind` - This function takes three arguments, a //! `fmt::Arguments`, a `&str`, and a `usize`. These three arguments dictate @@ -47,6 +46,8 @@ // Since libcore defines many fundamental lang items, all tests live in a // separate crate, libcoretest, to avoid bizarre issues. +// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364) +#![cfg_attr(stage0, feature(custom_attribute))] #![crate_name = "core"] #![unstable(feature = "core")] #![staged_api] diff --git a/src/libcore/macros.rs b/src/libcore/macros.rs index f56206e8782d2..c2860d435114f 100644 --- a/src/libcore/macros.rs +++ b/src/libcore/macros.rs @@ -100,10 +100,12 @@ macro_rules! assert_eq { /// This will invoke the `panic!` macro if the provided expression cannot be /// evaluated to `true` at runtime. /// -/// Unlike `assert!`, `debug_assert!` statements can be disabled by passing -/// `--cfg ndebug` to the compiler. This makes `debug_assert!` useful for -/// checks that are too expensive to be present in a release build but may be -/// helpful during development. +/// Unlike `assert!`, `debug_assert!` statements are only enabled in non +/// optimized builds by default. An optimized build will omit all +/// `debug_assert!` statements unless `-C debug-assertions` is passed to the +/// compiler. This makes `debug_assert!` useful for checks that are too +/// expensive to be present in a release build but may be helpful during +/// development. /// /// # Example /// @@ -125,7 +127,7 @@ macro_rules! assert_eq { #[macro_export] #[stable(feature = "rust1", since = "1.0.0")] macro_rules! debug_assert { - ($($arg:tt)*) => (if cfg!(not(ndebug)) { assert!($($arg)*); }) + ($($arg:tt)*) => (if cfg!(debug_assertions) { assert!($($arg)*); }) } /// Asserts that two expressions are equal to each other, testing equality in @@ -133,10 +135,12 @@ macro_rules! debug_assert { /// /// On panic, this macro will print the values of the expressions. /// -/// Unlike `assert_eq!`, `debug_assert_eq!` statements can be disabled by -/// passing `--cfg ndebug` to the compiler. This makes `debug_assert_eq!` -/// useful for checks that are too expensive to be present in a release build -/// but may be helpful during development. +/// Unlike `assert_eq!`, `debug_assert_eq!` statements are only enabled in non +/// optimized builds by default. An optimized build will omit all +/// `debug_assert_eq!` statements unless `-C debug-assertions` is passed to the +/// compiler. This makes `debug_assert_eq!` useful for checks that are too +/// expensive to be present in a release build but may be helpful during +/// development. /// /// # Example /// @@ -147,7 +151,7 @@ macro_rules! debug_assert { /// ``` #[macro_export] macro_rules! debug_assert_eq { - ($($arg:tt)*) => (if cfg!(not(ndebug)) { assert_eq!($($arg)*); }) + ($($arg:tt)*) => (if cfg!(debug_assertions) { assert_eq!($($arg)*); }) } /// Short circuiting evaluation on Err diff --git a/src/libcoretest/lib.rs b/src/libcoretest/lib.rs index 03924910e0485..1dbbb845d46e0 100644 --- a/src/libcoretest/lib.rs +++ b/src/libcoretest/lib.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364) +#![cfg_attr(stage0, feature(custom_attribute))] #![feature(box_syntax)] #![feature(int_uint)] #![feature(unboxed_closures)] diff --git a/src/libflate/lib.rs b/src/libflate/lib.rs index 585318300438b..a5cfe908aa86e 100644 --- a/src/libflate/lib.rs +++ b/src/libflate/lib.rs @@ -14,6 +14,8 @@ //! [def]: https://en.wikipedia.org/wiki/DEFLATE //! [mz]: https://code.google.com/p/miniz/ +// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364) +#![cfg_attr(stage0, feature(custom_attribute))] #![crate_name = "flate"] #![unstable(feature = "rustc_private")] #![staged_api] diff --git a/src/libfmt_macros/lib.rs b/src/libfmt_macros/lib.rs index 4e25e51e9a466..9b220409ef597 100644 --- a/src/libfmt_macros/lib.rs +++ b/src/libfmt_macros/lib.rs @@ -14,6 +14,8 @@ //! Parsing does not happen at runtime: structures of `std::fmt::rt` are //! generated instead. +// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364) +#![cfg_attr(stage0, feature(custom_attribute))] #![crate_name = "fmt_macros"] #![unstable(feature = "rustc_private")] #![staged_api] diff --git a/src/libgetopts/lib.rs b/src/libgetopts/lib.rs index 6b9d6cb0000f2..617edb4bea60c 100644 --- a/src/libgetopts/lib.rs +++ b/src/libgetopts/lib.rs @@ -77,6 +77,9 @@ //! } //! ``` + +// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364) +#![cfg_attr(stage0, feature(custom_attribute))] #![crate_name = "getopts"] #![unstable(feature = "rustc_private", reason = "use the crates.io `getopts` library instead")] @@ -92,8 +95,8 @@ #![feature(collections)] #![feature(int_uint)] #![feature(staged_api)] -#![feature(str_words)] #![feature(core)] +#![feature(str_words)] #![cfg_attr(test, feature(rustc_private))] #[cfg(test)] #[macro_use] extern crate log; diff --git a/src/libgraphviz/lib.rs b/src/libgraphviz/lib.rs index 2f60a9e2cca2a..5f6bfd196f031 100644 --- a/src/libgraphviz/lib.rs +++ b/src/libgraphviz/lib.rs @@ -264,6 +264,8 @@ //! //! * [DOT language](http://www.graphviz.org/doc/info/lang.html) +// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364) +#![cfg_attr(stage0, feature(custom_attribute))] #![crate_name = "graphviz"] #![unstable(feature = "rustc_private")] #![feature(staged_api)] diff --git a/src/liblibc/lib.rs b/src/liblibc/lib.rs index f59108607a01f..11aba40afad73 100644 --- a/src/liblibc/lib.rs +++ b/src/liblibc/lib.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364) +#![cfg_attr(stage0, feature(custom_attribute))] #![crate_name = "libc"] #![crate_type = "rlib"] #![cfg_attr(not(feature = "cargo-build"), unstable(feature = "libc"))] @@ -383,7 +385,8 @@ pub mod types { target_arch = "mips", target_arch = "mipsel", target_arch = "powerpc", - target_arch = "le32"))] + target_arch = "le32", + all(target_arch = "arm", not(target_os = "android"))))] pub mod posix88 { pub type off_t = i32; pub type dev_t = u64; @@ -395,7 +398,7 @@ pub mod types { pub type mode_t = u32; pub type ssize_t = i32; } - #[cfg(target_arch = "arm")] + #[cfg(all(target_arch = "arm", target_os = "android"))] pub mod posix88 { pub type off_t = i32; pub type dev_t = u32; @@ -409,7 +412,8 @@ pub mod types { } #[cfg(any(target_arch = "x86", target_arch = "le32", - target_arch = "powerpc"))] + target_arch = "powerpc", + all(target_arch = "arm", not(target_os = "android"))))] pub mod posix01 { use types::os::arch::c95::{c_short, c_long, time_t}; use types::os::arch::posix88::{dev_t, gid_t, ino_t}; @@ -455,7 +459,7 @@ pub mod types { pub __size: [u32; 9] } } - #[cfg(target_arch = "arm")] + #[cfg(all(target_arch = "arm", target_os = "android"))] pub mod posix01 { use types::os::arch::c95::{c_uchar, c_uint, c_ulong, time_t}; use types::os::arch::c99::{c_longlong, c_ulonglong}; @@ -4999,9 +5003,36 @@ pub mod funcs { use types::os::arch::c95::{c_char, c_int}; use types::os::arch::posix88::mode_t; + mod open_shim { + extern { + #[cfg(any(target_os = "macos", + target_os = "ios"))] + pub fn open(path: *const ::c_char, oflag: ::c_int, ...) + -> ::c_int; + + #[cfg(not(any(target_os = "macos", + target_os = "ios")))] + pub fn open(path: *const ::c_char, oflag: ::c_int, mode: ::mode_t) + -> ::c_int; + } + } + + #[cfg(any(target_os = "macos", + target_os = "ios"))] + #[inline] + pub unsafe extern fn open(path: *const c_char, oflag: c_int, mode: mode_t) -> c_int { + use types::os::arch::c95::c_uint; + open_shim::open(path, oflag, mode as c_uint) + } + + #[cfg(not(any(target_os = "macos", + target_os = "ios")))] + #[inline] + pub unsafe extern fn open(path: *const c_char, oflag: c_int, mode: mode_t) -> c_int { + open_shim::open(path, oflag, mode) + } + extern { - pub fn open(path: *const c_char, oflag: c_int, mode: mode_t) - -> c_int; pub fn creat(path: *const c_char, mode: mode_t) -> c_int; pub fn fcntl(fd: c_int, cmd: c_int, ...) -> c_int; } diff --git a/src/liblog/lib.rs b/src/liblog/lib.rs index d0105bb65776e..3b6e1d0469148 100644 --- a/src/liblog/lib.rs +++ b/src/liblog/lib.rs @@ -155,6 +155,8 @@ //! they're turned off (just a load and an integer comparison). This also means that //! if logging is disabled, none of the components of the log will be executed. +// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364) +#![cfg_attr(stage0, feature(custom_attribute))] #![crate_name = "log"] #![unstable(feature = "rustc_private", reason = "use the crates.io `log` library instead")] diff --git a/src/liblog/macros.rs b/src/liblog/macros.rs index 4a9a9bd40600b..f0f861a3831a1 100644 --- a/src/liblog/macros.rs +++ b/src/liblog/macros.rs @@ -157,7 +157,7 @@ macro_rules! info { /// ``` #[macro_export] macro_rules! debug { - ($($arg:tt)*) => (if cfg!(not(ndebug)) { log!(::log::DEBUG, $($arg)*) }) + ($($arg:tt)*) => (if cfg!(debug_assertions) { log!(::log::DEBUG, $($arg)*) }) } /// A macro to test whether a log level is enabled for the current module. @@ -192,7 +192,7 @@ macro_rules! debug { macro_rules! log_enabled { ($lvl:expr) => ({ let lvl = $lvl; - (lvl != ::log::DEBUG || cfg!(not(ndebug))) && + (lvl != ::log::DEBUG || cfg!(debug_assertions)) && lvl <= ::log::log_level() && ::log::mod_enabled(lvl, module_path!()) }) diff --git a/src/librand/lib.rs b/src/librand/lib.rs index c92f6c5e52db7..6bc56ce9084b3 100644 --- a/src/librand/lib.rs +++ b/src/librand/lib.rs @@ -16,6 +16,8 @@ //! is not recommended to use this library directly, but rather the official //! interface through `std::rand`. +// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364) +#![cfg_attr(stage0, feature(custom_attribute))] #![crate_name = "rand"] #![crate_type = "rlib"] #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk.png", diff --git a/src/librbml/lib.rs b/src/librbml/lib.rs index f0b79640f7d44..d71bcdf29243c 100644 --- a/src/librbml/lib.rs +++ b/src/librbml/lib.rs @@ -111,6 +111,8 @@ //! //! First 0x20 tags are reserved by RBML; custom tags start at 0x20. +// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364) +#![cfg_attr(stage0, feature(custom_attribute))] #![crate_name = "rbml"] #![unstable(feature = "rustc_private")] #![staged_api] diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index 2d542eafbe1ae..f424ac0cda271 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -14,6 +14,8 @@ //! //! This API is completely unstable and subject to change. +// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364) +#![cfg_attr(stage0, feature(custom_attribute))] #![crate_name = "rustc"] #![unstable(feature = "rustc_private")] #![staged_api] @@ -38,10 +40,10 @@ #![feature(unsafe_destructor)] #![feature(staged_api)] #![feature(std_misc)] -#![feature(os)] #![feature(path)] -#![feature(fs)] #![feature(io)] +#![feature(path_ext)] +#![feature(str_words)] #![cfg_attr(test, feature(test))] extern crate arena; diff --git a/src/librustc/middle/traits/select.rs b/src/librustc/middle/traits/select.rs index e57c16b5a0fb8..7dfbccea0dccd 100644 --- a/src/librustc/middle/traits/select.rs +++ b/src/librustc/middle/traits/select.rs @@ -1692,6 +1692,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } } + // for `PhantomData`, we pass `T` + ty::ty_struct(def_id, substs) + if Some(def_id) == self.tcx().lang_items.phantom_data() => + { + Some(substs.types.get_slice(TypeSpace).to_vec()) + } + ty::ty_struct(def_id, substs) => { Some(ty::struct_fields(self.tcx(), def_id, substs).iter() .map(|f| f.mt.ty) diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index a4355803f4a4e..1b09be050203b 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -81,6 +81,7 @@ pub struct Options { pub gc: bool, pub optimize: OptLevel, + pub debug_assertions: bool, pub debuginfo: DebugInfoLevel, pub lint_opts: Vec<(String, lint::Level)>, pub describe_lints: bool, @@ -238,7 +239,8 @@ pub fn basic_options() -> Options { crate_name: None, alt_std_name: None, libs: Vec::new(), - unstable_features: UnstableFeatures::Disallow + unstable_features: UnstableFeatures::Disallow, + debug_assertions: true, } } @@ -528,6 +530,8 @@ options! {CodegenOptions, CodegenSetter, basic_codegen_options, 2 = full debug info with variable and type information"), opt_level: Option = (None, parse_opt_uint, "Optimize with possible levels 0-3"), + debug_assertions: Option = (None, parse_opt_bool, + "explicitly enable the cfg(debug_assertions) directive"), } @@ -621,7 +625,7 @@ pub fn default_configuration(sess: &Session) -> ast::CrateConfig { }; let mk = attr::mk_name_value_item_str; - return vec!(// Target bindings. + let mut ret = vec![ // Target bindings. attr::mk_word_item(fam.clone()), mk(InternedString::new("target_os"), intern(os)), mk(InternedString::new("target_family"), fam), @@ -629,7 +633,11 @@ pub fn default_configuration(sess: &Session) -> ast::CrateConfig { mk(InternedString::new("target_endian"), intern(end)), mk(InternedString::new("target_pointer_width"), intern(wordsz)) - ); + ]; + if sess.opts.debug_assertions { + ret.push(attr::mk_word_item(InternedString::new("debug_assertions"))); + } + return ret; } pub fn append_configuration(cfg: &mut ast::CrateConfig, @@ -923,6 +931,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options { } } }; + let debug_assertions = cg.debug_assertions.unwrap_or(opt_level == No); let gc = debugging_opts.gc; let debuginfo = if matches.opt_present("g") { if cg.debuginfo.is_some() { @@ -1064,6 +1073,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options { alt_std_name: None, libs: libs, unstable_features: get_unstable_features_setting(), + debug_assertions: debug_assertions, } } diff --git a/src/librustc_back/archive.rs b/src/librustc_back/archive.rs index a6994387f8d6a..ed44bf8952951 100644 --- a/src/librustc_back/archive.rs +++ b/src/librustc_back/archive.rs @@ -11,7 +11,7 @@ //! A helper class for dealing with static archives use std::env; -use std::fs::{self, TempDir}; +use std::fs; use std::io::prelude::*; use std::io; use std::path::{Path, PathBuf}; @@ -19,6 +19,8 @@ use std::process::{Command, Output, Stdio}; use std::str; use syntax::diagnostic::Handler as ErrorHandler; +use tempdir::TempDir; + pub const METADATA_FILENAME: &'static str = "rust.metadata.bin"; pub struct ArchiveConfig<'a> { diff --git a/src/librustc_back/lib.rs b/src/librustc_back/lib.rs index 2b028a5c62623..333c97b446ba3 100644 --- a/src/librustc_back/lib.rs +++ b/src/librustc_back/lib.rs @@ -21,6 +21,8 @@ //! one that doesn't; the one that doesn't might get decent parallel //! build speedups. +// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364) +#![cfg_attr(stage0, feature(custom_attribute))] #![crate_name = "rustc_back"] #![unstable(feature = "rustc_private")] #![staged_api] @@ -34,7 +36,6 @@ #![feature(collections)] #![feature(core)] #![feature(old_fs)] -#![feature(fs)] #![feature(hash)] #![feature(int_uint)] #![feature(io)] @@ -44,7 +45,8 @@ #![feature(path)] #![feature(rustc_private)] #![feature(staged_api)] -#![feature(tempdir)] +#![feature(rand)] +#![feature(path_ext)] extern crate syntax; extern crate serialize; @@ -52,6 +54,7 @@ extern crate serialize; pub mod abi; pub mod archive; +pub mod tempdir; pub mod arm; pub mod fs; pub mod mips; diff --git a/src/librustc_back/target/apple_ios_base.rs b/src/librustc_back/target/apple_ios_base.rs index 904b337c03f46..2fbbe7d1f7c5e 100644 --- a/src/librustc_back/target/apple_ios_base.rs +++ b/src/librustc_back/target/apple_ios_base.rs @@ -8,7 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use std::old_io::{Command, IoError, OtherIoError}; +use std::io; +use std::process::Command; use target::TargetOptions; use self::Arch::*; @@ -40,16 +41,15 @@ pub fn get_sdk_root(sdk_name: &str) -> String { .arg("--show-sdk-path") .arg("-sdk") .arg(sdk_name) - .spawn() - .and_then(|c| c.wait_with_output()) + .output() .and_then(|output| { if output.status.success() { - Ok(String::from_utf8(output.output).unwrap()) + Ok(String::from_utf8(output.stdout).unwrap()) } else { - Err(IoError { - kind: OtherIoError, - desc: "process exit with error", - detail: String::from_utf8(output.error).ok()}) + let error = String::from_utf8(output.stderr); + Err(io::Error::new(io::ErrorKind::Other, + "process exit with error", + error.ok())) } }); diff --git a/src/librustc_back/tempdir.rs b/src/librustc_back/tempdir.rs new file mode 100644 index 0000000000000..4d8619a81216f --- /dev/null +++ b/src/librustc_back/tempdir.rs @@ -0,0 +1,121 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use std::env; +use std::io::{self, Error, ErrorKind}; +use std::fs; +use std::path::{self, PathBuf, AsPath}; +use std::rand::{thread_rng, Rng}; + +/// A wrapper for a path to temporary directory implementing automatic +/// scope-based deletion. +pub struct TempDir { + path: Option, +} + +// How many times should we (re)try finding an unused random name? It should be +// enough that an attacker will run out of luck before we run out of patience. +const NUM_RETRIES: u32 = 1 << 31; +// How many characters should we include in a random file name? It needs to +// be enough to dissuade an attacker from trying to preemptively create names +// of that length, but not so huge that we unnecessarily drain the random number +// generator of entropy. +const NUM_RAND_CHARS: uint = 12; + +impl TempDir { + /// Attempts to make a temporary directory inside of `tmpdir` whose name + /// will have the prefix `prefix`. The directory will be automatically + /// deleted once the returned wrapper is destroyed. + /// + /// If no directory can be created, `Err` is returned. + #[allow(deprecated)] // rand usage + pub fn new_in(tmpdir: &P, prefix: &str) + -> io::Result { + let storage; + let mut tmpdir = tmpdir.as_path(); + if !tmpdir.is_absolute() { + let cur_dir = try!(env::current_dir()); + storage = cur_dir.join(tmpdir); + tmpdir = &storage; + // return TempDir::new_in(&cur_dir.join(tmpdir), prefix); + } + + let mut rng = thread_rng(); + for _ in 0..NUM_RETRIES { + let suffix: String = rng.gen_ascii_chars().take(NUM_RAND_CHARS).collect(); + let leaf = if prefix.len() > 0 { + format!("{}.{}", prefix, suffix) + } else { + // If we're given an empty string for a prefix, then creating a + // directory starting with "." would lead to it being + // semi-invisible on some systems. + suffix + }; + let path = tmpdir.join(&leaf); + match fs::create_dir(&path) { + Ok(_) => return Ok(TempDir { path: Some(path) }), + Err(ref e) if e.kind() == ErrorKind::PathAlreadyExists => {} + Err(e) => return Err(e) + } + } + + Err(Error::new(ErrorKind::PathAlreadyExists, + "too many temporary directories already exist", + None)) + } + + /// Attempts to make a temporary directory inside of `env::temp_dir()` whose + /// name will have the prefix `prefix`. The directory will be automatically + /// deleted once the returned wrapper is destroyed. + /// + /// If no directory can be created, `Err` is returned. + #[allow(deprecated)] + pub fn new(prefix: &str) -> io::Result { + TempDir::new_in(&env::temp_dir(), prefix) + } + + /// Unwrap the wrapped `std::path::Path` from the `TempDir` wrapper. + /// This discards the wrapper so that the automatic deletion of the + /// temporary directory is prevented. + pub fn into_path(mut self) -> PathBuf { + self.path.take().unwrap() + } + + /// Access the wrapped `std::path::Path` to the temporary directory. + pub fn path(&self) -> &path::Path { + self.path.as_ref().unwrap() + } + + /// Close and remove the temporary directory + /// + /// Although `TempDir` removes the directory on drop, in the destructor + /// any errors are ignored. To detect errors cleaning up the temporary + /// directory, call `close` instead. + pub fn close(mut self) -> io::Result<()> { + self.cleanup_dir() + } + + fn cleanup_dir(&mut self) -> io::Result<()> { + match self.path { + Some(ref p) => fs::remove_dir_all(p), + None => Ok(()) + } + } +} + +impl Drop for TempDir { + fn drop(&mut self) { + let _ = self.cleanup_dir(); + } +} + +// the tests for this module need to change the path using change_dir, +// and this doesn't play nicely with other tests so these unit tests are located +// in src/test/run-pass/tempfile.rs diff --git a/src/librustc_bitflags/lib.rs b/src/librustc_bitflags/lib.rs index 2199beb7a2012..c15ddf3ae779f 100644 --- a/src/librustc_bitflags/lib.rs +++ b/src/librustc_bitflags/lib.rs @@ -8,6 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. + +// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364) +#![cfg_attr(stage0, feature(custom_attribute))] #![crate_name = "rustc_bitflags"] #![feature(staged_api)] #![staged_api] diff --git a/src/librustc_borrowck/lib.rs b/src/librustc_borrowck/lib.rs index b7cfda2809257..e09457970e12f 100644 --- a/src/librustc_borrowck/lib.rs +++ b/src/librustc_borrowck/lib.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364) +#![cfg_attr(stage0, feature(custom_attribute))] #![crate_name = "rustc_borrowck"] #![unstable(feature = "rustc_private")] #![staged_api] diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index 6ec36886252f0..565782b29e971 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -814,7 +814,9 @@ fn write_out_deps(sess: &Session, // Build a list of files used to compile the output and // write Makefile-compatible dependency rules let files: Vec = sess.codemap().files.borrow() - .iter().filter(|fmap| fmap.is_real_file()) + .iter() + .filter(|fmap| fmap.is_real_file()) + .filter(|fmap| !fmap.is_imported()) .map(|fmap| escape_dep_filename(&fmap.name)) .collect(); let mut file = try!(fs::File::create(&deps_filename)); diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index aa8b7c7785d20..c09b018ab6345 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -14,6 +14,8 @@ //! //! This API is completely unstable and subject to change. +// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364) +#![cfg_attr(stage0, feature(custom_attribute))] #![crate_name = "rustc_driver"] #![unstable(feature = "rustc_private")] #![staged_api] @@ -29,7 +31,6 @@ #![feature(int_uint)] #![feature(old_io)] #![feature(libc)] -#![feature(os)] #![feature(quote)] #![feature(rustc_diagnostic_macros)] #![feature(rustc_private)] @@ -39,7 +40,6 @@ #![feature(exit_status)] #![feature(path)] #![feature(io)] -#![feature(fs)] extern crate arena; extern crate flate; @@ -775,6 +775,7 @@ fn parse_crate_attrs(sess: &Session, input: &Input) -> /// /// The diagnostic emitter yielded to the procedure should be used for reporting /// errors of the compiler. +#[allow(deprecated)] pub fn monitor(f: F) { const STACK_SIZE: uint = 8 * 1024 * 1024; // 8MB diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index 9eef0f1cf8b0f..9781e9944f642 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -19,6 +19,8 @@ //! //! This API is completely unstable and subject to change. +// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364) +#![cfg_attr(stage0, feature(custom_attribute))] #![crate_name = "rustc_lint"] #![unstable(feature = "rustc_private")] #![staged_api] diff --git a/src/librustc_llvm/lib.rs b/src/librustc_llvm/lib.rs index 0a1416ff5664a..0ff96784e58dc 100644 --- a/src/librustc_llvm/lib.rs +++ b/src/librustc_llvm/lib.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364) +#![cfg_attr(stage0, feature(custom_attribute))] #![allow(non_upper_case_globals)] #![allow(non_camel_case_types)] #![allow(non_snake_case)] @@ -29,8 +31,8 @@ #![feature(libc)] #![feature(link_args)] #![feature(staged_api)] -#![feature(std_misc)] #![feature(path)] +#![cfg_attr(unix, feature(std_misc))] extern crate libc; #[macro_use] #[no_link] extern crate rustc_bitflags; diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index ab3b56c31b62a..c766b20389e73 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364) +#![cfg_attr(stage0, feature(custom_attribute))] #![crate_name = "rustc_privacy"] #![unstable(feature = "rustc_private")] #![staged_api] diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 0ddfd707f0089..ccca99f8b4e4a 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364) +#![cfg_attr(stage0, feature(custom_attribute))] #![crate_name = "rustc_resolve"] #![unstable(feature = "rustc_private")] #![staged_api] diff --git a/src/librustc_trans/back/link.rs b/src/librustc_trans/back/link.rs index 1e84bc4b8e0bb..3087a8ea45ddc 100644 --- a/src/librustc_trans/back/link.rs +++ b/src/librustc_trans/back/link.rs @@ -26,9 +26,10 @@ use middle::ty::{self, Ty}; use util::common::time; use util::ppaux; use util::sha2::{Digest, Sha256}; +use rustc_back::tempdir::TempDir; -use std::ffi::{AsOsStr, OsString}; -use std::fs::{self, TempDir, PathExt}; +use std::ffi::OsString; +use std::fs::{self, PathExt}; use std::io::{self, Read, Write}; use std::mem; use std::path::{Path, PathBuf}; @@ -882,7 +883,7 @@ fn link_args(cmd: &mut Command, let morestack = lib_path.join("libmorestack.a"); let mut v = OsString::from_str("-Wl,-force_load,"); - v.push_os_str(morestack.as_os_str()); + v.push(&morestack); cmd.arg(&v); } else { cmd.args(&["-Wl,--whole-archive", "-lmorestack", "-Wl,--no-whole-archive"]); @@ -1007,7 +1008,7 @@ fn link_args(cmd: &mut Command, if sess.opts.cg.rpath { let mut v = OsString::from_str("-Wl,-install_name,@rpath/"); - v.push_os_str(out_filename.file_name().unwrap()); + v.push(out_filename.file_name().unwrap()); cmd.arg(&v); } } else { @@ -1107,7 +1108,7 @@ fn add_local_native_libraries(cmd: &mut Command, sess: &Session) { &search_path[..], &sess.diagnostic().handler); let mut v = OsString::from_str("-Wl,-force_load,"); - v.push_os_str(lib.as_os_str()); + v.push(&lib); cmd.arg(&v); } } diff --git a/src/librustc_trans/lib.rs b/src/librustc_trans/lib.rs index dcc79e90cc572..b74f85aa86610 100644 --- a/src/librustc_trans/lib.rs +++ b/src/librustc_trans/lib.rs @@ -14,6 +14,8 @@ //! //! This API is completely unstable and subject to change. +// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364) +#![cfg_attr(stage0, feature(custom_attribute))] #![crate_name = "rustc_trans"] #![unstable(feature = "rustc_private")] #![staged_api] @@ -35,13 +37,12 @@ #![feature(rustc_private)] #![feature(unsafe_destructor)] #![feature(staged_api)] -#![feature(std_misc)] #![feature(unicode)] #![feature(io)] -#![feature(fs)] #![feature(path)] -#![feature(os)] -#![feature(tempdir)] +#![feature(path_ext)] +#![feature(fs)] +#![feature(hash)] extern crate arena; extern crate flate; diff --git a/src/librustc_trans/trans/base.rs b/src/librustc_trans/trans/base.rs index 8302d0abe214e..f49905613d24c 100644 --- a/src/librustc_trans/trans/base.rs +++ b/src/librustc_trans/trans/base.rs @@ -3089,7 +3089,7 @@ pub fn trans_crate<'tcx>(analysis: ty::CrateAnalysis<'tcx>) let check_overflow = if let Some(v) = tcx.sess.opts.debugging_opts.force_overflow_checks { v } else { - !attr::contains_name(&krate.config, "ndebug") + tcx.sess.opts.debug_assertions }; // Before we touch LLVM, make sure that multithreading is enabled. diff --git a/src/librustc_trans/trans/consts.rs b/src/librustc_trans/trans/consts.rs index a39f5d42b555f..39b430b7ad51e 100644 --- a/src/librustc_trans/trans/consts.rs +++ b/src/librustc_trans/trans/consts.rs @@ -173,7 +173,7 @@ pub fn get_const_expr<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, &**expr } else { ccx.sess().span_bug(ref_expr.span, - &format!("get_const_val given non-constant item {}", + &format!("get_const_expr given non-constant item {}", item.repr(ccx.tcx()))); } } diff --git a/src/librustc_trans/trans/debuginfo.rs b/src/librustc_trans/trans/debuginfo.rs index 142262a25bd43..95c39270cc6d9 100644 --- a/src/librustc_trans/trans/debuginfo.rs +++ b/src/librustc_trans/trans/debuginfo.rs @@ -697,6 +697,7 @@ struct FunctionDebugContextData { fn_metadata: DISubprogram, argument_counter: Cell, source_locations_enabled: Cell, + source_location_override: Cell, } enum VariableAccess<'a> { @@ -1176,6 +1177,12 @@ pub fn set_source_location(fcx: &FunctionContext, return; } FunctionDebugContext::RegularContext(box ref function_debug_context) => { + if function_debug_context.source_location_override.get() { + // Just ignore any attempts to set a new debug location while + // the override is active. + return; + } + let cx = fcx.ccx; debug!("set_source_location: {}", cx.sess().codemap().span_to_string(span)); @@ -1194,6 +1201,35 @@ pub fn set_source_location(fcx: &FunctionContext, } } +/// This function makes sure that all debug locations emitted while executing +/// `wrapped_function` are set to the given `debug_loc`. +pub fn with_source_location_override(fcx: &FunctionContext, + debug_loc: DebugLoc, + wrapped_function: F) -> R + where F: FnOnce() -> R +{ + match fcx.debug_context { + FunctionDebugContext::DebugInfoDisabled => { + wrapped_function() + } + FunctionDebugContext::FunctionWithoutDebugInfo => { + set_debug_location(fcx.ccx, UnknownLocation); + wrapped_function() + } + FunctionDebugContext::RegularContext(box ref function_debug_context) => { + if function_debug_context.source_location_override.get() { + wrapped_function() + } else { + debug_loc.apply(fcx); + function_debug_context.source_location_override.set(true); + let result = wrapped_function(); + function_debug_context.source_location_override.set(false); + result + } + } + } +} + /// Clears the current debug location. /// /// Instructions generated hereafter won't be assigned a source location. @@ -1414,6 +1450,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, fn_metadata: fn_metadata, argument_counter: Cell::new(1), source_locations_enabled: Cell::new(false), + source_location_override: Cell::new(false), }; diff --git a/src/librustc_trans/trans/expr.rs b/src/librustc_trans/trans/expr.rs index 60455119d5872..96d3e16d253b4 100644 --- a/src/librustc_trans/trans/expr.rs +++ b/src/librustc_trans/trans/expr.rs @@ -147,7 +147,7 @@ pub fn trans_into<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, ast::ExprPath(..) => { match bcx.def(expr.id) { def::DefConst(did) => { - let expr = consts::get_const_expr(bcx.ccx(), did, expr); + let const_expr = consts::get_const_expr(bcx.ccx(), did, expr); // Temporarily get cleanup scopes out of the way, // as they require sub-expressions to be contained // inside the current AST scope. @@ -155,7 +155,13 @@ pub fn trans_into<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, // can't have destructors. let scopes = mem::replace(&mut *bcx.fcx.scopes.borrow_mut(), vec![]); - bcx = trans_into(bcx, expr, dest); + // Lock emitted debug locations to the location of + // the constant reference expression. + debuginfo::with_source_location_override(bcx.fcx, + expr.debug_loc(), + || { + bcx = trans_into(bcx, const_expr, dest) + }); let scopes = mem::replace(&mut *bcx.fcx.scopes.borrow_mut(), scopes); assert!(scopes.is_empty()); diff --git a/src/librustc_typeck/check/wf.rs b/src/librustc_typeck/check/wf.rs index aa7e2b6dcce89..8185f48cb8c70 100644 --- a/src/librustc_typeck/check/wf.rs +++ b/src/librustc_typeck/check/wf.rs @@ -118,7 +118,7 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> { self.check_variances_for_type_defn(item, ast_generics); } - ast::ItemTrait(_, ref ast_generics, _, _) => { + ast::ItemTrait(_, ref ast_generics, _, ref items) => { let trait_predicates = ty::lookup_predicates(ccx.tcx, local_def(item.id)); reject_non_type_param_bounds( @@ -127,6 +127,14 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> { &trait_predicates); self.check_variances(item, ast_generics, &trait_predicates, self.tcx().lang_items.phantom_fn()); + if ty::trait_has_default_impl(ccx.tcx, local_def(item.id)) { + if !items.is_empty() { + ccx.tcx.sess.span_err( + item.span, + "traits with default impls (`e.g. unsafe impl Trait for ..`) must \ + have no methods or associated items") + } + } } _ => {} } diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index 78dd66c8e7dbb..bbc64a54013b7 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -62,7 +62,8 @@ independently: This API is completely unstable and subject to change. */ - +// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364) +#![cfg_attr(stage0, feature(custom_attribute))] #![crate_name = "rustc_typeck"] #![unstable(feature = "rustc_private")] #![staged_api] diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index add44769bab60..435317c4fb6ff 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -38,7 +38,6 @@ use std::cell::RefCell; use std::cmp::Ordering; use std::collections::{HashMap, HashSet}; use std::default::Default; -use std::ffi::OsStr; use std::fmt; use std::fs::{self, File}; use std::io::prelude::*; @@ -67,12 +66,10 @@ use html::item_type::ItemType; use html::layout; use html::markdown::Markdown; use html::markdown; -use html::escape::Escape; use stability_summary; /// A pair of name and its optional document. -#[derive(Clone, Eq, Ord, PartialEq, PartialOrd)] -pub struct NameDoc(String, Option); +pub type NameDoc = (String, Option); /// Major driving force in all rustdoc rendering. This contains information /// about where in the tree-like hierarchy rendering is occurring and controls @@ -98,12 +95,6 @@ pub struct Context { /// This describes the layout of each page, and is not modified after /// creation of the context (contains info like the favicon and added html). pub layout: layout::Layout, - /// This map is a list of what should be displayed on the sidebar of the - /// current page. The key is the section header (traits, modules, - /// functions), and the value is the list of containers belonging to this - /// header. This map will change depending on the surrounding context of the - /// page. - pub sidebar: HashMap>, /// This flag indicates whether [src] links should be generated or not. If /// the source files are present in the html rendering, then this will be /// `true`. @@ -271,7 +262,6 @@ pub fn run(mut krate: clean::Crate, passes: passes, current: Vec::new(), root_path: String::new(), - sidebar: HashMap::new(), layout: layout::Layout { logo: "".to_string(), favicon: "".to_string(), @@ -770,7 +760,7 @@ impl<'a> SourceCollector<'a> { let mut fname = p.file_name().expect("source has no filename") .to_os_string(); - fname.push_os_str(OsStr::from_str(".html")); + fname.push(".html"); cur.push(&fname); let mut w = BufWriter::new(try!(File::create(&cur))); @@ -1232,7 +1222,16 @@ impl Context { clean::ModuleItem(m) => m, _ => unreachable!() }; - this.sidebar = this.build_sidebar(&m); + + // render sidebar-items.js used throughout this module + { + let items = this.build_sidebar_items(&m); + let js_dst = this.dst.join("sidebar-items.js"); + let mut js_out = BufWriter::new(try!(File::create(&js_dst))); + try!(write!(&mut js_out, "initSidebarItems({});", + json::as_json(&items))); + } + for item in m.items { f(this,item); } @@ -1252,15 +1251,11 @@ impl Context { } } - fn build_sidebar(&self, m: &clean::Module) -> HashMap> { + fn build_sidebar_items(&self, m: &clean::Module) -> HashMap> { let mut map = HashMap::new(); for item in &m.items { if self.ignore_private_item(item) { continue } - // avoid putting foreign items to the sidebar. - if let &clean::ForeignFunctionItem(..) = &item.inner { continue } - if let &clean::ForeignStaticItem(..) = &item.inner { continue } - let short = shortty(item).to_static_str(); let myname = match item.name { None => continue, @@ -1269,7 +1264,7 @@ impl Context { let short = short.to_string(); let v = map.entry(short).get().unwrap_or_else( |vacant_entry| vacant_entry.insert(Vec::with_capacity(1))); - v.push(NameDoc(myname, Some(shorter_line(item.doc_value())))); + v.push((myname, Some(shorter_line(item.doc_value())))); } for (_, items) in &mut map { @@ -2216,9 +2211,18 @@ impl<'a> fmt::Display for Sidebar<'a> { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { let cx = self.cx; let it = self.item; + let parentlen = cx.current.len() - if it.is_mod() {1} else {0}; + + // the sidebar is designed to display sibling functions, modules and + // other miscellaneous informations. since there are lots of sibling + // items (and that causes quadratic growth in large modules), + // we refactor common parts into a shared JavaScript file per module. + // still, we don't move everything into JS because we want to preserve + // as much HTML as possible in order to allow non-JS-enabled browsers + // to navigate the documentation (though slightly inefficiently). + try!(write!(fmt, "

")); - let len = cx.current.len() - if it.is_mod() {1} else {0}; - for (i, name) in cx.current.iter().take(len).enumerate() { + for (i, name) in cx.current.iter().take(parentlen).enumerate() { if i > 0 { try!(write!(fmt, "::")); } @@ -2228,40 +2232,25 @@ impl<'a> fmt::Display for Sidebar<'a> { } try!(write!(fmt, "

")); - fn block(w: &mut fmt::Formatter, short: &str, longty: &str, - cur: &clean::Item, cx: &Context) -> fmt::Result { - let items = match cx.sidebar.get(short) { - Some(items) => items, - None => return Ok(()) - }; - try!(write!(w, "

{}

", short, longty)); - for &NameDoc(ref name, ref doc) in items { - let curty = shortty(cur).to_static_str(); - let class = if cur.name.as_ref().unwrap() == name && - short == curty { "current" } else { "" }; - try!(write!(w, "{name}", - ty = short, - class = class, - href = if curty == "mod" {"../"} else {""}, - path = if short == "mod" { - format!("{}/index.html", name) - } else { - format!("{}.{}.html", short, name) - }, - title = Escape(doc.as_ref().unwrap()), - name = name)); - } - try!(write!(w, "
")); - Ok(()) + // sidebar refers to the enclosing module, not this module + let relpath = if shortty(it) == ItemType::Module { "../" } else { "" }; + try!(write!(fmt, + "", + name = it.name.as_ref().map(|x| &x[..]).unwrap_or(""), + ty = shortty(it).to_static_str(), + path = relpath)); + if parentlen == 0 { + // there is no sidebar-items.js beyond the crate root path + // FIXME maybe dynamic crate loading can be merged here + } else { + try!(write!(fmt, "", + path = relpath)); } - try!(block(fmt, "mod", "Modules", it, cx)); - try!(block(fmt, "struct", "Structs", it, cx)); - try!(block(fmt, "enum", "Enums", it, cx)); - try!(block(fmt, "trait", "Traits", it, cx)); - try!(block(fmt, "fn", "Functions", it, cx)); - try!(block(fmt, "macro", "Macros", it, cx)); Ok(()) } } diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index aac3985f0cc9c..a9b233dd128d4 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -15,6 +15,27 @@ "use strict"; var resizeTimeout, interval; + // This mapping table should match the discriminants of + // `rustdoc::html::item_type::ItemType` type in Rust. + var itemTypes = ["mod", + "externcrate", + "import", + "struct", + "enum", + "fn", + "type", + "static", + "trait", + "impl", + "tymethod", + "method", + "structfield", + "variant", + "macro", + "primitive", + "associatedtype", + "constant"]; + $('.js-only').removeClass('js-only'); function getQueryStringParams() { @@ -552,27 +573,6 @@ showResults(results); } - // This mapping table should match the discriminants of - // `rustdoc::html::item_type::ItemType` type in Rust. - var itemTypes = ["mod", - "externcrate", - "import", - "struct", - "enum", - "fn", - "type", - "static", - "trait", - "impl", - "tymethod", - "method", - "structfield", - "variant", - "macro", - "primitive", - "associatedtype", - "constant"]; - function itemTypeFromName(typename) { for (var i = 0; i < itemTypes.length; ++i) { if (itemTypes[i] === typename) return i; @@ -708,6 +708,50 @@ window.initSearch = initSearch; + // delayed sidebar rendering. + function initSidebarItems(items) { + var sidebar = $('.sidebar'); + var current = window.sidebarCurrent; + + function block(shortty, longty) { + var filtered = items[shortty]; + if (!filtered) return; + + var div = $('
').attr('class', 'block ' + shortty); + div.append($('

').text(longty)); + + for (var i = 0; i < filtered.length; ++i) { + var item = filtered[i]; + var name = item[0]; + var desc = item[1]; // can be null + + var klass = shortty; + if (name === current.name && shortty == current.ty) { + klass += ' current'; + } + var path; + if (shortty === 'mod') { + path = name + '/index.html'; + } else { + path = shortty + '.' + name + '.html'; + } + div.append($('', {'href': current.relpath + path, + 'title': desc, + 'class': klass}).text(name)); + } + sidebar.append(div); + } + + block("mod", "Modules"); + block("struct", "Structs"); + block("enum", "Enums"); + block("trait", "Traits"); + block("fn", "Functions"); + block("macro", "Macros"); + } + + window.initSidebarItems = initSidebarItems; + window.register_implementors = function(imp) { var list = $('#implementors-list'); var libs = Object.getOwnPropertyNames(imp); diff --git a/src/librustdoc/html/static/playpen.js b/src/librustdoc/html/static/playpen.js index 687f764f02077..8fb979875cd76 100644 --- a/src/librustdoc/html/static/playpen.js +++ b/src/librustdoc/html/static/playpen.js @@ -15,7 +15,7 @@ if (window.playgroundUrl) { $('pre.rust').hover(function() { var a = $('').text('⇱').attr('class', 'test-arrow'); - var code = $(this).siblings(".rusttest").text(); + var code = $(this).prev(".rusttest").text(); a.attr('href', window.playgroundUrl + '?code=' + encodeURIComponent(code)); a.attr('target', '_blank'); diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index b4522ad680b77..c203dc0e7199e 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364) +#![cfg_attr(stage0, feature(custom_attribute))] #![crate_name = "rustdoc"] #![unstable(feature = "rustdoc")] #![staged_api] @@ -35,9 +37,9 @@ #![feature(unicode)] #![feature(str_words)] #![feature(io)] -#![feature(fs)] #![feature(path)] -#![feature(tempdir)] +#![feature(file_path)] +#![feature(path_ext)] extern crate arena; extern crate getopts; @@ -47,6 +49,7 @@ extern crate rustc_trans; extern crate rustc_driver; extern crate rustc_resolve; extern crate rustc_lint; +extern crate rustc_back; extern crate serialize; extern crate syntax; extern crate "test" as testing; diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index 9fd38ecb13627..c785d78dc9303 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -13,7 +13,6 @@ use std::collections::{HashSet, HashMap}; use std::dynamic_lib::DynamicLibrary; use std::env; use std::ffi::OsString; -use std::fs::TempDir; use std::old_io; use std::io; use std::path::PathBuf; @@ -28,6 +27,7 @@ use rustc_lint; use rustc::session::{self, config}; use rustc::session::config::get_unstable_features_setting; use rustc::session::search_paths::{SearchPaths, PathKind}; +use rustc_back::tempdir::TempDir; use rustc_driver::{driver, Compilation}; use syntax::codemap::CodeMap; use syntax::diagnostic; @@ -111,6 +111,7 @@ pub fn run(input: &str, 0 } +#[allow(deprecated)] fn runtest(test: &str, cratename: &str, libs: SearchPaths, externs: core::Externs, should_fail: bool, no_run: bool, as_test_harness: bool) { diff --git a/src/libserialize/lib.rs b/src/libserialize/lib.rs index bfc6b1bf0ef13..ad7908c6dd57c 100644 --- a/src/libserialize/lib.rs +++ b/src/libserialize/lib.rs @@ -14,6 +14,8 @@ Core encoding and decoding interfaces. */ +// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364) +#![cfg_attr(stage0, feature(custom_attribute))] #![crate_name = "serialize"] #![unstable(feature = "rustc_private", reason = "deprecated in favor of rustc-serialize on crates.io")] diff --git a/src/libstd/ffi/c_str.rs b/src/libstd/ffi/c_str.rs index c94edb9d2a1c5..ec9f90723be96 100644 --- a/src/libstd/ffi/c_str.rs +++ b/src/libstd/ffi/c_str.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![unstable(feature = "std_misc")] + use cmp::{PartialEq, Eq, PartialOrd, Ord, Ordering}; use error::{Error, FromError}; use fmt; @@ -59,6 +61,7 @@ use vec::Vec; /// # } /// ``` #[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Hash)] +#[stable(feature = "rust1", since = "1.0.0")] pub struct CString { inner: Vec, } @@ -110,13 +113,19 @@ pub struct CString { /// } /// ``` #[derive(Hash)] +#[stable(feature = "rust1", since = "1.0.0")] pub struct CStr { + // FIXME: this should not be represented with a DST slice but rather with + // just a raw `libc::c_char` along with some form of marker to make + // this an unsized type. Essentially `sizeof(&CStr)` should be the + // same as `sizeof(&c_char)` but `CStr` should be an unsized type. inner: [libc::c_char] } /// An error returned from `CString::new` to indicate that a nul byte was found /// in the vector provided. #[derive(Clone, PartialEq, Debug)] +#[stable(feature = "rust1", since = "1.0.0")] pub struct NulError(usize, Vec); /// A conversion trait used by the constructor of `CString` for types that can @@ -153,6 +162,7 @@ impl CString { /// This function will return an error if the bytes yielded contain an /// internal 0 byte. The error returned will contain the bytes as well as /// the position of the nul byte. + #[stable(feature = "rust1", since = "1.0.0")] pub fn new(t: T) -> Result { let bytes = t.into_bytes(); match bytes.iter().position(|x| *x == 0) { @@ -216,6 +226,7 @@ impl CString { /// /// This method is equivalent to `from_vec` except that no runtime assertion /// is made that `v` contains no 0 bytes. + #[stable(feature = "rust1", since = "1.0.0")] pub unsafe fn from_vec_unchecked(mut v: Vec) -> CString { v.push(0); CString { inner: v } @@ -225,17 +236,20 @@ impl CString { /// /// The returned slice does **not** contain the trailing nul separator and /// it is guaranteed to not have any interior nul bytes. + #[stable(feature = "rust1", since = "1.0.0")] pub fn as_bytes(&self) -> &[u8] { &self.inner[..self.inner.len() - 1] } /// Equivalent to the `as_bytes` function except that the returned slice /// includes the trailing nul byte. + #[stable(feature = "rust1", since = "1.0.0")] pub fn as_bytes_with_nul(&self) -> &[u8] { &self.inner } } +#[stable(feature = "rust1", since = "1.0.0")] impl Deref for CString { type Target = CStr; @@ -254,23 +268,28 @@ impl fmt::Debug for CString { impl NulError { /// Returns the position of the nul byte in the slice that was provided to /// `CString::from_vec`. + #[stable(feature = "rust1", since = "1.0.0")] pub fn nul_position(&self) -> usize { self.0 } /// Consumes this error, returning the underlying vector of bytes which /// generated the error in the first place. + #[stable(feature = "rust1", since = "1.0.0")] pub fn into_vec(self) -> Vec { self.1 } } +#[stable(feature = "rust1", since = "1.0.0")] impl Error for NulError { fn description(&self) -> &str { "nul byte found in data" } } +#[stable(feature = "rust1", since = "1.0.0")] impl fmt::Display for NulError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "nul byte found in provided data at position: {}", self.0) } } +#[stable(feature = "rust1", since = "1.0.0")] impl FromError for io::Error { fn from_error(_: NulError) -> io::Error { io::Error::new(io::ErrorKind::InvalidInput, @@ -278,6 +297,7 @@ impl FromError for io::Error { } } +#[stable(feature = "rust1", since = "1.0.0")] impl FromError for old_io::IoError { fn from_error(_: NulError) -> old_io::IoError { old_io::IoError { @@ -325,6 +345,7 @@ impl CStr { /// } /// # } /// ``` + #[stable(feature = "rust1", since = "1.0.0")] pub unsafe fn from_ptr<'a>(ptr: *const libc::c_char) -> &'a CStr { let len = libc::strlen(ptr); mem::transmute(slice::from_raw_parts(ptr, len as usize + 1)) @@ -335,6 +356,7 @@ impl CStr { /// The returned pointer will be valid for as long as `self` is and points /// to a contiguous region of memory terminated with a 0 byte to represent /// the end of the string. + #[stable(feature = "rust1", since = "1.0.0")] pub fn as_ptr(&self) -> *const libc::c_char { self.inner.as_ptr() } @@ -351,6 +373,7 @@ impl CStr { /// > **Note**: This method is currently implemented as a 0-cost cast, but /// > it is planned to alter its definition in the future to perform the /// > length calculation whenever this method is called. + #[stable(feature = "rust1", since = "1.0.0")] pub fn to_bytes(&self) -> &[u8] { let bytes = self.to_bytes_with_nul(); &bytes[..bytes.len() - 1] @@ -364,22 +387,27 @@ impl CStr { /// > **Note**: This method is currently implemented as a 0-cost cast, but /// > it is planned to alter its definition in the future to perform the /// > length calculation whenever this method is called. + #[stable(feature = "rust1", since = "1.0.0")] pub fn to_bytes_with_nul(&self) -> &[u8] { unsafe { mem::transmute::<&[libc::c_char], &[u8]>(&self.inner) } } } +#[stable(feature = "rust1", since = "1.0.0")] impl PartialEq for CStr { fn eq(&self, other: &CStr) -> bool { self.to_bytes().eq(other.to_bytes()) } } +#[stable(feature = "rust1", since = "1.0.0")] impl Eq for CStr {} +#[stable(feature = "rust1", since = "1.0.0")] impl PartialOrd for CStr { fn partial_cmp(&self, other: &CStr) -> Option { self.to_bytes().partial_cmp(&other.to_bytes()) } } +#[stable(feature = "rust1", since = "1.0.0")] impl Ord for CStr { fn cmp(&self, other: &CStr) -> Ordering { self.to_bytes().cmp(&other.to_bytes()) diff --git a/src/libstd/ffi/mod.rs b/src/libstd/ffi/mod.rs index 1bff6afb77607..f17dc6542491b 100644 --- a/src/libstd/ffi/mod.rs +++ b/src/libstd/ffi/mod.rs @@ -10,17 +10,19 @@ //! Utilities related to FFI bindings. -#![unstable(feature = "std_misc", - reason = "module just underwent fairly large reorganization and the dust \ - still needs to settle")] +#![stable(feature = "rust1", since = "1.0.0")] -pub use self::c_str::{CString, CStr, NulError, IntoBytes}; +#[stable(feature = "rust1", since = "1.0.0")] +pub use self::c_str::{CString, CStr}; +pub use self::c_str::{NulError, IntoBytes}; #[allow(deprecated)] pub use self::c_str::c_str_to_bytes; #[allow(deprecated)] pub use self::c_str::c_str_to_bytes_with_nul; +#[stable(feature = "rust1", since = "1.0.0")] pub use self::os_str::OsString; +#[stable(feature = "rust1", since = "1.0.0")] pub use self::os_str::OsStr; mod c_str; @@ -28,6 +30,7 @@ mod os_str; // FIXME (#21670): these should be defined in the os_str module /// Freely convertible to an `&OsStr` slice. +#[unstable(feature = "std_misc")] pub trait AsOsStr { /// Convert to an `&OsStr` slice. fn as_os_str(&self) -> &OsStr; diff --git a/src/libstd/ffi/os_str.rs b/src/libstd/ffi/os_str.rs index 926d8e03f2c3b..77df831bbfe37 100644 --- a/src/libstd/ffi/os_str.rs +++ b/src/libstd/ffi/os_str.rs @@ -49,17 +49,20 @@ use super::AsOsStr; /// Owned, mutable OS strings. #[derive(Clone)] +#[stable(feature = "rust1", since = "1.0.0")] pub struct OsString { inner: Buf } /// Slices into OS strings. +#[stable(feature = "rust1", since = "1.0.0")] pub struct OsStr { inner: Slice } impl OsString { /// Constructs an `OsString` at no cost by consuming a `String`. + #[stable(feature = "rust1", since = "1.0.0")] pub fn from_string(s: String) -> OsString { OsString { inner: Buf::from_string(s) } } @@ -67,11 +70,13 @@ impl OsString { /// Constructs an `OsString` by copying from a `&str` slice. /// /// Equivalent to: `OsString::from_string(String::from_str(s))`. + #[stable(feature = "rust1", since = "1.0.0")] pub fn from_str(s: &str) -> OsString { OsString { inner: Buf::from_str(s) } } /// Constructs a new empty `OsString`. + #[stable(feature = "rust1", since = "1.0.0")] pub fn new() -> OsString { OsString { inner: Buf::from_string(String::new()) } } @@ -79,16 +84,26 @@ impl OsString { /// Convert the `OsString` into a `String` if it contains valid Unicode data. /// /// On failure, ownership of the original `OsString` is returned. + #[stable(feature = "rust1", since = "1.0.0")] pub fn into_string(self) -> Result { self.inner.into_string().map_err(|buf| OsString { inner: buf} ) } /// Extend the string with the given `&OsStr` slice. + #[deprecated(since = "1.0.0", reason = "renamed to `push`")] + #[unstable(feature = "os")] pub fn push_os_str(&mut self, s: &OsStr) { self.inner.push_slice(&s.inner) } + + /// Extend the string with the given `&OsStr` slice. + #[stable(feature = "rust1", since = "1.0.0")] + pub fn push(&mut self, s: &T) { + self.inner.push_slice(&s.as_os_str().inner) + } } +#[stable(feature = "rust1", since = "1.0.0")] impl ops::Index for OsString { type Output = OsStr; @@ -98,6 +113,7 @@ impl ops::Index for OsString { } } +#[stable(feature = "rust1", since = "1.0.0")] impl ops::Deref for OsString { type Target = OsStr; @@ -107,32 +123,38 @@ impl ops::Deref for OsString { } } +#[stable(feature = "rust1", since = "1.0.0")] impl Debug for OsString { fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> { fmt::Debug::fmt(&**self, formatter) } } +#[stable(feature = "rust1", since = "1.0.0")] impl PartialEq for OsString { fn eq(&self, other: &OsString) -> bool { &**self == &**other } } +#[stable(feature = "rust1", since = "1.0.0")] impl PartialEq for OsString { fn eq(&self, other: &str) -> bool { &**self == other } } +#[stable(feature = "rust1", since = "1.0.0")] impl PartialEq for str { fn eq(&self, other: &OsString) -> bool { &**other == self } } +#[stable(feature = "rust1", since = "1.0.0")] impl Eq for OsString {} +#[stable(feature = "rust1", since = "1.0.0")] impl PartialOrd for OsString { #[inline] fn partial_cmp(&self, other: &OsString) -> Option { @@ -148,6 +170,7 @@ impl PartialOrd for OsString { fn ge(&self, other: &OsString) -> bool { &**self >= &**other } } +#[stable(feature = "rust1", since = "1.0.0")] impl PartialOrd for OsString { #[inline] fn partial_cmp(&self, other: &str) -> Option { @@ -155,6 +178,7 @@ impl PartialOrd for OsString { } } +#[stable(feature = "rust1", since = "1.0.0")] impl Ord for OsString { #[inline] fn cmp(&self, other: &OsString) -> cmp::Ordering { @@ -172,6 +196,7 @@ impl Hash for OsString { impl OsStr { /// Coerce directly from a `&str` slice to a `&OsStr` slice. + #[stable(feature = "rust1", since = "1.0.0")] pub fn from_str(s: &str) -> &OsStr { unsafe { mem::transmute(Slice::from_str(s)) } } @@ -179,6 +204,7 @@ impl OsStr { /// Yield a `&str` slice if the `OsStr` is valid unicode. /// /// This conversion may entail doing a check for UTF-8 validity. + #[stable(feature = "rust1", since = "1.0.0")] pub fn to_str(&self) -> Option<&str> { self.inner.to_str() } @@ -186,11 +212,13 @@ impl OsStr { /// Convert an `OsStr` to a `Cow`. /// /// Any non-Unicode sequences are replaced with U+FFFD REPLACEMENT CHARACTER. + #[stable(feature = "rust1", since = "1.0.0")] pub fn to_string_lossy(&self) -> Cow { self.inner.to_string_lossy() } /// Copy the slice into an owned `OsString`. + #[stable(feature = "rust1", since = "1.0.0")] pub fn to_os_string(&self) -> OsString { OsString { inner: self.inner.to_owned() } } @@ -204,26 +232,31 @@ impl OsStr { } } +#[stable(feature = "rust1", since = "1.0.0")] impl PartialEq for OsStr { fn eq(&self, other: &OsStr) -> bool { self.bytes().eq(other.bytes()) } } +#[stable(feature = "rust1", since = "1.0.0")] impl PartialEq for OsStr { fn eq(&self, other: &str) -> bool { *self == *OsStr::from_str(other) } } +#[stable(feature = "rust1", since = "1.0.0")] impl PartialEq for str { fn eq(&self, other: &OsStr) -> bool { *other == *OsStr::from_str(self) } } +#[stable(feature = "rust1", since = "1.0.0")] impl Eq for OsStr {} +#[stable(feature = "rust1", since = "1.0.0")] impl PartialOrd for OsStr { #[inline] fn partial_cmp(&self, other: &OsStr) -> Option { @@ -239,6 +272,7 @@ impl PartialOrd for OsStr { fn ge(&self, other: &OsStr) -> bool { self.bytes().ge(other.bytes()) } } +#[stable(feature = "rust1", since = "1.0.0")] impl PartialOrd for OsStr { #[inline] fn partial_cmp(&self, other: &str) -> Option { @@ -249,6 +283,7 @@ impl PartialOrd for OsStr { // FIXME (#19470): cannot provide PartialOrd for str until we // have more flexible coherence rules. +#[stable(feature = "rust1", since = "1.0.0")] impl Ord for OsStr { #[inline] fn cmp(&self, other: &OsStr) -> cmp::Ordering { self.bytes().cmp(other.bytes()) } @@ -262,21 +297,25 @@ impl Hash for OsStr { } } +#[stable(feature = "rust1", since = "1.0.0")] impl Debug for OsStr { fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> { self.inner.fmt(formatter) } } +#[stable(feature = "rust1", since = "1.0.0")] impl Borrow for OsString { fn borrow(&self) -> &OsStr { &self[..] } } +#[stable(feature = "rust1", since = "1.0.0")] impl ToOwned for OsStr { type Owned = OsString; fn to_owned(&self) -> OsString { self.to_os_string() } } +#[stable(feature = "rust1", since = "1.0.0")] impl<'a, T: AsOsStr + ?Sized> AsOsStr for &'a T { fn as_os_str(&self) -> &OsStr { (*self).as_os_str() @@ -307,15 +346,12 @@ impl AsOsStr for String { } } -#[cfg(unix)] impl AsOsStr for Path { + #[cfg(unix)] fn as_os_str(&self) -> &OsStr { unsafe { mem::transmute(self.as_vec()) } } -} - -#[cfg(windows)] -impl AsOsStr for Path { + #[cfg(windows)] fn as_os_str(&self) -> &OsStr { // currently .as_str() is actually infallible on windows OsStr::from_str(self.as_str().unwrap()) diff --git a/src/libstd/fs/mod.rs b/src/libstd/fs/mod.rs index 565c0b13efead..80ec9909824bb 100644 --- a/src/libstd/fs/mod.rs +++ b/src/libstd/fs/mod.rs @@ -15,7 +15,7 @@ //! operations. Extra platform-specific functionality can be found in the //! extension traits of `std::os::$platform`. -#![unstable(feature = "fs")] +#![stable(feature = "rust1", since = "1.0.0")] use core::prelude::*; @@ -25,6 +25,7 @@ use sys::fs2 as fs_imp; use sys_common::{AsInnerMut, FromInner, AsInner}; use vec::Vec; +#[allow(deprecated)] pub use self::tempdir::TempDir; mod tempdir; @@ -52,6 +53,7 @@ mod tempdir; /// # Ok(()) /// # } /// ``` +#[stable(feature = "rust1", since = "1.0.0")] pub struct File { inner: fs_imp::File, path: PathBuf, @@ -62,6 +64,7 @@ pub struct File { /// This structure is returned from the `metadata` function or method and /// represents known metadata about a file such as its permissions, size, /// modification times, etc. +#[stable(feature = "rust1", since = "1.0.0")] pub struct Metadata(fs_imp::FileAttr); /// Iterator over the entries in a directory. @@ -70,6 +73,7 @@ pub struct Metadata(fs_imp::FileAttr); /// will yield instances of `io::Result`. Through a `DirEntry` /// information like the entry's path and possibly other metadata can be /// learned. +#[stable(feature = "rust1", since = "1.0.0")] pub struct ReadDir(fs_imp::ReadDir); /// Entries returned by the `ReadDir` iterator. @@ -77,9 +81,14 @@ pub struct ReadDir(fs_imp::ReadDir); /// An instance of `DirEntry` represents an entry inside of a directory on the /// filesystem. Each entry can be inspected via methods to learn about the full /// path or possibly other metadata through per-platform extension traits. +#[stable(feature = "rust1", since = "1.0.0")] pub struct DirEntry(fs_imp::DirEntry); /// An iterator that recursively walks over the contents of a directory. +#[unstable(feature = "fs_walk", + reason = "the precise semantics and defaults for a recursive walk \ + may change and this may end up accounting for files such \ + as symlinks differently")] pub struct WalkDir { cur: Option, stack: Vec>, @@ -92,6 +101,7 @@ pub struct WalkDir { /// `File::create` methods are aliases for commonly used options using this /// builder. #[derive(Clone)] +#[stable(feature = "rust1", since = "1.0.0")] pub struct OpenOptions(fs_imp::OpenOptions); /// Representation of the various permissions on a file. @@ -101,6 +111,7 @@ pub struct OpenOptions(fs_imp::OpenOptions); /// functionality, such as mode bits, is available through the /// `os::unix::PermissionsExt` trait. #[derive(Clone, PartialEq, Eq, Debug)] +#[stable(feature = "rust1", since = "1.0.0")] pub struct Permissions(fs_imp::FilePermissions); impl File { @@ -112,6 +123,7 @@ impl File { /// /// This function will return an error if `path` does not already exist. /// Other errors may also be returned according to `OpenOptions::open`. + #[stable(feature = "rust1", since = "1.0.0")] pub fn open(path: &P) -> io::Result { OpenOptions::new().read(true).open(path) } @@ -122,11 +134,15 @@ impl File { /// and will truncate it if it does. /// /// See the `OpenOptions::open` function for more details. + #[stable(feature = "rust1", since = "1.0.0")] pub fn create(path: &P) -> io::Result { OpenOptions::new().write(true).create(true).truncate(true).open(path) } /// Returns the original path that was used to open this file. + #[unstable(feature = "file_path", + reason = "this abstraction is imposed by this library instead \ + of the underlying OS and may be removed")] pub fn path(&self) -> Option<&Path> { Some(&self.path) } @@ -135,6 +151,7 @@ impl File { /// /// This function will attempt to ensure that all in-core data reaches the /// filesystem before returning. + #[stable(feature = "rust1", since = "1.0.0")] pub fn sync_all(&self) -> io::Result<()> { self.inner.fsync() } @@ -148,6 +165,7 @@ impl File { /// /// Note that some platforms may simply implement this in terms of /// `sync_all`. + #[stable(feature = "rust1", since = "1.0.0")] pub fn sync_data(&self) -> io::Result<()> { self.inner.datasync() } @@ -159,11 +177,13 @@ impl File { /// be shrunk. If it is greater than the current file's size, then the file /// will be extended to `size` and have all of the intermediate data filled /// in with 0s. + #[stable(feature = "rust1", since = "1.0.0")] pub fn set_len(&self, size: u64) -> io::Result<()> { self.inner.truncate(size) } - /// Queries information about the underlying file. + /// Queries metadata about the underlying file. + #[stable(feature = "rust1", since = "1.0.0")] pub fn metadata(&self) -> io::Result { self.inner.file_attr().map(Metadata) } @@ -172,33 +192,39 @@ impl File { impl AsInner for File { fn as_inner(&self) -> &fs_imp::File { &self.inner } } +#[stable(feature = "rust1", since = "1.0.0")] impl Read for File { fn read(&mut self, buf: &mut [u8]) -> io::Result { self.inner.read(buf) } } +#[stable(feature = "rust1", since = "1.0.0")] impl Write for File { fn write(&mut self, buf: &[u8]) -> io::Result { self.inner.write(buf) } fn flush(&mut self) -> io::Result<()> { self.inner.flush() } } +#[stable(feature = "rust1", since = "1.0.0")] impl Seek for File { fn seek(&mut self, pos: SeekFrom) -> io::Result { self.inner.seek(pos) } } +#[stable(feature = "rust1", since = "1.0.0")] impl<'a> Read for &'a File { fn read(&mut self, buf: &mut [u8]) -> io::Result { self.inner.read(buf) } } +#[stable(feature = "rust1", since = "1.0.0")] impl<'a> Write for &'a File { fn write(&mut self, buf: &[u8]) -> io::Result { self.inner.write(buf) } fn flush(&mut self) -> io::Result<()> { self.inner.flush() } } +#[stable(feature = "rust1", since = "1.0.0")] impl<'a> Seek for &'a File { fn seek(&mut self, pos: SeekFrom) -> io::Result { self.inner.seek(pos) @@ -209,6 +235,7 @@ impl OpenOptions { /// Creates a blank net set of options ready for configuration. /// /// All options are initially set to `false`. + #[stable(feature = "rust1", since = "1.0.0")] pub fn new() -> OpenOptions { OpenOptions(fs_imp::OpenOptions::new()) } @@ -217,6 +244,7 @@ impl OpenOptions { /// /// This option, when true, will indicate that the file should be /// `read`-able if opened. + #[stable(feature = "rust1", since = "1.0.0")] pub fn read(&mut self, read: bool) -> &mut OpenOptions { self.0.read(read); self } @@ -225,6 +253,7 @@ impl OpenOptions { /// /// This option, when true, will indicate that the file should be /// `write`-able if opened. + #[stable(feature = "rust1", since = "1.0.0")] pub fn write(&mut self, write: bool) -> &mut OpenOptions { self.0.write(write); self } @@ -233,6 +262,7 @@ impl OpenOptions { /// /// This option, when true, means that writes will append to a file instead /// of overwriting previous contents. + #[stable(feature = "rust1", since = "1.0.0")] pub fn append(&mut self, append: bool) -> &mut OpenOptions { self.0.append(append); self } @@ -241,6 +271,7 @@ impl OpenOptions { /// /// If a file is successfully opened with this option set it will truncate /// the file to 0 length if it already exists. + #[stable(feature = "rust1", since = "1.0.0")] pub fn truncate(&mut self, truncate: bool) -> &mut OpenOptions { self.0.truncate(truncate); self } @@ -249,6 +280,7 @@ impl OpenOptions { /// /// This option indicates whether a new file will be created if the file /// does not yet already exist. + #[stable(feature = "rust1", since = "1.0.0")] pub fn create(&mut self, create: bool) -> &mut OpenOptions { self.0.create(create); self } @@ -264,37 +296,33 @@ impl OpenOptions { /// * Attempting to open a file with access that the user lacks /// permissions for /// * Filesystem-level errors (full disk, etc) + #[stable(feature = "rust1", since = "1.0.0")] pub fn open(&self, path: &P) -> io::Result { let path = path.as_path(); let inner = try!(fs_imp::File::open(path, &self.0)); - - // On *BSD systems, we can open a directory as a file and read from - // it: fd=open("/tmp", O_RDONLY); read(fd, buf, N); due to an old - // tradition before the introduction of opendir(3). We explicitly - // reject it because there are few use cases. - if cfg!(not(any(target_os = "linux", target_os = "android"))) && - try!(inner.file_attr()).is_dir() { - Err(Error::new(ErrorKind::InvalidInput, "is a directory", None)) - } else { - Ok(File { path: path.to_path_buf(), inner: inner }) - } + Ok(File { path: path.to_path_buf(), inner: inner }) } } + impl AsInnerMut for OpenOptions { fn as_inner_mut(&mut self) -> &mut fs_imp::OpenOptions { &mut self.0 } } impl Metadata { /// Returns whether this metadata is for a directory. + #[stable(feature = "rust1", since = "1.0.0")] pub fn is_dir(&self) -> bool { self.0.is_dir() } /// Returns whether this metadata is for a regular file. + #[stable(feature = "rust1", since = "1.0.0")] pub fn is_file(&self) -> bool { self.0.is_file() } /// Returns the size of the file, in bytes, this metadata is for. + #[stable(feature = "rust1", since = "1.0.0")] pub fn len(&self) -> u64 { self.0.size() } /// Returns the permissions of the file this metadata is for. + #[stable(feature = "rust1", since = "1.0.0")] pub fn permissions(&self) -> Permissions { Permissions(self.0.perm()) } @@ -302,22 +330,32 @@ impl Metadata { /// Returns the most recent access time for a file. /// /// The return value is in milliseconds since the epoch. + #[unstable(feature = "fs_time", + reason = "the return type of u64 is not quite appropriate for \ + this method and may change if the standard library \ + gains a type to represent a moment in time")] pub fn accessed(&self) -> u64 { self.0.accessed() } /// Returns the most recent modification time for a file. /// /// The return value is in milliseconds since the epoch. + #[unstable(feature = "fs_time", + reason = "the return type of u64 is not quite appropriate for \ + this method and may change if the standard library \ + gains a type to represent a moment in time")] pub fn modified(&self) -> u64 { self.0.modified() } } impl Permissions { /// Returns whether these permissions describe a readonly file. + #[stable(feature = "rust1", since = "1.0.0")] pub fn readonly(&self) -> bool { self.0.readonly() } /// Modify the readonly flag for this set of permissions. /// /// This operation does **not** modify the filesystem. To modify the /// filesystem use the `fs::set_permissions` function. + #[stable(feature = "rust1", since = "1.0.0")] pub fn set_readonly(&mut self, readonly: bool) { self.0.set_readonly(readonly) } @@ -333,6 +371,7 @@ impl AsInner for Permissions { fn as_inner(&self) -> &fs_imp::FilePermissions { &self.0 } } +#[stable(feature = "rust1", since = "1.0.0")] impl Iterator for ReadDir { type Item = io::Result; @@ -341,11 +380,13 @@ impl Iterator for ReadDir { } } +#[stable(feature = "rust1", since = "1.0.0")] impl DirEntry { /// Returns the full path to the file that this entry represents. /// /// The full path is created by joining the original path to `read_dir` or /// `walk_dir` with the filename of this entry. + #[stable(feature = "rust1", since = "1.0.0")] pub fn path(&self) -> PathBuf { self.0.path() } } @@ -368,31 +409,9 @@ impl DirEntry { /// This function will return an error if `path` points to a directory, if the /// user lacks permissions to remove the file, or if some other filesystem-level /// error occurs. +#[stable(feature = "rust1", since = "1.0.0")] pub fn remove_file(path: &P) -> io::Result<()> { - let path = path.as_path(); - let e = match fs_imp::unlink(path) { - Ok(()) => return Ok(()), - Err(e) => e, - }; - if !cfg!(windows) { return Err(e) } - - // On unix, a readonly file can be successfully removed. On windows, - // however, it cannot. To keep the two platforms in line with - // respect to their behavior, catch this case on windows, attempt to - // change it to read-write, and then remove the file. - if e.kind() != ErrorKind::PermissionDenied { return Err(e) } - - let attr = match metadata(path) { Ok(a) => a, Err(..) => return Err(e) }; - let mut perms = attr.permissions(); - if !perms.readonly() { return Err(e) } - perms.set_readonly(false); - - if set_permissions(path, perms).is_err() { return Err(e) } - if fs_imp::unlink(path).is_ok() { return Ok(()) } - - // Oops, try to put things back the way we found it - let _ = set_permissions(path, attr.permissions()); - Err(e) + fs_imp::unlink(path.as_path()) } /// Given a path, query the file system to get information about a file, @@ -418,6 +437,7 @@ pub fn remove_file(path: &P) -> io::Result<()> { /// This function will return an error if the user lacks the requisite /// permissions to perform a `metadata` call on the given `path` or if there /// is no entry in the filesystem at the provided path. +#[stable(feature = "rust1", since = "1.0.0")] pub fn metadata(path: &P) -> io::Result { fs_imp::stat(path.as_path()).map(Metadata) } @@ -438,6 +458,7 @@ pub fn metadata(path: &P) -> io::Result { /// the process lacks permissions to view the contents, if `from` and `to` /// reside on separate filesystems, or if some other intermittent I/O error /// occurs. +#[stable(feature = "rust1", since = "1.0.0")] pub fn rename(from: &P, to: &Q) -> io::Result<()> { fs_imp::rename(from.as_path(), to.as_path()) @@ -468,6 +489,7 @@ pub fn rename(from: &P, to: &Q) /// * The `from` file does not exist /// * The current process does not have the permission rights to access /// `from` or write `to` +#[stable(feature = "rust1", since = "1.0.0")] pub fn copy(from: &P, to: &Q) -> io::Result { let from = from.as_path(); @@ -490,6 +512,7 @@ pub fn copy(from: &P, to: &Q) /// /// The `dst` path will be a link pointing to the `src` path. Note that systems /// often require these two paths to both be located on the same filesystem. +#[stable(feature = "rust1", since = "1.0.0")] pub fn hard_link(src: &P, dst: &Q) -> io::Result<()> { fs_imp::link(src.as_path(), dst.as_path()) @@ -498,6 +521,7 @@ pub fn hard_link(src: &P, dst: &Q) /// Creates a new soft link on the filesystem. /// /// The `dst` path will be a soft link pointing to the `src` path. +#[stable(feature = "rust1", since = "1.0.0")] pub fn soft_link(src: &P, dst: &Q) -> io::Result<()> { fs_imp::symlink(src.as_path(), dst.as_path()) @@ -510,6 +534,7 @@ pub fn soft_link(src: &P, dst: &Q) /// This function will return an error on failure. Failure conditions include /// reading a file that does not exist or reading a file that is not a soft /// link. +#[stable(feature = "rust1", since = "1.0.0")] pub fn read_link(path: &P) -> io::Result { fs_imp::readlink(path.as_path()) } @@ -528,6 +553,7 @@ pub fn read_link(path: &P) -> io::Result { /// /// This function will return an error if the user lacks permissions to make a /// new directory at the provided `path`, or if the directory already exists. +#[stable(feature = "rust1", since = "1.0.0")] pub fn create_dir(path: &P) -> io::Result<()> { fs_imp::mkdir(path.as_path()) } @@ -541,6 +567,7 @@ pub fn create_dir(path: &P) -> io::Result<()> { /// does not already exist and it could not be created otherwise. The specific /// error conditions for when a directory is being created (after it is /// determined to not exist) are outlined by `fs::create_dir`. +#[stable(feature = "rust1", since = "1.0.0")] pub fn create_dir_all(path: &P) -> io::Result<()> { let path = path.as_path(); if path.is_dir() { return Ok(()) } @@ -572,6 +599,7 @@ pub fn create_dir_all(path: &P) -> io::Result<()> { /// /// This function will return an error if the user lacks permissions to remove /// the directory at the provided `path`, or if the directory isn't empty. +#[stable(feature = "rust1", since = "1.0.0")] pub fn remove_dir(path: &P) -> io::Result<()> { fs_imp::rmdir(path.as_path()) } @@ -585,6 +613,7 @@ pub fn remove_dir(path: &P) -> io::Result<()> { /// # Errors /// /// See `file::remove_file` and `fs::remove_dir` +#[stable(feature = "rust1", since = "1.0.0")] pub fn remove_dir_all(path: &P) -> io::Result<()> { let path = path.as_path(); for child in try!(read_dir(path)) { @@ -637,6 +666,7 @@ pub fn remove_dir_all(path: &P) -> io::Result<()> { /// This function will return an error if the provided `path` doesn't exist, if /// the process lacks permissions to view the contents or if the `path` points /// at a non-directory file +#[stable(feature = "rust1", since = "1.0.0")] pub fn read_dir(path: &P) -> io::Result { fs_imp::readdir(path.as_path()).map(ReadDir) } @@ -649,11 +679,16 @@ pub fn read_dir(path: &P) -> io::Result { /// /// The iterator will yield instances of `io::Result`. New errors may /// be encountered after an iterator is initially constructed. +#[unstable(feature = "fs_walk", + reason = "the precise semantics and defaults for a recursive walk \ + may change and this may end up accounting for files such \ + as symlinks differently")] pub fn walk_dir(path: &P) -> io::Result { let start = try!(read_dir(path)); Ok(WalkDir { cur: Some(start), stack: Vec::new() }) } +#[unstable(feature = "fs_walk")] impl Iterator for WalkDir { type Item = io::Result; @@ -683,6 +718,9 @@ impl Iterator for WalkDir { } /// Utility methods for paths. +#[unstable(feature = "path_ext", + reason = "the precise set of methods exposed on this trait may \ + change and some methods may be removed")] pub trait PathExt { /// Get information on the file, directory, etc at this path. /// @@ -727,6 +765,10 @@ impl PathExt for Path { /// The file at the path specified will have its last access time set to /// `atime` and its modification time set to `mtime`. The times specified should /// be in milliseconds. +#[unstable(feature = "fs_time", + reason = "the argument type of u64 is not quite appropriate for \ + this function and may change if the standard library \ + gains a type to represent a moment in time")] pub fn set_file_times(path: &P, accessed: u64, modified: u64) -> io::Result<()> { fs_imp::utimes(path.as_path(), accessed, modified) @@ -752,6 +794,10 @@ pub fn set_file_times(path: &P, accessed: u64, /// This function will return an error if the provided `path` doesn't exist, if /// the process lacks permissions to change the attributes of the file, or if /// some other I/O error is encountered. +#[unstable(feature = "fs", + reason = "a more granual ability to set specific permissions may \ + be exposed on the Permissions structure itself and this \ + method may not always exist")] pub fn set_permissions(path: &P, perm: Permissions) -> io::Result<()> { fs_imp::set_perm(path.as_path(), perm.0) @@ -1267,6 +1313,8 @@ mod tests { check!(fs::set_permissions(&input, p)); check!(fs::copy(&input, &out)); assert!(check!(out.metadata()).permissions().readonly()); + check!(fs::set_permissions(&input, attr.permissions())); + check!(fs::set_permissions(&out, attr.permissions())); } #[cfg(not(windows))] // FIXME(#10264) operation not permitted? @@ -1350,10 +1398,13 @@ mod tests { let attr = check!(fs::metadata(&file)); assert!(attr.permissions().readonly()); - match fs::set_permissions(&tmpdir.join("foo"), p) { - Ok(..) => panic!("wanted a panic"), + match fs::set_permissions(&tmpdir.join("foo"), p.clone()) { + Ok(..) => panic!("wanted an error"), Err(..) => {} } + + p.set_readonly(false); + check!(fs::set_permissions(&file, p)); } #[test] @@ -1506,6 +1557,7 @@ mod tests { } #[test] + #[cfg(not(windows))] fn unlink_readonly() { let tmpdir = tmpdir(); let path = tmpdir.join("file"); diff --git a/src/libstd/fs/tempdir.rs b/src/libstd/fs/tempdir.rs index 79bdb35dd48cd..c1da77a6668f5 100644 --- a/src/libstd/fs/tempdir.rs +++ b/src/libstd/fs/tempdir.rs @@ -9,6 +9,9 @@ // except according to those terms. #![unstable(feature = "tempdir", reason = "needs an RFC before stabilization")] +#![deprecated(since = "1.0.0", + reason = "use the `tempdir` crate from crates.io instead")] +#![allow(deprecated)] use prelude::v1::*; diff --git a/src/libstd/io/cursor.rs b/src/libstd/io/cursor.rs index 8a841742de4ec..2445f5a7a4040 100644 --- a/src/libstd/io/cursor.rs +++ b/src/libstd/io/cursor.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![allow(missing_copy_implementations)] - use prelude::v1::*; use io::prelude::*; @@ -32,6 +30,7 @@ use slice; /// Implementations of the I/O traits for `Cursor` are not currently generic /// over `T` itself. Instead, specific implementations are provided for various /// in-memory buffer types like `Vec` and `&[u8]`. +#[stable(feature = "rust1", since = "1.0.0")] pub struct Cursor { inner: T, pos: u64, @@ -39,26 +38,32 @@ pub struct Cursor { impl Cursor { /// Create a new cursor wrapping the provided underlying I/O object. + #[stable(feature = "rust1", since = "1.0.0")] pub fn new(inner: T) -> Cursor { Cursor { pos: 0, inner: inner } } /// Consume this cursor, returning the underlying value. + #[stable(feature = "rust1", since = "1.0.0")] pub fn into_inner(self) -> T { self.inner } /// Get a reference to the underlying value in this cursor. + #[stable(feature = "rust1", since = "1.0.0")] pub fn get_ref(&self) -> &T { &self.inner } /// Get a mutable reference to the underlying value in this cursor. /// /// Care should be taken to avoid modifying the internal I/O state of the /// underlying value as it may corrupt this cursor's position. + #[stable(feature = "rust1", since = "1.0.0")] pub fn get_mut(&mut self) -> &mut T { &mut self.inner } /// Returns the current value of this cursor + #[stable(feature = "rust1", since = "1.0.0")] pub fn position(&self) -> u64 { self.pos } /// Sets the value of this cursor + #[stable(feature = "rust1", since = "1.0.0")] pub fn set_position(&mut self, pos: u64) { self.pos = pos; } } @@ -83,8 +88,11 @@ macro_rules! seek { } } +#[stable(feature = "rust1", since = "1.0.0")] impl<'a> io::Seek for Cursor<&'a [u8]> { seek!(); } +#[stable(feature = "rust1", since = "1.0.0")] impl<'a> io::Seek for Cursor<&'a mut [u8]> { seek!(); } +#[stable(feature = "rust1", since = "1.0.0")] impl io::Seek for Cursor> { seek!(); } macro_rules! read { @@ -97,8 +105,11 @@ macro_rules! read { } } +#[stable(feature = "rust1", since = "1.0.0")] impl<'a> Read for Cursor<&'a [u8]> { read!(); } +#[stable(feature = "rust1", since = "1.0.0")] impl<'a> Read for Cursor<&'a mut [u8]> { read!(); } +#[stable(feature = "rust1", since = "1.0.0")] impl Read for Cursor> { read!(); } macro_rules! buffer { @@ -111,10 +122,14 @@ macro_rules! buffer { } } +#[stable(feature = "rust1", since = "1.0.0")] impl<'a> BufRead for Cursor<&'a [u8]> { buffer!(); } +#[stable(feature = "rust1", since = "1.0.0")] impl<'a> BufRead for Cursor<&'a mut [u8]> { buffer!(); } +#[stable(feature = "rust1", since = "1.0.0")] impl<'a> BufRead for Cursor> { buffer!(); } +#[stable(feature = "rust1", since = "1.0.0")] impl<'a> Write for Cursor<&'a mut [u8]> { fn write(&mut self, data: &[u8]) -> io::Result { let pos = cmp::min(self.pos, self.inner.len() as u64); @@ -125,6 +140,7 @@ impl<'a> Write for Cursor<&'a mut [u8]> { fn flush(&mut self) -> io::Result<()> { Ok(()) } } +#[stable(feature = "rust1", since = "1.0.0")] impl Write for Cursor> { fn write(&mut self, buf: &[u8]) -> io::Result { // Make sure the internal buffer is as least as big as where we diff --git a/src/libstd/io/impls.rs b/src/libstd/io/impls.rs index 82b69ddebff68..c968415d3efdc 100644 --- a/src/libstd/io/impls.rs +++ b/src/libstd/io/impls.rs @@ -22,57 +22,88 @@ use vec::Vec; // ============================================================================= // Forwarding implementations +#[stable(feature = "rust1", since = "1.0.0")] impl<'a, R: Read + ?Sized> Read for &'a mut R { - fn read(&mut self, buf: &mut [u8]) -> io::Result { (**self).read(buf) } - - fn read_to_end(&mut self, buf: &mut Vec) -> io::Result<()> { (**self).read_to_end(buf) } - + fn read(&mut self, buf: &mut [u8]) -> io::Result { + (**self).read(buf) + } + fn read_to_end(&mut self, buf: &mut Vec) -> io::Result<()> { + (**self).read_to_end(buf) + } fn read_to_string(&mut self, buf: &mut String) -> io::Result<()> { (**self).read_to_string(buf) } } +#[stable(feature = "rust1", since = "1.0.0")] impl<'a, W: Write + ?Sized> Write for &'a mut W { fn write(&mut self, buf: &[u8]) -> io::Result { (**self).write(buf) } - - fn write_all(&mut self, buf: &[u8]) -> io::Result<()> { (**self).write_all(buf) } - - fn write_fmt(&mut self, fmt: fmt::Arguments) -> io::Result<()> { (**self).write_fmt(fmt) } - fn flush(&mut self) -> io::Result<()> { (**self).flush() } + fn write_all(&mut self, buf: &[u8]) -> io::Result<()> { + (**self).write_all(buf) + } + fn write_fmt(&mut self, fmt: fmt::Arguments) -> io::Result<()> { + (**self).write_fmt(fmt) + } } +#[stable(feature = "rust1", since = "1.0.0")] impl<'a, S: Seek + ?Sized> Seek for &'a mut S { fn seek(&mut self, pos: SeekFrom) -> io::Result { (**self).seek(pos) } } +#[stable(feature = "rust1", since = "1.0.0")] impl<'a, B: BufRead + ?Sized> BufRead for &'a mut B { fn fill_buf(&mut self) -> io::Result<&[u8]> { (**self).fill_buf() } - fn consume(&mut self, amt: usize) { (**self).consume(amt) } - fn read_until(&mut self, byte: u8, buf: &mut Vec) -> io::Result<()> { (**self).read_until(byte, buf) } - - fn read_line(&mut self, buf: &mut String) -> io::Result<()> { (**self).read_line(buf) } + fn read_line(&mut self, buf: &mut String) -> io::Result<()> { + (**self).read_line(buf) + } } +#[stable(feature = "rust1", since = "1.0.0")] impl Read for Box { - fn read(&mut self, buf: &mut [u8]) -> io::Result { (**self).read(buf) } + fn read(&mut self, buf: &mut [u8]) -> io::Result { + (**self).read(buf) + } + fn read_to_end(&mut self, buf: &mut Vec) -> io::Result<()> { + (**self).read_to_end(buf) + } + fn read_to_string(&mut self, buf: &mut String) -> io::Result<()> { + (**self).read_to_string(buf) + } } +#[stable(feature = "rust1", since = "1.0.0")] impl Write for Box { fn write(&mut self, buf: &[u8]) -> io::Result { (**self).write(buf) } fn flush(&mut self) -> io::Result<()> { (**self).flush() } + fn write_all(&mut self, buf: &[u8]) -> io::Result<()> { + (**self).write_all(buf) + } + fn write_fmt(&mut self, fmt: fmt::Arguments) -> io::Result<()> { + (**self).write_fmt(fmt) + } } +#[stable(feature = "rust1", since = "1.0.0")] impl Seek for Box { fn seek(&mut self, pos: SeekFrom) -> io::Result { (**self).seek(pos) } } +#[stable(feature = "rust1", since = "1.0.0")] impl BufRead for Box { fn fill_buf(&mut self) -> io::Result<&[u8]> { (**self).fill_buf() } fn consume(&mut self, amt: usize) { (**self).consume(amt) } + fn read_until(&mut self, byte: u8, buf: &mut Vec) -> io::Result<()> { + (**self).read_until(byte, buf) + } + fn read_line(&mut self, buf: &mut String) -> io::Result<()> { + (**self).read_line(buf) + } } // ============================================================================= // In-memory buffer implementations +#[stable(feature = "rust1", since = "1.0.0")] impl<'a> Read for &'a [u8] { fn read(&mut self, buf: &mut [u8]) -> io::Result { let amt = cmp::min(buf.len(), self.len()); @@ -83,11 +114,13 @@ impl<'a> Read for &'a [u8] { } } +#[stable(feature = "rust1", since = "1.0.0")] impl<'a> BufRead for &'a [u8] { fn fill_buf(&mut self) -> io::Result<&[u8]> { Ok(*self) } fn consume(&mut self, amt: usize) { *self = &self[amt..]; } } +#[stable(feature = "rust1", since = "1.0.0")] impl<'a> Write for &'a mut [u8] { fn write(&mut self, data: &[u8]) -> io::Result { let amt = cmp::min(data.len(), self.len()); @@ -108,6 +141,7 @@ impl<'a> Write for &'a mut [u8] { fn flush(&mut self) -> io::Result<()> { Ok(()) } } +#[stable(feature = "rust1", since = "1.0.0")] impl Write for Vec { fn write(&mut self, buf: &[u8]) -> io::Result { self.push_all(buf); @@ -115,7 +149,7 @@ impl Write for Vec { } fn write_all(&mut self, buf: &[u8]) -> io::Result<()> { - try!(self.write(buf)); + self.push_all(buf); Ok(()) } diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs index 46547ac583637..9137068076b46 100644 --- a/src/libstd/io/mod.rs +++ b/src/libstd/io/mod.rs @@ -237,11 +237,13 @@ pub trait Read { /// Extension methods for all instances of `Read`, typically imported through /// `std::io::prelude::*`. +#[unstable(feature = "io", reason = "may merge into the Read trait")] pub trait ReadExt: Read + Sized { /// Create a "by reference" adaptor for this instance of `Read`. /// /// The returned adaptor also implements `Read` and will simply borrow this /// current reader. + #[stable(feature = "rust1", since = "1.0.0")] fn by_ref(&mut self) -> &mut Self { self } /// Transform this `Read` instance to an `Iterator` over its bytes. @@ -250,6 +252,7 @@ pub trait ReadExt: Read + Sized { /// R::Err>`. The yielded item is `Ok` if a byte was successfully read and /// `Err` otherwise for I/O errors. EOF is mapped to returning `None` from /// this iterator. + #[stable(feature = "rust1", since = "1.0.0")] fn bytes(self) -> Bytes { Bytes { inner: self } } @@ -264,6 +267,9 @@ pub trait ReadExt: Read + Sized { /// /// Currently this adaptor will discard intermediate data read, and should /// be avoided if this is not desired. + #[unstable(feature = "io", reason = "the semantics of a partial read/write \ + of where errors happen is currently \ + unclear and may change")] fn chars(self) -> Chars { Chars { inner: self } } @@ -273,6 +279,7 @@ pub trait ReadExt: Read + Sized { /// The returned `Read` instance will first read all bytes from this object /// until EOF is encountered. Afterwards the output is equivalent to the /// output of `next`. + #[stable(feature = "rust1", since = "1.0.0")] fn chain(self, next: R) -> Chain { Chain { first: self, second: next, done_first: false } } @@ -283,6 +290,7 @@ pub trait ReadExt: Read + Sized { /// `limit` bytes, after which it will always return EOF (`Ok(0)`). Any /// read errors will not count towards the number of bytes read and future /// calls to `read` may succeed. + #[stable(feature = "rust1", since = "1.0.0")] fn take(self, limit: u64) -> Take { Take { inner: self, limit: limit } } @@ -293,6 +301,9 @@ pub trait ReadExt: Read + Sized { /// Whenever the returned `Read` instance is read it will write the read /// data to `out`. The current semantics of this implementation imply that /// a `write` error will not report how much data was initially read. + #[unstable(feature = "io", reason = "the semantics of a partial read/write \ + of where errors happen is currently \ + unclear and may change")] fn tee(self, out: W) -> Tee { Tee { reader: self, writer: out } } @@ -415,11 +426,13 @@ pub trait Write { /// Extension methods for all instances of `Write`, typically imported through /// `std::io::prelude::*`. +#[unstable(feature = "io", reason = "may merge into the Read trait")] pub trait WriteExt: Write + Sized { /// Create a "by reference" adaptor for this instance of `Write`. /// /// The returned adaptor also implements `Write` and will simply borrow this /// current writer. + #[stable(feature = "rust1", since = "1.0.0")] fn by_ref(&mut self) -> &mut Self { self } /// Creates a new writer which will write all data to both this writer and @@ -430,11 +443,15 @@ pub trait WriteExt: Write + Sized { /// implementation do not precisely track where errors happen. For example /// an error on the second call to `write` will not report that the first /// call to `write` succeeded. + #[unstable(feature = "io", reason = "the semantics of a partial read/write \ + of where errors happen is currently \ + unclear and may change")] fn broadcast(self, other: W) -> Broadcast { Broadcast { first: self, second: other } } } +#[stable(feature = "rust1", since = "1.0.0")] impl WriteExt for T {} /// An object implementing `Seek` internally has some form of cursor which can @@ -592,6 +609,8 @@ pub trait BufReadExt: BufRead + Sized { /// /// This function will yield errors whenever `read_until` would have also /// yielded an error. + #[unstable(feature = "io", reason = "may be renamed to not conflict with \ + SliceExt::split")] fn split(self, byte: u8) -> Split { Split { buf: self, delim: byte } } @@ -604,11 +623,13 @@ pub trait BufReadExt: BufRead + Sized { /// /// This function will yield errors whenever `read_string` would have also /// yielded an error. + #[stable(feature = "rust1", since = "1.0.0")] fn lines(self) -> Lines { Lines { buf: self } } } +#[stable(feature = "rust1", since = "1.0.0")] impl BufReadExt for T {} /// A `Write` adaptor which will write data to multiple locations. @@ -635,12 +656,14 @@ impl Write for Broadcast { /// Adaptor to chain together two instances of `Read`. /// /// For more information, see `ReadExt::chain`. +#[stable(feature = "rust1", since = "1.0.0")] pub struct Chain { first: T, second: U, done_first: bool, } +#[stable(feature = "rust1", since = "1.0.0")] impl Read for Chain { fn read(&mut self, buf: &mut [u8]) -> Result { if !self.done_first { @@ -656,11 +679,13 @@ impl Read for Chain { /// Reader adaptor which limits the bytes read from an underlying reader. /// /// For more information, see `ReadExt::take`. +#[stable(feature = "rust1", since = "1.0.0")] pub struct Take { inner: T, limit: u64, } +#[stable(feature = "rust1", since = "1.0.0")] impl Take { /// Returns the number of bytes that can be read before this instance will /// return EOF. @@ -669,9 +694,11 @@ impl Take { /// /// This instance may reach EOF after reading fewer bytes than indicated by /// this method if the underlying `Read` instance reaches EOF. + #[stable(feature = "rust1", since = "1.0.0")] pub fn limit(&self) -> u64 { self.limit } } +#[stable(feature = "rust1", since = "1.0.0")] impl Read for Take { fn read(&mut self, buf: &mut [u8]) -> Result { // Don't call into inner reader at all at EOF because it may still block @@ -686,6 +713,7 @@ impl Read for Take { } } +#[stable(feature = "rust1", since = "1.0.0")] impl BufRead for Take { fn fill_buf(&mut self) -> Result<&[u8]> { let buf = try!(self.inner.fill_buf()); @@ -721,10 +749,12 @@ impl Read for Tee { /// A bridge from implementations of `Read` to an `Iterator` of `u8`. /// /// See `ReadExt::bytes` for more information. +#[stable(feature = "rust1", since = "1.0.0")] pub struct Bytes { inner: R, } +#[stable(feature = "rust1", since = "1.0.0")] impl Iterator for Bytes { type Item = Result; @@ -845,10 +875,12 @@ impl Iterator for Split { /// byte. /// /// See `BufReadExt::lines` for more information. +#[stable(feature = "rust1", since = "1.0.0")] pub struct Lines { buf: B, } +#[stable(feature = "rust1", since = "1.0.0")] impl Iterator for Lines { type Item = Result; diff --git a/src/libstd/io/stdio.rs b/src/libstd/io/stdio.rs index 61ad9905771a4..4027f741654b6 100644 --- a/src/libstd/io/stdio.rs +++ b/src/libstd/io/stdio.rs @@ -157,9 +157,6 @@ impl Read for Stdin { impl<'a> Read for StdinLock<'a> { fn read(&mut self, buf: &mut [u8]) -> io::Result { - // Flush stdout so that weird issues like a print!'d prompt not being - // shown until after the user hits enter. - drop(stdout().flush()); self.inner.read(buf) } } diff --git a/src/libstd/io/util.rs b/src/libstd/io/util.rs index 3d342137c62dd..20426025257c3 100644 --- a/src/libstd/io/util.rs +++ b/src/libstd/io/util.rs @@ -12,7 +12,7 @@ use prelude::v1::*; -use io::{self, Read, Write, ErrorKind}; +use io::{self, Read, Write, ErrorKind, BufRead}; /// Copies the entire contents of a reader into a writer. /// @@ -27,6 +27,7 @@ use io::{self, Read, Write, ErrorKind}; /// This function will return an error immediately if any call to `read` or /// `write` returns an error. All instances of `ErrorKind::Interrupted` are /// handled by this function and the underlying operation is retried. +#[stable(feature = "rust1", since = "1.0.0")] pub fn copy(r: &mut R, w: &mut W) -> io::Result { let mut buf = [0; super::DEFAULT_BUF_SIZE]; let mut written = 0; @@ -43,26 +44,37 @@ pub fn copy(r: &mut R, w: &mut W) -> io::Result { } /// A reader which is always at EOF. +#[stable(feature = "rust1", since = "1.0.0")] pub struct Empty { _priv: () } /// Creates an instance of an empty reader. /// /// All reads from the returned reader will return `Ok(0)`. +#[stable(feature = "rust1", since = "1.0.0")] pub fn empty() -> Empty { Empty { _priv: () } } +#[stable(feature = "rust1", since = "1.0.0")] impl Read for Empty { fn read(&mut self, _buf: &mut [u8]) -> io::Result { Ok(0) } } +#[stable(feature = "rust1", since = "1.0.0")] +impl BufRead for Empty { + fn fill_buf(&mut self) -> io::Result<&[u8]> { Ok(&[]) } + fn consume(&mut self, _n: usize) {} +} /// A reader which infinitely yields one byte. +#[stable(feature = "rust1", since = "1.0.0")] pub struct Repeat { byte: u8 } /// Creates an instance of a reader that infinitely repeats one byte. /// /// All reads from this reader will succeed by filling the specified buffer with /// the given byte. +#[stable(feature = "rust1", since = "1.0.0")] pub fn repeat(byte: u8) -> Repeat { Repeat { byte: byte } } +#[stable(feature = "rust1", since = "1.0.0")] impl Read for Repeat { fn read(&mut self, buf: &mut [u8]) -> io::Result { for slot in buf.iter_mut() { @@ -73,14 +85,17 @@ impl Read for Repeat { } /// A writer which will move data into the void. +#[stable(feature = "rust1", since = "1.0.0")] pub struct Sink { _priv: () } /// Creates an instance of a writer which will successfully consume all data. /// /// All calls to `write` on the returned instance will return `Ok(buf.len())` /// and the contents of the buffer will not be inspected. +#[stable(feature = "rust1", since = "1.0.0")] pub fn sink() -> Sink { Sink { _priv: () } } +#[stable(feature = "rust1", since = "1.0.0")] impl Write for Sink { fn write(&mut self, buf: &[u8]) -> io::Result { Ok(buf.len()) } fn flush(&mut self) -> io::Result<()> { Ok(()) } diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index c0db163e0874d..ce14967090e0f 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -94,7 +94,8 @@ //! to all code by default. [`macros`](macros/index.html) contains //! all the standard macros, such as `assert!`, `panic!`, `println!`, //! and `format!`, also available to all Rust code. - +// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364) +#![cfg_attr(stage0, feature(custom_attribute))] #![crate_name = "std"] #![stable(feature = "rust1", since = "1.0.0")] #![staged_api] diff --git a/src/libstd/net/addr.rs b/src/libstd/net/addr.rs index 916abe78eb3b3..101aae3eb248b 100644 --- a/src/libstd/net/addr.rs +++ b/src/libstd/net/addr.rs @@ -293,7 +293,7 @@ impl ToSocketAddrs for str { } // split the string by ':' and convert the second part to u16 - let mut parts_iter = self.rsplitn(2, ':'); + let mut parts_iter = self.rsplitn(1, ':'); let port_str = try_opt!(parts_iter.next(), "invalid socket address"); let host = try_opt!(parts_iter.next(), "invalid socket address"); let port: u16 = try_opt!(port_str.parse().ok(), "invalid port value"); @@ -590,4 +590,10 @@ mod tests { let a = SocketAddr::new(IpAddr::new_v4(127, 0, 0, 1), 23924); assert!(tsa("localhost:23924").unwrap().contains(&a)); } + + #[test] + #[cfg(not(windows))] + fn to_socket_addr_str_bad() { + assert!(tsa("1200::AB00:1234::2552:7777:1313:34300").is_err()); + } } diff --git a/src/libstd/net/tcp.rs b/src/libstd/net/tcp.rs index 6ce3a939c6a49..fd723ea13e962 100644 --- a/src/libstd/net/tcp.rs +++ b/src/libstd/net/tcp.rs @@ -233,13 +233,13 @@ mod tests { } } - // FIXME #11530 this fails on android because tests are run as root - #[cfg_attr(any(windows, target_os = "android"), ignore)] #[test] fn bind_error() { - match TcpListener::bind("0.0.0.0:1") { + match TcpListener::bind("1.1.1.1:9999") { Ok(..) => panic!(), - Err(e) => assert_eq!(e.kind(), ErrorKind::PermissionDenied), + Err(e) => + // EADDRNOTAVAIL is mapped to ConnectionRefused + assert_eq!(e.kind(), ErrorKind::ConnectionRefused), } } diff --git a/src/libstd/old_io/net/mod.rs b/src/libstd/old_io/net/mod.rs index bbe3a71dcc0d1..a3567290b0e16 100644 --- a/src/libstd/old_io/net/mod.rs +++ b/src/libstd/old_io/net/mod.rs @@ -10,6 +10,10 @@ //! Networking I/O +#![deprecated(since = "1.0.0", + reason = "replaced with new I/O primitives in `std::net`")] +#![unstable(feature = "old_io")] + use old_io::{IoError, IoResult, InvalidInput}; use ops::FnMut; use option::Option::None; diff --git a/src/libstd/old_io/net/pipe.rs b/src/libstd/old_io/net/pipe.rs index d05669d32b8cf..2ecaf515f081b 100644 --- a/src/libstd/old_io/net/pipe.rs +++ b/src/libstd/old_io/net/pipe.rs @@ -19,6 +19,12 @@ //! instances as clients. #![allow(missing_docs)] +#![deprecated(since = "1.0.0", + reason = "will be removed to be reintroduced at a later date; \ + in the meantime consider using the `unix_socket` crate \ + for unix sockets; there is currently no replacement \ + for named pipes")] +#![unstable(feature = "old_io")] use prelude::v1::*; diff --git a/src/libstd/old_io/process.rs b/src/libstd/old_io/process.rs index a13295b1ccb50..e02e863516ab1 100644 --- a/src/libstd/old_io/process.rs +++ b/src/libstd/old_io/process.rs @@ -11,6 +11,9 @@ //! Bindings for executing child processes #![allow(non_upper_case_globals)] +#![unstable(feature = "old_io")] +#![deprecated(since = "1.0.0", + reason = "replaced with the std::process module")] pub use self::StdioContainer::*; pub use self::ProcessExit::*; diff --git a/src/libstd/old_io/util.rs b/src/libstd/old_io/util.rs index 5283b28e20db7..4faf8af57b4c4 100644 --- a/src/libstd/old_io/util.rs +++ b/src/libstd/old_io/util.rs @@ -10,6 +10,8 @@ //! Utility implementations of Reader and Writer +#![allow(deprecated)] + use prelude::v1::*; use cmp; use old_io; @@ -17,13 +19,19 @@ use slice::bytes::MutableByteVector; /// Wraps a `Reader`, limiting the number of bytes that can be read from it. #[derive(Debug)] +#[deprecated(since = "1.0.0", reason = "use std::io::Take")] +#[unstable(feature = "old_io")] pub struct LimitReader { limit: uint, inner: R } +#[deprecated(since = "1.0.0", reason = "use std::io::Take")] +#[unstable(feature = "old_io")] impl LimitReader { /// Creates a new `LimitReader` + #[deprecated(since = "1.0.0", reason = "use std::io's take method instead")] + #[unstable(feature = "old_io")] pub fn new(r: R, limit: uint) -> LimitReader { LimitReader { limit: limit, inner: r } } @@ -41,6 +49,8 @@ impl LimitReader { pub fn limit(&self) -> uint { self.limit } } +#[deprecated(since = "1.0.0", reason = "use std::io's take method instead")] +#[unstable(feature = "old_io")] impl Reader for LimitReader { fn read(&mut self, buf: &mut [u8]) -> old_io::IoResult { if self.limit == 0 { @@ -57,6 +67,8 @@ impl Reader for LimitReader { } } +#[deprecated(since = "1.0.0", reason = "use std::io's take method instead")] +#[unstable(feature = "old_io")] impl Buffer for LimitReader { fn fill_buf<'a>(&'a mut self) -> old_io::IoResult<&'a [u8]> { let amt = try!(self.inner.fill_buf()); @@ -79,8 +91,12 @@ impl Buffer for LimitReader { /// A `Writer` which ignores bytes written to it, like /dev/null. #[derive(Copy, Debug)] +#[deprecated(since = "1.0.0", reason = "use std::io::sink() instead")] +#[unstable(feature = "old_io")] pub struct NullWriter; +#[deprecated(since = "1.0.0", reason = "use std::io::sink() instead")] +#[unstable(feature = "old_io")] impl Writer for NullWriter { #[inline] fn write_all(&mut self, _buf: &[u8]) -> old_io::IoResult<()> { Ok(()) } @@ -88,8 +104,12 @@ impl Writer for NullWriter { /// A `Reader` which returns an infinite stream of 0 bytes, like /dev/zero. #[derive(Copy, Debug)] +#[deprecated(since = "1.0.0", reason = "use std::io::repeat(0) instead")] +#[unstable(feature = "old_io")] pub struct ZeroReader; +#[deprecated(since = "1.0.0", reason = "use std::io::repeat(0) instead")] +#[unstable(feature = "old_io")] impl Reader for ZeroReader { #[inline] fn read(&mut self, buf: &mut [u8]) -> old_io::IoResult { @@ -98,6 +118,8 @@ impl Reader for ZeroReader { } } +#[deprecated(since = "1.0.0", reason = "use std::io::repeat(0) instead")] +#[unstable(feature = "old_io")] impl Buffer for ZeroReader { fn fill_buf<'a>(&'a mut self) -> old_io::IoResult<&'a [u8]> { static DATA: [u8; 64] = [0; 64]; @@ -109,8 +131,12 @@ impl Buffer for ZeroReader { /// A `Reader` which is always at EOF, like /dev/null. #[derive(Copy, Debug)] +#[deprecated(since = "1.0.0", reason = "use std::io::empty() instead")] +#[unstable(feature = "old_io")] pub struct NullReader; +#[deprecated(since = "1.0.0", reason = "use std::io::empty() instead")] +#[unstable(feature = "old_io")] impl Reader for NullReader { #[inline] fn read(&mut self, _buf: &mut [u8]) -> old_io::IoResult { @@ -118,6 +144,8 @@ impl Reader for NullReader { } } +#[deprecated(since = "1.0.0", reason = "use std::io::empty() instead")] +#[unstable(feature = "old_io")] impl Buffer for NullReader { fn fill_buf<'a>(&'a mut self) -> old_io::IoResult<&'a [u8]> { Err(old_io::standard_error(old_io::EndOfFile)) @@ -130,17 +158,23 @@ impl Buffer for NullReader { /// The `Writer`s are delegated to in order. If any `Writer` returns an error, /// that error is returned immediately and remaining `Writer`s are not called. #[derive(Debug)] +#[deprecated(since = "1.0.0", reason = "use std::io::Broadcast instead")] +#[unstable(feature = "old_io")] pub struct MultiWriter { writers: Vec } impl MultiWriter where W: Writer { /// Creates a new `MultiWriter` + #[deprecated(since = "1.0.0", reason = "use std::io's broadcast method instead")] + #[unstable(feature = "old_io")] pub fn new(writers: Vec) -> MultiWriter { MultiWriter { writers: writers } } } +#[deprecated(since = "1.0.0", reason = "use std::io::Broadcast instead")] +#[unstable(feature = "old_io")] impl Writer for MultiWriter where W: Writer { #[inline] fn write_all(&mut self, buf: &[u8]) -> old_io::IoResult<()> { @@ -162,6 +196,8 @@ impl Writer for MultiWriter where W: Writer { /// A `Reader` which chains input from multiple `Reader`s, reading each to /// completion before moving onto the next. #[derive(Clone, Debug)] +#[deprecated(since = "1.0.0", reason = "use std::io::Chain instead")] +#[unstable(feature = "old_io")] pub struct ChainedReader { readers: I, cur_reader: Option, @@ -169,12 +205,16 @@ pub struct ChainedReader { impl> ChainedReader { /// Creates a new `ChainedReader` + #[deprecated(since = "1.0.0", reason = "use std::io's chain method instead")] + #[unstable(feature = "old_io")] pub fn new(mut readers: I) -> ChainedReader { let r = readers.next(); ChainedReader { readers: readers, cur_reader: r } } } +#[deprecated(since = "1.0.0", reason = "use std::io::Chain instead")] +#[unstable(feature = "old_io")] impl> Reader for ChainedReader { fn read(&mut self, buf: &mut [u8]) -> old_io::IoResult { loop { @@ -201,13 +241,19 @@ impl> Reader for ChainedReader { /// A `Reader` which forwards input from another `Reader`, passing it along to /// a `Writer` as well. Similar to the `tee(1)` command. #[derive(Debug)] +#[deprecated(since = "1.0.0", reason = "use std::io::Tee instead")] +#[unstable(feature = "old_io")] pub struct TeeReader { reader: R, writer: W, } +#[deprecated(since = "1.0.0", reason = "use std::io::Tee instead")] +#[unstable(feature = "old_io")] impl TeeReader { /// Creates a new `TeeReader` + #[deprecated(since = "1.0.0", reason = "use std::io's tee method instead")] + #[unstable(feature = "old_io")] pub fn new(r: R, w: W) -> TeeReader { TeeReader { reader: r, writer: w } } @@ -220,6 +266,8 @@ impl TeeReader { } } +#[deprecated(since = "1.0.0", reason = "use std::io::Tee instead")] +#[unstable(feature = "old_io")] impl Reader for TeeReader { fn read(&mut self, buf: &mut [u8]) -> old_io::IoResult { self.reader.read(buf).and_then(|len| { @@ -229,6 +277,8 @@ impl Reader for TeeReader { } /// Copies all data from a `Reader` to a `Writer`. +#[deprecated(since = "1.0.0", reason = "use std::io's copy function instead")] +#[unstable(feature = "old_io")] pub fn copy(r: &mut R, w: &mut W) -> old_io::IoResult<()> { let mut buf = [0; super::DEFAULT_BUF_SIZE]; loop { diff --git a/src/libstd/path.rs b/src/libstd/path.rs old mode 100755 new mode 100644 index b85a0dcec8180..ad8e17fed24c2 --- a/src/libstd/path.rs +++ b/src/libstd/path.rs @@ -90,7 +90,7 @@ //! * Repeated separators are ignored: `a/b` and `a//b` both have components `a` //! and `b`. //! -//! * Paths ending in a separator are treated as if they has a current directory +//! * Paths ending in a separator are treated as if they have a current directory //! component at the end (or, in verbatim paths, an empty component). For //! example, while `a/b` has components `a` and `b`, the paths `a/b/` and //! `a/b/.` both have components `a`, `b`, and `.` (current directory). The @@ -872,10 +872,10 @@ impl PathBuf { // `path` is a pure relative path } else if need_sep { - self.inner.push_os_str(OsStr::from_str(MAIN_SEP_STR)); + self.inner.push(MAIN_SEP_STR); } - self.inner.push_os_str(path.as_os_str()); + self.inner.push(path); } /// Truncate `self` to `self.parent()`. @@ -937,8 +937,8 @@ impl PathBuf { let extension = extension.as_os_str(); if os_str_as_u8_slice(extension).len() > 0 { - stem.push_os_str(OsStr::from_str(".")); - stem.push_os_str(extension.as_os_str()); + stem.push("."); + stem.push(extension); } self.set_file_name(&stem); @@ -1193,7 +1193,7 @@ impl Path { iter_after(self.components(), base.as_path().components()).is_some() } - /// Determines whether `base` is a suffix of `self`. + /// Determines whether `child` is a suffix of `self`. pub fn ends_with(&self, child: &P) -> bool where P: AsPath { iter_after(self.components().rev(), child.as_path().components().rev()).is_some() } diff --git a/src/libstd/sys/common/net.rs b/src/libstd/sys/common/net.rs index 228362e3d62ae..344645dfc1a15 100644 --- a/src/libstd/sys/common/net.rs +++ b/src/libstd/sys/common/net.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![allow(deprecated)] + use prelude::v1::*; use self::SocketStatus::*; use self::InAddr::*; diff --git a/src/libstd/sys/unix/ext.rs b/src/libstd/sys/unix/ext.rs index 45042d6f03255..ca7f7c4c0ca44 100644 --- a/src/libstd/sys/unix/ext.rs +++ b/src/libstd/sys/unix/ext.rs @@ -73,42 +73,49 @@ impl AsRawFd for old_io::pipe::PipeStream { } } +#[allow(deprecated)] impl AsRawFd for old_io::net::pipe::UnixStream { fn as_raw_fd(&self) -> Fd { self.as_inner().fd() } } +#[allow(deprecated)] impl AsRawFd for old_io::net::pipe::UnixListener { fn as_raw_fd(&self) -> Fd { self.as_inner().fd() } } +#[allow(deprecated)] impl AsRawFd for old_io::net::pipe::UnixAcceptor { fn as_raw_fd(&self) -> Fd { self.as_inner().fd() } } +#[allow(deprecated)] impl AsRawFd for old_io::net::tcp::TcpStream { fn as_raw_fd(&self) -> Fd { self.as_inner().fd() } } +#[allow(deprecated)] impl AsRawFd for old_io::net::tcp::TcpListener { fn as_raw_fd(&self) -> Fd { self.as_inner().fd() } } +#[allow(deprecated)] impl AsRawFd for old_io::net::tcp::TcpAcceptor { fn as_raw_fd(&self) -> Fd { self.as_inner().fd() } } +#[allow(deprecated)] impl AsRawFd for old_io::net::udp::UdpSocket { fn as_raw_fd(&self) -> Fd { self.as_inner().fd() diff --git a/src/libstd/sys/unix/process.rs b/src/libstd/sys/unix/process.rs index 68c5c65e7cdb1..62a1799de94c9 100644 --- a/src/libstd/sys/unix/process.rs +++ b/src/libstd/sys/unix/process.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![allow(deprecated)] + use prelude::v1::*; use self::Req::*; diff --git a/src/libstd/sys/unix/tcp.rs b/src/libstd/sys/unix/tcp.rs index b08f6ef9b9032..4fcaf504c3da5 100644 --- a/src/libstd/sys/unix/tcp.rs +++ b/src/libstd/sys/unix/tcp.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![allow(deprecated)] + use prelude::v1::*; use old_io::net::ip; diff --git a/src/libstd/sys/windows/ext.rs b/src/libstd/sys/windows/ext.rs index df18b404f5fe9..b30aec0843927 100644 --- a/src/libstd/sys/windows/ext.rs +++ b/src/libstd/sys/windows/ext.rs @@ -58,18 +58,21 @@ impl AsRawHandle for old_io::pipe::PipeStream { } } +#[allow(deprecated)] impl AsRawHandle for old_io::net::pipe::UnixStream { fn as_raw_handle(&self) -> Handle { self.as_inner().handle() } } +#[allow(deprecated)] impl AsRawHandle for old_io::net::pipe::UnixListener { fn as_raw_handle(&self) -> Handle { self.as_inner().handle() } } +#[allow(deprecated)] impl AsRawHandle for old_io::net::pipe::UnixAcceptor { fn as_raw_handle(&self) -> Handle { self.as_inner().handle() @@ -81,24 +84,28 @@ pub trait AsRawSocket { fn as_raw_socket(&self) -> Socket; } +#[allow(deprecated)] impl AsRawSocket for old_io::net::tcp::TcpStream { fn as_raw_socket(&self) -> Socket { self.as_inner().fd() } } +#[allow(deprecated)] impl AsRawSocket for old_io::net::tcp::TcpListener { fn as_raw_socket(&self) -> Socket { self.as_inner().socket() } } +#[allow(deprecated)] impl AsRawSocket for old_io::net::tcp::TcpAcceptor { fn as_raw_socket(&self) -> Socket { self.as_inner().socket() } } +#[allow(deprecated)] impl AsRawSocket for old_io::net::udp::UdpSocket { fn as_raw_socket(&self) -> Socket { self.as_inner().fd() diff --git a/src/libstd/sys/windows/process.rs b/src/libstd/sys/windows/process.rs index 53a037ef07e61..ca3ed54eb036a 100644 --- a/src/libstd/sys/windows/process.rs +++ b/src/libstd/sys/windows/process.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![allow(deprecated)] + use prelude::v1::*; use collections; diff --git a/src/libstd/sys/windows/tcp.rs b/src/libstd/sys/windows/tcp.rs index 25b70918591d0..8547de145f8c4 100644 --- a/src/libstd/sys/windows/tcp.rs +++ b/src/libstd/sys/windows/tcp.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![allow(deprecated)] + use old_io::net::ip; use old_io::IoResult; use libc; diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs index 7bd9cc3b85515..ba3f495cdaced 100644 --- a/src/libsyntax/lib.rs +++ b/src/libsyntax/lib.rs @@ -14,6 +14,8 @@ //! //! This API is completely unstable and subject to change. +// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364) +#![cfg_attr(stage0, feature(custom_attribute))] #![crate_name = "syntax"] #![unstable(feature = "rustc_private")] #![staged_api] @@ -37,8 +39,8 @@ #![feature(std_misc)] #![feature(unicode)] #![feature(path)] -#![feature(fs)] #![feature(io)] +#![feature(path_ext)] extern crate arena; extern crate fmt_macros; diff --git a/src/libterm/lib.rs b/src/libterm/lib.rs index d3f2319681741..1dad5d0909263 100644 --- a/src/libterm/lib.rs +++ b/src/libterm/lib.rs @@ -38,6 +38,8 @@ //! [win]: http://msdn.microsoft.com/en-us/library/windows/desktop/ms682010%28v=vs.85%29.aspx //! [ti]: https://en.wikipedia.org/wiki/Terminfo +// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364) +#![cfg_attr(stage0, feature(custom_attribute))] #![crate_name = "term"] #![unstable(feature = "rustc_private", reason = "use the crates.io `term` library instead")] @@ -52,7 +54,6 @@ #![feature(box_syntax)] #![feature(collections)] -#![feature(fs)] #![feature(int_uint)] #![feature(io)] #![feature(old_io)] @@ -61,6 +62,7 @@ #![feature(staged_api)] #![feature(std_misc)] #![feature(unicode)] +#![feature(path_ext)] #![cfg_attr(windows, feature(libc))] #[macro_use] extern crate log; diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs index a855d80f42a40..44aaeec6145e5 100644 --- a/src/libtest/lib.rs +++ b/src/libtest/lib.rs @@ -23,6 +23,8 @@ // running tests while providing a base that other test frameworks may // build off of. +// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364) +#![cfg_attr(stage0, feature(custom_attribute))] #![crate_name = "test"] #![unstable(feature = "test")] #![staged_api] @@ -39,7 +41,6 @@ #![feature(int_uint)] #![feature(old_io)] #![feature(path)] -#![feature(fs)] #![feature(rustc_private)] #![feature(staged_api)] #![feature(std_misc)] diff --git a/src/libunicode/lib.rs b/src/libunicode/lib.rs index 791886be1ce5b..2095b6921c840 100644 --- a/src/libunicode/lib.rs +++ b/src/libunicode/lib.rs @@ -20,6 +20,8 @@ //! provide for basic string-related manipulations. This crate does not //! (yet) aim to provide a full set of Unicode tables. +// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364) +#![cfg_attr(stage0, feature(custom_attribute))] #![crate_name = "unicode"] #![unstable(feature = "unicode")] #![feature(staged_api)] diff --git a/src/rustbook/build.rs b/src/rustbook/build.rs index 1fb30e15400ef..731773917e091 100644 --- a/src/rustbook/build.rs +++ b/src/rustbook/build.rs @@ -11,10 +11,11 @@ //! Implementation of the `build` subcommand, used to compile a book. use std::env; -use std::fs::{self, File, TempDir}; +use std::fs::{self, File}; use std::io::prelude::*; use std::io::{self, BufWriter}; use std::path::{Path, PathBuf}; +use rustc_back::tempdir::TempDir; use subcommand::Subcommand; use term::Term; diff --git a/src/rustbook/main.rs b/src/rustbook/main.rs index 848f960839e6e..8df622b0b5d0c 100644 --- a/src/rustbook/main.rs +++ b/src/rustbook/main.rs @@ -12,14 +12,14 @@ #![feature(core)] #![feature(exit_status)] -#![feature(fs)] #![feature(io)] #![feature(old_io)] #![feature(path)] #![feature(rustdoc)] -#![feature(tempdir)] +#![feature(rustc_private)] extern crate rustdoc; +extern crate rustc_back; use std::env; use std::error::Error; diff --git a/src/test/auxiliary/lint_output_format.rs b/src/test/auxiliary/lint_output_format.rs old mode 100755 new mode 100644 diff --git a/src/test/compile-fail/issue-23080-2.rs b/src/test/compile-fail/issue-23080-2.rs new file mode 100644 index 0000000000000..ff5ac9de8d944 --- /dev/null +++ b/src/test/compile-fail/issue-23080-2.rs @@ -0,0 +1,29 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// ignore-tidy-linelength + +#![feature(optin_builtin_traits)] + +use std::marker::MarkerTrait; + +unsafe trait Trait: MarkerTrait { +//~^ error: traits with default impls (`e.g. unsafe impl Trait for ..`) must have no methods or associated items + type Output; +} + +unsafe impl Trait for .. {} + +fn call_method(x: T) {} + +fn main() { + // ICE + call_method(()); +} diff --git a/src/test/compile-fail/issue-23080.rs b/src/test/compile-fail/issue-23080.rs new file mode 100644 index 0000000000000..99373a69697ae --- /dev/null +++ b/src/test/compile-fail/issue-23080.rs @@ -0,0 +1,31 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// ignore-tidy-linelength + +#![feature(optin_builtin_traits)] + +unsafe trait Trait { +//~^ error: traits with default impls (`e.g. unsafe impl Trait for ..`) must have no methods or associated items + fn method(&self) { + println!("Hello"); + } +} + +unsafe impl Trait for .. {} + +fn call_method(x: T) { + x.method(); +} + +fn main() { + // ICE + call_method(()); +} diff --git a/src/test/compile-fail/phantom-oibit.rs b/src/test/compile-fail/phantom-oibit.rs new file mode 100644 index 0000000000000..c912d084daa86 --- /dev/null +++ b/src/test/compile-fail/phantom-oibit.rs @@ -0,0 +1,41 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Ensure that OIBIT checks `T` when it encounters a `PhantomData` field, instead of checking +// the `PhantomData` type itself (which almost always implements a "default" trait +// (`impl Trait for ..`)) + +#![feature(optin_builtin_traits)] + +use std::marker::{MarkerTrait, PhantomData}; + +unsafe trait Zen: MarkerTrait {} + +unsafe impl Zen for .. {} + +unsafe impl<'a, T: 'a> Zen for &'a T where T: Sync {} + +struct Guard<'a, T: 'a> { + _marker: PhantomData<&'a T>, +} + +struct Nested(T); + +fn is_zen(_: T) {} + +fn not_sync(x: Guard) { + is_zen(x) //~ error: the trait `core::marker::Sync` is not implemented for the type `T` +} + +fn nested_not_sync(x: Nested>) { + is_zen(x) //~ error: the trait `core::marker::Sync` is not implemented for the type `T` +} + +fn main() {} diff --git a/src/test/compile-fail/privacy5.rs b/src/test/compile-fail/privacy5.rs index df570fd464792..a7f6a514b96af 100644 --- a/src/test/compile-fail/privacy5.rs +++ b/src/test/compile-fail/privacy5.rs @@ -9,7 +9,6 @@ // except according to those terms. // aux-build:privacy-tuple-struct.rs -// ignore-fast extern crate "privacy-tuple-struct" as other; diff --git a/src/test/compile-fail/send-is-not-static-ensures-scoping.rs b/src/test/compile-fail/send-is-not-static-ensures-scoping.rs old mode 100755 new mode 100644 diff --git a/src/test/debuginfo/constant-debug-locs.rs b/src/test/debuginfo/constant-debug-locs.rs new file mode 100644 index 0000000000000..24332e3177508 --- /dev/null +++ b/src/test/debuginfo/constant-debug-locs.rs @@ -0,0 +1,67 @@ +// Copyright 2013-2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// ignore-android: FIXME(#10381) +// min-lldb-version: 310 + +// compile-flags:-g + +#![allow(unused_variables)] +#![allow(dead_code)] +#![omit_gdb_pretty_printer_section] + +// This test makes sure that the compiler doesn't crash when trying to assign +// debug locations to const-expressions. + +use std::sync::MUTEX_INIT; +use std::cell::UnsafeCell; + +const CONSTANT: u64 = 3 + 4; + +struct Struct { + a: isize, + b: usize, +} +const STRUCT: Struct = Struct { a: 1, b: 2 }; + +struct TupleStruct(u32); +const TUPLE_STRUCT: TupleStruct = TupleStruct(4); + +enum Enum { + Variant1(char), + Variant2 { a: u8 }, + Variant3 +} + +const VARIANT1: Enum = Enum::Variant1('v'); +const VARIANT2: Enum = Enum::Variant2 { a: 2 }; +const VARIANT3: Enum = Enum::Variant3; + +const STRING: &'static str = "String"; + +const VEC: [u32; 8] = [0; 8]; + +const NESTED: (Struct, TupleStruct) = (STRUCT, TUPLE_STRUCT); + +const UNSAFE_CELL: UnsafeCell = UnsafeCell { value: false }; + +fn main() { + let mut _constant = CONSTANT; + let mut _struct = STRUCT; + let mut _tuple_struct = TUPLE_STRUCT; + let mut _variant1 = VARIANT1; + let mut _variant2 = VARIANT2; + let mut _variant3 = VARIANT3; + let mut _string = STRING; + let mut _vec = VEC; + let mut _nested = NESTED; + let mut _extern = MUTEX_INIT; + let mut _unsafe_cell = UNSAFE_CELL; +} diff --git a/src/test/debuginfo/extern-c-fn.rs b/src/test/debuginfo/extern-c-fn.rs new file mode 100644 index 0000000000000..9e73417e7de74 --- /dev/null +++ b/src/test/debuginfo/extern-c-fn.rs @@ -0,0 +1,68 @@ +// Copyright 2013-2014 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. + +// min-lldb-version: 310 + +// compile-flags:-g + +// === GDB TESTS =================================================================================== +// gdb-command:run + +// gdb-command:print s +// gdb-check:$1 = [...]"abcd" +// gdb-command:print len +// gdb-check:$2 = 20 +// gdb-command:print local0 +// gdb-check:$3 = 19 +// gdb-command:print local1 +// gdb-check:$4 = true +// gdb-command:print local2 +// gdb-check:$5 = 20.5 + +// gdb-command:continue + +// === LLDB TESTS ================================================================================== +// lldb-command:run + +// lldb-command:print len +// lldb-check:[...]$0 = 20 +// lldb-command:print local0 +// lldb-check:[...]$1 = 19 +// lldb-command:print local1 +// lldb-check:[...]$2 = true +// lldb-command:print local2 +// lldb-check:[...]$3 = 20.5 + +// lldb-command:continue + +#![allow(unused_variables)] +#![allow(dead_code)] +#![omit_gdb_pretty_printer_section] + + +#[no_mangle] +pub unsafe extern "C" fn fn_with_c_abi(s: *const u8, len: i32) -> i32 { + let local0 = len - 1; + let local1 = len > 2; + let local2 = (len as f64) + 0.5; + + zzz(); // #break + + return 0; +} + +fn main() { + unsafe { + fn_with_c_abi(b"abcd\0".as_ptr(), 20); + } +} + +#[inline(never)] +fn zzz() {()} diff --git a/src/test/run-fail/overflowing-add.rs b/src/test/run-fail/overflowing-add.rs index 34a03e5f0080d..cd13b817c2b8c 100644 --- a/src/test/run-fail/overflowing-add.rs +++ b/src/test/run-fail/overflowing-add.rs @@ -9,6 +9,7 @@ // except according to those terms. // error-pattern:thread '
' panicked at 'arithmetic operation overflowed' +// compile-flags: -C debug-assertions // (Work around constant-evaluation) fn value() -> u8 { 200 } diff --git a/src/test/run-fail/overflowing-mul.rs b/src/test/run-fail/overflowing-mul.rs index b18d99cd232e8..5d2f53962406c 100644 --- a/src/test/run-fail/overflowing-mul.rs +++ b/src/test/run-fail/overflowing-mul.rs @@ -9,6 +9,7 @@ // except according to those terms. // error-pattern:thread '
' panicked at 'arithmetic operation overflowed' +// compile-flags: -C debug-assertions // (Work around constant-evaluation) fn value() -> u8 { 200 } diff --git a/src/test/run-fail/overflowing-sub.rs b/src/test/run-fail/overflowing-sub.rs index ee32291eca6b2..b089dccbaa52f 100644 --- a/src/test/run-fail/overflowing-sub.rs +++ b/src/test/run-fail/overflowing-sub.rs @@ -9,6 +9,7 @@ // except according to those terms. // error-pattern:thread '
' panicked at 'arithmetic operation overflowed' +// compile-flags: -C debug-assertions // (Work around constant-evaluation) fn value() -> u8 { 42 } diff --git a/src/test/run-make/debug-assertions/Makefile b/src/test/run-make/debug-assertions/Makefile new file mode 100644 index 0000000000000..7129756276864 --- /dev/null +++ b/src/test/run-make/debug-assertions/Makefile @@ -0,0 +1,21 @@ +-include ../tools.mk + +all: + $(RUSTC) debug.rs -C debug-assertions=no + $(call RUN,debug) good + $(RUSTC) debug.rs -C opt-level=0 + $(call RUN,debug) bad + $(RUSTC) debug.rs -C opt-level=1 + $(call RUN,debug) good + $(RUSTC) debug.rs -C opt-level=2 + $(call RUN,debug) good + $(RUSTC) debug.rs -C opt-level=3 + $(call RUN,debug) good + $(RUSTC) debug.rs -O + $(call RUN,debug) good + $(RUSTC) debug.rs + $(call RUN,debug) bad + $(RUSTC) debug.rs -C debug-assertions=yes -O + $(call RUN,debug) bad + $(RUSTC) debug.rs -C debug-assertions=yes -C opt-level=1 + $(call RUN,debug) bad diff --git a/src/test/run-make/debug-assertions/debug.rs b/src/test/run-make/debug-assertions/debug.rs new file mode 100644 index 0000000000000..a0ccc75afd05b --- /dev/null +++ b/src/test/run-make/debug-assertions/debug.rs @@ -0,0 +1,42 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![deny(warnings)] + +use std::env; +use std::thread; + +fn main() { + let should_fail = env::args().nth(1) == Some("bad".to_string()); + + assert_eq!(thread::spawn(debug_assert_eq).join().is_err(), should_fail); + assert_eq!(thread::spawn(debug_assert).join().is_err(), should_fail); + assert_eq!(thread::spawn(overflow).join().is_err(), should_fail); +} + +fn debug_assert_eq() { + let mut hit1 = false; + let mut hit2 = false; + debug_assert_eq!({ hit1 = true; 1 }, { hit2 = true; 2 }); + assert!(!hit1); + assert!(!hit2); +} + +fn debug_assert() { + let mut hit = false; + debug_assert!({ hit = true; false }); + assert!(!hit); +} + +fn overflow() { + fn add(a: u8, b: u8) -> u8 { a + b } + + add(200u8, 200u8); +} diff --git a/src/test/run-make/mismatching-target-triples/bar.rs b/src/test/run-make/mismatching-target-triples/bar.rs old mode 100755 new mode 100644 diff --git a/src/test/run-make/mismatching-target-triples/foo.rs b/src/test/run-make/mismatching-target-triples/foo.rs old mode 100755 new mode 100644 diff --git a/src/test/run-make/pretty-expanded-hygiene/input.pp.rs b/src/test/run-make/pretty-expanded-hygiene/input.pp.rs old mode 100755 new mode 100644 diff --git a/src/test/run-make/pretty-expanded-hygiene/input.rs b/src/test/run-make/pretty-expanded-hygiene/input.rs old mode 100755 new mode 100644 diff --git a/src/test/run-make/simd-ffi/simd.rs b/src/test/run-make/simd-ffi/simd.rs old mode 100755 new mode 100644 diff --git a/src/test/run-pass/c-stack-returning-int64.rs b/src/test/run-pass/c-stack-returning-int64.rs index 6246ee9c6c41a..1de7520d2b1d0 100644 --- a/src/test/run-pass/c-stack-returning-int64.rs +++ b/src/test/run-pass/c-stack-returning-int64.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// ignore-fast doesn't like extern crate extern crate libc; diff --git a/src/test/run-pass/conditional-debug-macro-off.rs b/src/test/run-pass/conditional-debug-macro-off.rs index b5a5f57d07abd..90142350772b8 100644 --- a/src/test/run-pass/conditional-debug-macro-off.rs +++ b/src/test/run-pass/conditional-debug-macro-off.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// compile-flags: --cfg ndebug +// compile-flags: -C debug-assertions=no // exec-env:RUST_LOG=conditional-debug-macro-off=4 #[macro_use] diff --git a/src/test/run-pass/extern-stress.rs b/src/test/run-pass/extern-stress.rs deleted file mode 100644 index b9e08e47b378d..0000000000000 --- a/src/test/run-pass/extern-stress.rs +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright 2012 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. - -// This creates a bunch of descheduling tasks that run concurrently -// while holding onto C stacks - -extern crate libc; -use std::thread::Thread; - -mod rustrt { - extern crate libc; - - #[link(name = "rust_test_helpers")] - extern { - pub fn rust_dbg_call(cb: extern "C" fn(libc::uintptr_t) -> libc::uintptr_t, - data: libc::uintptr_t) - -> libc::uintptr_t; - } -} - -extern fn cb(data: libc::uintptr_t) -> libc::uintptr_t { - if data == 1 { - data - } else { - Thread::yield_now(); - count(data - 1) + count(data - 1) - } -} - -fn count(n: libc::uintptr_t) -> libc::uintptr_t { - unsafe { - rustrt::rust_dbg_call(cb, n) - } -} - -pub fn main() { - (0_usize..100).map(|_| { - Thread::scoped(move|| { - assert_eq!(count(5), 16); - }) - }).collect::>(); -} diff --git a/src/test/run-pass/extern-yield.rs b/src/test/run-pass/extern-yield.rs deleted file mode 100644 index 80428d787f21c..0000000000000 --- a/src/test/run-pass/extern-yield.rs +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -extern crate libc; -use std::thread::Thread; - -mod rustrt { - extern crate libc; - - #[link(name = "rust_test_helpers")] - extern { - pub fn rust_dbg_call(cb: extern "C" fn (libc::uintptr_t) -> libc::uintptr_t, - data: libc::uintptr_t) - -> libc::uintptr_t; - } -} - -extern fn cb(data: libc::uintptr_t) -> libc::uintptr_t { - if data == 1 { - data - } else { - count(data - 1) + count(data - 1) - } -} - -fn count(n: libc::uintptr_t) -> libc::uintptr_t { - unsafe { - Thread::yield_now(); - rustrt::rust_dbg_call(cb, n) - } -} - -pub fn main() { - (0..10_usize).map(|i| { - Thread::scoped(move|| { - let result = count(5); - println!("result = {}", result); - assert_eq!(result, 16); - }) - }).collect::>(); -} diff --git a/src/test/run-pass/foreign-fn-linkname.rs b/src/test/run-pass/foreign-fn-linkname.rs index 1c36ad73238c8..172ece0c4bfd9 100644 --- a/src/test/run-pass/foreign-fn-linkname.rs +++ b/src/test/run-pass/foreign-fn-linkname.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// ignore-fast doesn't like extern crate extern crate libc; use std::ffi::CString; diff --git a/src/test/run-pass/foreign-mod-unused-const.rs b/src/test/run-pass/foreign-mod-unused-const.rs index e1ed0b8ea3b0c..03023f032335f 100644 --- a/src/test/run-pass/foreign-mod-unused-const.rs +++ b/src/test/run-pass/foreign-mod-unused-const.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// ignore-fast doesn't like extern crate extern crate libc; diff --git a/src/test/run-pass/foreign2.rs b/src/test/run-pass/foreign2.rs index ce2f895566439..5ebc4effb3718 100644 --- a/src/test/run-pass/foreign2.rs +++ b/src/test/run-pass/foreign2.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// ignore-fast doesn't like extern crate extern crate libc; diff --git a/src/test/run-pass/issue-4735.rs b/src/test/run-pass/issue-4735.rs index bf422bd0405a1..196e9748b1073 100644 --- a/src/test/run-pass/issue-4735.rs +++ b/src/test/run-pass/issue-4735.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// ignore-fast doesn't like extern crate #![allow(unknown_features)] #![feature(box_syntax)] diff --git a/src/test/run-pass/lint-cstack.rs b/src/test/run-pass/iter-cloned-type-inference.rs similarity index 51% rename from src/test/run-pass/lint-cstack.rs rename to src/test/run-pass/iter-cloned-type-inference.rs index f180ffcd4e823..6ce226bbecac2 100644 --- a/src/test/run-pass/lint-cstack.rs +++ b/src/test/run-pass/iter-cloned-type-inference.rs @@ -1,4 +1,4 @@ -// Copyright 2013 The Rust Project Developers. See the COPYRIGHT +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -8,19 +8,18 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -extern crate libc; +// Test to see that the element type of .cloned() can be inferred +// properly. Previously this would fail to deduce the type of `sum`. -extern { - fn rust_get_test_int() -> libc::intptr_t; -} +#![feature(core)] + +use std::iter::AdditiveIterator; -trait A { - fn foo(&self) { - unsafe { - rust_get_test_int(); - } - } +fn square_sum(v: &[i64]) -> i64 { + let sum = v.iter().cloned().sum(); + sum * sum } -pub fn main() { +fn main() { + assert_eq!(36, square_sum(&[1,2,3])); } diff --git a/src/test/run-pass/logging-enabled-debug.rs b/src/test/run-pass/logging-enabled-debug.rs index 262d9b21eb48b..dfc9272827066 100644 --- a/src/test/run-pass/logging-enabled-debug.rs +++ b/src/test/run-pass/logging-enabled-debug.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// compile-flags:--cfg ndebug +// compile-flags:-C debug-assertions=no // exec-env:RUST_LOG=logging-enabled-debug=debug #[macro_use] diff --git a/src/test/run-pass/logging-separate-lines.rs b/src/test/run-pass/logging-separate-lines.rs index 8526dfe72da13..82a155b117301 100644 --- a/src/test/run-pass/logging-separate-lines.rs +++ b/src/test/run-pass/logging-separate-lines.rs @@ -10,6 +10,7 @@ // ignore-windows // exec-env:RUST_LOG=debug +// compile-flags:-C debug-assertions=y #[macro_use] extern crate log; diff --git a/src/test/run-pass/newtype-struct-with-dtor.rs b/src/test/run-pass/newtype-struct-with-dtor.rs index 8631755f37fd9..15c4e8b045339 100644 --- a/src/test/run-pass/newtype-struct-with-dtor.rs +++ b/src/test/run-pass/newtype-struct-with-dtor.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// ignore-fast doesn't like extern crate extern crate libc; use libc::c_int; diff --git a/src/test/run-pass/send-is-not-static-par-for.rs b/src/test/run-pass/send-is-not-static-par-for.rs old mode 100755 new mode 100644 diff --git a/src/test/run-pass/variadic-ffi.rs b/src/test/run-pass/variadic-ffi.rs index 5a476ed9ee2f8..b3fff6977a545 100644 --- a/src/test/run-pass/variadic-ffi.rs +++ b/src/test/run-pass/variadic-ffi.rs @@ -13,7 +13,6 @@ extern crate libc; use std::ffi::{self, CString}; use libc::{c_char, c_int}; -// ignore-fast doesn't like extern crate extern { fn sprintf(s: *mut c_char, format: *const c_char, ...) -> c_int;