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

View file

@ -590,7 +590,7 @@ TEST_SREQ$(1)_T_$(2)_H_$(3) = \
# The tests select when to use debug configuration on their own;
# remove directive, if present, from CFG_RUSTC_FLAGS (issue #7898).
CTEST_RUSTC_FLAGS := $$(subst --cfg ndebug,,$$(CFG_RUSTC_FLAGS))
CTEST_RUSTC_FLAGS := $$(subst -C debug-assertions,,$$(CFG_RUSTC_FLAGS))
# The tests cannot be optimized while the rest of the compiler is optimized, so
# filter out the optimization (if any) from rustc and then figure out if we need

View file

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

View file

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

View file

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

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,
this is just convention.)
There's an alternate form of `vec!` for repeating an initial value:
```
let v = vec![0; 10]; // ten zeroes
```
You can get the length of, iterate over, and subscript vectors just like
arrays. In addition, (mutable) vectors can grow automatically:

View file

@ -56,6 +56,8 @@
//! The [`heap`](heap/index.html) module defines the low-level interface to the
//! default global allocator. It is not compatible with the libc allocator API.
// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364)
#![cfg_attr(stage0, feature(custom_attribute))]
#![crate_name = "alloc"]
#![unstable(feature = "alloc")]
#![feature(staged_api)]

View file

@ -19,6 +19,8 @@
//! arena but can only hold objects of a single type, and `Arena`, which is a
//! more complex, slower arena which can hold objects of any type.
// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364)
#![cfg_attr(stage0, feature(custom_attribute))]
#![crate_name = "arena"]
#![unstable(feature = "rustc_private")]
#![staged_api]

View file

@ -12,7 +12,8 @@
//!
//! See [std::collections](../std/collections) for a detailed discussion of collections in Rust.
// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364)
#![cfg_attr(stage0, feature(custom_attribute))]
#![crate_name = "collections"]
#![unstable(feature = "collections")]
#![staged_api]

View file

@ -1086,7 +1086,7 @@ fn char_range_at(&self, start: usize) -> CharRange {
///
/// let s = "中华Việt Nam";
/// let mut i = s.len();
/// while i < 0 {
/// while i > 0 {
/// let CharRange {ch, next} = s.char_range_at_reverse(i);
/// println!("{}: {}", i, ch);
/// i = next;

View file

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

View file

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

View file

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

View file

@ -8,6 +8,8 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364)
#![cfg_attr(stage0, feature(custom_attribute))]
#![feature(box_syntax)]
#![feature(int_uint)]
#![feature(unboxed_closures)]

View file

@ -14,6 +14,8 @@
//! [def]: https://en.wikipedia.org/wiki/DEFLATE
//! [mz]: https://code.google.com/p/miniz/
// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364)
#![cfg_attr(stage0, feature(custom_attribute))]
#![crate_name = "flate"]
#![unstable(feature = "rustc_private")]
#![staged_api]

View file

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

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"]
#![unstable(feature = "rustc_private",
reason = "use the crates.io `getopts` library instead")]
@ -92,8 +95,8 @@
#![feature(collections)]
#![feature(int_uint)]
#![feature(staged_api)]
#![feature(str_words)]
#![feature(core)]
#![feature(str_words)]
#![cfg_attr(test, feature(rustc_private))]
#[cfg(test)] #[macro_use] extern crate log;

View file

@ -264,6 +264,8 @@
//!
//! * [DOT language](http://www.graphviz.org/doc/info/lang.html)
// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364)
#![cfg_attr(stage0, feature(custom_attribute))]
#![crate_name = "graphviz"]
#![unstable(feature = "rustc_private")]
#![feature(staged_api)]

View file

@ -8,6 +8,8 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364)
#![cfg_attr(stage0, feature(custom_attribute))]
#![crate_name = "libc"]
#![crate_type = "rlib"]
#![cfg_attr(not(feature = "cargo-build"), unstable(feature = "libc"))]
@ -383,7 +385,8 @@ pub mod c99 {
target_arch = "mips",
target_arch = "mipsel",
target_arch = "powerpc",
target_arch = "le32"))]
target_arch = "le32",
all(target_arch = "arm", not(target_os = "android"))))]
pub mod posix88 {
pub type off_t = i32;
pub type dev_t = u64;
@ -395,7 +398,7 @@ pub mod posix88 {
pub type mode_t = u32;
pub type ssize_t = i32;
}
#[cfg(target_arch = "arm")]
#[cfg(all(target_arch = "arm", target_os = "android"))]
pub mod posix88 {
pub type off_t = i32;
pub type dev_t = u32;
@ -409,7 +412,8 @@ pub mod posix88 {
}
#[cfg(any(target_arch = "x86",
target_arch = "le32",
target_arch = "powerpc"))]
target_arch = "powerpc",
all(target_arch = "arm", not(target_os = "android"))))]
pub mod posix01 {
use types::os::arch::c95::{c_short, c_long, time_t};
use types::os::arch::posix88::{dev_t, gid_t, ino_t};
@ -455,7 +459,7 @@ pub mod posix01 {
pub __size: [u32; 9]
}
}
#[cfg(target_arch = "arm")]
#[cfg(all(target_arch = "arm", target_os = "android"))]
pub mod posix01 {
use types::os::arch::c95::{c_uchar, c_uint, c_ulong, time_t};
use types::os::arch::c99::{c_longlong, c_ulonglong};
@ -4999,9 +5003,36 @@ pub mod fcntl {
use types::os::arch::c95::{c_char, c_int};
use types::os::arch::posix88::mode_t;
mod open_shim {
extern {
#[cfg(any(target_os = "macos",
target_os = "ios"))]
pub fn open(path: *const ::c_char, oflag: ::c_int, ...)
-> ::c_int;
#[cfg(not(any(target_os = "macos",
target_os = "ios")))]
pub fn open(path: *const ::c_char, oflag: ::c_int, mode: ::mode_t)
-> ::c_int;
}
}
#[cfg(any(target_os = "macos",
target_os = "ios"))]
#[inline]
pub unsafe extern fn open(path: *const c_char, oflag: c_int, mode: mode_t) -> c_int {
use types::os::arch::c95::c_uint;
open_shim::open(path, oflag, mode as c_uint)
}
#[cfg(not(any(target_os = "macos",
target_os = "ios")))]
#[inline]
pub unsafe extern fn open(path: *const c_char, oflag: c_int, mode: mode_t) -> c_int {
open_shim::open(path, oflag, mode)
}
extern {
pub fn open(path: *const c_char, oflag: c_int, mode: mode_t)
-> c_int;
pub fn creat(path: *const c_char, mode: mode_t) -> c_int;
pub fn fcntl(fd: c_int, cmd: c_int, ...) -> c_int;
}

View file

@ -155,6 +155,8 @@
//! they're turned off (just a load and an integer comparison). This also means that
//! if logging is disabled, none of the components of the log will be executed.
// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364)
#![cfg_attr(stage0, feature(custom_attribute))]
#![crate_name = "log"]
#![unstable(feature = "rustc_private",
reason = "use the crates.io `log` library instead")]

View file

