mirror of
https://github.com/rust-lang/rust
synced 2024-10-04 15:50:51 +00:00
Auto merge of #23107 - Manishearth:rollup, r=alexcrichton
This commit is contained in:
commit
270a677d4d
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -22,10 +22,9 @@
|
|||
#![feature(unicode)]
|
||||
#![feature(core)]
|
||||
#![feature(path)]
|
||||
#![feature(os)]
|
||||
#![feature(io)]
|
||||
#![feature(fs)]
|
||||
#![feature(net)]
|
||||
#![feature(path_ext)]
|
||||
|
||||
#![deny(warnings)]
|
||||
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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).
|
||||
|
|
|
@ -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:
|
||||
|
||||
|
|
|
@ -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)]
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)]
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)]
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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")]
|
||||
|
|
|
@ -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!())
|
||||
})
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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> {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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()))
|
||||
}
|
||||
});
|
||||
|
||||
|
|
121
src/librustc_back/tempdir.rs
Normal file
121
src/librustc_back/tempdir.rs
Normal 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
|
|
@ -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]
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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())));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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),
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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")
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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(())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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');
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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")]
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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::*;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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(())
|
||||
}
|
||||
|
||||
|
|
|
@ -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>;
|
||||
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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(()) }
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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::*;
|
||||
|
||||
|
|
|
@ -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::*;
|
||||
|
|
|
@ -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
12
src/libstd/path.rs
Executable file → Normal 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()
|
||||
}
|
||||
|
|
|
@ -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::*;
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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::*;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)]
|
||||
|
|
|
@ -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)]
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
0
src/test/auxiliary/lint_output_format.rs
Executable file → Normal file
29
src/test/compile-fail/issue-23080-2.rs
Normal file
29
src/test/compile-fail/issue-23080-2.rs
Normal 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(());
|
||||
}
|
31
src/test/compile-fail/issue-23080.rs
Normal file
31
src/test/compile-fail/issue-23080.rs
Normal 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(());
|
||||
}
|
41
src/test/compile-fail/phantom-oibit.rs
Normal file
41
src/test/compile-fail/phantom-oibit.rs
Normal 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() {}
|
|
@ -9,7 +9,6 @@
|
|||
// except according to those terms.
|
||||
|
||||
// aux-build:privacy-tuple-struct.rs
|
||||
// ignore-fast
|
||||
|
||||
extern crate "privacy-tuple-struct" as other;
|
||||
|
||||
|
|
0
src/test/compile-fail/send-is-not-static-ensures-scoping.rs
Executable file → Normal file
0
src/test/compile-fail/send-is-not-static-ensures-scoping.rs
Executable file → Normal file
67
src/test/debuginfo/constant-debug-locs.rs
Normal file
67
src/test/debuginfo/constant-debug-locs.rs
Normal 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;
|
||||
}
|
68
src/test/debuginfo/extern-c-fn.rs
Normal file
68
src/test/debuginfo/extern-c-fn.rs
Normal 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() {()}
|
|
@ -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 }
|
||||
|
|
|
@ -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 }
|
||||
|
|
|
@ -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 }
|
||||
|
|
21
src/test/run-make/debug-assertions/Makefile
Normal file
21
src/test/run-make/debug-assertions/Makefile
Normal 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
|
42
src/test/run-make/debug-assertions/debug.rs
Normal file
42
src/test/run-make/debug-assertions/debug.rs
Normal 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
0
src/test/run-make/mismatching-target-triples/bar.rs
Executable file → Normal file
0
src/test/run-make/mismatching-target-triples/foo.rs
Executable file → Normal file
0
src/test/run-make/mismatching-target-triples/foo.rs
Executable file → Normal file
0
src/test/run-make/pretty-expanded-hygiene/input.pp.rs
Executable file → Normal file
0
src/test/run-make/pretty-expanded-hygiene/input.pp.rs
Executable file → Normal file
0
src/test/run-make/pretty-expanded-hygiene/input.rs
Executable file → Normal file
0
src/test/run-make/pretty-expanded-hygiene/input.rs
Executable file → Normal file
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue