1
Fork 0

Auto merge of #23107 - Manishearth:rollup, r=alexcrichton

This commit is contained in:
bors 2015-03-07 03:28:03 +00:00
commit 270a677d4d
115 changed files with 1234 additions and 401 deletions

View file

@ -18,7 +18,7 @@ CFG_RELEASE_NUM=1.0.0
# An optional number to put after the label, e.g. '.2' -> '-beta.2' # 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 # NB Make sure it starts with a dot to conform to semver pre-release
# versions (section 9) # versions (section 9)
CFG_PRERELEASE_VERSION=.2 CFG_PRERELEASE_VERSION=
CFG_FILENAME_EXTRA=4e7c5e5c CFG_FILENAME_EXTRA=4e7c5e5c
@ -30,8 +30,8 @@ CFG_PACKAGE_VERS=$(CFG_RELEASE_NUM)
CFG_DISABLE_UNSTABLE_FEATURES=1 CFG_DISABLE_UNSTABLE_FEATURES=1
endif endif
ifeq ($(CFG_RELEASE_CHANNEL),beta) ifeq ($(CFG_RELEASE_CHANNEL),beta)
CFG_RELEASE=$(CFG_RELEASE_NUM)-alpha$(CFG_PRERELEASE_VERSION) CFG_RELEASE=$(CFG_RELEASE_NUM)-beta(CFG_PRERELEASE_VERSION)
CFG_PACKAGE_VERS=$(CFG_RELEASE_NUM)-alpha$(CFG_PRERELEASE_VERSION) CFG_PACKAGE_VERS=$(CFG_RELEASE_NUM)-beta(CFG_PRERELEASE_VERSION)
CFG_DISABLE_UNSTABLE_FEATURES=1 CFG_DISABLE_UNSTABLE_FEATURES=1
endif endif
ifeq ($(CFG_RELEASE_CHANNEL),nightly) ifeq ($(CFG_RELEASE_CHANNEL),nightly)

View file

@ -590,7 +590,7 @@ TEST_SREQ$(1)_T_$(2)_H_$(3) = \
# The tests select when to use debug configuration on their own; # The tests select when to use debug configuration on their own;
# remove directive, if present, from CFG_RUSTC_FLAGS (issue #7898). # 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 # 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 # filter out the optimization (if any) from rustc and then figure out if we need

View file

@ -22,10 +22,9 @@
#![feature(unicode)] #![feature(unicode)]
#![feature(core)] #![feature(core)]
#![feature(path)] #![feature(path)]
#![feature(os)]
#![feature(io)] #![feature(io)]
#![feature(fs)]
#![feature(net)] #![feature(net)]
#![feature(path_ext)]
#![deny(warnings)] #![deny(warnings)]

View file

@ -20,7 +20,6 @@ use procsrv;
use util::logv; use util::logv;
use std::env; use std::env;
use std::ffi::OsStr;
use std::fmt; use std::fmt;
use std::fs::{self, File}; use std::fs::{self, File};
use std::io::BufReader; 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); let mut f = output_base_name(config, testfile);
if !env::consts::EXE_SUFFIX.is_empty() { if !env::consts::EXE_SUFFIX.is_empty() {
let mut fname = f.file_name().unwrap().to_os_string(); 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.set_file_name(&fname);
} }
f 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 { fn aux_output_dir_name(config: &Config, testfile: &Path) -> PathBuf {
let f = output_base_name(config, testfile); let f = output_base_name(config, testfile);
let mut fname = f.file_name().unwrap().to_os_string(); 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) f.with_file_name(&fname)
} }
@ -1647,8 +1646,8 @@ fn append_suffix_to_stem(p: &Path, suffix: &str) -> PathBuf {
p.to_path_buf() p.to_path_buf()
} else { } else {
let mut stem = p.file_stem().unwrap().to_os_string(); let mut stem = p.file_stem().unwrap().to_os_string();
stem.push_os_str(OsStr::from_str("-")); stem.push("-");
stem.push_os_str(OsStr::from_str(suffix)); stem.push(suffix);
p.with_file_name(&stem) p.with_file_name(&stem)
} }
} }

View file

@ -1,4 +1,4 @@
% The (old) Rust Threads and Communication Guide % The (old) Rust Threads and Communication Guide
This content has moved into This content has moved into
[the Rust Programming Language book](book/tasks.html). [the Rust Programming Language book](book/concurrency.html).

View file

@ -60,6 +60,12 @@ let v = vec![1, 2, 3]; // v: Vec<i32>
brackets `[]` with `vec!`. Rust allows you to use either in either situation, brackets `[]` with `vec!`. Rust allows you to use either in either situation,
this is just convention.) 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 You can get the length of, iterate over, and subscript vectors just like
arrays. In addition, (mutable) vectors can grow automatically: arrays. In addition, (mutable) vectors can grow automatically:

View file

@ -56,6 +56,8 @@
//! The [`heap`](heap/index.html) module defines the low-level interface to the //! 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. //! 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"] #![crate_name = "alloc"]
#![unstable(feature = "alloc")] #![unstable(feature = "alloc")]
#![feature(staged_api)] #![feature(staged_api)]

View file

@ -19,6 +19,8 @@
//! arena but can only hold objects of a single type, and `Arena`, which is a //! 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. //! 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"] #![crate_name = "arena"]
#![unstable(feature = "rustc_private")] #![unstable(feature = "rustc_private")]
#![staged_api] #![staged_api]

View file

@ -12,7 +12,8 @@
//! //!
//! See [std::collections](../std/collections) for a detailed discussion of collections in Rust. //! 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"] #![crate_name = "collections"]
#![unstable(feature = "collections")] #![unstable(feature = "collections")]
#![staged_api] #![staged_api]

View file