@ -157,7 +157,7 @@ macro_rules! info {
/// ```
#[macro_export]
macro_rules! debug {
($($arg:tt)*) => (if cfg!(not(ndebug)) { log!(::log::DEBUG, $($arg)*) })
($($arg:tt)*) => (if cfg!(debug_assertions) { log!(::log::DEBUG, $($arg)*) })
}
/// A macro to test whether a log level is enabled for the current module.
@ -192,7 +192,7 @@ macro_rules! debug {
macro_rules! log_enabled {
($lvl:expr) => ({
let lvl = $lvl;
(lvl != ::log::DEBUG || cfg!(not(ndebug))) &&
(lvl != ::log::DEBUG || cfg!(debug_assertions)) &&
lvl <= ::log::log_level() &&
::log::mod_enabled(lvl, module_path!())
})

View file

@ -16,6 +16,8 @@
//! is not recommended to use this library directly, but rather the official
//! interface through `std::rand`.
// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364)
#![cfg_attr(stage0, feature(custom_attribute))]
#![crate_name = "rand"]
#![crate_type = "rlib"]
#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk.png",

View file

@ -111,6 +111,8 @@
//!
//! First 0x20 tags are reserved by RBML; custom tags start at 0x20.
// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364)
#![cfg_attr(stage0, feature(custom_attribute))]
#![crate_name = "rbml"]
#![unstable(feature = "rustc_private")]
#![staged_api]

View file

@ -14,6 +14,8 @@
//!
//! This API is completely unstable and subject to change.
// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364)
#![cfg_attr(stage0, feature(custom_attribute))]
#![crate_name = "rustc"]
#![unstable(feature = "rustc_private")]
#![staged_api]
@ -38,10 +40,10 @@
#![feature(unsafe_destructor)]
#![feature(staged_api)]
#![feature(std_misc)]
#![feature(os)]
#![feature(path)]
#![feature(fs)]
#![feature(io)]
#![feature(path_ext)]
#![feature(str_words)]
#![cfg_attr(test, feature(test))]
extern crate arena;

View file

@ -1692,6 +1692,13 @@ fn constituent_types_for_ty(&self, t: Ty<'tcx>) -> Option<Vec<Ty<'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) => {
Some(ty::struct_fields(self.tcx(), def_id, substs).iter()
.map(|f| f.mt.ty)

View file

@ -81,6 +81,7 @@ pub struct Options {
pub gc: bool,
pub optimize: OptLevel,
pub debug_assertions: bool,
pub debuginfo: DebugInfoLevel,
pub lint_opts: Vec<(String, lint::Level)>,
pub describe_lints: bool,
@ -238,7 +239,8 @@ pub fn basic_options() -> Options {
crate_name: None,
alt_std_name: None,
libs: Vec::new(),
unstable_features: UnstableFeatures::Disallow
unstable_features: UnstableFeatures::Disallow,
debug_assertions: true,
}
}
@ -528,6 +530,8 @@ fn parse_passes(slot: &mut Passes, v: Option<&str>) -> bool {
2 = full debug info with variable and type information"),
opt_level: Option<uint> = (None, parse_opt_uint,
"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;
return vec!(// Target bindings.
let mut ret = vec![ // Target bindings.
attr::mk_word_item(fam.clone()),
mk(InternedString::new("target_os"), intern(os)),
mk(InternedString::new("target_family"), fam),
@ -629,7 +633,11 @@ pub fn default_configuration(sess: &Session) -> ast::CrateConfig {
mk(InternedString::new("target_endian"), intern(end)),
mk(InternedString::new("target_pointer_width"),
intern(wordsz))
);
];
if sess.opts.debug_assertions {
ret.push(attr::mk_word_item(InternedString::new("debug_assertions")));
}
return ret;
}
pub fn append_configuration(cfg: &mut ast::CrateConfig,
@ -923,6 +931,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
}
}
};
let debug_assertions = cg.debug_assertions.unwrap_or(opt_level == No);
let gc = debugging_opts.gc;
let debuginfo = if matches.opt_present("g") {
if cg.debuginfo.is_some() {
@ -1064,6 +1073,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
alt_std_name: None,
libs: libs,
unstable_features: get_unstable_features_setting(),
debug_assertions: debug_assertions,
}
}

View file

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

View file

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

View file

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

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
// except according to those terms.
// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364)
#![cfg_attr(stage0, feature(custom_attribute))]
#![crate_name = "rustc_bitflags"]
#![feature(staged_api)]
#![staged_api]

View file

@ -8,6 +8,8 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364)
#![cfg_attr(stage0, feature(custom_attribute))]
#![crate_name = "rustc_borrowck"]
#![unstable(feature = "rustc_private")]
#![staged_api]

View file

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

View file

@ -14,6 +14,8 @@
//!
//! This API is completely unstable and subject to change.
// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364)
#![cfg_attr(stage0, feature(custom_attribute))]
#![crate_name = "rustc_driver"]
#![unstable(feature = "rustc_private")]
#![staged_api]
@ -29,7 +31,6 @@
#![feature(int_uint)]
#![feature(old_io)]
#![feature(libc)]
#![feature(os)]
#![feature(quote)]
#![feature(rustc_diagnostic_macros)]
#![feature(rustc_private)]
@ -39,7 +40,6 @@
#![feature(exit_status)]
#![feature(path)]
#![feature(io)]
#![feature(fs)]
extern crate arena;
extern crate flate;
@ -775,6 +775,7 @@ fn parse_crate_attrs(sess: &Session, input: &Input) ->
///
/// The diagnostic emitter yielded to the procedure should be used for reporting
/// errors of the compiler.
#[allow(deprecated)]
pub fn monitor<F:FnOnce()+Send+'static>(f: F) {
const STACK_SIZE: uint = 8 * 1024 * 1024; // 8MB

View file

@ -19,6 +19,8 @@
//!
//! This API is completely unstable and subject to change.
// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364)
#![cfg_attr(stage0, feature(custom_attribute))]
#![crate_name = "rustc_lint"]
#![unstable(feature = "rustc_private")]
#![staged_api]

View file

@ -8,6 +8,8 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364)
#![cfg_attr(stage0, feature(custom_attribute))]
#![allow(non_upper_case_globals)]
#![allow(non_camel_case_types)]
#![allow(non_snake_case)]
@ -29,8 +31,8 @@
#![feature(libc)]
#![feature(link_args)]
#![feature(staged_api)]
#![feature(std_misc)]
#![feature(path)]
#![cfg_attr(unix, feature(std_misc))]
extern crate libc;
#[macro_use] #[no_link] extern crate rustc_bitflags;

View file

@ -8,6 +8,8 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364)
#![cfg_attr(stage0, feature(custom_attribute))]
#![crate_name = "rustc_privacy"]
#![unstable(feature = "rustc_private")]
#![staged_api]

View file

@ -8,6 +8,8 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364)
#![cfg_attr(stage0, feature(custom_attribute))]
#![crate_name = "rustc_resolve"]
#![unstable(feature = "rustc_private")]
#![staged_api]

View file

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

View file

@ -14,6 +14,8 @@
//!
//! This API is completely unstable and subject to change.
// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364)
#![cfg_attr(stage0, feature(custom_attribute))]
#![crate_name = "rustc_trans"]
#![unstable(feature = "rustc_private")]
#![staged_api]
@ -35,13 +37,12 @@
#![feature(rustc_private)]
#![feature(unsafe_destructor)]
#![feature(staged_api)]
#![feature(std_misc)]
#![feature(unicode)]
#![feature(io)]
#![feature(fs)]
#![feature(path)]
#![feature(os)]
#![feature(tempdir)]
#![feature(path_ext)]
#![feature(fs)]
#![feature(hash)]
extern crate arena;
extern crate flate;

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 {
v
} else {
!attr::contains_name(&krate.config, "ndebug")
tcx.sess.opts.debug_assertions
};
// 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
} else {
ccx.sess().span_bug(ref_expr.span,
&format!("get_const_val given non-constant item {}",
&format!("get_const_expr given non-constant item {}",
item.repr(ccx.tcx())));
}
}

View file

@ -697,6 +697,7 @@ struct FunctionDebugContextData {
fn_metadata: DISubprogram,
argument_counter: Cell<uint>,
source_locations_enabled: Cell<bool>,
source_location_override: Cell<bool>,
}
enum VariableAccess<'a> {
@ -1176,6 +1177,12 @@ pub fn set_source_location(fcx: &FunctionContext,
return;
}
FunctionDebugContext::RegularContext(box ref function_debug_context) => {
if function_debug_context.source_location_override.get() {
// Just ignore any attempts to set a new debug location while
// the override is active.
return;
}
let cx = fcx.ccx;
debug!("set_source_location: {}", cx.sess().codemap().span_to_string(span));
@ -1194,6 +1201,35 @@ pub fn set_source_location(fcx: &FunctionContext,
}
}
/// This function makes sure that all debug locations emitted while executing
/// `wrapped_function` are set to the given `debug_loc`.
pub fn with_source_location_override<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.
///
/// Instructions generated hereafter won't be assigned a source location.
@ -1414,6 +1450,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
fn_metadata: fn_metadata,
argument_counter: Cell::new(1),
source_locations_enabled: Cell::new(false),
source_location_override: Cell::new(false),
};

View file

@ -147,7 +147,7 @@ pub fn trans_into<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
ast::ExprPath(..) => {
match bcx.def(expr.id) {
def::DefConst(did) => {
let expr = consts::get_const_expr(bcx.ccx(), did, expr);
let const_expr = consts::get_const_expr(bcx.ccx(), did, expr);
// Temporarily get cleanup scopes out of the way,
// as they require sub-expressions to be contained
// inside the current AST scope.
@ -155,7 +155,13 @@ pub fn trans_into<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
// can't have destructors.
let scopes = mem::replace(&mut *bcx.fcx.scopes.borrow_mut(),
vec![]);
bcx = trans_into(bcx, expr, dest);
// Lock emitted debug locations to the location of
// the constant reference expression.
debuginfo::with_source_location_override(bcx.fcx,
expr.debug_loc(),
|| {
bcx = trans_into(bcx, const_expr, dest)
});
let scopes = mem::replace(&mut *bcx.fcx.scopes.borrow_mut(),
scopes);
assert!(scopes.is_empty());

View file

@ -118,7 +118,7 @@ fn check_item_well_formed(&mut self, item: &ast::Item) {
self.check_variances_for_type_defn(item, ast_generics);
}
ast::ItemTrait(_, ref ast_generics, _, _) => {
ast::ItemTrait(_, ref ast_generics, _, ref items) => {
let trait_predicates =
ty::lookup_predicates(ccx.tcx, local_def(item.id));
reject_non_type_param_bounds(
@ -127,6 +127,14 @@ fn check_item_well_formed(&mut self, item: &ast::Item) {
&trait_predicates);
self.check_variances(item, ast_generics, &trait_predicates,
self.tcx().lang_items.phantom_fn());
if ty::trait_has_default_impl(ccx.tcx, local_def(item.id)) {
if !items.is_empty() {
ccx.tcx.sess.span_err(
item.span,
"traits with default impls (`e.g. unsafe impl Trait for ..`) must \
have no methods or associated items")
}
}
}
_ => {}
}

View file

@ -62,7 +62,8 @@
This API is completely unstable and subject to change.
*/
// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364)
#![cfg_attr(stage0, feature(custom_attribute))]
#![crate_name = "rustc_typeck"]
#![unstable(feature = "rustc_private")]
#![staged_api]

View file

@ -38,7 +38,6 @@
use std::cmp::Ordering;
use std::collections::{HashMap, HashSet};
use std::default::Default;
use std::ffi::OsStr;
use std::fmt;
use std::fs::{self, File};
use std::io::prelude::*;
@ -67,12 +66,10 @@
use html::layout;
use html::markdown::Markdown;
use html::markdown;
use html::escape::Escape;
use stability_summary;
/// A pair of name and its optional document.
#[derive(Clone, Eq, Ord, PartialEq, PartialOrd)]
pub struct NameDoc(String, Option<String>);
pub type NameDoc = (String, Option<String>);
/// Major driving force in all rustdoc rendering. This contains information
/// about where in the tree-like hierarchy rendering is occurring and controls
@ -98,12 +95,6 @@ pub struct Context {
/// This describes the layout of each page, and is not modified after
/// creation of the context (contains info like the favicon and added html).
pub layout: layout::Layout,
/// This map is a list of what should be displayed on the sidebar of the
/// current page. The key is the section header (traits, modules,
/// functions), and the value is the list of containers belonging to this
/// header. This map will change depending on the surrounding context of the
/// page.
pub sidebar: HashMap<String, Vec<NameDoc>>,
/// This flag indicates whether [src] links should be generated or not. If
/// the source files are present in the html rendering, then this will be
/// `true`.
@ -271,7 +262,6 @@ pub fn run(mut krate: clean::Crate,
passes: passes,
current: Vec::new(),
root_path: String::new(),
sidebar: HashMap::new(),
layout: layout::Layout {
logo: "".to_string(),
favicon: "".to_string(),
@ -770,7 +760,7 @@ fn emit_source(&mut self, filename: &str) -> io::Result<()> {
let mut fname = p.file_name().expect("source has no filename")
.to_os_string();
fname.push_os_str(OsStr::from_str(".html"));
fname.push(".html");
cur.push(&fname);
let mut w = BufWriter::new(try!(File::create(&cur)));
@ -1232,7 +1222,16 @@ fn render(w: File, cx: &Context, it: &clean::Item,
clean::ModuleItem(m) => m,
_ => unreachable!()
};
this.sidebar = this.build_sidebar(&m);
// render sidebar-items.js used throughout this module
{
let items = this.build_sidebar_items(&m);
let js_dst = this.dst.join("sidebar-items.js");
let mut js_out = BufWriter::new(try!(File::create(&js_dst)));
try!(write!(&mut js_out, "initSidebarItems({});",
json::as_json(&items)));
}
for item in m.items {
f(this,item);
}
@ -1252,15 +1251,11 @@ fn render(w: File, cx: &Context, it: &clean::Item,
}
}
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();
for item in &m.items {
if self.ignore_private_item(item) { continue }
// avoid putting foreign items to the sidebar.
if let &clean::ForeignFunctionItem(..) = &item.inner { continue }
if let &clean::ForeignStaticItem(..) = &item.inner { continue }
let short = shortty(item).to_static_str();
let myname = match item.name {
None => continue,
@ -1269,7 +1264,7 @@ fn build_sidebar(&self, m: &clean::Module) -> HashMap<String, Vec<NameDoc>> {
let short = short.to_string();
let v = map.entry(short).get().unwrap_or_else(
|vacant_entry| vacant_entry.insert(Vec::with_capacity(1)));
v.push(NameDoc(myname, Some(shorter_line(item.doc_value()))));
v.push((myname, Some(shorter_line(item.doc_value()))));
}
for (_, items) in &mut map {
@ -2216,9 +2211,18 @@ impl<'a> fmt::Display for Sidebar<'a> {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
let cx = self.cx;
let it = self.item;
let parentlen = cx.current.len() - if it.is_mod() {1} else {0};
// the sidebar is designed to display sibling functions, modules and
// other miscellaneous informations. since there are lots of sibling
// items (and that causes quadratic growth in large modules),
// we refactor common parts into a shared JavaScript file per module.
// still, we don't move everything into JS because we want to preserve
// as much HTML as possible in order to allow non-JS-enabled browsers
// to navigate the documentation (though slightly inefficiently).
try!(write!(fmt, "<p class='location'>"));
let len = cx.current.len() - if it.is_mod() {1} else {0};
for (i, name) in cx.current.iter().take(len).enumerate() {
for (i, name) in cx.current.iter().take(parentlen).enumerate() {
if i > 0 {
try!(write!(fmt, "::<wbr>"));
}
@ -2228,40 +2232,25 @@ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
}
try!(write!(fmt, "</p>"));
fn block(w: &mut fmt::Formatter, short: &str, longty: &str,
cur: &clean::Item, cx: &Context) -> fmt::Result {
let items = match cx.sidebar.get(short) {
Some(items) => items,
None => return Ok(())
};
try!(write!(w, "<div class='block {}'><h2>{}</h2>", short, longty));
for &NameDoc(ref name, ref doc) in items {
let curty = shortty(cur).to_static_str();
let class = if cur.name.as_ref().unwrap() == name &&
short == curty { "current" } else { "" };
try!(write!(w, "<a class='{ty} {class}' href='{href}{path}' \
title='{title}'>{name}</a>",
ty = short,
class = class,
href = if curty == "mod" {"../"} else {""},
path = if short == "mod" {
format!("{}/index.html", name)
} else {
format!("{}.{}.html", short, name)
},
title = Escape(doc.as_ref().unwrap()),
name = name));
}
try!(write!(w, "</div>"));
Ok(())
// sidebar refers to the enclosing module, not this module
let relpath = if shortty(it) == ItemType::Module { "../" } else { "" };
try!(write!(fmt,
"<script>window.sidebarCurrent = {{\
name: '{name}', \
ty: '{ty}', \
relpath: '{path}'\
}};</script>",
name = it.name.as_ref().map(|x| &x[..]).unwrap_or(""),
ty = shortty(it).to_static_str(),
path = relpath));
if parentlen == 0 {
// there is no sidebar-items.js beyond the crate root path
// FIXME maybe dynamic crate loading can be merged here
} else {
try!(write!(fmt, "<script async src=\"{path}sidebar-items.js\"></script>",
path = relpath));
}
try!(block(fmt, "mod", "Modules", it, cx));
try!(block(fmt, "struct", "Structs", it, cx));
try!(block(fmt, "enum", "Enums", it, cx));
try!(block(fmt, "trait", "Traits", it, cx));
try!(block(fmt, "fn", "Functions", it, cx));
try!(block(fmt, "macro", "Macros", it, cx));
Ok(())
}
}

View file

@ -15,6 +15,27 @@
"use strict";
var resizeTimeout, interval;
// This mapping table should match the discriminants of
// `rustdoc::html::item_type::ItemType` type in Rust.
var itemTypes = ["mod",
"externcrate",
"import",
"struct",
"enum",
"fn",
"type",
"static",
"trait",
"impl",
"tymethod",
"method",
"structfield",
"variant",
"macro",
"primitive",
"associatedtype",
"constant"];
$('.js-only').removeClass('js-only');
function getQueryStringParams() {
@ -552,27 +573,6 @@
showResults(results);
}
// This mapping table should match the discriminants of
// `rustdoc::html::item_type::ItemType` type in Rust.
var itemTypes = ["mod",
"externcrate",
"import",
"struct",
"enum",
"fn",
"type",
"static",
"trait",
"impl",
"tymethod",
"method",
"structfield",
"variant",
"macro",
"primitive",
"associatedtype",
"constant"];
function itemTypeFromName(typename) {
for (var i = 0; i < itemTypes.length; ++i) {
if (itemTypes[i] === typename) return i;
@ -708,6 +708,50 @@
window.initSearch = initSearch;
// delayed sidebar rendering.
function initSidebarItems(items) {
var sidebar = $('.sidebar');
var current = window.sidebarCurrent;
function block(shortty, longty) {
var filtered = items[shortty];
if (!filtered) return;
var div = $('<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) {
var list = $('#implementors-list');
var libs = Object.getOwnPropertyNames(imp);

View file

@ -15,7 +15,7 @@
if (window.playgroundUrl) {
$('pre.rust').hover(function() {
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=' +
encodeURIComponent(code));
a.attr('target', '_blank');

View file

@ -8,6 +8,8 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364)
#![cfg_attr(stage0, feature(custom_attribute))]
#![crate_name = "rustdoc"]
#![unstable(feature = "rustdoc")]
#![staged_api]
@ -35,9 +37,9 @@
#![feature(unicode)]
#![feature(str_words)]
#![feature(io)]
#![feature(fs)]
#![feature(path)]
#![feature(tempdir)]
#![feature(file_path)]
#![feature(path_ext)]
extern crate arena;
extern crate getopts;
@ -47,6 +49,7 @@
extern crate rustc_driver;
extern crate rustc_resolve;
extern crate rustc_lint;
extern crate rustc_back;
extern crate serialize;
extern crate syntax;
extern crate "test" as testing;

View file

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

View file

@ -14,6 +14,8 @@
Core encoding and decoding interfaces.
*/
// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364)
#![cfg_attr(stage0, feature(custom_attribute))]
#![crate_name = "serialize"]
#![unstable(feature = "rustc_private",
reason = "deprecated in favor of rustc-serialize on crates.io")]

View file

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

View file

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

View file

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

View file

@ -15,7 +15,7 @@
//! operations. Extra platform-specific functionality can be found in the
//! extension traits of `std::os::$platform`.
#![unstable(feature = "fs")]
#![stable(feature = "rust1", since = "1.0.0")]
use core::prelude::*;
@ -25,6 +25,7 @@
use sys_common::{AsInnerMut, FromInner, AsInner};
use vec::Vec;
#[allow(deprecated)]
pub use self::tempdir::TempDir;
mod tempdir;
@ -52,6 +53,7 @@
/// # Ok(())
/// # }
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub struct File {
inner: fs_imp::File,
path: PathBuf,
@ -62,6 +64,7 @@ pub struct File {
/// This structure is returned from the `metadata` function or method and
/// represents known metadata about a file such as its permissions, size,
/// modification times, etc.
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Metadata(fs_imp::FileAttr);
/// Iterator over the entries in a directory.
@ -70,6 +73,7 @@ pub struct File {
/// will yield instances of `io::Result<DirEntry>`. Through a `DirEntry`
/// information like the entry's path and possibly other metadata can be
/// learned.
#[stable(feature = "rust1", since = "1.0.0")]
pub struct ReadDir(fs_imp::ReadDir);
/// Entries returned by the `ReadDir` iterator.
@ -77,9 +81,14 @@ pub struct File {
/// An instance of `DirEntry` represents an entry inside of a directory on the
/// filesystem. Each entry can be inspected via methods to learn about the full
/// path or possibly other metadata through per-platform extension traits.
#[stable(feature = "rust1", since = "1.0.0")]
pub struct DirEntry(fs_imp::DirEntry);
/// An iterator that recursively walks over the contents of a directory.
#[unstable(feature = "fs_walk",
reason = "the precise semantics and defaults for a recursive walk \
may change and this may end up accounting for files such \
as symlinks differently")]
pub struct WalkDir {
cur: Option<ReadDir>,
stack: Vec<io::Result<ReadDir>>,
@ -92,6 +101,7 @@ pub struct WalkDir {
/// `File::create` methods are aliases for commonly used options using this
/// builder.
#[derive(Clone)]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct OpenOptions(fs_imp::OpenOptions);
/// Representation of the various permissions on a file.
@ -101,6 +111,7 @@ pub struct WalkDir {
/// functionality, such as mode bits, is available through the
/// `os::unix::PermissionsExt` trait.
#[derive(Clone, PartialEq, Eq, Debug)]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Permissions(fs_imp::FilePermissions);
impl File {
@ -112,6 +123,7 @@ impl File {
///
/// This function will return an error if `path` does not already exist.
/// Other errors may also be returned according to `OpenOptions::open`.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn open<P: AsPath + ?Sized>(path: &P) -> io::Result<File> {
OpenOptions::new().read(true).open(path)
}
@ -122,11 +134,15 @@ pub fn open<P: AsPath + ?Sized>(path: &P) -> io::Result<File> {
/// and will truncate it if it does.
///
/// See the `OpenOptions::open` function for more details.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn create<P: AsPath + ?Sized>(path: &P) -> io::Result<File> {
OpenOptions::new().write(true).create(true).truncate(true).open(path)
}
/// Returns the original path that was used to open this file.
#[unstable(feature = "file_path",
reason = "this abstraction is imposed by this library instead \
of the underlying OS and may be removed")]
pub fn path(&self) -> Option<&Path> {
Some(&self.path)
}
@ -135,6 +151,7 @@ pub fn path(&self) -> Option<&Path> {
///
/// This function will attempt to ensure that all in-core data reaches the
/// filesystem before returning.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn sync_all(&self) -> io::Result<()> {
self.inner.fsync()
}
@ -148,6 +165,7 @@ pub fn sync_all(&self) -> io::Result<()> {
///
/// Note that some platforms may simply implement this in terms of
/// `sync_all`.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn sync_data(&self) -> io::Result<()> {
self.inner.datasync()
}
@ -159,11 +177,13 @@ pub fn sync_data(&self) -> io::Result<()> {
/// be shrunk. If it is greater than the current file's size, then the file
/// will be extended to `size` and have all of the intermediate data filled
/// in with 0s.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn set_len(&self, size: u64) -> io::Result<()> {
self.inner.truncate(size)
}
/// Queries information about the underlying file.
/// Queries metadata about the underlying file.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn metadata(&self) -> io::Result<Metadata> {
self.inner.file_attr().map(Metadata)
}
@ -172,33 +192,39 @@ pub fn metadata(&self) -> io::Result<Metadata> {
impl AsInner<fs_imp::File> for File {
fn as_inner(&self) -> &fs_imp::File { &self.inner }
}
#[stable(feature = "rust1", since = "1.0.0")]
impl Read for File {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
self.inner.read(buf)
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl Write for File {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.inner.write(buf)
}
fn flush(&mut self) -> io::Result<()> { self.inner.flush() }
}
#[stable(feature = "rust1", since = "1.0.0")]
impl Seek for File {
fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
self.inner.seek(pos)
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a> Read for &'a File {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
self.inner.read(buf)
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a> Write for &'a File {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.inner.write(buf)
}
fn flush(&mut self) -> io::Result<()> { self.inner.flush() }
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a> Seek for &'a File {
fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
self.inner.seek(pos)
@ -209,6 +235,7 @@ impl OpenOptions {
/// Creates a blank net set of options ready for configuration.
///
/// All options are initially set to `false`.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn new() -> OpenOptions {
OpenOptions(fs_imp::OpenOptions::new())
}
@ -217,6 +244,7 @@ pub fn new() -> OpenOptions {
///
/// This option, when true, will indicate that the file should be
/// `read`-able if opened.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn read(&mut self, read: bool) -> &mut OpenOptions {
self.0.read(read); self
}
@ -225,6 +253,7 @@ pub fn read(&mut self, read: bool) -> &mut OpenOptions {
///
/// This option, when true, will indicate that the file should be
/// `write`-able if opened.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn write(&mut self, write: bool) -> &mut OpenOptions {
self.0.write(write); self
}
@ -233,6 +262,7 @@ pub fn write(&mut self, write: bool) -> &mut OpenOptions {
///
/// This option, when true, means that writes will append to a file instead
/// of overwriting previous contents.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn append(&mut self, append: bool) -> &mut OpenOptions {
self.0.append(append); self
}
@ -241,6 +271,7 @@ pub fn append(&mut self, append: bool) -> &mut OpenOptions {
///
/// If a file is successfully opened with this option set it will truncate
/// the file to 0 length if it already exists.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn truncate(&mut self, truncate: bool) -> &mut OpenOptions {
self.0.truncate(truncate); self
}
@ -249,6 +280,7 @@ pub fn truncate(&mut self, truncate: bool) -> &mut OpenOptions {
///
/// This option indicates whether a new file will be created if the file
/// does not yet already exist.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn create(&mut self, create: bool) -> &mut OpenOptions {
self.0.create(create); self
}
@ -264,37 +296,33 @@ pub fn create(&mut self, create: bool) -> &mut OpenOptions {
/// * Attempting to open a file with access that the user lacks
/// permissions for
/// * Filesystem-level errors (full disk, etc)
#[stable(feature = "rust1", since = "1.0.0")]
pub fn open<P: AsPath + ?Sized>(&self, path: &P) -> io::Result<File> {
let path = path.as_path();
let inner = try!(fs_imp::File::open(path, &self.0));
// On *BSD systems, we can open a directory as a file and read from
// it: fd=open("/tmp", O_RDONLY); read(fd, buf, N); due to an old
// tradition before the introduction of opendir(3). We explicitly
// reject it because there are few use cases.
if cfg!(not(any(target_os = "linux", target_os = "android"))) &&
try!(inner.file_attr()).is_dir() {
Err(Error::new(ErrorKind::InvalidInput, "is a directory", None))
} else {
Ok(File { path: path.to_path_buf(), inner: inner })
}
Ok(File { path: path.to_path_buf(), inner: inner })
}
}
impl AsInnerMut<fs_imp::OpenOptions> for OpenOptions {
fn as_inner_mut(&mut self) -> &mut fs_imp::OpenOptions { &mut self.0 }
}
impl Metadata {
/// Returns whether this metadata is for a directory.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn is_dir(&self) -> bool { self.0.is_dir() }
/// Returns whether this metadata is for a regular file.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn is_file(&self) -> bool { self.0.is_file() }
/// Returns the size of the file, in bytes, this metadata is for.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn len(&self) -> u64 { self.0.size() }
/// Returns the permissions of the file this metadata is for.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn permissions(&self) -> Permissions {
Permissions(self.0.perm())
}
@ -302,22 +330,32 @@ pub fn permissions(&self) -> Permissions {
/// Returns the most recent access time for a file.
///
/// The return value is in milliseconds since the epoch.
#[unstable(feature = "fs_time",
reason = "the return type of u64 is not quite appropriate for \
this method and may change if the standard library \
gains a type to represent a moment in time")]
pub fn accessed(&self) -> u64 { self.0.accessed() }
/// Returns the most recent modification time for a file.
///
/// The return value is in milliseconds since the epoch.
#[unstable(feature = "fs_time",
reason = "the return type of u64 is not quite appropriate for \
this method and may change if the standard library \
gains a type to represent a moment in time")]
pub fn modified(&self) -> u64 { self.0.modified() }
}
impl Permissions {
/// Returns whether these permissions describe a readonly file.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn readonly(&self) -> bool { self.0.readonly() }
/// Modify the readonly flag for this set of permissions.
///
/// This operation does **not** modify the filesystem. To modify the
/// filesystem use the `fs::set_permissions` function.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn set_readonly(&mut self, readonly: bool) {
self.0.set_readonly(readonly)
}
@ -333,6 +371,7 @@ impl AsInner<fs_imp::FilePermissions> for Permissions {
fn as_inner(&self) -> &fs_imp::FilePermissions { &self.0 }
}
#[stable(feature = "rust1", since = "1.0.0")]
impl Iterator for ReadDir {
type Item = io::Result<DirEntry>;
@ -341,11 +380,13 @@ fn next(&mut self) -> Option<io::Result<DirEntry>> {
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl DirEntry {
/// Returns the full path to the file that this entry represents.
///
/// The full path is created by joining the original path to `read_dir` or
/// `walk_dir` with the filename of this entry.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn path(&self) -> PathBuf { self.0.path() }
}
@ -368,31 +409,9 @@ pub fn path(&self) -> PathBuf { self.0.path() }
/// This function will return an error if `path` points to a directory, if the
/// user lacks permissions to remove the file, or if some other filesystem-level
/// error occurs.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn remove_file<P: AsPath + ?Sized>(path: &P) -> io::Result<()> {
let path = path.as_path();
let e = match fs_imp::unlink(path) {
Ok(()) => return Ok(()),
Err(e) => e,
};
if !cfg!(windows) { return Err(e) }
// On unix, a readonly file can be successfully removed. On windows,
// however, it cannot. To keep the two platforms in line with
// respect to their behavior, catch this case on windows, attempt to
// change it to read-write, and then remove the file.
if e.kind() != ErrorKind::PermissionDenied { return Err(e) }
let attr = match metadata(path) { Ok(a) => a, Err(..) => return Err(e) };
let mut perms = attr.permissions();
if !perms.readonly() { return Err(e) }
perms.set_readonly(false);
if set_permissions(path, perms).is_err() { return Err(e) }
if fs_imp::unlink(path).is_ok() { return Ok(()) }
// Oops, try to put things back the way we found it
let _ = set_permissions(path, attr.permissions());
Err(e)
fs_imp::unlink(path.as_path())
}
/// Given a path, query the file system to get information about a file,
@ -418,6 +437,7 @@ pub fn remove_file<P: AsPath + ?Sized>(path: &P) -> io::Result<()> {
/// This function will return an error if the user lacks the requisite
/// permissions to perform a `metadata` call on the given `path` or if there
/// is no entry in the filesystem at the provided path.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn metadata<P: AsPath + ?Sized>(path: &P) -> io::Result<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`
/// reside on separate filesystems, or if some other intermittent I/O error
/// occurs.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn rename<P: AsPath + ?Sized, Q: AsPath + ?Sized>(from: &P, to: &Q)
-> io::Result<()> {
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 current process does not have the permission rights to access
/// `from` or write `to`
#[stable(feature = "rust1", since = "1.0.0")]
pub fn copy<P: AsPath + ?Sized, Q: AsPath + ?Sized>(from: &P, to: &Q)
-> io::Result<u64> {
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
/// 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)
-> io::Result<()> {
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.
///
/// 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)
-> io::Result<()> {
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
/// reading a file that does not exist or reading a file that is not a soft
/// link.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn read_link<P: AsPath + ?Sized>(path: &P) -> io::Result<PathBuf> {
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
/// 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<()> {
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
/// error conditions for when a directory is being created (after it is
/// determined to not exist) are outlined by `fs::create_dir`.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn create_dir_all<P: AsPath + ?Sized>(path: &P) -> io::Result<()> {
let path = path.as_path();
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
/// 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<()> {
fs_imp::rmdir(path.as_path())
}
@ -585,6 +613,7 @@ pub fn remove_dir<P: AsPath + ?Sized>(path: &P) -> io::Result<()> {
/// # Errors
///
/// See `file::remove_file` and `fs::remove_dir`
#[stable(feature = "rust1", since = "1.0.0")]
pub fn remove_dir_all<P: AsPath + ?Sized>(path: &P) -> io::Result<()> {
let path = path.as_path();
for child in try!(read_dir(path)) {
@ -637,6 +666,7 @@ fn lstat(path: &Path) -> io::Result<fs_imp::FileAttr> { fs_imp::stat(path) }
/// This function will return an error if the provided `path` doesn't exist, if
/// the process lacks permissions to view the contents or if the `path` points
/// at a non-directory file
#[stable(feature = "rust1", since = "1.0.0")]
pub fn read_dir<P: AsPath + ?Sized>(path: &P) -> io::Result<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
/// 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> {
let start = try!(read_dir(path));
Ok(WalkDir { cur: Some(start), stack: Vec::new() })
}
#[unstable(feature = "fs_walk")]
impl Iterator for WalkDir {
type Item = io::Result<DirEntry>;
@ -683,6 +718,9 @@ fn next(&mut self) -> Option<io::Result<DirEntry>> {
}
/// Utility methods for paths.
#[unstable(feature = "path_ext",
reason = "the precise set of methods exposed on this trait may \
change and some methods may be removed")]
pub trait PathExt {
/// Get information on the file, directory, etc at this path.
///
@ -727,6 +765,10 @@ fn is_dir(&self) -> bool {
/// The file at the path specified will have its last access time set to
/// `atime` and its modification time set to `mtime`. The times specified should
/// be in milliseconds.
#[unstable(feature = "fs_time",
reason = "the argument type of u64 is not quite appropriate for \
this function and may change if the standard library \
gains a type to represent a moment in time")]
pub fn set_file_times<P: AsPath + ?Sized>(path: &P, accessed: u64,
modified: u64) -> io::Result<()> {
fs_imp::utimes(path.as_path(), accessed, modified)
@ -752,6 +794,10 @@ pub fn set_file_times<P: AsPath + ?Sized>(path: &P, accessed: u64,
/// This function will return an error if the provided `path` doesn't exist, if
/// the process lacks permissions to change the attributes of the file, or if
/// some other I/O error is encountered.
#[unstable(feature = "fs",
reason = "a more granual ability to set specific permissions may \
be exposed on the Permissions structure itself and this \
method may not always exist")]
pub fn set_permissions<P: AsPath + ?Sized>(path: &P, perm: Permissions)
-> io::Result<()> {
fs_imp::set_perm(path.as_path(), perm.0)
@ -1267,6 +1313,8 @@ fn copy_file_preserves_perm_bits() {
check!(fs::set_permissions(&input, p));
check!(fs::copy(&input, &out));
assert!(check!(out.metadata()).permissions().readonly());
check!(fs::set_permissions(&input, attr.permissions()));
check!(fs::set_permissions(&out, attr.permissions()));
}
#[cfg(not(windows))] // FIXME(#10264) operation not permitted?
@ -1350,10 +1398,13 @@ fn chmod_works() {
let attr = check!(fs::metadata(&file));
assert!(attr.permissions().readonly());
match fs::set_permissions(&tmpdir.join("foo"), p) {
Ok(..) => panic!("wanted a panic"),
match fs::set_permissions(&tmpdir.join("foo"), p.clone()) {
Ok(..) => panic!("wanted an error"),
Err(..) => {}
}
p.set_readonly(false);
check!(fs::set_permissions(&file, p));
}
#[test]
@ -1506,6 +1557,7 @@ fn binary_file() {
}
#[test]
#[cfg(not(windows))]
fn unlink_readonly() {
let tmpdir = tmpdir();
let path = tmpdir.join("file");

View file

@ -9,6 +9,9 @@
// except according to those terms.
#![unstable(feature = "tempdir", reason = "needs an RFC before stabilization")]
#![deprecated(since = "1.0.0",
reason = "use the `tempdir` crate from crates.io instead")]
#![allow(deprecated)]
use prelude::v1::*;

View file

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

View file

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

View file

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

View file

@ -157,9 +157,6 @@ fn read_to_string(&mut self, buf: &mut String) -> io::Result<()> {
impl<'a> Read for StdinLock<'a> {
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)
}
}

View file

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

View file

@ -94,7 +94,8 @@
//! to all code by default. [`macros`](macros/index.html) contains
//! all the standard macros, such as `assert!`, `panic!`, `println!`,
//! and `format!`, also available to all Rust code.
// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364)
#![cfg_attr(stage0, feature(custom_attribute))]
#![crate_name = "std"]
#![stable(feature = "rust1", since = "1.0.0")]
#![staged_api]

View file

@ -293,7 +293,7 @@ macro_rules! try_opt {
}
// split the string by ':' and convert the second part to u16
let mut parts_iter = self.rsplitn(2, ':');
let mut parts_iter = self.rsplitn(1, ':');
let port_str = try_opt!(parts_iter.next(), "invalid socket address");
let host = try_opt!(parts_iter.next(), "invalid socket address");
let port: u16 = try_opt!(port_str.parse().ok(), "invalid port value");
@ -590,4 +590,10 @@ fn to_socket_addr_str() {
let a = SocketAddr::new(IpAddr::new_v4(127, 0, 0, 1), 23924);
assert!(tsa("localhost:23924").unwrap().contains(&a));
}
#[test]
#[cfg(not(windows))]
fn to_socket_addr_str_bad() {
assert!(tsa("1200::AB00:1234::2552:7777:1313:34300").is_err());
}
}

View file

@ -233,13 +233,13 @@ macro_rules! t {
}
}
// FIXME #11530 this fails on android because tests are run as root
#[cfg_attr(any(windows, target_os = "android"), ignore)]
#[test]
fn bind_error() {
match TcpListener::bind("0.0.0.0:1") {
match TcpListener::bind("1.1.1.1:9999") {
Ok(..) => panic!(),
Err(e) => assert_eq!(e.kind(), ErrorKind::PermissionDenied),
Err(e) =>
// EADDRNOTAVAIL is mapped to ConnectionRefused
assert_eq!(e.kind(), ErrorKind::ConnectionRefused),
}
}

View file

@ -10,6 +10,10 @@
//! Networking I/O
#![deprecated(since = "1.0.0",
reason = "replaced with new I/O primitives in `std::net`")]
#![unstable(feature = "old_io")]
use old_io::{IoError, IoResult, InvalidInput};
use ops::FnMut;
use option::Option::None;

View file

@ -19,6 +19,12 @@
//! instances as clients.
#![allow(missing_docs)]
#![deprecated(since = "1.0.0",
reason = "will be removed to be reintroduced at a later date; \
in the meantime consider using the `unix_socket` crate \
for unix sockets; there is currently no replacement \
for named pipes")]
#![unstable(feature = "old_io")]
use prelude::v1::*;

View file

@ -11,6 +11,9 @@
//! Bindings for executing child processes
#![allow(non_upper_case_globals)]
#![unstable(feature = "old_io")]
#![deprecated(since = "1.0.0",
reason = "replaced with the std::process module")]
pub use self::StdioContainer::*;
pub use self::ProcessExit::*;

View file

@ -10,6 +10,8 @@
//! Utility implementations of Reader and Writer
#![allow(deprecated)]
use prelude::v1::*;
use cmp;
use old_io;
@ -17,13 +19,19 @@
/// Wraps a `Reader`, limiting the number of bytes that can be read from it.
#[derive(Debug)]
#[deprecated(since = "1.0.0", reason = "use std::io::Take")]
#[unstable(feature = "old_io")]
pub struct LimitReader<R> {
limit: uint,
inner: R
}
#[deprecated(since = "1.0.0", reason = "use std::io::Take")]
#[unstable(feature = "old_io")]
impl<R: Reader> LimitReader<R> {
/// 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> {
LimitReader { limit: limit, inner: r }
}
@ -41,6 +49,8 @@ pub fn into_inner(self) -> R { self.inner }
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> {
fn read(&mut self, buf: &mut [u8]) -> old_io::IoResult<uint> {
if self.limit == 0 {
@ -57,6 +67,8 @@ fn read(&mut self, buf: &mut [u8]) -> old_io::IoResult<uint> {
}
}
#[deprecated(since = "1.0.0", reason = "use std::io's take method instead")]
#[unstable(feature = "old_io")]
impl<R: Buffer> Buffer for LimitReader<R> {
fn fill_buf<'a>(&'a mut self) -> old_io::IoResult<&'a [u8]> {
let amt = try!(self.inner.fill_buf());
@ -79,8 +91,12 @@ fn consume(&mut self, amt: uint) {
/// A `Writer` which ignores bytes written to it, like /dev/null.
#[derive(Copy, Debug)]
#[deprecated(since = "1.0.0", reason = "use std::io::sink() instead")]
#[unstable(feature = "old_io")]
pub struct NullWriter;
#[deprecated(since = "1.0.0", reason = "use std::io::sink() instead")]
#[unstable(feature = "old_io")]
impl Writer for NullWriter {
#[inline]
fn write_all(&mut self, _buf: &[u8]) -> old_io::IoResult<()> { Ok(()) }
@ -88,8 +104,12 @@ fn write_all(&mut self, _buf: &[u8]) -> old_io::IoResult<()> { Ok(()) }
/// A `Reader` which returns an infinite stream of 0 bytes, like /dev/zero.
#[derive(Copy, Debug)]
#[deprecated(since = "1.0.0", reason = "use std::io::repeat(0) instead")]
#[unstable(feature = "old_io")]
pub struct ZeroReader;
#[deprecated(since = "1.0.0", reason = "use std::io::repeat(0) instead")]
#[unstable(feature = "old_io")]
impl Reader for ZeroReader {
#[inline]
fn read(&mut self, buf: &mut [u8]) -> old_io::IoResult<uint> {
@ -98,6 +118,8 @@ fn read(&mut self, buf: &mut [u8]) -> old_io::IoResult<uint> {
}
}
#[deprecated(since = "1.0.0", reason = "use std::io::repeat(0) instead")]
#[unstable(feature = "old_io")]
impl Buffer for ZeroReader {
fn fill_buf<'a>(&'a mut self) -> old_io::IoResult<&'a [u8]> {
static DATA: [u8; 64] = [0; 64];
@ -109,8 +131,12 @@ fn consume(&mut self, _amt: uint) {}
/// A `Reader` which is always at EOF, like /dev/null.
#[derive(Copy, Debug)]
#[deprecated(since = "1.0.0", reason = "use std::io::empty() instead")]
#[unstable(feature = "old_io")]
pub struct NullReader;
#[deprecated(since = "1.0.0", reason = "use std::io::empty() instead")]
#[unstable(feature = "old_io")]
impl Reader for NullReader {
#[inline]
fn read(&mut self, _buf: &mut [u8]) -> old_io::IoResult<uint> {
@ -118,6 +144,8 @@ fn read(&mut self, _buf: &mut [u8]) -> old_io::IoResult<uint> {
}
}
#[deprecated(since = "1.0.0", reason = "use std::io::empty() instead")]
#[unstable(feature = "old_io")]
impl Buffer for NullReader {
fn fill_buf<'a>(&'a mut self) -> old_io::IoResult<&'a [u8]> {
Err(old_io::standard_error(old_io::EndOfFile))
@ -130,17 +158,23 @@ fn consume(&mut self, _amt: uint) {}
/// The `Writer`s are delegated to in order. If any `Writer` returns an error,
/// that error is returned immediately and remaining `Writer`s are not called.
#[derive(Debug)]
#[deprecated(since = "1.0.0", reason = "use std::io::Broadcast instead")]
#[unstable(feature = "old_io")]
pub struct MultiWriter<W> {
writers: Vec<W>
}
impl<W> MultiWriter<W> where W: Writer {
/// Creates a new `MultiWriter`
#[deprecated(since = "1.0.0", reason = "use std::io's broadcast method instead")]
#[unstable(feature = "old_io")]
pub fn new(writers: Vec<W>) -> MultiWriter<W> {
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 {
#[inline]
fn write_all(&mut self, buf: &[u8]) -> old_io::IoResult<()> {
@ -162,6 +196,8 @@ fn flush(&mut self) -> old_io::IoResult<()> {
/// A `Reader` which chains input from multiple `Reader`s, reading each to
/// completion before moving onto the next.
#[derive(Clone, Debug)]
#[deprecated(since = "1.0.0", reason = "use std::io::Chain instead")]
#[unstable(feature = "old_io")]
pub struct ChainedReader<I, R> {
readers: I,
cur_reader: Option<R>,
@ -169,12 +205,16 @@ pub struct ChainedReader<I, R> {
impl<R: Reader, I: Iterator<Item=R>> ChainedReader<I, R> {
/// 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> {
let r = readers.next();
ChainedReader { readers: readers, cur_reader: r }
}
}
#[deprecated(since = "1.0.0", reason = "use std::io::Chain instead")]
#[unstable(feature = "old_io")]
impl<R: Reader, I: Iterator<Item=R>> Reader for ChainedReader<I, R> {
fn read(&mut self, buf: &mut [u8]) -> old_io::IoResult<uint> {
loop {
@ -201,13 +241,19 @@ fn read(&mut self, buf: &mut [u8]) -> old_io::IoResult<uint> {
/// A `Reader` which forwards input from another `Reader`, passing it along to
/// a `Writer` as well. Similar to the `tee(1)` command.
#[derive(Debug)]
#[deprecated(since = "1.0.0", reason = "use std::io::Tee instead")]
#[unstable(feature = "old_io")]
pub struct TeeReader<R, W> {
reader: R,
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> {
/// 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> {
TeeReader { reader: r, writer: w }
}
@ -220,6 +266,8 @@ pub fn into_inner(self) -> (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> {
fn read(&mut self, buf: &mut [u8]) -> old_io::IoResult<uint> {
self.reader.read(buf).and_then(|len| {
@ -229,6 +277,8 @@ fn read(&mut self, buf: &mut [u8]) -> old_io::IoResult<uint> {
}
/// 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<()> {
let mut buf = [0; super::DEFAULT_BUF_SIZE];
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`
//! and `b`.
//!
//! * Paths ending in a separator are treated as if they has a current directory
//! * Paths ending in a separator are treated as if they have a current directory
//! component at the end (or, in verbatim paths, an empty component). For
//! example, while `a/b` has components `a` and `b`, the paths `a/b/` and
//! `a/b/.` both have components `a`, `b`, and `.` (current directory). The
@ -872,10 +872,10 @@ pub fn push<P: ?Sized>(&mut self, path: &P) where P: AsPath {
// `path` is a pure relative path
} else if need_sep {
self.inner.push_os_str(OsStr::from_str(MAIN_SEP_STR));
self.inner.push(MAIN_SEP_STR);
}
self.inner.push_os_str(path.as_os_str());
self.inner.push(path);
}
/// Truncate `self` to `self.parent()`.
@ -937,8 +937,8 @@ pub fn set_extension<S: ?Sized + AsOsStr>(&mut self, extension: &S) -> bool {
let extension = extension.as_os_str();
if os_str_as_u8_slice(extension).len() > 0 {
stem.push_os_str(OsStr::from_str("."));
stem.push_os_str(extension.as_os_str());
stem.push(".");
stem.push(extension);
}
self.set_file_name(&stem);
@ -1193,7 +1193,7 @@ pub fn starts_with<P: ?Sized>(&self, base: &P) -> bool where P: AsPath {
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 {
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
// except according to those terms.
#![allow(deprecated)]
use prelude::v1::*;
use self::SocketStatus::*;
use self::InAddr::*;

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -14,6 +14,8 @@
//!
//! This API is completely unstable and subject to change.
// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364)
#![cfg_attr(stage0, feature(custom_attribute))]
#![crate_name = "syntax"]
#![unstable(feature = "rustc_private")]
#![staged_api]
@ -37,8 +39,8 @@
#![feature(std_misc)]
#![feature(unicode)]
#![feature(path)]
#![feature(fs)]
#![feature(io)]
#![feature(path_ext)]
extern crate arena;
extern crate fmt_macros;

View file

@ -38,6 +38,8 @@
//! [win]: http://msdn.microsoft.com/en-us/library/windows/desktop/ms682010%28v=vs.85%29.aspx
//! [ti]: https://en.wikipedia.org/wiki/Terminfo
// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364)
#![cfg_attr(stage0, feature(custom_attribute))]
#![crate_name = "term"]
#![unstable(feature = "rustc_private",
reason = "use the crates.io `term` library instead")]
@ -52,7 +54,6 @@
#![feature(box_syntax)]
#![feature(collections)]
#![feature(fs)]
#![feature(int_uint)]
#![feature(io)]
#![feature(old_io)]
@ -61,6 +62,7 @@
#![feature(staged_api)]
#![feature(std_misc)]
#![feature(unicode)]
#![feature(path_ext)]
#![cfg_attr(windows, feature(libc))]
#[macro_use] extern crate log;

View file

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

View file

@ -20,6 +20,8 @@
//! provide for basic string-related manipulations. This crate does not
//! (yet) aim to provide a full set of Unicode tables.
// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364)
#![cfg_attr(stage0, feature(custom_attribute))]
#![crate_name = "unicode"]
#![unstable(feature = "unicode")]
#![feature(staged_api)]

View file

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

View file

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

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.
// aux-build:privacy-tuple-struct.rs
// ignore-fast
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.
// error-pattern:thread '<main>' panicked at 'arithmetic operation overflowed'
// compile-flags: -C debug-assertions
// (Work around constant-evaluation)
fn value() -> u8 { 200 }

View file

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

View file

@ -9,6 +9,7 @@
// except according to those terms.
// error-pattern:thread '<main>' panicked at 'arithmetic operation overflowed'
// compile-flags: -C debug-assertions
// (Work around constant-evaluation)
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