@ -1086,7 +1086,7 @@ pub trait StrExt: Index<RangeFull, Output = str> {
/// ///
/// let s = "中华Việt Nam"; /// let s = "中华Việt Nam";
/// let mut i = s.len(); /// let mut i = s.len();
/// while i < 0 { /// while i > 0 {
/// let CharRange {ch, next} = s.char_range_at_reverse(i); /// let CharRange {ch, next} = s.char_range_at_reverse(i);
/// println!("{}: {}", i, ch); /// println!("{}: {}", i, ch);
/// i = next; /// i = next;

View file

@ -1279,14 +1279,14 @@ pub struct Cloned<I> {
} }
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
impl<T, D, I> Iterator for Cloned<I> where impl<I> Iterator for Cloned<I> where
T: Clone, I: Iterator,
D: Deref<Target=T>, I::Item: Deref,
I: Iterator<Item=D>, <I::Item as Deref>::Target: Clone
{ {
type Item = T; type Item = <I::Item as Deref>::Target;
fn next(&mut self) -> Option<T> { fn next(&mut self) -> Option<<Self as Iterator>::Item> {
self.it.next().cloned() self.it.next().cloned()
} }
@ -1296,28 +1296,28 @@ impl<T, D, I> Iterator for Cloned<I> where
} }
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
impl<T, D, I> DoubleEndedIterator for Cloned<I> where impl<I> DoubleEndedIterator for Cloned<I> where
T: Clone, I: DoubleEndedIterator,
D: Deref<Target=T>, I::Item: Deref,
I: DoubleEndedIterator<Item=D>, <I::Item as Deref>::Target: Clone
{ {
fn next_back(&mut self) -> Option<T> { fn next_back(&mut self) -> Option<<Self as Iterator>::Item> {
self.it.next_back().cloned() self.it.next_back().cloned()
} }
} }
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
impl<T, D, I> ExactSizeIterator for Cloned<I> where impl<I> ExactSizeIterator for Cloned<I> where
T: Clone, I: ExactSizeIterator,
D: Deref<Target=T>, I::Item: Deref,
I: ExactSizeIterator<Item=D>, <I::Item as Deref>::Target: Clone
{} {}
#[unstable(feature = "core", reason = "trait is experimental")] #[unstable(feature = "core", reason = "trait is experimental")]
impl<T, D, I> RandomAccessIterator for Cloned<I> where impl<I> RandomAccessIterator for Cloned<I> where
T: Clone, I: RandomAccessIterator,
D: Deref<Target=T>, I::Item: Deref,
I: RandomAccessIterator<Item=D> <I::Item as Deref>::Target: Clone
{ {
#[inline] #[inline]
fn indexable(&self) -> usize { fn indexable(&self) -> usize {
@ -1325,7 +1325,7 @@ impl<T, D, I> RandomAccessIterator for Cloned<I> where
} }
#[inline] #[inline]
fn idx(&mut self, index: usize) -> Option<T> { fn idx(&mut self, index: usize) -> Option<<Self as Iterator>::Item> {
self.it.idx(index).cloned() self.it.idx(index).cloned()
} }
} }
@ -1400,11 +1400,14 @@ pub struct Chain<A, B> {
} }
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
impl<T, A, B> Iterator for Chain<A, B> where A: Iterator<Item=T>, B: Iterator<Item=T> { impl<A, B> Iterator for Chain<A, B> where
type Item = T; A: Iterator,
B: Iterator<Item = A::Item>
{
type Item = A::Item;
#[inline] #[inline]
fn next(&mut self) -> Option<T> { fn next(&mut self) -> Option<A::Item> {
if self.flag { if self.flag {
self.b.next() self.b.next()
} else { } else {
@ -1434,12 +1437,12 @@ impl<T, A, B> Iterator for Chain<A, B> where A: Iterator<Item=T>, B: Iterator<It
} }
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
impl<T, A, B> DoubleEndedIterator for Chain<A, B> where impl<A, B> DoubleEndedIterator for Chain<A, B> where
A: DoubleEndedIterator<Item=T>, A: DoubleEndedIterator,
B: DoubleEndedIterator<Item=T>, B: DoubleEndedIterator<Item=A::Item>,
{ {
#[inline] #[inline]
fn next_back(&mut self) -> Option<T> { fn next_back(&mut self) -> Option<A::Item> {
match self.b.next_back() { match self.b.next_back() {
Some(x) => Some(x), Some(x) => Some(x),
None => self.a.next_back() None => self.a.next_back()
@ -1448,9 +1451,9 @@ impl<T, A, B> DoubleEndedIterator for Chain<A, B> where
} }
#[unstable(feature = "core", reason = "trait is experimental")] #[unstable(feature = "core", reason = "trait is experimental")]
impl<T, A, B> RandomAccessIterator for Chain<A, B> where impl<A, B> RandomAccessIterator for Chain<A, B> where
A: RandomAccessIterator<Item=T>, A: RandomAccessIterator,
B: RandomAccessIterator<Item=T>, B: RandomAccessIterator<Item = A::Item>,
{ {
#[inline] #[inline]
fn indexable(&self) -> usize { fn indexable(&self) -> usize {
@ -1459,7 +1462,7 @@ impl<T, A, B> RandomAccessIterator for Chain<A, B> where
} }
#[inline] #[inline]
fn idx(&mut self, index: usize) -> Option<T> { fn idx(&mut self, index: usize) -> Option<A::Item> {
let len = self.a.indexable(); let len = self.a.indexable();
if index < len { if index < len {
self.a.idx(index) self.a.idx(index)
@ -1479,14 +1482,12 @@ pub struct Zip<A, B> {
} }
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
impl<T, U, A, B> Iterator for Zip<A, B> where impl<A, B> Iterator for Zip<A, B> where A: Iterator, B: Iterator
A: Iterator<Item = T>,
B: Iterator<Item = U>,
{ {
type Item = (T, U); type Item = (A::Item, B::Item);
#[inline] #[inline]
fn next(&mut self) -> Option<(T, U)> { fn next(&mut self) -> Option<(A::Item, B::Item)> {
match self.a.next() { match self.a.next() {
None => None, None => None,
Some(x) => match self.b.next() { Some(x) => match self.b.next() {
@ -1515,12 +1516,12 @@ impl<T, U, A, B> Iterator for Zip<A, B> where
} }
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
impl<T, U, A, B> DoubleEndedIterator for Zip<A, B> where impl<A, B> DoubleEndedIterator for Zip<A, B> where
A: DoubleEndedIterator + ExactSizeIterator<Item=T>, A: DoubleEndedIterator + ExactSizeIterator,
B: DoubleEndedIterator + ExactSizeIterator<Item=U>, B: DoubleEndedIterator + ExactSizeIterator,
{ {
#[inline] #[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 a_sz = self.a.len();
let b_sz = self.b.len(); let b_sz = self.b.len();
if a_sz != b_sz { if a_sz != b_sz {
@ -1540,9 +1541,9 @@ impl<T, U, A, B> DoubleEndedIterator for Zip<A, B> where
} }
#[unstable(feature = "core", reason = "trait is experimental")] #[unstable(feature = "core", reason = "trait is experimental")]
impl<T, U, A, B> RandomAccessIterator for Zip<A, B> where impl<A, B> RandomAccessIterator for Zip<A, B> where
A: RandomAccessIterator<Item=T>, A: RandomAccessIterator,
B: RandomAccessIterator<Item=U>, B: RandomAccessIterator
{ {
#[inline] #[inline]
fn indexable(&self) -> usize { fn indexable(&self) -> usize {
@ -1550,7 +1551,7 @@ impl<T, U, A, B> RandomAccessIterator for Zip<A, B> where
} }
#[inline] #[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) { match self.a.idx(index) {
None => None, None => None,
Some(x) => match self.b.idx(index) { Some(x) => match self.b.idx(index) {
@ -2058,8 +2059,9 @@ pub struct Scan<I, St, F> {
} }
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
impl<A, B, I: Iterator<Item=A>, St, F> Iterator for Scan<I, St, F> where impl<B, I, St, F> Iterator for Scan<I, St, F> where
F: FnMut(&mut St, A) -> Option<B>, I: Iterator,
F: FnMut(&mut St, I::Item) -> Option<B>,
{ {
type Item = B; type Item = B;

View file

@ -35,8 +35,7 @@
//! often generated by LLVM. Additionally, this library can make explicit //! often generated by LLVM. Additionally, this library can make explicit
//! calls to these functions. Their signatures are the same as found in C. //! 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 //! These functions are often provided by the system libc, but can also be
//! provided by `librlibc` which is distributed with the standard rust //! provided by the [rlibc crate](https://crates.io/crates/rlibc).
//! distribution.
//! //!
//! * `rust_begin_unwind` - This function takes three arguments, a //! * `rust_begin_unwind` - This function takes three arguments, a
//! `fmt::Arguments`, a `&str`, and a `usize`. These three arguments dictate //! `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 // Since libcore defines many fundamental lang items, all tests live in a
// separate crate, libcoretest, to avoid bizarre issues. // 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"] #![crate_name = "core"]
#![unstable(feature = "core")] #![unstable(feature = "core")]
#![staged_api] #![staged_api]

View file

@ -100,10 +100,12 @@ macro_rules! assert_eq {
/// This will invoke the `panic!` macro if the provided expression cannot be /// This will invoke the `panic!` macro if the provided expression cannot be
/// evaluated to `true` at runtime. /// evaluated to `true` at runtime.
/// ///
/// Unlike `assert!`, `debug_assert!` statements can be disabled by passing /// Unlike `assert!`, `debug_assert!` statements are only enabled in non
/// `--cfg ndebug` to the compiler. This makes `debug_assert!` useful for /// optimized builds by default. An optimized build will omit all
/// checks that are too expensive to be present in a release build but may be /// `debug_assert!` statements unless `-C debug-assertions` is passed to the
/// helpful during development. /// 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 /// # Example
/// ///
@ -125,7 +127,7 @@ macro_rules! assert_eq {
#[macro_export] #[macro_export]
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
macro_rules! debug_assert { 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 /// 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. /// On panic, this macro will print the values of the expressions.
/// ///
/// Unlike `assert_eq!`, `debug_assert_eq!` statements can be disabled by /// Unlike `assert_eq!`, `debug_assert_eq!` statements are only enabled in non
/// passing `--cfg ndebug` to the compiler. This makes `debug_assert_eq!` /// optimized builds by default. An optimized build will omit all
/// useful for checks that are too expensive to be present in a release build /// `debug_assert_eq!` statements unless `-C debug-assertions` is passed to the
/// but may be helpful during development. /// 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 /// # Example
/// ///
@ -147,7 +151,7 @@ macro_rules! debug_assert {
/// ``` /// ```
#[macro_export] #[macro_export]
macro_rules! debug_assert_eq { 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 /// Short circuiting evaluation on Err

View file

@ -8,6 +8,8 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // 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(box_syntax)]
#![feature(int_uint)] #![feature(int_uint)]
#![feature(unboxed_closures)] #![feature(unboxed_closures)]

View file

@ -14,6 +14,8 @@
//! [def]: https://en.wikipedia.org/wiki/DEFLATE //! [def]: https://en.wikipedia.org/wiki/DEFLATE
//! [mz]: https://code.google.com/p/miniz/ //! [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"] #![crate_name = "flate"]
#![unstable(feature = "rustc_private")] #![unstable(feature = "rustc_private")]
#![staged_api] #![staged_api]

View file

@ -14,6 +14,8 @@
//! Parsing does not happen at runtime: structures of `std::fmt::rt` are //! Parsing does not happen at runtime: structures of `std::fmt::rt` are
//! generated instead. //! generated instead.
// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364)
#![cfg_attr(stage0, feature(custom_attribute))]
#![crate_name = "fmt_macros"] #![crate_name = "fmt_macros"]
#![unstable(feature = "rustc_private")] #![unstable(feature = "rustc_private")]
#![staged_api] #![staged_api]

View file

@ -77,6 +77,9 @@
//! } //! }
//! ``` //! ```
// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364)
#![cfg_attr(stage0, feature(custom_attribute))]
#![crate_name = "getopts"] #![crate_name = "getopts"]
#![unstable(feature = "rustc_private", #![unstable(feature = "rustc_private",
reason = "use the crates.io `getopts` library instead")] reason = "use the crates.io `getopts` library instead")]
@ -92,8 +95,8 @@
#![feature(collections)] #![feature(collections)]
#![feature(int_uint)] #![feature(int_uint)]
#![feature(staged_api)] #![feature(staged_api)]
#![feature(str_words)]
#![feature(core)] #![feature(core)]
#![feature(str_words)]
#![cfg_attr(test, feature(rustc_private))] #![cfg_attr(test, feature(rustc_private))]
#[cfg(test)] #[macro_use] extern crate log; #[cfg(test)] #[macro_use] extern crate log;

View file

@ -264,6 +264,8 @@
//! //!
//! * [DOT language](http://www.graphviz.org/doc/info/lang.html) //! * [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"] #![crate_name = "graphviz"]
#![unstable(feature = "rustc_private")] #![unstable(feature = "rustc_private")]
#![feature(staged_api)] #![feature(staged_api)]

View file

@ -8,6 +8,8 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // 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_name = "libc"]
#![crate_type = "rlib"] #![crate_type = "rlib"]
#![cfg_attr(not(feature = "cargo-build"), unstable(feature = "libc"))] #![cfg_attr(not(feature = "cargo-build"), unstable(feature = "libc"))]
@ -383,7 +385,8 @@ pub mod types {
target_arch = "mips", target_arch = "mips",
target_arch = "mipsel", target_arch = "mipsel",
target_arch = "powerpc", target_arch = "powerpc",
target_arch = "le32"))] target_arch = "le32",
all(target_arch = "arm", not(target_os = "android"))))]
pub mod posix88 { pub mod posix88 {
pub type off_t = i32; pub type off_t = i32;
pub type dev_t = u64; pub type dev_t = u64;
@ -395,7 +398,7 @@ pub mod types {
pub type mode_t = u32; pub type mode_t = u32;
pub type ssize_t = i32; pub type ssize_t = i32;
} }
#[cfg(target_arch = "arm")] #[cfg(all(target_arch = "arm", target_os = "android"))]
pub mod posix88 { pub mod posix88 {
pub type off_t = i32; pub type off_t = i32;
pub type dev_t = u32; pub type dev_t = u32;
@ -409,7 +412,8 @@ pub mod types {
} }
#[cfg(any(target_arch = "x86", #[cfg(any(target_arch = "x86",
target_arch = "le32", target_arch = "le32",
target_arch = "powerpc"))] target_arch = "powerpc",
all(target_arch = "arm", not(target_os = "android"))))]
pub mod posix01 { pub mod posix01 {
use types::os::arch::c95::{c_short, c_long, time_t}; use types::os::arch::c95::{c_short, c_long, time_t};
use types::os::arch::posix88::{dev_t, gid_t, ino_t}; use types::os::arch::posix88::{dev_t, gid_t, ino_t};
@ -455,7 +459,7 @@ pub mod types {
pub __size: [u32; 9] pub __size: [u32; 9]
} }
} }
#[cfg(target_arch = "arm")] #[cfg(all(target_arch = "arm", target_os = "android"))]
pub mod posix01 { pub mod posix01 {
use types::os::arch::c95::{c_uchar, c_uint, c_ulong, time_t}; use types::os::arch::c95::{c_uchar, c_uint, c_ulong, time_t};
use types::os::arch::c99::{c_longlong, c_ulonglong}; 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::c95::{c_char, c_int};
use types::os::arch::posix88::mode_t; 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 { 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 creat(path: *const c_char, mode: mode_t) -> c_int;
pub fn fcntl(fd: c_int, cmd: c_int, ...) -> c_int; pub fn fcntl(fd: c_int, cmd: c_int, ...) -> c_int;
} }

View file

@ -155,6 +155,8 @@
//! they're turned off (just a load and an integer comparison). This also means that //! 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. //! 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"] #![crate_name = "log"]
#![unstable(feature = "rustc_private", #![unstable(feature = "rustc_private",
reason = "use the crates.io `log` library instead")] reason = "use the crates.io `log` library instead")]

View file

@ -157,7 +157,7 @@ macro_rules! info {
/// ``` /// ```
#[macro_export] #[macro_export]
macro_rules! debug { 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. /// 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 { macro_rules! log_enabled {
($lvl:expr) => ({ ($lvl:expr) => ({
let lvl = $lvl; let lvl = $lvl;
(lvl != ::log::DEBUG || cfg!(not(ndebug))) && (lvl != ::log::DEBUG || cfg!(debug_assertions)) &&
lvl <= ::log::log_level() && lvl <= ::log::log_level() &&
::log::mod_enabled(lvl, module_path!()) ::log::mod_enabled(lvl, module_path!())
}) })

View file

@ -16,6 +16,8 @@
//! is not recommended to use this library directly, but rather the official //! is not recommended to use this library directly, but rather the official
//! interface through `std::rand`. //! 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_name = "rand"]
#![crate_type = "rlib"] #![crate_type = "rlib"]
#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk.png", #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk.png",

View file

@ -111,6 +111,8 @@
//! //!
//! First 0x20 tags are reserved by RBML; custom tags start at 0x20. //! 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"] #![crate_name = "rbml"]
#![unstable(feature = "rustc_private")] #![unstable(feature = "rustc_private")]
#![staged_api] #![staged_api]

View file

@ -14,6 +14,8 @@
//! //!
//! This API is completely unstable and subject to change. //! 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"] #![crate_name = "rustc"]
#![unstable(feature = "rustc_private")] #![unstable(feature = "rustc_private")]
#![staged_api] #![staged_api]
@ -38,10 +40,10 @@
#![feature(unsafe_destructor)] #![feature(unsafe_destructor)]
#![feature(staged_api)] #![feature(staged_api)]
#![feature(std_misc)] #![feature(std_misc)]
#![feature(os)]
#![feature(path)] #![feature(path)]
#![feature(fs)]
#![feature(io)] #![feature(io)]
#![feature(path_ext)]
#![feature(str_words)]
#![cfg_attr(test, feature(test))] #![cfg_attr(test, feature(test))]
extern crate arena; extern crate arena;

View file

@ -1692,6 +1692,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
} }
} }
// for `PhantomData<T>`, 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) => { ty::ty_struct(def_id, substs) => {
Some(ty::struct_fields(self.tcx(), def_id, substs).iter() Some(ty::struct_fields(self.tcx(), def_id, substs).iter()
.map(|f| f.mt.ty) .map(|f| f.mt.ty)

View file

@ -81,6 +81,7 @@ pub struct Options {
pub gc: bool, pub gc: bool,
pub optimize: OptLevel, pub optimize: OptLevel,
pub debug_assertions: bool,
pub debuginfo: DebugInfoLevel, pub debuginfo: DebugInfoLevel,
pub lint_opts: Vec<(String, lint::Level)>, pub lint_opts: Vec<(String, lint::Level)>,
pub describe_lints: bool, pub describe_lints: bool,
@ -238,7 +239,8 @@ pub fn basic_options() -> Options {
crate_name: None, crate_name: None,
alt_std_name: None, alt_std_name: None,
libs: Vec::new(), 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"), 2 = full debug info with variable and type information"),
opt_level: Option<uint> = (None, parse_opt_uint, opt_level: Option<uint> = (None, parse_opt_uint,
"Optimize with possible levels 0-3"), "Optimize with possible levels 0-3"),
debug_assertions: Option<bool> = (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; let mk = attr::mk_name_value_item_str;
return vec!(// Target bindings. let mut ret = vec![ // Target bindings.
attr::mk_word_item(fam.clone()), attr::mk_word_item(fam.clone()),
mk(InternedString::new("target_os"), intern(os)), mk(InternedString::new("target_os"), intern(os)),
mk(InternedString::new("target_family"), fam), 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_endian"), intern(end)),
mk(InternedString::new("target_pointer_width"), mk(InternedString::new("target_pointer_width"),
intern(wordsz)) 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, 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 gc = debugging_opts.gc;
let debuginfo = if matches.opt_present("g") { let debuginfo = if matches.opt_present("g") {
if cg.debuginfo.is_some() { if cg.debuginfo.is_some() {
@ -1064,6 +1073,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
alt_std_name: None, alt_std_name: None,
libs: libs, libs: libs,
unstable_features: get_unstable_features_setting(), unstable_features: get_unstable_features_setting(),
debug_assertions: debug_assertions,
} }
} }

View file

@ -11,7 +11,7 @@
//! A helper class for dealing with static archives //! A helper class for dealing with static archives
use std::env; use std::env;
use std::fs::{self, TempDir}; use std::fs;
use std::io::prelude::*; use std::io::prelude::*;
use std::io; use std::io;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
@ -19,6 +19,8 @@ use std::process::{Command, Output, Stdio};
use std::str; use std::str;
use syntax::diagnostic::Handler as ErrorHandler; use syntax::diagnostic::Handler as ErrorHandler;
use tempdir::TempDir;
pub const METADATA_FILENAME: &'static str = "rust.metadata.bin"; pub const METADATA_FILENAME: &'static str = "rust.metadata.bin";
pub struct ArchiveConfig<'a> { pub struct ArchiveConfig<'a> {

View file

@ -21,6 +21,8 @@
//! one that doesn't; the one that doesn't might get decent parallel //! one that doesn't; the one that doesn't might get decent parallel
//! build speedups. //! build speedups.
// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364)
#![cfg_attr(stage0, feature(custom_attribute))]
#![crate_name = "rustc_back"] #![crate_name = "rustc_back"]
#![unstable(feature = "rustc_private")] #![unstable(feature = "rustc_private")]
#![staged_api] #![staged_api]
@ -34,7 +36,6 @@
#![feature(collections)] #![feature(collections)]
#![feature(core)] #![feature(core)]
#![feature(old_fs)] #![feature(old_fs)]
#![feature(fs)]
#![feature(hash)] #![feature(hash)]
#![feature(int_uint)] #![feature(int_uint)]
#![feature(io)] #![feature(io)]
@ -44,7 +45,8 @@
#![feature(path)] #![feature(path)]
#![feature(rustc_private)] #![feature(rustc_private)]
#![feature(staged_api)] #![feature(staged_api)]
#![feature(tempdir)] #![feature(rand)]
#![feature(path_ext)]
extern crate syntax; extern crate syntax;
extern crate serialize; extern crate serialize;
@ -52,6 +54,7 @@ extern crate serialize;
pub mod abi; pub mod abi;
pub mod archive; pub mod archive;
pub mod tempdir;
pub mod arm; pub mod arm;
pub mod fs; pub mod fs;
pub mod mips; pub mod mips;

View file

@ -8,7 +8,8 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
use std::old_io::{Command, IoError, OtherIoError}; use std::io;
use std::process::Command;
use target::TargetOptions; use target::TargetOptions;
use self::Arch::*; use self::Arch::*;
@ -40,16 +41,15 @@ pub fn get_sdk_root(sdk_name: &str) -> String {
.arg("--show-sdk-path") .arg("--show-sdk-path")
.arg("-sdk") .arg("-sdk")
.arg(sdk_name) .arg(sdk_name)
.spawn() .output()
.and_then(|c| c.wait_with_output())
.and_then(|output| { .and_then(|output| {
if output.status.success() { if output.status.success() {
Ok(String::from_utf8(output.output).unwrap()) Ok(String::from_utf8(output.stdout).unwrap())
} else { } else {
Err(IoError { let error = String::from_utf8(output.stderr);
kind: OtherIoError, Err(io::Error::new(io::ErrorKind::Other,
desc: "process exit with error", "process exit with error",
detail: String::from_utf8(output.error).ok()}) error.ok()))
} }
}); });

View file

@ -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 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use std::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<PathBuf>,
}
// 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<P: AsPath + ?Sized>(tmpdir: &P, prefix: &str)
-> io::Result<TempDir> {
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> {
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

View file

@ -8,6 +8,9 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // 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"] #![crate_name = "rustc_bitflags"]
#![feature(staged_api)] #![feature(staged_api)]
#![staged_api] #![staged_api]

View file

@ -8,6 +8,8 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // 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"] #![crate_name = "rustc_borrowck"]
#![unstable(feature = "rustc_private")] #![unstable(feature = "rustc_private")]
#![staged_api] #![staged_api]

View file

@ -814,7 +814,9 @@ fn write_out_deps(sess: &Session,
// Build a list of files used to compile the output and // Build a list of files used to compile the output and
// write Makefile-compatible dependency rules // write Makefile-compatible dependency rules
let files: Vec<String> = sess.codemap().files.borrow() let files: Vec<String> = 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)) .map(|fmap| escape_dep_filename(&fmap.name))
.collect(); .collect();
let mut file = try!(fs::File::create(&deps_filename)); let mut file = try!(fs::File::create(&deps_filename));

View file

@ -14,6 +14,8 @@
//! //!
//! This API is completely unstable and subject to change. //! 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"] #![crate_name = "rustc_driver"]
#![unstable(feature = "rustc_private")] #![unstable(feature = "rustc_private")]
#![staged_api] #![staged_api]
@ -29,7 +31,6 @@
#![feature(int_uint)] #![feature(int_uint)]
#![feature(old_io)] #![feature(old_io)]
#![feature(libc)] #![feature(libc)]
#![feature(os)]
#![feature(quote)] #![feature(quote)]
#![feature(rustc_diagnostic_macros)] #![feature(rustc_diagnostic_macros)]
#![feature(rustc_private)] #![feature(rustc_private)]
@ -39,7 +40,6 @@
#![feature(exit_status)] #![feature(exit_status)]
#![feature(path)] #![feature(path)]
#![feature(io)] #![feature(io)]
#![feature(fs)]
extern crate arena; extern crate arena;
extern crate flate; 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 /// The diagnostic emitter yielded to the procedure should be used for reporting
/// errors of the compiler. /// errors of the compiler.
#[allow(deprecated)]
pub fn monitor<F:FnOnce()+Send+'static>(f: F) { pub fn monitor<F:FnOnce()+Send+'static>(f: F) {
const STACK_SIZE: uint = 8 * 1024 * 1024; // 8MB const STACK_SIZE: uint = 8 * 1024 * 1024; // 8MB

View file

@ -19,6 +19,8 @@
//! //!
//! This API is completely unstable and subject to change. //! 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"] #![crate_name = "rustc_lint"]
#![unstable(feature = "rustc_private")] #![unstable(feature = "rustc_private")]
#![staged_api] #![staged_api]

View file

@ -8,6 +8,8 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // 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_upper_case_globals)]
#![allow(non_camel_case_types)] #![allow(non_camel_case_types)]
#![allow(non_snake_case)] #![allow(non_snake_case)]
@ -29,8 +31,8 @@
#![feature(libc)] #![feature(libc)]
#![feature(link_args)] #![feature(link_args)]
#![feature(staged_api)] #![feature(staged_api)]
#![feature(std_misc)]
#![feature(path)] #![feature(path)]
#![cfg_attr(unix, feature(std_misc))]
extern crate libc; extern crate libc;
#[macro_use] #[no_link] extern crate rustc_bitflags; #[macro_use] #[no_link] extern crate rustc_bitflags;

View file

@ -8,6 +8,8 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // 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"] #![crate_name = "rustc_privacy"]
#![unstable(feature = "rustc_private")] #![unstable(feature = "rustc_private")]
#![staged_api] #![staged_api]

View file

@ -8,6 +8,8 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // 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"] #![crate_name = "rustc_resolve"]
#![unstable(feature = "rustc_private")] #![unstable(feature = "rustc_private")]
#![staged_api] #![staged_api]

View file

@ -26,9 +26,10 @@ use middle::ty::{self, Ty};
use util::common::time; use util::common::time;
use util::ppaux; use util::ppaux;
use util::sha2::{Digest, Sha256}; use util::sha2::{Digest, Sha256};
use rustc_back::tempdir::TempDir;
use std::ffi::{AsOsStr, OsString}; use std::ffi::OsString;
use std::fs::{self, TempDir, PathExt}; use std::fs::{self, PathExt};
use std::io::{self, Read, Write}; use std::io::{self, Read, Write};
use std::mem; use std::mem;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
@ -882,7 +883,7 @@ fn link_args(cmd: &mut Command,
let morestack = lib_path.join("libmorestack.a"); let morestack = lib_path.join("libmorestack.a");
let mut v = OsString::from_str("-Wl,-force_load,"); let mut v = OsString::from_str("-Wl,-force_load,");
v.push_os_str(morestack.as_os_str()); v.push(&morestack);
cmd.arg(&v); cmd.arg(&v);
} else { } else {
cmd.args(&["-Wl,--whole-archive", "-lmorestack", "-Wl,--no-whole-archive"]); 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 { if sess.opts.cg.rpath {
let mut v = OsString::from_str("-Wl,-install_name,@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); cmd.arg(&v);
} }
} else { } else {
@ -1107,7 +1108,7 @@ fn add_local_native_libraries(cmd: &mut Command, sess: &Session) {
&search_path[..], &search_path[..],
&sess.diagnostic().handler); &sess.diagnostic().handler);
let mut v = OsString::from_str("-Wl,-force_load,"); let mut v = OsString::from_str("-Wl,-force_load,");
v.push_os_str(lib.as_os_str()); v.push(&lib);
cmd.arg(&v); cmd.arg(&v);
} }
} }

View file

@ -14,6 +14,8 @@
//! //!
//! This API is completely unstable and subject to change. //! 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"] #![crate_name = "rustc_trans"]
#![unstable(feature = "rustc_private")] #![unstable(feature = "rustc_private")]
#![staged_api] #![staged_api]
@ -35,13 +37,12 @@
#![feature(rustc_private)] #![feature(rustc_private)]
#![feature(unsafe_destructor)] #![feature(unsafe_destructor)]
#![feature(staged_api)] #![feature(staged_api)]
#![feature(std_misc)]
#![feature(unicode)] #![feature(unicode)]
#![feature(io)] #![feature(io)]
#![feature(fs)]
#![feature(path)] #![feature(path)]
#![feature(os)] #![feature(path_ext)]
#![feature(tempdir)] #![feature(fs)]
#![feature(hash)]
extern crate arena; extern crate arena;
extern crate flate; extern crate flate;

View file

@ -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 { let check_overflow = if let Some(v) = tcx.sess.opts.debugging_opts.force_overflow_checks {
v v
} else { } else {
!attr::contains_name(&krate.config, "ndebug") tcx.sess.opts.debug_assertions
}; };
// Before we touch LLVM, make sure that multithreading is enabled. // Before we touch LLVM, make sure that multithreading is enabled.

View file

@ -173,7 +173,7 @@ pub fn get_const_expr<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
&**expr &**expr
} else { } else {
ccx.sess().span_bug(ref_expr.span, 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()))); item.repr(ccx.tcx())));
} }
} }

View file

@ -697,6 +697,7 @@ struct FunctionDebugContextData {
fn_metadata: DISubprogram, fn_metadata: DISubprogram,
argument_counter: Cell<uint>, argument_counter: Cell<uint>,
source_locations_enabled: Cell<bool>, source_locations_enabled: Cell<bool>,
source_location_override: Cell<bool>,
} }
enum VariableAccess<'a> { enum VariableAccess<'a> {
@ -1176,6 +1177,12 @@ pub fn set_source_location(fcx: &FunctionContext,
return; return;
} }
FunctionDebugContext::RegularContext(box ref function_debug_context) => { 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; let cx = fcx.ccx;
debug!("set_source_location: {}", cx.sess().codemap().span_to_string(span)); 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<F, R>(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. /// Clears the current debug location.
/// ///
/// Instructions generated hereafter won't be assigned a source 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, fn_metadata: fn_metadata,
argument_counter: Cell::new(1), argument_counter: Cell::new(1),
source_locations_enabled: Cell::new(false), source_locations_enabled: Cell::new(false),
source_location_override: Cell::new(false),
}; };

View file

@ -147,7 +147,7 @@ pub fn trans_into<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
ast::ExprPath(..) => { ast::ExprPath(..) => {
match bcx.def(expr.id) { match bcx.def(expr.id) {
def::DefConst(did) => { 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, // Temporarily get cleanup scopes out of the way,
// as they require sub-expressions to be contained // as they require sub-expressions to be contained
// inside the current AST scope. // inside the current AST scope.
@ -155,7 +155,13 @@ pub fn trans_into<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
// can't have destructors. // can't have destructors.
let scopes = mem::replace(&mut *bcx.fcx.scopes.borrow_mut(), let scopes = mem::replace(&mut *bcx.fcx.scopes.borrow_mut(),
vec![]); 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(), let scopes = mem::replace(&mut *bcx.fcx.scopes.borrow_mut(),
scopes); scopes);
assert!(scopes.is_empty()); assert!(scopes.is_empty());

View file

@ -118,7 +118,7 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> {
self.check_variances_for_type_defn(item, ast_generics); self.check_variances_for_type_defn(item, ast_generics);
} }
ast::ItemTrait(_, ref ast_generics, _, _) => { ast::ItemTrait(_, ref ast_generics, _, ref items) => {
let trait_predicates = let trait_predicates =
ty::lookup_predicates(ccx.tcx, local_def(item.id)); ty::lookup_predicates(ccx.tcx, local_def(item.id));
reject_non_type_param_bounds( reject_non_type_param_bounds(
@ -127,6 +127,14 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> {
&trait_predicates); &trait_predicates);
self.check_variances(item, ast_generics, &trait_predicates, self.check_variances(item, ast_generics, &trait_predicates,
self.tcx().lang_items.phantom_fn()); 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")
}
}
} }
_ => {} _ => {}
} }

View file

@ -62,7 +62,8 @@ independently:
This API is completely unstable and subject to change. 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"] #![crate_name = "rustc_typeck"]
#![unstable(feature = "rustc_private")] #![unstable(feature = "rustc_private")]
#![staged_api] #![staged_api]

View file

@ -38,7 +38,6 @@ use std::cell::RefCell;
use std::cmp::Ordering; use std::cmp::Ordering;
use std::collections::{HashMap, HashSet}; use std::collections::{HashMap, HashSet};
use std::default::Default; use std::default::Default;
use std::ffi::OsStr;
use std::fmt; use std::fmt;
use std::fs::{self, File}; use std::fs::{self, File};
use std::io::prelude::*; use std::io::prelude::*;
@ -67,12 +66,10 @@ use html::item_type::ItemType;
use html::layout; use html::layout;
use html::markdown::Markdown; use html::markdown::Markdown;
use html::markdown; use html::markdown;
use html::escape::Escape;
use stability_summary; use stability_summary;
/// A pair of name and its optional document. /// A pair of name and its optional document.
#[derive(Clone, Eq, Ord, PartialEq, PartialOrd)] pub type NameDoc = (String, Option<String>);
pub struct NameDoc(String, Option<String>);
/// Major driving force in all rustdoc rendering. This contains information /// Major driving force in all rustdoc rendering. This contains information
/// about where in the tree-like hierarchy rendering is occurring and controls /// 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 /// This describes the layout of each page, and is not modified after
/// creation of the context (contains info like the favicon and added html). /// creation of the context (contains info like the favicon and added html).
pub layout: layout::Layout, 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<String, Vec<NameDoc>>,
/// This flag indicates whether [src] links should be generated or not. If /// 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 /// the source files are present in the html rendering, then this will be
/// `true`. /// `true`.
@ -271,7 +262,6 @@ pub fn run(mut krate: clean::Crate,
passes: passes, passes: passes,
current: Vec::new(), current: Vec::new(),
root_path: String::new(), root_path: String::new(),
sidebar: HashMap::new(),
layout: layout::Layout { layout: layout::Layout {
logo: "".to_string(), logo: "".to_string(),
favicon: "".to_string(), favicon: "".to_string(),
@ -770,7 +760,7 @@ impl<'a> SourceCollector<'a> {
let mut fname = p.file_name().expect("source has no filename") let mut fname = p.file_name().expect("source has no filename")
.to_os_string(); .to_os_string();
fname.push_os_str(OsStr::from_str(".html")); fname.push(".html");
cur.push(&fname); cur.push(&fname);
let mut w = BufWriter::new(try!(File::create(&cur))); let mut w = BufWriter::new(try!(File::create(&cur)));
@ -1232,7 +1222,16 @@ impl Context {
clean::ModuleItem(m) => m, clean::ModuleItem(m) => m,
_ => unreachable!() _ => 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 { for item in m.items {
f(this,item); f(this,item);
} }
@ -1252,15 +1251,11 @@ impl Context {
} }
} }
fn build_sidebar(&self, m: &clean::Module) -> HashMap<String, Vec<NameDoc>> { fn build_sidebar_items(&self, m: &clean::Module) -> HashMap<String, Vec<NameDoc>> {
let mut map = HashMap::new(); let mut map = HashMap::new();
for item in &m.items { for item in &m.items {
if self.ignore_private_item(item) { continue } 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 short = shortty(item).to_static_str();
let myname = match item.name { let myname = match item.name {
None => continue, None => continue,
@ -1269,7 +1264,7 @@ impl Context {
let short = short.to_string(); let short = short.to_string();
let v = map.entry(short).get().unwrap_or_else( let v = map.entry(short).get().unwrap_or_else(
|vacant_entry| vacant_entry.insert(Vec::with_capacity(1))); |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 { 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 { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
let cx = self.cx; let cx = self.cx;
let it = self.item; 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, "<p class='location'>")); try!(write!(fmt, "<p class='location'>"));
let len = cx.current.len() - if it.is_mod() {1} else {0}; for (i, name) in cx.current.iter().take(parentlen).enumerate() {
for (i, name) in cx.current.iter().take(len).enumerate() {
if i > 0 { if i > 0 {
try!(write!(fmt, "::<wbr>")); try!(write!(fmt, "::<wbr>"));
} }
@ -2228,40 +2232,25 @@ impl<'a> fmt::Display for Sidebar<'a> {
} }
try!(write!(fmt, "</p>")); try!(write!(fmt, "</p>"));
fn block(w: &mut fmt::Formatter, short: &str, longty: &str, // sidebar refers to the enclosing module, not this module
cur: &clean::Item, cx: &Context) -> fmt::Result { let relpath = if shortty(it) == ItemType::Module { "../" } else { "" };
let items = match cx.sidebar.get(short) { try!(write!(fmt,
Some(items) => items, "<script>window.sidebarCurrent = {{\
None => return Ok(()) name: '{name}', \
}; ty: '{ty}', \
try!(write!(w, "<div class='block {}'><h2>{}</h2>", short, longty)); relpath: '{path}'\
for &NameDoc(ref name, ref doc) in items { }};</script>",
let curty = shortty(cur).to_static_str(); name = it.name.as_ref().map(|x| &x[..]).unwrap_or(""),
let class = if cur.name.as_ref().unwrap() == name && ty = shortty(it).to_static_str(),
short == curty { "current" } else { "" }; path = relpath));
try!(write!(w, "<a class='{ty} {class}' href='{href}{path}' \ if parentlen == 0 {
title='{title}'>{name}</a>", // there is no sidebar-items.js beyond the crate root path
ty = short, // FIXME maybe dynamic crate loading can be merged here
class = class,
href = if curty == "mod" {"../"} else {""},
path = if short == "mod" {
format!("{}/index.html", name)
} else { } else {
format!("{}.{}.html", short, name) try!(write!(fmt, "<script async src=\"{path}sidebar-items.js\"></script>",
}, path = relpath));
title = Escape(doc.as_ref().unwrap()),
name = name));
}
try!(write!(w, "</div>"));
Ok(())
} }
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(()) Ok(())
} }
} }

View file

@ -15,6 +15,27 @@
"use strict"; "use strict";
var resizeTimeout, interval; 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'); $('.js-only').removeClass('js-only');
function getQueryStringParams() { function getQueryStringParams() {
@ -552,27 +573,6 @@
showResults(results); 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) { function itemTypeFromName(typename) {
for (var i = 0; i < itemTypes.length; ++i) { for (var i = 0; i < itemTypes.length; ++i) {
if (itemTypes[i] === typename) return i; if (itemTypes[i] === typename) return i;
@ -708,6 +708,50 @@
window.initSearch = initSearch; 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 = $('<div>').attr('class', 'block ' + shortty);
div.append($('<h2>').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($('<a>', {'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) { window.register_implementors = function(imp) {
var list = $('#implementors-list'); var list = $('#implementors-list');
var libs = Object.getOwnPropertyNames(imp); var libs = Object.getOwnPropertyNames(imp);

View file

@ -15,7 +15,7 @@
if (window.playgroundUrl) { if (window.playgroundUrl) {
$('pre.rust').hover(function() { $('pre.rust').hover(function() {
var a = $('<a>').text('⇱').attr('class', 'test-arrow'); var a = $('<a>').text('⇱').attr('class', 'test-arrow');
var code = $(this).siblings(".rusttest").text(); var code = $(this).prev(".rusttest").text();
a.attr('href', window.playgroundUrl + '?code=' + a.attr('href', window.playgroundUrl + '?code=' +
encodeURIComponent(code)); encodeURIComponent(code));
a.attr('target', '_blank'); a.attr('target', '_blank');

View file

@ -8,6 +8,8 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // 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"] #![crate_name = "rustdoc"]
#![unstable(feature = "rustdoc")] #![unstable(feature = "rustdoc")]
#![staged_api] #![staged_api]
@ -35,9 +37,9 @@
#![feature(unicode)] #![feature(unicode)]
#![feature(str_words)] #![feature(str_words)]
#![feature(io)] #![feature(io)]
#![feature(fs)]
#![feature(path)] #![feature(path)]
#![feature(tempdir)] #![feature(file_path)]
#![feature(path_ext)]
extern crate arena; extern crate arena;
extern crate getopts; extern crate getopts;
@ -47,6 +49,7 @@ extern crate rustc_trans;
extern crate rustc_driver; extern crate rustc_driver;
extern crate rustc_resolve; extern crate rustc_resolve;
extern crate rustc_lint; extern crate rustc_lint;
extern crate rustc_back;
extern crate serialize; extern crate serialize;
extern crate syntax; extern crate syntax;
extern crate "test" as testing; extern crate "test" as testing;

View file

@ -13,7 +13,6 @@ use std::collections::{HashSet, HashMap};
use std::dynamic_lib::DynamicLibrary; use std::dynamic_lib::DynamicLibrary;
use std::env; use std::env;
use std::ffi::OsString; use std::ffi::OsString;
use std::fs::TempDir;
use std::old_io; use std::old_io;
use std::io; use std::io;
use std::path::PathBuf; use std::path::PathBuf;
@ -28,6 +27,7 @@ use rustc_lint;
use rustc::session::{self, config}; use rustc::session::{self, config};
use rustc::session::config::get_unstable_features_setting; use rustc::session::config::get_unstable_features_setting;
use rustc::session::search_paths::{SearchPaths, PathKind}; use rustc::session::search_paths::{SearchPaths, PathKind};
use rustc_back::tempdir::TempDir;
use rustc_driver::{driver, Compilation}; use rustc_driver::{driver, Compilation};
use syntax::codemap::CodeMap; use syntax::codemap::CodeMap;
use syntax::diagnostic; use syntax::diagnostic;
@ -111,6 +111,7 @@ pub fn run(input: &str,
0 0
} }
#[allow(deprecated)]
fn runtest(test: &str, cratename: &str, libs: SearchPaths, fn runtest(test: &str, cratename: &str, libs: SearchPaths,
externs: core::Externs, externs: core::Externs,
should_fail: bool, no_run: bool, as_test_harness: bool) { should_fail: bool, no_run: bool, as_test_harness: bool) {

View file

@ -14,6 +14,8 @@
Core encoding and decoding interfaces. 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"] #![crate_name = "serialize"]
#![unstable(feature = "rustc_private", #![unstable(feature = "rustc_private",
reason = "deprecated in favor of rustc-serialize on crates.io")] reason = "deprecated in favor of rustc-serialize on crates.io")]

View file

@ -8,6 +8,8 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
#![unstable(feature = "std_misc")]
use cmp::{PartialEq, Eq, PartialOrd, Ord, Ordering}; use cmp::{PartialEq, Eq, PartialOrd, Ord, Ordering};
use error::{Error, FromError}; use error::{Error, FromError};
use fmt; use fmt;
@ -59,6 +61,7 @@ use vec::Vec;
/// # } /// # }
/// ``` /// ```
#[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Hash)] #[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct CString { pub struct CString {
inner: Vec<u8>, inner: Vec<u8>,
} }
@ -110,13 +113,19 @@ pub struct CString {
/// } /// }
/// ``` /// ```
#[derive(Hash)] #[derive(Hash)]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct CStr { 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] inner: [libc::c_char]
} }
/// An error returned from `CString::new` to indicate that a nul byte was found /// An error returned from `CString::new` to indicate that a nul byte was found
/// in the vector provided. /// in the vector provided.
#[derive(Clone, PartialEq, Debug)] #[derive(Clone, PartialEq, Debug)]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct NulError(usize, Vec<u8>); pub struct NulError(usize, Vec<u8>);
/// A conversion trait used by the constructor of `CString` for types that can /// 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 /// 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 /// internal 0 byte. The error returned will contain the bytes as well as
/// the position of the nul byte. /// the position of the nul byte.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn new<T: IntoBytes>(t: T) -> Result<CString, NulError> { pub fn new<T: IntoBytes>(t: T) -> Result<CString, NulError> {
let bytes = t.into_bytes(); let bytes = t.into_bytes();
match bytes.iter().position(|x| *x == 0) { 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 /// This method is equivalent to `from_vec` except that no runtime assertion
/// is made that `v` contains no 0 bytes. /// is made that `v` contains no 0 bytes.
#[stable(feature = "rust1", since = "1.0.0")]
pub unsafe fn from_vec_unchecked(mut v: Vec<u8>) -> CString { pub unsafe fn from_vec_unchecked(mut v: Vec<u8>) -> CString {
v.push(0); v.push(0);
CString { inner: v } CString { inner: v }
@ -225,17 +236,20 @@ impl CString {
/// ///
/// The returned slice does **not** contain the trailing nul separator and /// The returned slice does **not** contain the trailing nul separator and
/// it is guaranteed to not have any interior nul bytes. /// it is guaranteed to not have any interior nul bytes.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn as_bytes(&self) -> &[u8] { pub fn as_bytes(&self) -> &[u8] {
&self.inner[..self.inner.len() - 1] &self.inner[..self.inner.len() - 1]
} }
/// Equivalent to the `as_bytes` function except that the returned slice /// Equivalent to the `as_bytes` function except that the returned slice
/// includes the trailing nul byte. /// includes the trailing nul byte.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn as_bytes_with_nul(&self) -> &[u8] { pub fn as_bytes_with_nul(&self) -> &[u8] {
&self.inner &self.inner
} }
} }
#[stable(feature = "rust1", since = "1.0.0")]
impl Deref for CString { impl Deref for CString {
type Target = CStr; type Target = CStr;
@ -254,23 +268,28 @@ impl fmt::Debug for CString {
impl NulError { impl NulError {
/// Returns the position of the nul byte in the slice that was provided to /// Returns the position of the nul byte in the slice that was provided to
/// `CString::from_vec`. /// `CString::from_vec`.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn nul_position(&self) -> usize { self.0 } pub fn nul_position(&self) -> usize { self.0 }
/// Consumes this error, returning the underlying vector of bytes which /// Consumes this error, returning the underlying vector of bytes which
/// generated the error in the first place. /// generated the error in the first place.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn into_vec(self) -> Vec<u8> { self.1 } pub fn into_vec(self) -> Vec<u8> { self.1 }
} }
#[stable(feature = "rust1", since = "1.0.0")]
impl Error for NulError { impl Error for NulError {
fn description(&self) -> &str { "nul byte found in data" } fn description(&self) -> &str { "nul byte found in data" }
} }
#[stable(feature = "rust1", since = "1.0.0")]
impl fmt::Display for NulError { impl fmt::Display for NulError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "nul byte found in provided data at position: {}", self.0) write!(f, "nul byte found in provided data at position: {}", self.0)
} }
} }
#[stable(feature = "rust1", since = "1.0.0")]
impl FromError<NulError> for io::Error { impl FromError<NulError> for io::Error {
fn from_error(_: NulError) -> io::Error { fn from_error(_: NulError) -> io::Error {
io::Error::new(io::ErrorKind::InvalidInput, io::Error::new(io::ErrorKind::InvalidInput,
@ -278,6 +297,7 @@ impl FromError<NulError> for io::Error {
} }
} }
#[stable(feature = "rust1", since = "1.0.0")]
impl FromError<NulError> for old_io::IoError { impl FromError<NulError> for old_io::IoError {
fn from_error(_: NulError) -> old_io::IoError { fn from_error(_: NulError) -> old_io::IoError {
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 { pub unsafe fn from_ptr<'a>(ptr: *const libc::c_char) -> &'a CStr {
let len = libc::strlen(ptr); let len = libc::strlen(ptr);
mem::transmute(slice::from_raw_parts(ptr, len as usize + 1)) 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 /// 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 /// to a contiguous region of memory terminated with a 0 byte to represent
/// the end of the string. /// the end of the string.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn as_ptr(&self) -> *const libc::c_char { pub fn as_ptr(&self) -> *const libc::c_char {
self.inner.as_ptr() self.inner.as_ptr()
} }
@ -351,6 +373,7 @@ impl CStr {
/// > **Note**: This method is currently implemented as a 0-cost cast, but /// > **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 /// > it is planned to alter its definition in the future to perform the
/// > length calculation whenever this method is called. /// > length calculation whenever this method is called.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn to_bytes(&self) -> &[u8] { pub fn to_bytes(&self) -> &[u8] {
let bytes = self.to_bytes_with_nul(); let bytes = self.to_bytes_with_nul();
&bytes[..bytes.len() - 1] &bytes[..bytes.len() - 1]
@ -364,22 +387,27 @@ impl CStr {
/// > **Note**: This method is currently implemented as a 0-cost cast, but /// > **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 /// > it is planned to alter its definition in the future to perform the
/// > length calculation whenever this method is called. /// > length calculation whenever this method is called.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn to_bytes_with_nul(&self) -> &[u8] { pub fn to_bytes_with_nul(&self) -> &[u8] {
unsafe { mem::transmute::<&[libc::c_char], &[u8]>(&self.inner) } unsafe { mem::transmute::<&[libc::c_char], &[u8]>(&self.inner) }
} }
} }
#[stable(feature = "rust1", since = "1.0.0")]
impl PartialEq for CStr { impl PartialEq for CStr {
fn eq(&self, other: &CStr) -> bool { fn eq(&self, other: &CStr) -> bool {
self.to_bytes().eq(other.to_bytes()) self.to_bytes().eq(other.to_bytes())
} }
} }
#[stable(feature = "rust1", since = "1.0.0")]
impl Eq for CStr {} impl Eq for CStr {}
#[stable(feature = "rust1", since = "1.0.0")]
impl PartialOrd for CStr { impl PartialOrd for CStr {
fn partial_cmp(&self, other: &CStr) -> Option<Ordering> { fn partial_cmp(&self, other: &CStr) -> Option<Ordering> {
self.to_bytes().partial_cmp(&other.to_bytes()) self.to_bytes().partial_cmp(&other.to_bytes())
} }
} }
#[stable(feature = "rust1", since = "1.0.0")]
impl Ord for CStr { impl Ord for CStr {
fn cmp(&self, other: &CStr) -> Ordering { fn cmp(&self, other: &CStr) -> Ordering {
self.to_bytes().cmp(&other.to_bytes()) self.to_bytes().cmp(&other.to_bytes())

View file

@ -10,17 +10,19 @@
//! Utilities related to FFI bindings. //! Utilities related to FFI bindings.
#![unstable(feature = "std_misc", #![stable(feature = "rust1", since = "1.0.0")]
reason = "module just underwent fairly large reorganization and the dust \
still needs to settle")]
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)] #[allow(deprecated)]
pub use self::c_str::c_str_to_bytes; pub use self::c_str::c_str_to_bytes;
#[allow(deprecated)] #[allow(deprecated)]
pub use self::c_str::c_str_to_bytes_with_nul; pub use self::c_str::c_str_to_bytes_with_nul;
#[stable(feature = "rust1", since = "1.0.0")]
pub use self::os_str::OsString; pub use self::os_str::OsString;
#[stable(feature = "rust1", since = "1.0.0")]
pub use self::os_str::OsStr; pub use self::os_str::OsStr;
mod c_str; mod c_str;
@ -28,6 +30,7 @@ mod os_str;
// FIXME (#21670): these should be defined in the os_str module // FIXME (#21670): these should be defined in the os_str module
/// Freely convertible to an `&OsStr` slice. /// Freely convertible to an `&OsStr` slice.
#[unstable(feature = "std_misc")]
pub trait AsOsStr { pub trait AsOsStr {
/// Convert to an `&OsStr` slice. /// Convert to an `&OsStr` slice.
fn as_os_str(&self) -> &OsStr; fn as_os_str(&self) -> &OsStr;

View file

@ -49,17 +49,20 @@ use super::AsOsStr;
/// Owned, mutable OS strings. /// Owned, mutable OS strings.
#[derive(Clone)] #[derive(Clone)]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct OsString { pub struct OsString {
inner: Buf inner: Buf
} }
/// Slices into OS strings. /// Slices into OS strings.
#[stable(feature = "rust1", since = "1.0.0")]
pub struct OsStr { pub struct OsStr {
inner: Slice inner: Slice
} }
impl OsString { impl OsString {
/// Constructs an `OsString` at no cost by consuming a `String`. /// Constructs an `OsString` at no cost by consuming a `String`.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn from_string(s: String) -> OsString { pub fn from_string(s: String) -> OsString {
OsString { inner: Buf::from_string(s) } OsString { inner: Buf::from_string(s) }
} }
@ -67,11 +70,13 @@ impl OsString {
/// Constructs an `OsString` by copying from a `&str` slice. /// Constructs an `OsString` by copying from a `&str` slice.
/// ///
/// Equivalent to: `OsString::from_string(String::from_str(s))`. /// Equivalent to: `OsString::from_string(String::from_str(s))`.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn from_str(s: &str) -> OsString { pub fn from_str(s: &str) -> OsString {
OsString { inner: Buf::from_str(s) } OsString { inner: Buf::from_str(s) }
} }
/// Constructs a new empty `OsString`. /// Constructs a new empty `OsString`.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn new() -> OsString { pub fn new() -> OsString {
OsString { inner: Buf::from_string(String::new()) } 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. /// Convert the `OsString` into a `String` if it contains valid Unicode data.
/// ///
/// On failure, ownership of the original `OsString` is returned. /// On failure, ownership of the original `OsString` is returned.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn into_string(self) -> Result<String, OsString> { pub fn into_string(self) -> Result<String, OsString> {
self.inner.into_string().map_err(|buf| OsString { inner: buf} ) self.inner.into_string().map_err(|buf| OsString { inner: buf} )
} }
/// Extend the string with the given `&OsStr` slice. /// 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) { pub fn push_os_str(&mut self, s: &OsStr) {
self.inner.push_slice(&s.inner) self.inner.push_slice(&s.inner)
} }
/// Extend the string with the given `&OsStr` slice.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn push<T: AsOsStr + ?Sized>(&mut self, s: &T) {
self.inner.push_slice(&s.as_os_str().inner)
}
} }
#[stable(feature = "rust1", since = "1.0.0")]
impl ops::Index<ops::RangeFull> for OsString { impl ops::Index<ops::RangeFull> for OsString {
type Output = OsStr; type Output = OsStr;
@ -98,6 +113,7 @@ impl ops::Index<ops::RangeFull> for OsString {
} }
} }
#[stable(feature = "rust1", since = "1.0.0")]
impl ops::Deref for OsString { impl ops::Deref for OsString {
type Target = OsStr; type Target = OsStr;
@ -107,32 +123,38 @@ impl ops::Deref for OsString {
} }
} }
#[stable(feature = "rust1", since = "1.0.0")]
impl Debug for OsString { impl Debug for OsString {
fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> { fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
fmt::Debug::fmt(&**self, formatter) fmt::Debug::fmt(&**self, formatter)
} }
} }
#[stable(feature = "rust1", since = "1.0.0")]
impl PartialEq for OsString { impl PartialEq for OsString {
fn eq(&self, other: &OsString) -> bool { fn eq(&self, other: &OsString) -> bool {
&**self == &**other &**self == &**other
} }
} }
#[stable(feature = "rust1", since = "1.0.0")]
impl PartialEq<str> for OsString { impl PartialEq<str> for OsString {
fn eq(&self, other: &str) -> bool { fn eq(&self, other: &str) -> bool {
&**self == other &**self == other
} }
} }
#[stable(feature = "rust1", since = "1.0.0")]
impl PartialEq<OsString> for str { impl PartialEq<OsString> for str {
fn eq(&self, other: &OsString) -> bool { fn eq(&self, other: &OsString) -> bool {
&**other == self &**other == self
} }
} }
#[stable(feature = "rust1", since = "1.0.0")]
impl Eq for OsString {} impl Eq for OsString {}
#[stable(feature = "rust1", since = "1.0.0")]
impl PartialOrd for OsString { impl PartialOrd for OsString {
#[inline] #[inline]
fn partial_cmp(&self, other: &OsString) -> Option<cmp::Ordering> { fn partial_cmp(&self, other: &OsString) -> Option<cmp::Ordering> {
@ -148,6 +170,7 @@ impl PartialOrd for OsString {
fn ge(&self, other: &OsString) -> bool { &**self >= &**other } fn ge(&self, other: &OsString) -> bool { &**self >= &**other }
} }
#[stable(feature = "rust1", since = "1.0.0")]
impl PartialOrd<str> for OsString { impl PartialOrd<str> for OsString {
#[inline] #[inline]
fn partial_cmp(&self, other: &str) -> Option<cmp::Ordering> { fn partial_cmp(&self, other: &str) -> Option<cmp::Ordering> {
@ -155,6 +178,7 @@ impl PartialOrd<str> for OsString {
} }
} }
#[stable(feature = "rust1", since = "1.0.0")]
impl Ord for OsString { impl Ord for OsString {
#[inline] #[inline]
fn cmp(&self, other: &OsString) -> cmp::Ordering { fn cmp(&self, other: &OsString) -> cmp::Ordering {
@ -172,6 +196,7 @@ impl Hash for OsString {
impl OsStr { impl OsStr {
/// Coerce directly from a `&str` slice to a `&OsStr` slice. /// Coerce directly from a `&str` slice to a `&OsStr` slice.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn from_str(s: &str) -> &OsStr { pub fn from_str(s: &str) -> &OsStr {
unsafe { mem::transmute(Slice::from_str(s)) } unsafe { mem::transmute(Slice::from_str(s)) }
} }
@ -179,6 +204,7 @@ impl OsStr {
/// Yield a `&str` slice if the `OsStr` is valid unicode. /// Yield a `&str` slice if the `OsStr` is valid unicode.
/// ///
/// This conversion may entail doing a check for UTF-8 validity. /// 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> { pub fn to_str(&self) -> Option<&str> {
self.inner.to_str() self.inner.to_str()
} }
@ -186,11 +212,13 @@ impl OsStr {
/// Convert an `OsStr` to a `Cow<str>`. /// Convert an `OsStr` to a `Cow<str>`.
/// ///
/// Any non-Unicode sequences are replaced with U+FFFD REPLACEMENT CHARACTER. /// 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<str> { pub fn to_string_lossy(&self) -> Cow<str> {
self.inner.to_string_lossy() self.inner.to_string_lossy()
} }
/// Copy the slice into an owned `OsString`. /// Copy the slice into an owned `OsString`.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn to_os_string(&self) -> OsString { pub fn to_os_string(&self) -> OsString {
OsString { inner: self.inner.to_owned() } OsString { inner: self.inner.to_owned() }
} }
@ -204,26 +232,31 @@ impl OsStr {
} }
} }
#[stable(feature = "rust1", since = "1.0.0")]
impl PartialEq for OsStr { impl PartialEq for OsStr {
fn eq(&self, other: &OsStr) -> bool { fn eq(&self, other: &OsStr) -> bool {
self.bytes().eq(other.bytes()) self.bytes().eq(other.bytes())
} }
} }
#[stable(feature = "rust1", since = "1.0.0")]
impl PartialEq<str> for OsStr { impl PartialEq<str> for OsStr {
fn eq(&self, other: &str) -> bool { fn eq(&self, other: &str) -> bool {
*self == *OsStr::from_str(other) *self == *OsStr::from_str(other)
} }
} }
#[stable(feature = "rust1", since = "1.0.0")]
impl PartialEq<OsStr> for str { impl PartialEq<OsStr> for str {
fn eq(&self, other: &OsStr) -> bool { fn eq(&self, other: &OsStr) -> bool {
*other == *OsStr::from_str(self) *other == *OsStr::from_str(self)
} }
} }
#[stable(feature = "rust1", since = "1.0.0")]
impl Eq for OsStr {} impl Eq for OsStr {}
#[stable(feature = "rust1", since = "1.0.0")]
impl PartialOrd for OsStr { impl PartialOrd for OsStr {
#[inline] #[inline]
fn partial_cmp(&self, other: &OsStr) -> Option<cmp::Ordering> { fn partial_cmp(&self, other: &OsStr) -> Option<cmp::Ordering> {
@ -239,6 +272,7 @@ impl PartialOrd for OsStr {
fn ge(&self, other: &OsStr) -> bool { self.bytes().ge(other.bytes()) } fn ge(&self, other: &OsStr) -> bool { self.bytes().ge(other.bytes()) }
} }
#[stable(feature = "rust1", since = "1.0.0")]
impl PartialOrd<str> for OsStr { impl PartialOrd<str> for OsStr {
#[inline] #[inline]
fn partial_cmp(&self, other: &str) -> Option<cmp::Ordering> { fn partial_cmp(&self, other: &str) -> Option<cmp::Ordering> {
@ -249,6 +283,7 @@ impl PartialOrd<str> for OsStr {
// FIXME (#19470): cannot provide PartialOrd<OsStr> for str until we // FIXME (#19470): cannot provide PartialOrd<OsStr> for str until we
// have more flexible coherence rules. // have more flexible coherence rules.
#[stable(feature = "rust1", since = "1.0.0")]
impl Ord for OsStr { impl Ord for OsStr {
#[inline] #[inline]
fn cmp(&self, other: &OsStr) -> cmp::Ordering { self.bytes().cmp(other.bytes()) } 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 { impl Debug for OsStr {
fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> { fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
self.inner.fmt(formatter) self.inner.fmt(formatter)
} }
} }
#[stable(feature = "rust1", since = "1.0.0")]
impl Borrow<OsStr> for OsString { impl Borrow<OsStr> for OsString {
fn borrow(&self) -> &OsStr { &self[..] } fn borrow(&self) -> &OsStr { &self[..] }
} }
#[stable(feature = "rust1", since = "1.0.0")]
impl ToOwned for OsStr { impl ToOwned for OsStr {
type Owned = OsString; type Owned = OsString;
fn to_owned(&self) -> OsString { self.to_os_string() } 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 { impl<'a, T: AsOsStr + ?Sized> AsOsStr for &'a T {
fn as_os_str(&self) -> &OsStr { fn as_os_str(&self) -> &OsStr {
(*self).as_os_str() (*self).as_os_str()
@ -307,15 +346,12 @@ impl AsOsStr for String {
} }
} }
#[cfg(unix)]
impl AsOsStr for Path { impl AsOsStr for Path {
#[cfg(unix)]
fn as_os_str(&self) -> &OsStr { fn as_os_str(&self) -> &OsStr {
unsafe { mem::transmute(self.as_vec()) } unsafe { mem::transmute(self.as_vec()) }
} }
} #[cfg(windows)]
#[cfg(windows)]
impl AsOsStr for Path {
fn as_os_str(&self) -> &OsStr { fn as_os_str(&self) -> &OsStr {
// currently .as_str() is actually infallible on windows // currently .as_str() is actually infallible on windows
OsStr::from_str(self.as_str().unwrap()) OsStr::from_str(self.as_str().unwrap())

View file

@ -15,7 +15,7 @@
//! operations. Extra platform-specific functionality can be found in the //! operations. Extra platform-specific functionality can be found in the
//! extension traits of `std::os::$platform`. //! extension traits of `std::os::$platform`.
#![unstable(feature = "fs")] #![stable(feature = "rust1", since = "1.0.0")]
use core::prelude::*; use core::prelude::*;
@ -25,6 +25,7 @@ use sys::fs2 as fs_imp;
use sys_common::{AsInnerMut, FromInner, AsInner}; use sys_common::{AsInnerMut, FromInner, AsInner};
use vec::Vec; use vec::Vec;
#[allow(deprecated)]
pub use self::tempdir::TempDir; pub use self::tempdir::TempDir;
mod tempdir; mod tempdir;
@ -52,6 +53,7 @@ mod tempdir;
/// # Ok(()) /// # Ok(())
/// # } /// # }
/// ``` /// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub struct File { pub struct File {
inner: fs_imp::File, inner: fs_imp::File,
path: PathBuf, path: PathBuf,
@ -62,6 +64,7 @@ pub struct File {
/// This structure is returned from the `metadata` function or method and /// This structure is returned from the `metadata` function or method and
/// represents known metadata about a file such as its permissions, size, /// represents known metadata about a file such as its permissions, size,
/// modification times, etc. /// modification times, etc.
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Metadata(fs_imp::FileAttr); pub struct Metadata(fs_imp::FileAttr);
/// Iterator over the entries in a directory. /// Iterator over the entries in a directory.
@ -70,6 +73,7 @@ pub struct Metadata(fs_imp::FileAttr);
/// will yield instances of `io::Result<DirEntry>`. Through a `DirEntry` /// will yield instances of `io::Result<DirEntry>`. Through a `DirEntry`
/// information like the entry's path and possibly other metadata can be /// information like the entry's path and possibly other metadata can be
/// learned. /// learned.
#[stable(feature = "rust1", since = "1.0.0")]
pub struct ReadDir(fs_imp::ReadDir); pub struct ReadDir(fs_imp::ReadDir);
/// Entries returned by the `ReadDir` iterator. /// 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 /// 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 /// filesystem. Each entry can be inspected via methods to learn about the full
/// path or possibly other metadata through per-platform extension traits. /// path or possibly other metadata through per-platform extension traits.
#[stable(feature = "rust1", since = "1.0.0")]
pub struct DirEntry(fs_imp::DirEntry); pub struct DirEntry(fs_imp::DirEntry);
/// An iterator that recursively walks over the contents of a directory. /// 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 { pub struct WalkDir {
cur: Option<ReadDir>, cur: Option<ReadDir>,
stack: Vec<io::Result<ReadDir>>, stack: Vec<io::Result<ReadDir>>,
@ -92,6 +101,7 @@ pub struct WalkDir {
/// `File::create` methods are aliases for commonly used options using this /// `File::create` methods are aliases for commonly used options using this
/// builder. /// builder.
#[derive(Clone)] #[derive(Clone)]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct OpenOptions(fs_imp::OpenOptions); pub struct OpenOptions(fs_imp::OpenOptions);
/// Representation of the various permissions on a file. /// 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 /// functionality, such as mode bits, is available through the
/// `os::unix::PermissionsExt` trait. /// `os::unix::PermissionsExt` trait.
#[derive(Clone, PartialEq, Eq, Debug)] #[derive(Clone, PartialEq, Eq, Debug)]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Permissions(fs_imp::FilePermissions); pub struct Permissions(fs_imp::FilePermissions);
impl File { impl File {
@ -112,6 +123,7 @@ impl File {
/// ///
/// This function will return an error if `path` does not already exist. /// This function will return an error if `path` does not already exist.
/// Other errors may also be returned according to `OpenOptions::open`. /// Other errors may also be returned according to `OpenOptions::open`.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn open<P: AsPath + ?Sized>(path: &P) -> io::Result<File> { pub fn open<P: AsPath + ?Sized>(path: &P) -> io::Result<File> {
OpenOptions::new().read(true).open(path) OpenOptions::new().read(true).open(path)
} }
@ -122,11 +134,15 @@ impl File {
/// and will truncate it if it does. /// and will truncate it if it does.
/// ///
/// See the `OpenOptions::open` function for more details. /// See the `OpenOptions::open` function for more details.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn create<P: AsPath + ?Sized>(path: &P) -> io::Result<File> { pub fn create<P: AsPath + ?Sized>(path: &P) -> io::Result<File> {
OpenOptions::new().write(true).create(true).truncate(true).open(path) OpenOptions::new().write(true).create(true).truncate(true).open(path)
} }
/// Returns the original path that was used to open this file. /// 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> { pub fn path(&self) -> Option<&Path> {
Some(&self.path) Some(&self.path)
} }
@ -135,6 +151,7 @@ impl File {
/// ///
/// This function will attempt to ensure that all in-core data reaches the /// This function will attempt to ensure that all in-core data reaches the
/// filesystem before returning. /// filesystem before returning.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn sync_all(&self) -> io::Result<()> { pub fn sync_all(&self) -> io::Result<()> {
self.inner.fsync() self.inner.fsync()
} }
@ -148,6 +165,7 @@ impl File {
/// ///
/// Note that some platforms may simply implement this in terms of /// Note that some platforms may simply implement this in terms of
/// `sync_all`. /// `sync_all`.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn sync_data(&self) -> io::Result<()> { pub fn sync_data(&self) -> io::Result<()> {
self.inner.datasync() self.inner.datasync()
} }
@ -159,11 +177,13 @@ impl File {
/// be shrunk. If it is greater than the current file's size, then the 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 /// will be extended to `size` and have all of the intermediate data filled
/// in with 0s. /// in with 0s.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn set_len(&self, size: u64) -> io::Result<()> { pub fn set_len(&self, size: u64) -> io::Result<()> {
self.inner.truncate(size) 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<Metadata> { pub fn metadata(&self) -> io::Result<Metadata> {
self.inner.file_attr().map(Metadata) self.inner.file_attr().map(Metadata)
} }
@ -172,33 +192,39 @@ impl File {
impl AsInner<fs_imp::File> for File { impl AsInner<fs_imp::File> for File {
fn as_inner(&self) -> &fs_imp::File { &self.inner } fn as_inner(&self) -> &fs_imp::File { &self.inner }
} }
#[stable(feature = "rust1", since = "1.0.0")]
impl Read for File { impl Read for File {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
self.inner.read(buf) self.inner.read(buf)
} }
} }
#[stable(feature = "rust1", since = "1.0.0")]
impl Write for File { impl Write for File {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> { fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.inner.write(buf) self.inner.write(buf)
} }
fn flush(&mut self) -> io::Result<()> { self.inner.flush() } fn flush(&mut self) -> io::Result<()> { self.inner.flush() }
} }
#[stable(feature = "rust1", since = "1.0.0")]
impl Seek for File { impl Seek for File {
fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> { fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
self.inner.seek(pos) self.inner.seek(pos)
} }
} }
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a> Read for &'a File { impl<'a> Read for &'a File {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
self.inner.read(buf) self.inner.read(buf)
} }
} }
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a> Write for &'a File { impl<'a> Write for &'a File {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> { fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.inner.write(buf) self.inner.write(buf)
} }
fn flush(&mut self) -> io::Result<()> { self.inner.flush() } fn flush(&mut self) -> io::Result<()> { self.inner.flush() }
} }
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a> Seek for &'a File { impl<'a> Seek for &'a File {
fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> { fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
self.inner.seek(pos) self.inner.seek(pos)
@ -209,6 +235,7 @@ impl OpenOptions {
/// Creates a blank net set of options ready for configuration. /// Creates a blank net set of options ready for configuration.
/// ///
/// All options are initially set to `false`. /// All options are initially set to `false`.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn new() -> OpenOptions { pub fn new() -> OpenOptions {
OpenOptions(fs_imp::OpenOptions::new()) OpenOptions(fs_imp::OpenOptions::new())
} }
@ -217,6 +244,7 @@ impl OpenOptions {
/// ///
/// This option, when true, will indicate that the file should be /// This option, when true, will indicate that the file should be
/// `read`-able if opened. /// `read`-able if opened.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn read(&mut self, read: bool) -> &mut OpenOptions { pub fn read(&mut self, read: bool) -> &mut OpenOptions {
self.0.read(read); self self.0.read(read); self
} }
@ -225,6 +253,7 @@ impl OpenOptions {
/// ///
/// This option, when true, will indicate that the file should be /// This option, when true, will indicate that the file should be
/// `write`-able if opened. /// `write`-able if opened.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn write(&mut self, write: bool) -> &mut OpenOptions { pub fn write(&mut self, write: bool) -> &mut OpenOptions {
self.0.write(write); self self.0.write(write); self
} }
@ -233,6 +262,7 @@ impl OpenOptions {
/// ///
/// This option, when true, means that writes will append to a file instead /// This option, when true, means that writes will append to a file instead
/// of overwriting previous contents. /// of overwriting previous contents.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn append(&mut self, append: bool) -> &mut OpenOptions { pub fn append(&mut self, append: bool) -> &mut OpenOptions {
self.0.append(append); self self.0.append(append); self
} }
@ -241,6 +271,7 @@ impl OpenOptions {
/// ///
/// If a file is successfully opened with this option set it will truncate /// If a file is successfully opened with this option set it will truncate
/// the file to 0 length if it already exists. /// 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 { pub fn truncate(&mut self, truncate: bool) -> &mut OpenOptions {
self.0.truncate(truncate); self self.0.truncate(truncate); self
} }
@ -249,6 +280,7 @@ impl OpenOptions {
/// ///
/// This option indicates whether a new file will be created if the file /// This option indicates whether a new file will be created if the file
/// does not yet already exist. /// does not yet already exist.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn create(&mut self, create: bool) -> &mut OpenOptions { pub fn create(&mut self, create: bool) -> &mut OpenOptions {
self.0.create(create); self self.0.create(create); self
} }
@ -264,37 +296,33 @@ impl OpenOptions {
/// * Attempting to open a file with access that the user lacks /// * Attempting to open a file with access that the user lacks
/// permissions for /// permissions for
/// * Filesystem-level errors (full disk, etc) /// * Filesystem-level errors (full disk, etc)
#[stable(feature = "rust1", since = "1.0.0")]
pub fn open<P: AsPath + ?Sized>(&self, path: &P) -> io::Result<File> { pub fn open<P: AsPath + ?Sized>(&self, path: &P) -> io::Result<File> {
let path = path.as_path(); let path = path.as_path();
let inner = try!(fs_imp::File::open(path, &self.0)); 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<fs_imp::OpenOptions> for OpenOptions { impl AsInnerMut<fs_imp::OpenOptions> for OpenOptions {
fn as_inner_mut(&mut self) -> &mut fs_imp::OpenOptions { &mut self.0 } fn as_inner_mut(&mut self) -> &mut fs_imp::OpenOptions { &mut self.0 }
} }
impl Metadata { impl Metadata {
/// Returns whether this metadata is for a directory. /// 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() } pub fn is_dir(&self) -> bool { self.0.is_dir() }
/// Returns whether this metadata is for a regular file. /// 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() } pub fn is_file(&self) -> bool { self.0.is_file() }
/// Returns the size of the file, in bytes, this metadata is for. /// 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() } pub fn len(&self) -> u64 { self.0.size() }
/// Returns the permissions of the file this metadata is for. /// Returns the permissions of the file this metadata is for.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn permissions(&self) -> Permissions { pub fn permissions(&self) -> Permissions {
Permissions(self.0.perm()) Permissions(self.0.perm())
} }
@ -302,22 +330,32 @@ impl Metadata {
/// Returns the most recent access time for a file. /// Returns the most recent access time for a file.
/// ///
/// The return value is in milliseconds since the epoch. /// 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() } pub fn accessed(&self) -> u64 { self.0.accessed() }
/// Returns the most recent modification time for a file. /// Returns the most recent modification time for a file.
/// ///
/// The return value is in milliseconds since the epoch. /// 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() } pub fn modified(&self) -> u64 { self.0.modified() }
} }
impl Permissions { impl Permissions {
/// Returns whether these permissions describe a readonly file. /// Returns whether these permissions describe a readonly file.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn readonly(&self) -> bool { self.0.readonly() } pub fn readonly(&self) -> bool { self.0.readonly() }
/// Modify the readonly flag for this set of permissions. /// Modify the readonly flag for this set of permissions.
/// ///
/// This operation does **not** modify the filesystem. To modify the /// This operation does **not** modify the filesystem. To modify the
/// filesystem use the `fs::set_permissions` function. /// filesystem use the `fs::set_permissions` function.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn set_readonly(&mut self, readonly: bool) { pub fn set_readonly(&mut self, readonly: bool) {
self.0.set_readonly(readonly) self.0.set_readonly(readonly)
} }
@ -333,6 +371,7 @@ impl AsInner<fs_imp::FilePermissions> for Permissions {
fn as_inner(&self) -> &fs_imp::FilePermissions { &self.0 } fn as_inner(&self) -> &fs_imp::FilePermissions { &self.0 }
} }
#[stable(feature = "rust1", since = "1.0.0")]
impl Iterator for ReadDir { impl Iterator for ReadDir {
type Item = io::Result<DirEntry>; type Item = io::Result<DirEntry>;
@ -341,11 +380,13 @@ impl Iterator for ReadDir {
} }
} }
#[stable(feature = "rust1", since = "1.0.0")]
impl DirEntry { impl DirEntry {
/// Returns the full path to the file that this entry represents. /// 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 /// The full path is created by joining the original path to `read_dir` or
/// `walk_dir` with the filename of this entry. /// `walk_dir` with the filename of this entry.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn path(&self) -> PathBuf { self.0.path() } 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 /// 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 /// user lacks permissions to remove the file, or if some other filesystem-level
/// error occurs. /// error occurs.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn remove_file<P: AsPath + ?Sized>(path: &P) -> io::Result<()> { pub fn remove_file<P: AsPath + ?Sized>(path: &P) -> io::Result<()> {
let path = path.as_path(); fs_imp::unlink(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)
} }
/// Given a path, query the file system to get information about a file, /// Given a path, query the file system to get information about a file,
@ -418,6 +437,7 @@ pub fn remove_file<P: AsPath + ?Sized>(path: &P) -> io::Result<()> {
/// This function will return an error if the user lacks the requisite /// 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 /// permissions to perform a `metadata` call on the given `path` or if there
/// is no entry in the filesystem at the provided path. /// is no entry in the filesystem at the provided path.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn metadata<P: AsPath + ?Sized>(path: &P) -> io::Result<Metadata> { pub fn metadata<P: AsPath + ?Sized>(path: &P) -> io::Result<Metadata> {
fs_imp::stat(path.as_path()).map(Metadata) fs_imp::stat(path.as_path()).map(Metadata)
} }
@ -438,6 +458,7 @@ pub fn metadata<P: AsPath + ?Sized>(path: &P) -> io::Result<Metadata> {
/// the process lacks permissions to view the contents, if `from` and `to` /// the process lacks permissions to view the contents, if `from` and `to`
/// reside on separate filesystems, or if some other intermittent I/O error /// reside on separate filesystems, or if some other intermittent I/O error
/// occurs. /// occurs.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn rename<P: AsPath + ?Sized, Q: AsPath + ?Sized>(from: &P, to: &Q) pub fn rename<P: AsPath + ?Sized, Q: AsPath + ?Sized>(from: &P, to: &Q)
-> io::Result<()> { -> io::Result<()> {
fs_imp::rename(from.as_path(), to.as_path()) fs_imp::rename(from.as_path(), to.as_path())
@ -468,6 +489,7 @@ pub fn rename<P: AsPath + ?Sized, Q: AsPath + ?Sized>(from: &P, to: &Q)
/// * The `from` file does not exist /// * The `from` file does not exist
/// * The current process does not have the permission rights to access /// * The current process does not have the permission rights to access
/// `from` or write `to` /// `from` or write `to`
#[stable(feature = "rust1", since = "1.0.0")]
pub fn copy<P: AsPath + ?Sized, Q: AsPath + ?Sized>(from: &P, to: &Q) pub fn copy<P: AsPath + ?Sized, Q: AsPath + ?Sized>(from: &P, to: &Q)
-> io::Result<u64> { -> io::Result<u64> {
let from = from.as_path(); let from = from.as_path();
@ -490,6 +512,7 @@ pub fn copy<P: AsPath + ?Sized, Q: AsPath + ?Sized>(from: &P, to: &Q)
/// ///
/// The `dst` path will be a link pointing to the `src` path. Note that systems /// 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. /// often require these two paths to both be located on the same filesystem.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn hard_link<P: AsPath + ?Sized, Q: AsPath + ?Sized>(src: &P, dst: &Q) pub fn hard_link<P: AsPath + ?Sized, Q: AsPath + ?Sized>(src: &P, dst: &Q)
-> io::Result<()> { -> io::Result<()> {
fs_imp::link(src.as_path(), dst.as_path()) fs_imp::link(src.as_path(), dst.as_path())
@ -498,6 +521,7 @@ pub fn hard_link<P: AsPath + ?Sized, Q: AsPath + ?Sized>(src: &P, dst: &Q)
/// Creates a new soft link on the filesystem. /// Creates a new soft link on the filesystem.
/// ///
/// The `dst` path will be a soft link pointing to the `src` path. /// The `dst` path will be a soft link pointing to the `src` path.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn soft_link<P: AsPath + ?Sized, Q: AsPath + ?Sized>(src: &P, dst: &Q) pub fn soft_link<P: AsPath + ?Sized, Q: AsPath + ?Sized>(src: &P, dst: &Q)
-> io::Result<()> { -> io::Result<()> {
fs_imp::symlink(src.as_path(), dst.as_path()) fs_imp::symlink(src.as_path(), dst.as_path())
@ -510,6 +534,7 @@ pub fn soft_link<P: AsPath + ?Sized, Q: AsPath + ?Sized>(src: &P, dst: &Q)
/// This function will return an error on failure. Failure conditions include /// 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 /// reading a file that does not exist or reading a file that is not a soft
/// link. /// link.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn read_link<P: AsPath + ?Sized>(path: &P) -> io::Result<PathBuf> { pub fn read_link<P: AsPath + ?Sized>(path: &P) -> io::Result<PathBuf> {
fs_imp::readlink(path.as_path()) fs_imp::readlink(path.as_path())
} }
@ -528,6 +553,7 @@ pub fn read_link<P: AsPath + ?Sized>(path: &P) -> io::Result<PathBuf> {
/// ///
/// This function will return an error if the user lacks permissions to make a /// 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. /// new directory at the provided `path`, or if the directory already exists.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn create_dir<P: AsPath + ?Sized>(path: &P) -> io::Result<()> { pub fn create_dir<P: AsPath + ?Sized>(path: &P) -> io::Result<()> {
fs_imp::mkdir(path.as_path()) fs_imp::mkdir(path.as_path())
} }
@ -541,6 +567,7 @@ pub fn create_dir<P: AsPath + ?Sized>(path: &P) -> io::Result<()> {
/// does not already exist and it could not be created otherwise. The specific /// 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 /// error conditions for when a directory is being created (after it is
/// determined to not exist) are outlined by `fs::create_dir`. /// determined to not exist) are outlined by `fs::create_dir`.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn create_dir_all<P: AsPath + ?Sized>(path: &P) -> io::Result<()> { pub fn create_dir_all<P: AsPath + ?Sized>(path: &P) -> io::Result<()> {
let path = path.as_path(); let path = path.as_path();
if path.is_dir() { return Ok(()) } if path.is_dir() { return Ok(()) }
@ -572,6 +599,7 @@ pub fn create_dir_all<P: AsPath + ?Sized>(path: &P) -> io::Result<()> {
/// ///
/// This function will return an error if the user lacks permissions to remove /// 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. /// the directory at the provided `path`, or if the directory isn't empty.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn remove_dir<P: AsPath + ?Sized>(path: &P) -> io::Result<()> { pub fn remove_dir<P: AsPath + ?Sized>(path: &P) -> io::Result<()> {
fs_imp::rmdir(path.as_path()) fs_imp::rmdir(path.as_path())
} }
@ -585,6 +613,7 @@ pub fn remove_dir<P: AsPath + ?Sized>(path: &P) -> io::Result<()> {
/// # Errors /// # Errors
/// ///
/// See `file::remove_file` and `fs::remove_dir` /// See `file::remove_file` and `fs::remove_dir`
#[stable(feature = "rust1", since = "1.0.0")]
pub fn remove_dir_all<P: AsPath + ?Sized>(path: &P) -> io::Result<()> { pub fn remove_dir_all<P: AsPath + ?Sized>(path: &P) -> io::Result<()> {
let path = path.as_path(); let path = path.as_path();
for child in try!(read_dir(path)) { for child in try!(read_dir(path)) {
@ -637,6 +666,7 @@ pub fn remove_dir_all<P: AsPath + ?Sized>(path: &P) -> io::Result<()> {
/// This function will return an error if the provided `path` doesn't exist, if /// 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 /// the process lacks permissions to view the contents or if the `path` points
/// at a non-directory file /// at a non-directory file
#[stable(feature = "rust1", since = "1.0.0")]
pub fn read_dir<P: AsPath + ?Sized>(path: &P) -> io::Result<ReadDir> { pub fn read_dir<P: AsPath + ?Sized>(path: &P) -> io::Result<ReadDir> {
fs_imp::readdir(path.as_path()).map(ReadDir) fs_imp::readdir(path.as_path()).map(ReadDir)
} }
@ -649,11 +679,16 @@ pub fn read_dir<P: AsPath + ?Sized>(path: &P) -> io::Result<ReadDir> {
/// ///
/// The iterator will yield instances of `io::Result<DirEntry>`. New errors may /// The iterator will yield instances of `io::Result<DirEntry>`. New errors may
/// be encountered after an iterator is initially constructed. /// 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<P: AsPath + ?Sized>(path: &P) -> io::Result<WalkDir> { pub fn walk_dir<P: AsPath + ?Sized>(path: &P) -> io::Result<WalkDir> {
let start = try!(read_dir(path)); let start = try!(read_dir(path));
Ok(WalkDir { cur: Some(start), stack: Vec::new() }) Ok(WalkDir { cur: Some(start), stack: Vec::new() })
} }
#[unstable(feature = "fs_walk")]
impl Iterator for WalkDir { impl Iterator for WalkDir {
type Item = io::Result<DirEntry>; type Item = io::Result<DirEntry>;
@ -683,6 +718,9 @@ impl Iterator for WalkDir {
} }
/// Utility methods for paths. /// 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 { pub trait PathExt {
/// Get information on the file, directory, etc at this path. /// 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 /// 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 /// `atime` and its modification time set to `mtime`. The times specified should
/// be in milliseconds. /// 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<P: AsPath + ?Sized>(path: &P, accessed: u64, pub fn set_file_times<P: AsPath + ?Sized>(path: &P, accessed: u64,
modified: u64) -> io::Result<()> { modified: u64) -> io::Result<()> {
fs_imp::utimes(path.as_path(), accessed, modified) fs_imp::utimes(path.as_path(), accessed, modified)
@ -752,6 +794,10 @@ pub fn set_file_times<P: AsPath + ?Sized>(path: &P, accessed: u64,
/// This function will return an error if the provided `path` doesn't exist, if /// 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 /// the process lacks permissions to change the attributes of the file, or if
/// some other I/O error is encountered. /// 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<P: AsPath + ?Sized>(path: &P, perm: Permissions) pub fn set_permissions<P: AsPath + ?Sized>(path: &P, perm: Permissions)
-> io::Result<()> { -> io::Result<()> {
fs_imp::set_perm(path.as_path(), perm.0) fs_imp::set_perm(path.as_path(), perm.0)
@ -1267,6 +1313,8 @@ mod tests {
check!(fs::set_permissions(&input, p)); check!(fs::set_permissions(&input, p));
check!(fs::copy(&input, &out)); check!(fs::copy(&input, &out));
assert!(check!(out.metadata()).permissions().readonly()); 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? #[cfg(not(windows))] // FIXME(#10264) operation not permitted?
@ -1350,10 +1398,13 @@ mod tests {
let attr = check!(fs::metadata(&file)); let attr = check!(fs::metadata(&file));
assert!(attr.permissions().readonly()); assert!(attr.permissions().readonly());
match fs::set_permissions(&tmpdir.join("foo"), p) { match fs::set_permissions(&tmpdir.join("foo"), p.clone()) {
Ok(..) => panic!("wanted a panic"), Ok(..) => panic!("wanted an error"),
Err(..) => {} Err(..) => {}
} }
p.set_readonly(false);
check!(fs::set_permissions(&file, p));
} }
#[test] #[test]
@ -1506,6 +1557,7 @@ mod tests {
} }
#[test] #[test]
#[cfg(not(windows))]
fn unlink_readonly() { fn unlink_readonly() {
let tmpdir = tmpdir(); let tmpdir = tmpdir();
let path = tmpdir.join("file"); let path = tmpdir.join("file");

View file

@ -9,6 +9,9 @@
// except according to those terms. // except according to those terms.
#![unstable(feature = "tempdir", reason = "needs an RFC before stabilization")] #![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::*; use prelude::v1::*;

View file

@ -8,8 +8,6 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
#![allow(missing_copy_implementations)]
use prelude::v1::*; use prelude::v1::*;
use io::prelude::*; use io::prelude::*;
@ -32,6 +30,7 @@ use slice;
/// Implementations of the I/O traits for `Cursor<T>` are not currently generic /// Implementations of the I/O traits for `Cursor<T>` are not currently generic
/// over `T` itself. Instead, specific implementations are provided for various /// over `T` itself. Instead, specific implementations are provided for various
/// in-memory buffer types like `Vec<u8>` and `&[u8]`. /// in-memory buffer types like `Vec<u8>` and `&[u8]`.
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Cursor<T> { pub struct Cursor<T> {
inner: T, inner: T,
pos: u64, pos: u64,
@ -39,26 +38,32 @@ pub struct Cursor<T> {
impl<T> Cursor<T> { impl<T> Cursor<T> {
/// Create a new cursor wrapping the provided underlying I/O object. /// Create a new cursor wrapping the provided underlying I/O object.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn new(inner: T) -> Cursor<T> { pub fn new(inner: T) -> Cursor<T> {
Cursor { pos: 0, inner: inner } Cursor { pos: 0, inner: inner }
} }
/// Consume this cursor, returning the underlying value. /// Consume this cursor, returning the underlying value.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn into_inner(self) -> T { self.inner } pub fn into_inner(self) -> T { self.inner }
/// Get a reference to the underlying value in this cursor. /// 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 } pub fn get_ref(&self) -> &T { &self.inner }
/// Get a mutable reference to the underlying value in this cursor. /// 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 /// Care should be taken to avoid modifying the internal I/O state of the
/// underlying value as it may corrupt this cursor's position. /// 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 } pub fn get_mut(&mut self) -> &mut T { &mut self.inner }
/// Returns the current value of this cursor /// Returns the current value of this cursor
#[stable(feature = "rust1", since = "1.0.0")]
pub fn position(&self) -> u64 { self.pos } pub fn position(&self) -> u64 { self.pos }
/// Sets the value of this cursor /// Sets the value of this cursor
#[stable(feature = "rust1", since = "1.0.0")]
pub fn set_position(&mut self, pos: u64) { self.pos = pos; } 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!(); } 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!(); } impl<'a> io::Seek for Cursor<&'a mut [u8]> { seek!(); }
#[stable(feature = "rust1", since = "1.0.0")]
impl io::Seek for Cursor<Vec<u8>> { seek!(); } impl io::Seek for Cursor<Vec<u8>> { seek!(); }
macro_rules! read { 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!(); } impl<'a> Read for Cursor<&'a [u8]> { read!(); }
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a> Read for Cursor<&'a mut [u8]> { read!(); } impl<'a> Read for Cursor<&'a mut [u8]> { read!(); }
#[stable(feature = "rust1", since = "1.0.0")]
impl Read for Cursor<Vec<u8>> { read!(); } impl Read for Cursor<Vec<u8>> { read!(); }
macro_rules! buffer { 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!(); } impl<'a> BufRead for Cursor<&'a [u8]> { buffer!(); }
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a> BufRead for Cursor<&'a mut [u8]> { buffer!(); } impl<'a> BufRead for Cursor<&'a mut [u8]> { buffer!(); }
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a> BufRead for Cursor<Vec<u8>> { buffer!(); } impl<'a> BufRead for Cursor<Vec<u8>> { buffer!(); }
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a> Write for Cursor<&'a mut [u8]> { impl<'a> Write for Cursor<&'a mut [u8]> {
fn write(&mut self, data: &[u8]) -> io::Result<usize> { fn write(&mut self, data: &[u8]) -> io::Result<usize> {
let pos = cmp::min(self.pos, self.inner.len() as u64); 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(()) } fn flush(&mut self) -> io::Result<()> { Ok(()) }
} }
#[stable(feature = "rust1", since = "1.0.0")]
impl Write for Cursor<Vec<u8>> { impl Write for Cursor<Vec<u8>> {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> { fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
// Make sure the internal buffer is as least as big as where we // Make sure the internal buffer is as least as big as where we

View file

@ -22,57 +22,88 @@ use vec::Vec;
// ============================================================================= // =============================================================================
// Forwarding implementations // Forwarding implementations
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, R: Read + ?Sized> Read for &'a mut R { impl<'a, R: Read + ?Sized> Read for &'a mut R {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { (**self).read(buf) } fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
(**self).read(buf)
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<()> { (**self).read_to_end(buf) } }
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<()> {
(**self).read_to_end(buf)
}
fn read_to_string(&mut self, buf: &mut String) -> io::Result<()> { fn read_to_string(&mut self, buf: &mut String) -> io::Result<()> {
(**self).read_to_string(buf) (**self).read_to_string(buf)
} }
} }
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, W: Write + ?Sized> Write for &'a mut W { impl<'a, W: Write + ?Sized> Write for &'a mut W {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> { (**self).write(buf) } fn write(&mut self, buf: &[u8]) -> io::Result<usize> { (**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 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 { impl<'a, S: Seek + ?Sized> Seek for &'a mut S {
fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> { (**self).seek(pos) } fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> { (**self).seek(pos) }
} }
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, B: BufRead + ?Sized> BufRead for &'a mut B { impl<'a, B: BufRead + ?Sized> BufRead for &'a mut B {
fn fill_buf(&mut self) -> io::Result<&[u8]> { (**self).fill_buf() } fn fill_buf(&mut self) -> io::Result<&[u8]> { (**self).fill_buf() }
fn consume(&mut self, amt: usize) { (**self).consume(amt) } fn consume(&mut self, amt: usize) { (**self).consume(amt) }
fn read_until(&mut self, byte: u8, buf: &mut Vec<u8>) -> io::Result<()> { fn read_until(&mut self, byte: u8, buf: &mut Vec<u8>) -> io::Result<()> {
(**self).read_until(byte, buf) (**self).read_until(byte, buf)
} }
fn read_line(&mut self, buf: &mut String) -> io::Result<()> {
fn read_line(&mut self, buf: &mut String) -> io::Result<()> { (**self).read_line(buf) } (**self).read_line(buf)
}
} }
#[stable(feature = "rust1", since = "1.0.0")]
impl<R: Read + ?Sized> Read for Box<R> { impl<R: Read + ?Sized> Read for Box<R> {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { (**self).read(buf) } fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
(**self).read(buf)
}
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> 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<W: Write + ?Sized> Write for Box<W> { impl<W: Write + ?Sized> Write for Box<W> {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> { (**self).write(buf) } fn write(&mut self, buf: &[u8]) -> io::Result<usize> { (**self).write(buf) }
fn flush(&mut self) -> io::Result<()> { (**self).flush() } 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<S: Seek + ?Sized> Seek for Box<S> { impl<S: Seek + ?Sized> Seek for Box<S> {
fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> { (**self).seek(pos) } fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> { (**self).seek(pos) }
} }
#[stable(feature = "rust1", since = "1.0.0")]
impl<B: BufRead + ?Sized> BufRead for Box<B> { impl<B: BufRead + ?Sized> BufRead for Box<B> {
fn fill_buf(&mut self) -> io::Result<&[u8]> { (**self).fill_buf() } fn fill_buf(&mut self) -> io::Result<&[u8]> { (**self).fill_buf() }
fn consume(&mut self, amt: usize) { (**self).consume(amt) } fn consume(&mut self, amt: usize) { (**self).consume(amt) }
fn read_until(&mut self, byte: u8, buf: &mut Vec<u8>) -> 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 // In-memory buffer implementations
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a> Read for &'a [u8] { impl<'a> Read for &'a [u8] {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
let amt = cmp::min(buf.len(), self.len()); 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] { impl<'a> BufRead for &'a [u8] {
fn fill_buf(&mut self) -> io::Result<&[u8]> { Ok(*self) } fn fill_buf(&mut self) -> io::Result<&[u8]> { Ok(*self) }
fn consume(&mut self, amt: usize) { *self = &self[amt..]; } fn consume(&mut self, amt: usize) { *self = &self[amt..]; }
} }
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a> Write for &'a mut [u8] { impl<'a> Write for &'a mut [u8] {
fn write(&mut self, data: &[u8]) -> io::Result<usize> { fn write(&mut self, data: &[u8]) -> io::Result<usize> {
let amt = cmp::min(data.len(), self.len()); 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(()) } fn flush(&mut self) -> io::Result<()> { Ok(()) }
} }
#[stable(feature = "rust1", since = "1.0.0")]
impl Write for Vec<u8> { impl Write for Vec<u8> {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> { fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.push_all(buf); self.push_all(buf);
@ -115,7 +149,7 @@ impl Write for Vec<u8> {
} }
fn write_all(&mut self, buf: &[u8]) -> io::Result<()> { fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
try!(self.write(buf)); self.push_all(buf);
Ok(()) Ok(())
} }

View file

@ -237,11 +237,13 @@ pub trait Read {
/// Extension methods for all instances of `Read`, typically imported through /// Extension methods for all instances of `Read`, typically imported through
/// `std::io::prelude::*`. /// `std::io::prelude::*`.
#[unstable(feature = "io", reason = "may merge into the Read trait")]
pub trait ReadExt: Read + Sized { pub trait ReadExt: Read + Sized {
/// Create a "by reference" adaptor for this instance of `Read`. /// Create a "by reference" adaptor for this instance of `Read`.
/// ///
/// The returned adaptor also implements `Read` and will simply borrow this /// The returned adaptor also implements `Read` and will simply borrow this
/// current reader. /// current reader.
#[stable(feature = "rust1", since = "1.0.0")]
fn by_ref(&mut self) -> &mut Self { self } fn by_ref(&mut self) -> &mut Self { self }
/// Transform this `Read` instance to an `Iterator` over its bytes. /// 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 /// 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 /// `Err` otherwise for I/O errors. EOF is mapped to returning `None` from
/// this iterator. /// this iterator.
#[stable(feature = "rust1", since = "1.0.0")]
fn bytes(self) -> Bytes<Self> { fn bytes(self) -> Bytes<Self> {
Bytes { inner: self } Bytes { inner: self }
} }
@ -264,6 +267,9 @@ pub trait ReadExt: Read + Sized {
/// ///
/// Currently this adaptor will discard intermediate data read, and should /// Currently this adaptor will discard intermediate data read, and should
/// be avoided if this is not desired. /// 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<Self> { fn chars(self) -> Chars<Self> {
Chars { inner: self } Chars { inner: self }
} }
@ -273,6 +279,7 @@ pub trait ReadExt: Read + Sized {
/// The returned `Read` instance will first read all bytes from this object /// The returned `Read` instance will first read all bytes from this object
/// until EOF is encountered. Afterwards the output is equivalent to the /// until EOF is encountered. Afterwards the output is equivalent to the
/// output of `next`. /// output of `next`.
#[stable(feature = "rust1", since = "1.0.0")]
fn chain<R: Read>(self, next: R) -> Chain<Self, R> { fn chain<R: Read>(self, next: R) -> Chain<Self, R> {
Chain { first: self, second: next, done_first: false } 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 /// `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 /// read errors will not count towards the number of bytes read and future
/// calls to `read` may succeed. /// calls to `read` may succeed.
#[stable(feature = "rust1", since = "1.0.0")]
fn take(self, limit: u64) -> Take<Self> { fn take(self, limit: u64) -> Take<Self> {
Take { inner: self, limit: limit } 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 /// Whenever the returned `Read` instance is read it will write the read
/// data to `out`. The current semantics of this implementation imply that /// data to `out`. The current semantics of this implementation imply that
/// a `write` error will not report how much data was initially read. /// 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<W: Write>(self, out: W) -> Tee<Self, W> { fn tee<W: Write>(self, out: W) -> Tee<Self, W> {
Tee { reader: self, writer: out } Tee { reader: self, writer: out }
} }
@ -415,11 +426,13 @@ pub trait Write {
/// Extension methods for all instances of `Write`, typically imported through /// Extension methods for all instances of `Write`, typically imported through
/// `std::io::prelude::*`. /// `std::io::prelude::*`.
#[unstable(feature = "io", reason = "may merge into the Read trait")]
pub trait WriteExt: Write + Sized { pub trait WriteExt: Write + Sized {
/// Create a "by reference" adaptor for this instance of `Write`. /// Create a "by reference" adaptor for this instance of `Write`.
/// ///
/// The returned adaptor also implements `Write` and will simply borrow this /// The returned adaptor also implements `Write` and will simply borrow this
/// current writer. /// current writer.
#[stable(feature = "rust1", since = "1.0.0")]
fn by_ref(&mut self) -> &mut Self { self } fn by_ref(&mut self) -> &mut Self { self }
/// Creates a new writer which will write all data to both this writer and /// 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 /// implementation do not precisely track where errors happen. For example
/// an error on the second call to `write` will not report that the first /// an error on the second call to `write` will not report that the first
/// call to `write` succeeded. /// 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<W: Write>(self, other: W) -> Broadcast<Self, W> { fn broadcast<W: Write>(self, other: W) -> Broadcast<Self, W> {
Broadcast { first: self, second: other } Broadcast { first: self, second: other }
} }
} }
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: Write> WriteExt for T {} impl<T: Write> WriteExt for T {}
/// An object implementing `Seek` internally has some form of cursor which can /// 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 /// This function will yield errors whenever `read_until` would have also
/// yielded an error. /// yielded an error.
#[unstable(feature = "io", reason = "may be renamed to not conflict with \
SliceExt::split")]
fn split(self, byte: u8) -> Split<Self> { fn split(self, byte: u8) -> Split<Self> {
Split { buf: self, delim: byte } 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 /// This function will yield errors whenever `read_string` would have also
/// yielded an error. /// yielded an error.
#[stable(feature = "rust1", since = "1.0.0")]
fn lines(self) -> Lines<Self> { fn lines(self) -> Lines<Self> {
Lines { buf: self } Lines { buf: self }
} }
} }
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: BufRead> BufReadExt for T {} impl<T: BufRead> BufReadExt for T {}
/// A `Write` adaptor which will write data to multiple locations. /// A `Write` adaptor which will write data to multiple locations.
@ -635,12 +656,14 @@ impl<T: Write, U: Write> Write for Broadcast<T, U> {
/// Adaptor to chain together two instances of `Read`. /// Adaptor to chain together two instances of `Read`.
/// ///
/// For more information, see `ReadExt::chain`. /// For more information, see `ReadExt::chain`.
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Chain<T, U> { pub struct Chain<T, U> {
first: T, first: T,
second: U, second: U,
done_first: bool, done_first: bool,
} }
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: Read, U: Read> Read for Chain<T, U> { impl<T: Read, U: Read> Read for Chain<T, U> {
fn read(&mut self, buf: &mut [u8]) -> Result<usize> { fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
if !self.done_first { if !self.done_first {
@ -656,11 +679,13 @@ impl<T: Read, U: Read> Read for Chain<T, U> {
/// Reader adaptor which limits the bytes read from an underlying reader. /// Reader adaptor which limits the bytes read from an underlying reader.
/// ///
/// For more information, see `ReadExt::take`. /// For more information, see `ReadExt::take`.
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Take<T> { pub struct Take<T> {
inner: T, inner: T,
limit: u64, limit: u64,
} }
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> Take<T> { impl<T> Take<T> {
/// Returns the number of bytes that can be read before this instance will /// Returns the number of bytes that can be read before this instance will
/// return EOF. /// return EOF.
@ -669,9 +694,11 @@ impl<T> Take<T> {
/// ///
/// This instance may reach EOF after reading fewer bytes than indicated by /// This instance may reach EOF after reading fewer bytes than indicated by
/// this method if the underlying `Read` instance reaches EOF. /// this method if the underlying `Read` instance reaches EOF.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn limit(&self) -> u64 { self.limit } pub fn limit(&self) -> u64 { self.limit }
} }
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: Read> Read for Take<T> { impl<T: Read> Read for Take<T> {
fn read(&mut self, buf: &mut [u8]) -> Result<usize> { fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
// Don't call into inner reader at all at EOF because it may still block // Don't call into inner reader at all at EOF because it may still block
@ -686,6 +713,7 @@ impl<T: Read> Read for Take<T> {
} }
} }
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: BufRead> BufRead for Take<T> { impl<T: BufRead> BufRead for Take<T> {
fn fill_buf(&mut self) -> Result<&[u8]> { fn fill_buf(&mut self) -> Result<&[u8]> {
let buf = try!(self.inner.fill_buf()); let buf = try!(self.inner.fill_buf());
@ -721,10 +749,12 @@ impl<R: Read, W: Write> Read for Tee<R, W> {
/// A bridge from implementations of `Read` to an `Iterator` of `u8`. /// A bridge from implementations of `Read` to an `Iterator` of `u8`.
/// ///
/// See `ReadExt::bytes` for more information. /// See `ReadExt::bytes` for more information.
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Bytes<R> { pub struct Bytes<R> {
inner: R, inner: R,
} }
#[stable(feature = "rust1", since = "1.0.0")]
impl<R: Read> Iterator for Bytes<R> { impl<R: Read> Iterator for Bytes<R> {
type Item = Result<u8>; type Item = Result<u8>;
@ -845,10 +875,12 @@ impl<B: BufRead> Iterator for Split<B> {
/// byte. /// byte.
/// ///
/// See `BufReadExt::lines` for more information. /// See `BufReadExt::lines` for more information.
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Lines<B> { pub struct Lines<B> {
buf: B, buf: B,
} }
#[stable(feature = "rust1", since = "1.0.0")]
impl<B: BufRead> Iterator for Lines<B> { impl<B: BufRead> Iterator for Lines<B> {
type Item = Result<String>; type Item = Result<String>;

View file

@ -157,9 +157,6 @@ impl Read for Stdin {
impl<'a> Read for StdinLock<'a> { impl<'a> Read for StdinLock<'a> {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
// 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) self.inner.read(buf)
} }
} }

View file

@ -12,7 +12,7 @@
use prelude::v1::*; 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. /// 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 /// This function will return an error immediately if any call to `read` or
/// `write` returns an error. All instances of `ErrorKind::Interrupted` are /// `write` returns an error. All instances of `ErrorKind::Interrupted` are
/// handled by this function and the underlying operation is retried. /// handled by this function and the underlying operation is retried.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn copy<R: Read, W: Write>(r: &mut R, w: &mut W) -> io::Result<u64> { pub fn copy<R: Read, W: Write>(r: &mut R, w: &mut W) -> io::Result<u64> {
let mut buf = [0; super::DEFAULT_BUF_SIZE]; let mut buf = [0; super::DEFAULT_BUF_SIZE];
let mut written = 0; let mut written = 0;
@ -43,26 +44,37 @@ pub fn copy<R: Read, W: Write>(r: &mut R, w: &mut W) -> io::Result<u64> {
} }
/// A reader which is always at EOF. /// A reader which is always at EOF.
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Empty { _priv: () } pub struct Empty { _priv: () }
/// Creates an instance of an empty reader. /// Creates an instance of an empty reader.
/// ///
/// All reads from the returned reader will return `Ok(0)`. /// All reads from the returned reader will return `Ok(0)`.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn empty() -> Empty { Empty { _priv: () } } pub fn empty() -> Empty { Empty { _priv: () } }
#[stable(feature = "rust1", since = "1.0.0")]
impl Read for Empty { impl Read for Empty {
fn read(&mut self, _buf: &mut [u8]) -> io::Result<usize> { Ok(0) } fn read(&mut self, _buf: &mut [u8]) -> io::Result<usize> { 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. /// A reader which infinitely yields one byte.
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Repeat { byte: u8 } pub struct Repeat { byte: u8 }
/// Creates an instance of a reader that infinitely repeats one byte. /// Creates an instance of a reader that infinitely repeats one byte.
/// ///
/// All reads from this reader will succeed by filling the specified buffer with /// All reads from this reader will succeed by filling the specified buffer with
/// the given byte. /// the given byte.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn repeat(byte: u8) -> Repeat { Repeat { byte: byte } } pub fn repeat(byte: u8) -> Repeat { Repeat { byte: byte } }
#[stable(feature = "rust1", since = "1.0.0")]
impl Read for Repeat { impl Read for Repeat {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
for slot in buf.iter_mut() { for slot in buf.iter_mut() {
@ -73,14 +85,17 @@ impl Read for Repeat {
} }
/// A writer which will move data into the void. /// A writer which will move data into the void.
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Sink { _priv: () } pub struct Sink { _priv: () }
/// Creates an instance of a writer which will successfully consume all data. /// 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())` /// All calls to `write` on the returned instance will return `Ok(buf.len())`
/// and the contents of the buffer will not be inspected. /// and the contents of the buffer will not be inspected.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn sink() -> Sink { Sink { _priv: () } } pub fn sink() -> Sink { Sink { _priv: () } }
#[stable(feature = "rust1", since = "1.0.0")]
impl Write for Sink { impl Write for Sink {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> { Ok(buf.len()) } fn write(&mut self, buf: &[u8]) -> io::Result<usize> { Ok(buf.len()) }
fn flush(&mut self) -> io::Result<()> { Ok(()) } fn flush(&mut self) -> io::Result<()> { Ok(()) }

View file

@ -94,7 +94,8 @@
//! to all code by default. [`macros`](macros/index.html) contains //! to all code by default. [`macros`](macros/index.html) contains
//! all the standard macros, such as `assert!`, `panic!`, `println!`, //! all the standard macros, such as `assert!`, `panic!`, `println!`,
//! and `format!`, also available to all Rust code. //! 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"] #![crate_name = "std"]
#![stable(feature = "rust1", since = "1.0.0")] #![stable(feature = "rust1", since = "1.0.0")]
#![staged_api] #![staged_api]

View file

@ -293,7 +293,7 @@ impl ToSocketAddrs for str {
} }
// split the string by ':' and convert the second part to u16 // 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 port_str = try_opt!(parts_iter.next(), "invalid socket address");
let host = 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"); 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); let a = SocketAddr::new(IpAddr::new_v4(127, 0, 0, 1), 23924);
assert!(tsa("localhost:23924").unwrap().contains(&a)); 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());
}
} }

View file

@ -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] #[test]
fn bind_error() { fn bind_error() {
match TcpListener::bind("0.0.0.0:1") { match TcpListener::bind("1.1.1.1:9999") {
Ok(..) => panic!(), Ok(..) => panic!(),
Err(e) => assert_eq!(e.kind(), ErrorKind::PermissionDenied), Err(e) =>
// EADDRNOTAVAIL is mapped to ConnectionRefused
assert_eq!(e.kind(), ErrorKind::ConnectionRefused),
} }
} }

View file

@ -10,6 +10,10 @@
//! Networking I/O //! 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 old_io::{IoError, IoResult, InvalidInput};
use ops::FnMut; use ops::FnMut;
use option::Option::None; use option::Option::None;

View file

@ -19,6 +19,12 @@
//! instances as clients. //! instances as clients.
#![allow(missing_docs)] #![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::*; use prelude::v1::*;

View file

@ -11,6 +11,9 @@
//! Bindings for executing child processes //! Bindings for executing child processes
#![allow(non_upper_case_globals)] #![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::StdioContainer::*;
pub use self::ProcessExit::*; pub use self::ProcessExit::*;

View file

@ -10,6 +10,8 @@
//! Utility implementations of Reader and Writer //! Utility implementations of Reader and Writer
#![allow(deprecated)]
use prelude::v1::*; use prelude::v1::*;
use cmp; use cmp;
use old_io; 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. /// Wraps a `Reader`, limiting the number of bytes that can be read from it.
#[derive(Debug)] #[derive(Debug)]
#[deprecated(since = "1.0.0", reason = "use std::io::Take")]
#[unstable(feature = "old_io")]
pub struct LimitReader<R> { pub struct LimitReader<R> {
limit: uint, limit: uint,
inner: R inner: R
} }
#[deprecated(since = "1.0.0", reason = "use std::io::Take")]
#[unstable(feature = "old_io")]
impl<R: Reader> LimitReader<R> { impl<R: Reader> LimitReader<R> {
/// Creates a new `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<R> { pub fn new(r: R, limit: uint) -> LimitReader<R> {
LimitReader { limit: limit, inner: r } LimitReader { limit: limit, inner: r }
} }
@ -41,6 +49,8 @@ impl<R: Reader> LimitReader<R> {
pub fn limit(&self) -> uint { self.limit } 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<R: Reader> Reader for LimitReader<R> { impl<R: Reader> Reader for LimitReader<R> {
fn read(&mut self, buf: &mut [u8]) -> old_io::IoResult<uint> { fn read(&mut self, buf: &mut [u8]) -> old_io::IoResult<uint> {
if self.limit == 0 { if self.limit == 0 {
@ -57,6 +67,8 @@ impl<R: Reader> Reader for LimitReader<R> {
} }
} }
#[deprecated(since = "1.0.0", reason = "use std::io's take method instead")]
#[unstable(feature = "old_io")]
impl<R: Buffer> Buffer for LimitReader<R> { impl<R: Buffer> Buffer for LimitReader<R> {
fn fill_buf<'a>(&'a mut self) -> old_io::IoResult<&'a [u8]> { fn fill_buf<'a>(&'a mut self) -> old_io::IoResult<&'a [u8]> {
let amt = try!(self.inner.fill_buf()); let amt = try!(self.inner.fill_buf());
@ -79,8 +91,12 @@ impl<R: Buffer> Buffer for LimitReader<R> {
/// A `Writer` which ignores bytes written to it, like /dev/null. /// A `Writer` which ignores bytes written to it, like /dev/null.
#[derive(Copy, Debug)] #[derive(Copy, Debug)]
#[deprecated(since = "1.0.0", reason = "use std::io::sink() instead")]
#[unstable(feature = "old_io")]
pub struct NullWriter; pub struct NullWriter;
#[deprecated(since = "1.0.0", reason = "use std::io::sink() instead")]
#[unstable(feature = "old_io")]
impl Writer for NullWriter { impl Writer for NullWriter {
#[inline] #[inline]
fn write_all(&mut self, _buf: &[u8]) -> old_io::IoResult<()> { Ok(()) } 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. /// A `Reader` which returns an infinite stream of 0 bytes, like /dev/zero.
#[derive(Copy, Debug)] #[derive(Copy, Debug)]
#[deprecated(since = "1.0.0", reason = "use std::io::repeat(0) instead")]
#[unstable(feature = "old_io")]
pub struct ZeroReader; pub struct ZeroReader;
#[deprecated(since = "1.0.0", reason = "use std::io::repeat(0) instead")]
#[unstable(feature = "old_io")]
impl Reader for ZeroReader { impl Reader for ZeroReader {
#[inline] #[inline]
fn read(&mut self, buf: &mut [u8]) -> old_io::IoResult<uint> { fn read(&mut self, buf: &mut [u8]) -> old_io::IoResult<uint> {
@ -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 { impl Buffer for ZeroReader {
fn fill_buf<'a>(&'a mut self) -> old_io::IoResult<&'a [u8]> { fn fill_buf<'a>(&'a mut self) -> old_io::IoResult<&'a [u8]> {
static DATA: [u8; 64] = [0; 64]; static DATA: [u8; 64] = [0; 64];
@ -109,8 +131,12 @@ impl Buffer for ZeroReader {
/// A `Reader` which is always at EOF, like /dev/null. /// A `Reader` which is always at EOF, like /dev/null.
#[derive(Copy, Debug)] #[derive(Copy, Debug)]
#[deprecated(since = "1.0.0", reason = "use std::io::empty() instead")]
#[unstable(feature = "old_io")]
pub struct NullReader; pub struct NullReader;
#[deprecated(since = "1.0.0", reason = "use std::io::empty() instead")]
#[unstable(feature = "old_io")]
impl Reader for NullReader { impl Reader for NullReader {
#[inline] #[inline]
fn read(&mut self, _buf: &mut [u8]) -> old_io::IoResult<uint> { fn read(&mut self, _buf: &mut [u8]) -> old_io::IoResult<uint> {
@ -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 { impl Buffer for NullReader {
fn fill_buf<'a>(&'a mut self) -> old_io::IoResult<&'a [u8]> { fn fill_buf<'a>(&'a mut self) -> old_io::IoResult<&'a [u8]> {
Err(old_io::standard_error(old_io::EndOfFile)) 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, /// 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. /// that error is returned immediately and remaining `Writer`s are not called.
#[derive(Debug)] #[derive(Debug)]
#[deprecated(since = "1.0.0", reason = "use std::io::Broadcast instead")]
#[unstable(feature = "old_io")]
pub struct MultiWriter<W> { pub struct MultiWriter<W> {
writers: Vec<W> writers: Vec<W>
} }
impl<W> MultiWriter<W> where W: Writer { impl<W> MultiWriter<W> where W: Writer {
/// Creates a new `MultiWriter` /// 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<W>) -> MultiWriter<W> { pub fn new(writers: Vec<W>) -> MultiWriter<W> {
MultiWriter { writers: writers } MultiWriter { writers: writers }
} }
} }
#[deprecated(since = "1.0.0", reason = "use std::io::Broadcast instead")]
#[unstable(feature = "old_io")]
impl<W> Writer for MultiWriter<W> where W: Writer { impl<W> Writer for MultiWriter<W> where W: Writer {
#[inline] #[inline]
fn write_all(&mut self, buf: &[u8]) -> old_io::IoResult<()> { fn write_all(&mut self, buf: &[u8]) -> old_io::IoResult<()> {
@ -162,6 +196,8 @@ impl<W> Writer for MultiWriter<W> where W: Writer {
/// A `Reader` which chains input from multiple `Reader`s, reading each to /// A `Reader` which chains input from multiple `Reader`s, reading each to
/// completion before moving onto the next. /// completion before moving onto the next.
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
#[deprecated(since = "1.0.0", reason = "use std::io::Chain instead")]
#[unstable(feature = "old_io")]
pub struct ChainedReader<I, R> { pub struct ChainedReader<I, R> {
readers: I, readers: I,
cur_reader: Option<R>, cur_reader: Option<R>,
@ -169,12 +205,16 @@ pub struct ChainedReader<I, R> {
impl<R: Reader, I: Iterator<Item=R>> ChainedReader<I, R> { impl<R: Reader, I: Iterator<Item=R>> ChainedReader<I, R> {
/// Creates a new `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<I, R> { pub fn new(mut readers: I) -> ChainedReader<I, R> {
let r = readers.next(); let r = readers.next();
ChainedReader { readers: readers, cur_reader: r } ChainedReader { readers: readers, cur_reader: r }
} }
} }
#[deprecated(since = "1.0.0", reason = "use std::io::Chain instead")]
#[unstable(feature = "old_io")]
impl<R: Reader, I: Iterator<Item=R>> Reader for ChainedReader<I, R> { impl<R: Reader, I: Iterator<Item=R>> Reader for ChainedReader<I, R> {
fn read(&mut self, buf: &mut [u8]) -> old_io::IoResult<uint> { fn read(&mut self, buf: &mut [u8]) -> old_io::IoResult<uint> {
loop { loop {
@ -201,13 +241,19 @@ impl<R: Reader, I: Iterator<Item=R>> Reader for ChainedReader<I, R> {
/// A `Reader` which forwards input from another `Reader`, passing it along to /// A `Reader` which forwards input from another `Reader`, passing it along to
/// a `Writer` as well. Similar to the `tee(1)` command. /// a `Writer` as well. Similar to the `tee(1)` command.
#[derive(Debug)] #[derive(Debug)]
#[deprecated(since = "1.0.0", reason = "use std::io::Tee instead")]
#[unstable(feature = "old_io")]
pub struct TeeReader<R, W> { pub struct TeeReader<R, W> {
reader: R, reader: R,
writer: W, writer: W,
} }
#[deprecated(since = "1.0.0", reason = "use std::io::Tee instead")]
#[unstable(feature = "old_io")]
impl<R: Reader, W: Writer> TeeReader<R, W> { impl<R: Reader, W: Writer> TeeReader<R, W> {
/// Creates a new `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<R, W> { pub fn new(r: R, w: W) -> TeeReader<R, W> {
TeeReader { reader: r, writer: w } TeeReader { reader: r, writer: w }
} }
@ -220,6 +266,8 @@ impl<R: Reader, W: Writer> TeeReader<R, W> {
} }
} }
#[deprecated(since = "1.0.0", reason = "use std::io::Tee instead")]
#[unstable(feature = "old_io")]
impl<R: Reader, W: Writer> Reader for TeeReader<R, W> { impl<R: Reader, W: Writer> Reader for TeeReader<R, W> {
fn read(&mut self, buf: &mut [u8]) -> old_io::IoResult<uint> { fn read(&mut self, buf: &mut [u8]) -> old_io::IoResult<uint> {
self.reader.read(buf).and_then(|len| { self.reader.read(buf).and_then(|len| {
@ -229,6 +277,8 @@ impl<R: Reader, W: Writer> Reader for TeeReader<R, W> {
} }
/// Copies all data from a `Reader` to a `Writer`. /// 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: Reader, W: Writer>(r: &mut R, w: &mut W) -> old_io::IoResult<()> { pub fn copy<R: Reader, W: Writer>(r: &mut R, w: &mut W) -> old_io::IoResult<()> {
let mut buf = [0; super::DEFAULT_BUF_SIZE]; let mut buf = [0; super::DEFAULT_BUF_SIZE];
loop { loop {

12
src/libstd/path.rs Executable file → Normal file
View file

@ -90,7 +90,7 @@
//! * Repeated separators are ignored: `a/b` and `a//b` both have components `a` //! * Repeated separators are ignored: `a/b` and `a//b` both have components `a`
//! and `b`. //! 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 //! 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 //! 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 //! `a/b/.` both have components `a`, `b`, and `.` (current directory). The
@ -872,10 +872,10 @@ impl PathBuf {
// `path` is a pure relative path // `path` is a pure relative path
} else if need_sep { } 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()`. /// Truncate `self` to `self.parent()`.
@ -937,8 +937,8 @@ impl PathBuf {
let extension = extension.as_os_str(); let extension = extension.as_os_str();
if os_str_as_u8_slice(extension).len() > 0 { if os_str_as_u8_slice(extension).len() > 0 {
stem.push_os_str(OsStr::from_str(".")); stem.push(".");
stem.push_os_str(extension.as_os_str()); stem.push(extension);
} }
self.set_file_name(&stem); self.set_file_name(&stem);
@ -1193,7 +1193,7 @@ impl Path {
iter_after(self.components(), base.as_path().components()).is_some() 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<P: ?Sized>(&self, child: &P) -> bool where P: AsPath { pub fn ends_with<P: ?Sized>(&self, child: &P) -> bool where P: AsPath {
iter_after(self.components().rev(), child.as_path().components().rev()).is_some() iter_after(self.components().rev(), child.as_path().components().rev()).is_some()
} }

View file

@ -8,6 +8,8 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
#![allow(deprecated)]
use prelude::v1::*; use prelude::v1::*;
use self::SocketStatus::*; use self::SocketStatus::*;
use self::InAddr::*; use self::InAddr::*;

View file

@ -73,42 +73,49 @@ impl AsRawFd for old_io::pipe::PipeStream {
} }
} }
#[allow(deprecated)]
impl AsRawFd for old_io::net::pipe::UnixStream { impl AsRawFd for old_io::net::pipe::UnixStream {
fn as_raw_fd(&self) -> Fd { fn as_raw_fd(&self) -> Fd {
self.as_inner().fd() self.as_inner().fd()
} }
} }
#[allow(deprecated)]
impl AsRawFd for old_io::net::pipe::UnixListener { impl AsRawFd for old_io::net::pipe::UnixListener {
fn as_raw_fd(&self) -> Fd { fn as_raw_fd(&self) -> Fd {
self.as_inner().fd() self.as_inner().fd()
} }
} }
#[allow(deprecated)]
impl AsRawFd for old_io::net::pipe::UnixAcceptor { impl AsRawFd for old_io::net::pipe::UnixAcceptor {
fn as_raw_fd(&self) -> Fd { fn as_raw_fd(&self) -> Fd {
self.as_inner().fd() self.as_inner().fd()
} }
} }
#[allow(deprecated)]
impl AsRawFd for old_io::net::tcp::TcpStream { impl AsRawFd for old_io::net::tcp::TcpStream {
fn as_raw_fd(&self) -> Fd { fn as_raw_fd(&self) -> Fd {
self.as_inner().fd() self.as_inner().fd()
} }
} }
#[allow(deprecated)]
impl AsRawFd for old_io::net::tcp::TcpListener { impl AsRawFd for old_io::net::tcp::TcpListener {
fn as_raw_fd(&self) -> Fd { fn as_raw_fd(&self) -> Fd {
self.as_inner().fd() self.as_inner().fd()
} }
} }
#[allow(deprecated)]
impl AsRawFd for old_io::net::tcp::TcpAcceptor { impl AsRawFd for old_io::net::tcp::TcpAcceptor {
fn as_raw_fd(&self) -> Fd { fn as_raw_fd(&self) -> Fd {
self.as_inner().fd() self.as_inner().fd()
} }
} }
#[allow(deprecated)]
impl AsRawFd for old_io::net::udp::UdpSocket { impl AsRawFd for old_io::net::udp::UdpSocket {
fn as_raw_fd(&self) -> Fd { fn as_raw_fd(&self) -> Fd {
self.as_inner().fd() self.as_inner().fd()

View file

@ -8,6 +8,8 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
#![allow(deprecated)]
use prelude::v1::*; use prelude::v1::*;
use self::Req::*; use self::Req::*;

View file

@ -8,6 +8,8 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
#![allow(deprecated)]
use prelude::v1::*; use prelude::v1::*;
use old_io::net::ip; use old_io::net::ip;

View file

@ -58,18 +58,21 @@ impl AsRawHandle for old_io::pipe::PipeStream {
} }
} }
#[allow(deprecated)]
impl AsRawHandle for old_io::net::pipe::UnixStream { impl AsRawHandle for old_io::net::pipe::UnixStream {
fn as_raw_handle(&self) -> Handle { fn as_raw_handle(&self) -> Handle {
self.as_inner().handle() self.as_inner().handle()
} }
} }
#[allow(deprecated)]
impl AsRawHandle for old_io::net::pipe::UnixListener { impl AsRawHandle for old_io::net::pipe::UnixListener {
fn as_raw_handle(&self) -> Handle { fn as_raw_handle(&self) -> Handle {
self.as_inner().handle() self.as_inner().handle()
} }
} }
#[allow(deprecated)]
impl AsRawHandle for old_io::net::pipe::UnixAcceptor { impl AsRawHandle for old_io::net::pipe::UnixAcceptor {
fn as_raw_handle(&self) -> Handle { fn as_raw_handle(&self) -> Handle {
self.as_inner().handle() self.as_inner().handle()
@ -81,24 +84,28 @@ pub trait AsRawSocket {
fn as_raw_socket(&self) -> Socket; fn as_raw_socket(&self) -> Socket;
} }
#[allow(deprecated)]
impl AsRawSocket for old_io::net::tcp::TcpStream { impl AsRawSocket for old_io::net::tcp::TcpStream {
fn as_raw_socket(&self) -> Socket { fn as_raw_socket(&self) -> Socket {
self.as_inner().fd() self.as_inner().fd()
} }
} }
#[allow(deprecated)]
impl AsRawSocket for old_io::net::tcp::TcpListener { impl AsRawSocket for old_io::net::tcp::TcpListener {
fn as_raw_socket(&self) -> Socket { fn as_raw_socket(&self) -> Socket {
self.as_inner().socket() self.as_inner().socket()
} }
} }
#[allow(deprecated)]
impl AsRawSocket for old_io::net::tcp::TcpAcceptor { impl AsRawSocket for old_io::net::tcp::TcpAcceptor {
fn as_raw_socket(&self) -> Socket { fn as_raw_socket(&self) -> Socket {
self.as_inner().socket() self.as_inner().socket()
} }
} }
#[allow(deprecated)]
impl AsRawSocket for old_io::net::udp::UdpSocket { impl AsRawSocket for old_io::net::udp::UdpSocket {
fn as_raw_socket(&self) -> Socket { fn as_raw_socket(&self) -> Socket {
self.as_inner().fd() self.as_inner().fd()

View file

@ -8,6 +8,8 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
#![allow(deprecated)]
use prelude::v1::*; use prelude::v1::*;
use collections; use collections;

View file

@ -8,6 +8,8 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
#![allow(deprecated)]
use old_io::net::ip; use old_io::net::ip;
use old_io::IoResult; use old_io::IoResult;
use libc; use libc;

View file

@ -14,6 +14,8 @@
//! //!
//! This API is completely unstable and subject to change. //! 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"] #![crate_name = "syntax"]
#![unstable(feature = "rustc_private")] #![unstable(feature = "rustc_private")]
#![staged_api] #![staged_api]
@ -37,8 +39,8 @@
#![feature(std_misc)] #![feature(std_misc)]
#![feature(unicode)] #![feature(unicode)]
#![feature(path)] #![feature(path)]
#![feature(fs)]
#![feature(io)] #![feature(io)]
#![feature(path_ext)]
extern crate arena; extern crate arena;
extern crate fmt_macros; extern crate fmt_macros;

View file

@ -38,6 +38,8 @@
//! [win]: http://msdn.microsoft.com/en-us/library/windows/desktop/ms682010%28v=vs.85%29.aspx //! [win]: http://msdn.microsoft.com/en-us/library/windows/desktop/ms682010%28v=vs.85%29.aspx
//! [ti]: https://en.wikipedia.org/wiki/Terminfo //! [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"] #![crate_name = "term"]
#![unstable(feature = "rustc_private", #![unstable(feature = "rustc_private",
reason = "use the crates.io `term` library instead")] reason = "use the crates.io `term` library instead")]
@ -52,7 +54,6 @@
#![feature(box_syntax)] #![feature(box_syntax)]
#![feature(collections)] #![feature(collections)]
#![feature(fs)]
#![feature(int_uint)] #![feature(int_uint)]
#![feature(io)] #![feature(io)]
#![feature(old_io)] #![feature(old_io)]
@ -61,6 +62,7 @@
#![feature(staged_api)] #![feature(staged_api)]
#![feature(std_misc)] #![feature(std_misc)]
#![feature(unicode)] #![feature(unicode)]
#![feature(path_ext)]
#![cfg_attr(windows, feature(libc))] #![cfg_attr(windows, feature(libc))]
#[macro_use] extern crate log; #[macro_use] extern crate log;

View file

@ -23,6 +23,8 @@
// running tests while providing a base that other test frameworks may // running tests while providing a base that other test frameworks may
// build off of. // build off of.
// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364)
#![cfg_attr(stage0, feature(custom_attribute))]
#![crate_name = "test"] #![crate_name = "test"]
#![unstable(feature = "test")] #![unstable(feature = "test")]
#![staged_api] #![staged_api]
@ -39,7 +41,6 @@
#![feature(int_uint)] #![feature(int_uint)]
#![feature(old_io)] #![feature(old_io)]
#![feature(path)] #![feature(path)]
#![feature(fs)]
#![feature(rustc_private)] #![feature(rustc_private)]
#![feature(staged_api)] #![feature(staged_api)]
#![feature(std_misc)] #![feature(std_misc)]

View file

@ -20,6 +20,8 @@
//! provide for basic string-related manipulations. This crate does not //! provide for basic string-related manipulations. This crate does not
//! (yet) aim to provide a full set of Unicode tables. //! (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"] #![crate_name = "unicode"]
#![unstable(feature = "unicode")] #![unstable(feature = "unicode")]
#![feature(staged_api)] #![feature(staged_api)]

View file

@ -11,10 +11,11 @@
//! Implementation of the `build` subcommand, used to compile a book. //! Implementation of the `build` subcommand, used to compile a book.
use std::env; use std::env;
use std::fs::{self, File, TempDir}; use std::fs::{self, File};
use std::io::prelude::*; use std::io::prelude::*;
use std::io::{self, BufWriter}; use std::io::{self, BufWriter};
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use rustc_back::tempdir::TempDir;
use subcommand::Subcommand; use subcommand::Subcommand;
use term::Term; use term::Term;

View file

@ -12,14 +12,14 @@
#![feature(core)] #![feature(core)]
#![feature(exit_status)] #![feature(exit_status)]
#![feature(fs)]
#![feature(io)] #![feature(io)]
#![feature(old_io)] #![feature(old_io)]
#![feature(path)] #![feature(path)]
#![feature(rustdoc)] #![feature(rustdoc)]
#![feature(tempdir)] #![feature(rustc_private)]
extern crate rustdoc; extern crate rustdoc;
extern crate rustc_back;
use std::env; use std::env;
use std::error::Error; use std::error::Error;

0
src/test/auxiliary/lint_output_format.rs Executable file → Normal file
View file

View file

@ -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 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// 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<T: Trait>(x: T) {}
fn main() {
// ICE
call_method(());
}

View file

@ -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 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// 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<T: Trait>(x: T) {
x.method();
}
fn main() {
// ICE
call_method(());
}

View file

@ -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 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// Ensure that OIBIT checks `T` when it encounters a `PhantomData<T>` field, instead of checking
// the `PhantomData<T>` 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>(T);
fn is_zen<T: Zen>(_: T) {}
fn not_sync<T>(x: Guard<T>) {
is_zen(x) //~ error: the trait `core::marker::Sync` is not implemented for the type `T`
}
fn nested_not_sync<T>(x: Nested<Guard<T>>) {
is_zen(x) //~ error: the trait `core::marker::Sync` is not implemented for the type `T`
}
fn main() {}

View file

@ -9,7 +9,6 @@
// except according to those terms. // except according to those terms.
// aux-build:privacy-tuple-struct.rs // aux-build:privacy-tuple-struct.rs
// ignore-fast
extern crate "privacy-tuple-struct" as other; extern crate "privacy-tuple-struct" as other;

View file

View file

@ -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 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// 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<bool> = 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;
}

View file

@ -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 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// 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() {()}

View file

@ -9,6 +9,7 @@
// except according to those terms. // except according to those terms.
// error-pattern:thread '<main>' panicked at 'arithmetic operation overflowed' // error-pattern:thread '<main>' panicked at 'arithmetic operation overflowed'
// compile-flags: -C debug-assertions
// (Work around constant-evaluation) // (Work around constant-evaluation)
fn value() -> u8 { 200 } fn value() -> u8 { 200 }

View file

@ -9,6 +9,7 @@
// except according to those terms. // except according to those terms.
// error-pattern:thread '<main>' panicked at 'arithmetic operation overflowed' // error-pattern:thread '<main>' panicked at 'arithmetic operation overflowed'
// compile-flags: -C debug-assertions
// (Work around constant-evaluation) // (Work around constant-evaluation)
fn value() -> u8 { 200 } fn value() -> u8 { 200 }

View file

@ -9,6 +9,7 @@
// except according to those terms. // except according to those terms.
// error-pattern:thread '<main>' panicked at 'arithmetic operation overflowed' // error-pattern:thread '<main>' panicked at 'arithmetic operation overflowed'
// compile-flags: -C debug-assertions
// (Work around constant-evaluation) // (Work around constant-evaluation)
fn value() -> u8 { 42 } fn value() -> u8 { 42 }

View file

@ -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

View file

@ -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 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![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);
}

0
src/test/run-make/mismatching-target-triples/bar.rs Executable file → Normal file
View file

0
src/test/run-make/mismatching-target-triples/foo.rs Executable file → Normal file
View file

0
src/test/run-make/pretty-expanded-hygiene/input.pp.rs Executable file → Normal file
View file

0
src/test/run-make/pretty-expanded-hygiene/input.rs Executable file → Normal file
View file

Some files were not shown because too many files have changed in this diff Show more