Remove broken links that should just point to the current page, and while we're at it, re-wrap to 100 chars.
######################################################################
# The main testing target. Tests lots of stuff.
-check: cleantmptestlogs cleantestlibs all check-stage2 tidy
+check: check-sanitycheck cleantmptestlogs cleantestlibs all check-stage2 tidy
$(Q)$(CFG_PYTHON) $(S)src/etc/check-summary.py tmp/*.log
# As above but don't bother running tidy.
# Not run as part of the normal test suite, but tested by bors on checkin.
check-secondary: check-build-compiletest check-build-lexer-verifier check-lexer check-pretty
+.PHONY: check-sanitycheck
+
+check-sanitycheck:
+ $(Q)$(CFG_PYTHON) $(S)src/etc/check-sanitycheck.py
+
# check + check-secondary.
#
# Issue #17883: build check-secondary first so hidden dependencies in
#![feature(std_misc)]
#![feature(test)]
#![feature(path_ext)]
-#![feature(convert)]
#![feature(str_char)]
#![deny(warnings)]
```
# #![feature(core)]
-use std::iter::range_step;
use std::option::Option::{Some, None};
use std::collections::hash_map::{self, HashMap};
fn bar(map1: HashMap<String, usize>, map2: hash_map::HashMap<String, usize>){}
fn main() {
- // Equivalent to 'std::iter::range_step(0, 10, 2);'
- range_step(0, 10, 2);
-
// Equivalent to 'foo(vec![std::option::Option::Some(1.0f64),
// std::option::Option::None]);'
foo(vec![Some(1.0f64), None]);
it to get a reference to the data. Real code would have more robust error handling
here. We're then free to mutate it, since we have the lock.
-This timer bit is a bit awkward, however. We have picked a reasonable amount of
-time to wait, but it's entirely possible that we've picked too high, and that
-we could be taking less time. It's also possible that we've picked too low,
-and that we aren't actually finishing this computation.
-
-Rust's standard library provides a few more mechanisms for two threads to
-synchronize with each other. Let's talk about one: channels.
+Lastly, while the threads are running, we wait on a short timer. But
+this is not ideal: we may have picked a reasonable amount of time to
+wait but it's more likely we'll either be waiting longer than
+necessary or not long enough, depending on just how much time the
+threads actually take to finish computing when the program runs.
+
+A more precise alternative to the timer would be to use one of the
+mechanisms provided by the Rust standard library for synchronizing
+threads with each other. Let's talk about one of them: channels.
## Channels
```
These two basic iterators should serve you well. There are some more
-advanced iterators, including ones that are infinite. Like `count`:
+advanced iterators, including ones that are infinite. Like using range syntax
+and `step_by`:
```rust
-# #![feature(core)]
-std::iter::count(1, 5);
+# #![feature(step_by)]
+(1..).step_by(5);
```
This iterator counts up from one, adding five each time. It will give
There are tons of interesting iterator adapters. `take(n)` will return an
iterator over the next `n` elements of the original iterator, note that this
has no side effect on the original iterator. Let's try it out with our infinite
-iterator from before, `count()`:
+iterator from before:
```rust
-# #![feature(core)]
-for i in std::iter::count(1, 5).take(5) {
+# #![feature(step_by)]
+for i in (1..).step_by(5).take(5) {
println!("{}", i);
}
```
```rust
let x: Vec<u32> = vec![1, 2, 3];
-# assert_eq!(&[1,2,3], &x);
+# assert_eq!(x, [1, 2, 3]);
```
This can't be an ordinary function, because it takes any number of arguments.
temp_vec.push(3);
temp_vec
};
-# assert_eq!(&[1,2,3], &x);
+# assert_eq!(x, [1, 2, 3]);
```
We can implement this shorthand, using a macro: [^actual]
};
}
# fn main() {
-# assert_eq!([1,2,3], vec![1,2,3]);
+# assert_eq!(vec![1,2,3], [1, 2, 3]);
# }
```
the item signature alone. However, for ergonomic reasons a very restricted
secondary inference algorithm called “lifetime elision” applies in function
signatures. It infers only based on the signature components themselves and not
-based on the body of the function, only infers lifetime paramters, and does
+based on the body of the function, only infers lifetime parameters, and does
this with only three easily memorizable and unambiguous rules. This makes
lifetime elision a shorthand for writing an item signature, while not hiding
away the actual types involved as full local inference would if applied to it.
--- /dev/null
+#!/usr/bin/env python
+#
+# Copyright 2012-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.
+
+import os
+import sys
+import functools
+import resource
+
+STATUS = 0
+
+
+def error_unless_permitted(env_var, message):
+ global STATUS
+ if not os.getenv(env_var):
+ sys.stderr.write(message)
+ STATUS = 1
+
+
+def only_on(platforms):
+ def decorator(func):
+ @functools.wraps(func)
+ def inner():
+ if any(map(lambda x: sys.platform.startswith(x), platforms)):
+ func()
+ return inner
+ return decorator
+
+
+@only_on(('linux', 'darwin', 'freebsd', 'openbsd'))
+def check_rlimit_core():
+ soft, hard = resource.getrlimit(resource.RLIMIT_CORE)
+ if soft > 0:
+ error_unless_permitted('ALLOW_NONZERO_RLIMIT_CORE', """\
+RLIMIT_CORE is set to a nonzero value (%d). During debuginfo, the test suite
+will segfault many rustc's, creating many potentially large core files.
+set ALLOW_NONZERO_RLIMIT_CORE to ignore this warning
+""" % (soft))
+
+
+def main():
+ check_rlimit_core()
+
+if __name__ == '__main__':
+ main()
+ sys.exit(STATUS)
/// let child_numbers = shared_numbers.clone();
///
/// thread::spawn(move || {
-/// let local_numbers = child_numbers.as_slice();
+/// let local_numbers = &child_numbers[..];
///
/// // Work with the local numbers
/// });
use core::any::Any;
use core::cmp::Ordering;
use core::default::Default;
-use core::error::{Error, FromError};
+use core::error::Error;
use core::fmt;
use core::hash::{self, Hash};
use core::mem;
}
}
-/// Extension methods for an owning `Any` trait object.
-#[unstable(feature = "alloc",
- reason = "this trait will likely disappear once compiler bugs blocking \
- a direct impl on `Box<Any>` have been fixed ")]
-// FIXME(#18737): this should be a direct impl on `Box<Any>`. If you're
-// removing this please make sure that you can downcase on
-// `Box<Any + Send>` as well as `Box<Any>`
-pub trait BoxAny {
- /// Returns the boxed value if it is of type `T`, or
- /// `Err(Self)` if it isn't.
- #[stable(feature = "rust1", since = "1.0.0")]
- fn downcast<T: Any>(self) -> Result<Box<T>, Box<Any>>;
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl BoxAny for Box<Any> {
+impl Box<Any> {
#[inline]
- fn downcast<T: Any>(self) -> Result<Box<T>, Box<Any>> {
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub fn downcast<T: Any>(self) -> Result<Box<T>, Box<Any>> {
if self.is::<T>() {
unsafe {
// Get the raw representation of the trait object
}
}
-#[stable(feature = "rust1", since = "1.0.0")]
-impl BoxAny for Box<Any+Send> {
+impl Box<Any+Send> {
#[inline]
- fn downcast<T: Any>(self) -> Result<Box<T>, Box<Any>> {
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub fn downcast<T: Any>(self) -> Result<Box<T>, Box<Any>> {
<Box<Any>>::downcast(self)
}
}
impl<I: ExactSizeIterator + ?Sized> ExactSizeIterator for Box<I> {}
#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, E: Error + 'a> FromError<E> for Box<Error + 'a> {
- fn from_error(err: E) -> Box<Error + 'a> {
+impl<'a, E: Error + 'a> From<E> for Box<Error + 'a> {
+ fn from(err: E) -> Box<Error + 'a> {
Box::new(err)
}
}
use std::boxed;
use std::boxed::Box;
-use std::boxed::BoxAny;
#[test]
fn test_owned_clone() {
//! [sieve]: http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes
//!
//! ```
-//! # #![feature(collections, core)]
+//! # #![feature(collections, core, step_by)]
//! use std::collections::{BitSet, BitVec};
//! use std::num::Float;
//! use std::iter;
//! if bv[i] {
//! // Mark all multiples of i as non-prime (any multiples below i * i
//! // will have been marked as non-prime previously)
-//! for j in iter::range_step(i * i, max_prime, i) { bv.set(j, false) }
+//! for j in (i * i..max_prime).step_by(i) { bv.set(j, false) }
//! }
//! }
//! BitSet::from_bit_vec(bv)
BitSet { bit_vec: bit_vec }
}
- /// Deprecated: use `from_bit_vec`.
- #[inline]
- #[deprecated(since = "1.0.0", reason = "renamed to from_bit_vec")]
- #[unstable(feature = "collections")]
- pub fn from_bitv(bit_vec: BitVec) -> BitSet {
- BitSet { bit_vec: bit_vec }
- }
-
/// Returns the capacity in bits for this bit vector. Inserting any
/// element less than this amount will not trigger a resizing.
///
#[stable(feature = "rust1", since = "1.0.0")]
pub trait Borrow<Borrowed: ?Sized> {
/// Immutably borrow from an owned value.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::borrow::Borrow;
+ ///
+ /// fn check<T: Borrow<str>>(s: T) {
+ /// assert_eq!("Hello", s.borrow());
+ /// }
+ ///
+ /// let s = "Hello".to_string();
+ ///
+ /// check(s);
+ ///
+ /// let s = "Hello";
+ ///
+ /// check(s);
+ /// ```
#[stable(feature = "rust1", since = "1.0.0")]
fn borrow(&self) -> &Borrowed;
}
#[stable(feature = "rust1", since = "1.0.0")]
pub trait BorrowMut<Borrowed: ?Sized> : Borrow<Borrowed> {
/// Mutably borrow from an owned value.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::borrow::BorrowMut;
+ ///
+ /// fn check<T: BorrowMut<[i32]>>(mut v: T) {
+ /// assert_eq!(&mut [1, 2, 3], v.borrow_mut());
+ /// }
+ ///
+ /// let v = vec![1, 2, 3];
+ ///
+ /// check(v);
+ /// ```
#[stable(feature = "rust1", since = "1.0.0")]
fn borrow_mut(&mut self) -> &mut Borrowed;
}
/// Acquire a mutable reference to the owned form of the data.
///
/// Copies the data if it is not already owned.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::borrow::Cow;
+ ///
+ /// let mut cow: Cow<[_]> = Cow::Owned(vec![1, 2, 3]);
+ ///
+ /// let hello = cow.to_mut();
+ ///
+ /// assert_eq!(hello, &[1, 2, 3]);
+ /// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn to_mut(&mut self) -> &mut <B as ToOwned>::Owned {
match *self {
/// Extract the owned data.
///
/// Copies the data if it is not already owned.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::borrow::Cow;
+ ///
+ /// let cow: Cow<[_]> = Cow::Owned(vec![1, 2, 3]);
+ ///
+ /// let hello = cow.into_owned();
+ ///
+ /// assert_eq!(vec![1, 2, 3], hello);
+ /// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn into_owned(self) -> <B as ToOwned>::Owned {
match self {
Owned(owned) => owned
}
}
-
- /// Returns true if this `Cow` wraps a borrowed value
- #[deprecated(since = "1.0.0", reason = "match on the enum instead")]
- #[unstable(feature = "std_misc")]
- pub fn is_borrowed(&self) -> bool {
- match *self {
- Borrowed(_) => true,
- _ => false,
- }
- }
-
- /// Returns true if this `Cow` wraps an owned value
- #[deprecated(since = "1.0.0", reason = "match on the enum instead")]
- #[unstable(feature = "std_misc")]
- pub fn is_owned(&self) -> bool {
- match *self {
- Owned(_) => true,
- _ => false,
- }
- }
}
#[stable(feature = "rust1", since = "1.0.0")]
}
}
- #[unstable(feature = "collections",
- reason = "matches entry v3 specification, waiting for dust to settle")]
+ #[stable(feature = "rust1", since = "1.0.0")]
/// Ensures a value is in the entry by inserting the default if empty, and returns
/// a mutable reference to the value in the entry.
pub fn or_insert(self, default: V) -> &'a mut V {
}
}
- #[unstable(feature = "collections",
- reason = "matches entry v3 specification, waiting for dust to settle")]
+ #[stable(feature = "rust1", since = "1.0.0")]
/// Ensures a value is in the entry by inserting the result of the default function if empty,
/// and returns a mutable reference to the value in the entry.
pub fn or_insert_with<F: FnOnce() -> V>(self, default: F) -> &'a mut V {
#![feature(unsafe_no_drop_flag, filling_drop)]
#![feature(step_by)]
#![feature(str_char)]
-#![feature(convert)]
#![feature(slice_patterns)]
#![feature(debug_builders)]
#![cfg_attr(test, feature(rand, rustc_private, test, hash, collections))]
pub use vec::Vec;
pub use vec_map::VecMap;
-#[deprecated(since = "1.0.0", reason = "renamed to vec_deque")]
-#[unstable(feature = "collections")]
-pub use vec_deque as ring_buf;
-
-#[deprecated(since = "1.0.0", reason = "renamed to linked_list")]
-#[unstable(feature = "collections")]
-pub use linked_list as dlist;
-
-#[deprecated(since = "1.0.0", reason = "renamed to bit_vec")]
-#[unstable(feature = "collections")]
-pub use bit_vec as bitv;
-
-#[deprecated(since = "1.0.0", reason = "renamed to bit_set")]
-#[unstable(feature = "collections")]
-pub use bit_set as bitv_set;
-
// Needed for the vec! macro
pub use alloc::boxed;
reason = "RFC 509")]
pub mod bit_vec {
pub use bit::{BitVec, Iter};
-
- #[deprecated(since = "1.0.0", reason = "renamed to BitVec")]
- #[unstable(feature = "collections")]
- pub use bit::BitVec as Bitv;
}
#[unstable(feature = "collections",
pub mod bit_set {
pub use bit::{BitSet, Union, Intersection, Difference, SymmetricDifference};
pub use bit::SetIter as Iter;
-
- #[deprecated(since = "1.0.0", reason = "renamed to BitSet")]
- #[unstable(feature = "collections")]
- pub use bit::BitSet as BitvSet;
}
#[stable(feature = "rust1", since = "1.0.0")]
use core::mem;
use core::ptr;
-#[deprecated(since = "1.0.0", reason = "renamed to LinkedList")]
-#[unstable(feature = "collections")]
-pub use LinkedList as DList;
-
/// A doubly-linked list.
#[stable(feature = "rust1", since = "1.0.0")]
pub struct LinkedList<T> {
/// }
/// println!("{}", b.len()); // prints 0
/// ```
+ #[stable(feature = "rust1", since = "1.0.0")]
pub fn append(&mut self, other: &mut LinkedList<T>) {
match self.list_tail.resolve() {
None => {
#[stable(feature = "rust1", since = "1.0.0")]
impl<A> FromIterator<A> for LinkedList<A> {
fn from_iter<T: IntoIterator<Item=A>>(iter: T) -> LinkedList<A> {
- let mut ret = DList::new();
+ let mut ret = LinkedList::new();
ret.extend(iter);
ret
}
thread::spawn(move || {
check_links(&n);
let a: &[_] = &[&1,&2,&3];
- assert_eq!(a, n.iter().collect::<Vec<_>>());
+ assert_eq!(a, &n.iter().collect::<Vec<_>>()[..]);
}).join().ok().unwrap();
}
use core::marker::Sized;
use core::mem::size_of;
use core::mem;
-#[cfg(stage0)]
-use core::num::wrapping::WrappingOps;
use core::ops::FnMut;
use core::option::Option::{self, Some, None};
use core::ptr;
pub use core::slice::{SplitN, RSplitN, SplitNMut, RSplitNMut};
pub use core::slice::{bytes, mut_ref_slice, ref_slice};
pub use core::slice::{from_raw_parts, from_raw_parts_mut};
-pub use core::slice::{from_raw_buf, from_raw_mut_buf};
////////////////////////////////////////////////////////////////////////////////
// Basic slice extension methods
cmp::min(self.len(), end-start)
}
- /// Deprecated: use `&s[start .. end]` notation instead.
- #[unstable(feature = "collections",
- reason = "will be replaced by slice syntax")]
- #[deprecated(since = "1.0.0", reason = "use &s[start .. end] instead")]
- #[inline]
- pub fn slice(&self, start: usize, end: usize) -> &[T] {
- &self[start .. end]
- }
-
- /// Deprecated: use `&s[start..]` notation instead.
- #[unstable(feature = "collections",
- reason = "will be replaced by slice syntax")]
- #[deprecated(since = "1.0.0", reason = "use &s[start..] instead")]
- #[inline]
- pub fn slice_from(&self, start: usize) -> &[T] {
- &self[start ..]
- }
-
- /// Deprecated: use `&s[..end]` notation instead.
- #[unstable(feature = "collections",
- reason = "will be replaced by slice syntax")]
- #[deprecated(since = "1.0.0", reason = "use &s[..end] instead")]
- #[inline]
- pub fn slice_to(&self, end: usize) -> &[T] {
- &self[.. end]
- }
-
/// Divides one slice into two at an index.
///
/// The first will contain all indices from `[0, mid)` (excluding
/// ```rust
/// # #![feature(core)]
/// let s = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
- /// let s = s.as_slice();
///
/// let seek = 13;
/// assert_eq!(s.binary_search_by(|probe| probe.cmp(&seek)), Ok(9));
core_slice::SliceExt::get_mut(self, index)
}
- /// Deprecated: use `&mut s[..]` instead.
- #[unstable(feature = "collections",
- reason = "will be replaced by slice syntax")]
- #[deprecated(since = "1.0.0", reason = "use &mut s[..] instead")]
- #[allow(deprecated)]
- pub fn as_mut_slice(&mut self) -> &mut [T] {
- core_slice::SliceExt::as_mut_slice(self)
- }
-
- /// Deprecated: use `&mut s[start .. end]` instead.
- #[unstable(feature = "collections",
- reason = "will be replaced by slice syntax")]
- #[deprecated(since = "1.0.0", reason = "use &mut s[start .. end] instead")]
- #[inline]
- pub fn slice_mut(&mut self, start: usize, end: usize) -> &mut [T] {
- &mut self[start .. end]
- }
-
- /// Deprecated: use `&mut s[start ..]` instead.
- #[unstable(feature = "collections",
- reason = "will be replaced by slice syntax")]
- #[deprecated(since = "1.0.0", reason = "use &mut s[start ..] instead")]
- #[inline]
- pub fn slice_from_mut(&mut self, start: usize) -> &mut [T] {
- &mut self[start ..]
- }
-
- /// Deprecated: use `&mut s[.. end]` instead.
- #[unstable(feature = "collections",
- reason = "will be replaced by slice syntax")]
- #[deprecated(since = "1.0.0", reason = "use &mut s[.. end] instead")]
- #[inline]
- pub fn slice_to_mut(&mut self, end: usize) -> &mut [T] {
- &mut self[.. end]
- }
-
/// Returns an iterator that allows modifying each value
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
/// ```rust
/// # #![feature(core)]
/// let s = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
- /// let s = s.as_slice();
///
/// assert_eq!(s.binary_search(&13), Ok(9));
/// assert_eq!(s.binary_search(&4), Err(7));
core_slice::SliceExt::binary_search(self, x)
}
- /// Deprecated: use `binary_search` instead.
- #[unstable(feature = "collections")]
- #[deprecated(since = "1.0.0", reason = "use binary_search instead")]
- pub fn binary_search_elem(&self, x: &T) -> Result<usize, usize> where T: Ord {
- self.binary_search(x)
- }
-
/// Mutates the slice to the next lexicographic permutation.
///
/// Returns `true` if successful and `false` if the slice is at the
use slice::SliceConcatExt;
pub use core::str::{FromStr, Utf8Error, Str};
-pub use core::str::{Lines, LinesAny, MatchIndices, SplitStr, CharRange};
+pub use core::str::{Lines, LinesAny, MatchIndices, CharRange};
pub use core::str::{Split, SplitTerminator, SplitN};
pub use core::str::{RSplit, RSplitN};
-pub use core::str::{from_utf8, CharEq, Chars, CharIndices, Bytes};
-pub use core::str::{from_utf8_unchecked, from_c_str, ParseBoolError};
+pub use core::str::{from_utf8, Chars, CharIndices, Bytes};
+pub use core::str::{from_utf8_unchecked, ParseBoolError};
pub use unicode::str::{Words, Graphemes, GraphemeIndices};
pub use core::str::Pattern;
pub use core::str::{Searcher, ReverseSearcher, DoubleEndedSearcher, SearchStep};
core_str::StrExt::contains(&self[..], pat)
}
- /// Returns `true` if `self` contains a `char`.
- ///
- /// # Examples
- ///
- /// ```
- /// # #![feature(collections)]
- /// assert!("hello".contains_char('e'));
- ///
- /// assert!(!"hello".contains_char('z'));
- /// ```
- #[unstable(feature = "collections")]
- #[deprecated(since = "1.0.0", reason = "use `contains()` with a char")]
- pub fn contains_char<'a, P: Pattern<'a>>(&'a self, pat: P) -> bool {
- core_str::StrExt::contains_char(&self[..], pat)
- }
-
/// An iterator over the codepoints of `self`.
///
/// # Examples
core_str::StrExt::match_indices(&self[..], pat)
}
- /// An iterator over the substrings of `self` separated by a `&str`.
- ///
- /// # Examples
- ///
- /// ```
- /// # #![feature(collections)]
- /// let v: Vec<&str> = "abcXXXabcYYYabc".split_str("abc").collect();
- /// assert_eq!(v, ["", "XXX", "YYY", ""]);
- ///
- /// let v: Vec<&str> = "1abcabc2".split_str("abc").collect();
- /// assert_eq!(v, ["1", "", "2"]);
- /// ```
- #[unstable(feature = "collections")]
- #[deprecated(since = "1.0.0", reason = "use `split()` with a `&str`")]
- #[allow(deprecated) /* for SplitStr */]
- pub fn split_str<'a, P: Pattern<'a>>(&'a self, pat: P) -> SplitStr<'a, P> {
- core_str::StrExt::split_str(&self[..], pat)
- }
-
/// An iterator over the lines of a string, separated by `\n`.
///
/// This does not include the empty string after a trailing `\n`.
pub fn lines_any(&self) -> LinesAny {
core_str::StrExt::lines_any(&self[..])
}
-
- /// Deprecated: use `s[a .. b]` instead.
- #[unstable(feature = "collections",
- reason = "use slice notation [a..b] instead")]
- #[deprecated(since = "1.0.0", reason = "use slice notation [a..b] instead")]
- pub fn slice(&self, begin: usize, end: usize) -> &str {
- &self[begin..end]
- }
-
- /// Deprecated: use `s[a..]` instead.
- #[unstable(feature = "collections",
- reason = "use slice notation [a..b] instead")]
- #[deprecated(since = "1.0.0", reason = "use slice notation [a..] instead")]
- pub fn slice_from(&self, begin: usize) -> &str {
- &self[begin..]
- }
-
- /// Deprecated: use `s[..a]` instead.
- #[unstable(feature = "collections",
- reason = "use slice notation [a..b] instead")]
- #[deprecated(since = "1.0.0", reason = "use slice notation [..a] instead")]
- pub fn slice_to(&self, end: usize) -> &str {
- &self[..end]
- }
-
/// Returns a slice of the string from the character range [`begin`..`end`).
///
/// That is, start at the `begin`-th code point of the string and continue
core_str::StrExt::rfind(&self[..], pat)
}
- /// Returns the byte index of the first matching substring if it exists.
- ///
- /// Returns `None` if it doesn't exist.
- ///
- /// The pattern can be a simple `&str`, or a closure that determines the split.
- ///
- /// # Examples
- ///
- /// ```
- /// # #![feature(collections)]
- /// let s = "Löwe 老虎 Léopard";
- ///
- /// assert_eq!(s.find_str("老虎 L"), Some(6));
- /// assert_eq!(s.find_str("muffin man"), None);
- /// ```
- #[unstable(feature = "collections")]
- #[deprecated(since = "1.0.0", reason = "use `find()` with a `&str`")]
- pub fn find_str<'a, P: Pattern<'a>>(&'a self, needle: P) -> Option<usize> {
- core_str::StrExt::find_str(&self[..], needle)
- }
-
/// Retrieves the first character from a `&str` and returns it.
///
/// This does not allocate a new string; instead, it returns a slice that points one character
/// let gr1 = "a\u{310}e\u{301}o\u{308}\u{332}".graphemes(true).collect::<Vec<&str>>();
/// let b: &[_] = &["a\u{310}", "e\u{301}", "o\u{308}\u{332}"];
///
- /// assert_eq!(gr1.as_slice(), b);
+ /// assert_eq!(&gr1[..], b);
///
/// let gr2 = "a\r\nb🇷🇺🇸🇹".graphemes(true).collect::<Vec<&str>>();
/// let b: &[_] = &["a", "\r\n", "b", "🇷🇺🇸🇹"];
///
- /// assert_eq!(gr2.as_slice(), b);
+ /// assert_eq!(&gr2[..], b);
/// ```
#[unstable(feature = "unicode",
reason = "this functionality may only be provided by libunicode")]
/// let gr_inds = "a̐éö̲\r\n".grapheme_indices(true).collect::<Vec<(usize, &str)>>();
/// let b: &[_] = &[(0, "a̐"), (3, "é"), (6, "ö̲"), (11, "\r\n")];
///
- /// assert_eq!(gr_inds.as_slice(), b);
+ /// assert_eq!(&gr_inds[..], b);
/// ```
#[unstable(feature = "unicode",
reason = "this functionality may only be provided by libunicode")]
/// ```
/// # #![feature(collections, core)]
/// let s = String::from_str("hello");
- /// assert_eq!(s.as_slice(), "hello");
+ /// assert_eq!(&s[..], "hello");
/// ```
#[inline]
#[unstable(feature = "collections",
self.vec
}
+ /// Extract a string slice containing the entire string.
+ #[inline]
+ #[unstable(feature = "convert",
+ reason = "waiting on RFC revision")]
+ pub fn as_str(&self) -> &str {
+ self
+ }
+
/// Pushes the given string onto this string buffer.
///
/// # Examples
#[allow(deprecated)]
impl Str for String {
#[inline]
- #[stable(feature = "rust1", since = "1.0.0")]
fn as_slice(&self) -> &str {
unsafe { mem::transmute(&*self.vec) }
}
}
}
-/// A clone-on-write string
-#[deprecated(since = "1.0.0", reason = "use Cow<'a, str> instead")]
-#[stable(feature = "rust1", since = "1.0.0")]
-pub type CowString<'a> = Cow<'a, str>;
-
#[stable(feature = "rust1", since = "1.0.0")]
impl fmt::Write for String {
#[inline]
/// Note that this will drop any excess capacity. Calling this and
/// converting back to a vector with `into_vec()` is equivalent to calling
/// `shrink_to_fit()`.
- #[unstable(feature = "collections")]
+ #[stable(feature = "rust1", since = "1.0.0")]
pub fn into_boxed_slice(mut self) -> Box<[T]> {
self.shrink_to_fit();
unsafe {
}
}
+ /// Extract a slice containing the entire vector.
+ #[inline]
+ #[unstable(feature = "convert",
+ reason = "waiting on RFC revision")]
+ pub fn as_slice(&self) -> &[T] {
+ self
+ }
+
/// Deprecated: use `&mut s[..]` instead.
#[inline]
- #[unstable(feature = "collections",
- reason = "will be replaced by slice syntax")]
- #[deprecated(since = "1.0.0", reason = "use &mut s[..] instead")]
+ #[unstable(feature = "convert",
+ reason = "waiting on RFC revision")]
pub fn as_mut_slice(&mut self) -> &mut [T] {
&mut self[..]
}
/// # #![feature(collections, core)]
/// let v = vec![0, 1, 2];
/// let w = v.map_in_place(|i| i + 3);
- /// assert_eq!(w.as_slice(), [3, 4, 5].as_slice());
+ /// assert_eq!(&w[..], &[3, 4, 5]);
///
/// #[derive(PartialEq, Debug)]
/// struct Newtype(u8);
/// let bytes = vec![0x11, 0x22];
/// let newtyped_bytes = bytes.map_in_place(|x| Newtype(x));
- /// assert_eq!(newtyped_bytes.as_slice(), [Newtype(0x11), Newtype(0x22)].as_slice());
+ /// assert_eq!(&newtyped_bytes[..], &[Newtype(0x11), Newtype(0x22)]);
/// ```
#[unstable(feature = "collections",
reason = "API may change to provide stronger guarantees")]
}
__impl_slice_eq1! { Vec<A>, Vec<B> }
-__impl_slice_eq2! { Vec<A>, &'b [B] }
-__impl_slice_eq2! { Vec<A>, &'b mut [B] }
-__impl_slice_eq2! { Cow<'a, [A]>, &'b [B], Clone }
-__impl_slice_eq2! { Cow<'a, [A]>, &'b mut [B], Clone }
-__impl_slice_eq2! { Cow<'a, [A]>, Vec<B>, Clone }
+__impl_slice_eq1! { Vec<A>, &'b [B] }
+__impl_slice_eq1! { Vec<A>, &'b mut [B] }
+__impl_slice_eq1! { Cow<'a, [A]>, &'b [B], Clone }
+__impl_slice_eq1! { Cow<'a, [A]>, &'b mut [B], Clone }
+__impl_slice_eq1! { Cow<'a, [A]>, Vec<B>, Clone }
macro_rules! array_impls {
($($N: expr)+) => {
$(
// NOTE: some less important impls are omitted to reduce code bloat
- __impl_slice_eq2! { Vec<A>, [B; $N] }
- __impl_slice_eq2! { Vec<A>, &'b [B; $N] }
- // __impl_slice_eq2! { Vec<A>, &'b mut [B; $N] }
- // __impl_slice_eq2! { Cow<'a, [A]>, [B; $N], Clone }
- // __impl_slice_eq2! { Cow<'a, [A]>, &'b [B; $N], Clone }
- // __impl_slice_eq2! { Cow<'a, [A]>, &'b mut [B; $N], Clone }
+ __impl_slice_eq1! { Vec<A>, [B; $N] }
+ __impl_slice_eq1! { Vec<A>, &'b [B; $N] }
+ // __impl_slice_eq1! { Vec<A>, &'b mut [B; $N] }
+ // __impl_slice_eq1! { Cow<'a, [A]>, [B; $N], Clone }
+ // __impl_slice_eq1! { Cow<'a, [A]>, &'b [B; $N], Clone }
+ // __impl_slice_eq1! { Cow<'a, [A]>, &'b mut [B; $N], Clone }
)+
}
}
}
}
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<T> Into<Vec<T>> for Vec<T> {
- fn into(self) -> Vec<T> {
- self
- }
-}
-
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> AsRef<[T]> for Vec<T> {
fn as_ref(&self) -> &[T] {
// Clone-on-write
////////////////////////////////////////////////////////////////////////////////
-/// A clone-on-write vector
-#[deprecated(since = "1.0.0", reason = "use Cow<'a, [T]> instead")]
-#[unstable(feature = "collections")]
-pub type CowVec<'a, T> = Cow<'a, [T]>;
-
#[unstable(feature = "collections")]
impl<'a, T> FromIterator<T> for Cow<'a, [T]> where T: Clone {
fn from_iter<I: IntoIterator<Item=T>>(it: I) -> Cow<'a, [T]> {
use core::fmt;
use core::iter::{self, repeat, FromIterator, IntoIterator, RandomAccessIterator};
use core::mem;
-#[cfg(stage0)]
-use core::num::wrapping::WrappingOps;
use core::ops::{Index, IndexMut};
use core::ptr::{self, Unique};
use core::slice;
use alloc::heap;
-#[deprecated(since = "1.0.0", reason = "renamed to VecDeque")]
-#[unstable(feature = "collections")]
-pub use VecDeque as RingBuf;
-
const INITIAL_CAPACITY: usize = 7; // 2^3 - 1
const MINIMUM_CAPACITY: usize = 1; // 2 - 1
/// buf.push_back(3);
/// buf.push_back(4);
/// let b: &[_] = &[&5, &3, &4];
- /// assert_eq!(buf.iter().collect::<Vec<&i32>>().as_slice(), b);
+ /// let c: Vec<&i32> = buf.iter().collect();
+ /// assert_eq!(&c[..], b);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn iter(&self) -> Iter<T> {
// len is the length *after* insertion
for len in 1..cap {
// 0, 1, 2, .., len - 1
- let expected = iter::count(0, 1).take(len).collect();
+ let expected = (0..).take(len).collect();
for tail_pos in 0..cap {
for to_insert in 0..len {
tester.tail = tail_pos;
// len is the length *after* removal
for len in 0..cap - 1 {
// 0, 1, 2, .., len - 1
- let expected = iter::count(0, 1).take(len).collect();
+ let expected = (0..).take(len).collect();
for tail_pos in 0..cap {
for to_remove in 0..len + 1 {
tester.tail = tail_pos;
for len in 0..cap + 1 {
// 0, 1, 2, .., len - 1
- let expected = iter::count(0, 1).take(len).collect();
+ let expected = (0..).take(len).collect();
for tail_pos in 0..max_cap + 1 {
tester.tail = tail_pos;
tester.head = tail_pos;
// index to split at
for at in 0..len + 1 {
// 0, 1, 2, .., at - 1 (may be empty)
- let expected_self = iter::count(0, 1).take(at).collect();
+ let expected_self = (0..).take(at).collect();
// at, at + 1, .., len - 1 (may be empty)
- let expected_other = iter::count(at, 1).take(len - at).collect();
+ let expected_other = (at..).take(len - at).collect();
for tail_pos in 0..cap {
tester.tail = tail_pos;
use std::cmp::Ordering::{Equal, Greater, Less};
use std::collections::{BitSet, BitVec};
-use std::iter::range_step;
#[test]
fn test_bit_set_show() {
assert_eq!(idxs, [0, 2, 3]);
let long: BitSet = (0..10000).filter(|&n| n % 2 == 0).collect();
- let real: Vec<_> = range_step(0, 10000, 2).collect();
+ let real: Vec<_> = (0..10000).step_by(2).collect();
let idxs: Vec<_> = long.iter().collect();
assert_eq!(idxs, real);
e1.insert(A);
let elems: Vec<_> = e1.iter().collect();
- assert_eq!([A], elems);
+ assert_eq!(elems, [A]);
e1.insert(C);
let elems: Vec<_> = e1.iter().collect();
- assert_eq!([A,C], elems);
+ assert_eq!(elems, [A,C]);
e1.insert(C);
let elems: Vec<_> = e1.iter().collect();
- assert_eq!([A,C], elems);
+ assert_eq!(elems, [A,C]);
e1.insert(B);
let elems: Vec<_> = e1.iter().collect();
- assert_eq!([A,B,C], elems);
+ assert_eq!(elems, [A,B,C]);
}
///////////////////////////////////////////////////////////////////////////
let e_union = e1 | e2;
let elems: Vec<_> = e_union.iter().collect();
- assert_eq!([A,B,C], elems);
+ assert_eq!(elems, [A,B,C]);
let e_intersection = e1 & e2;
let elems: Vec<_> = e_intersection.iter().collect();
- assert_eq!([C], elems);
+ assert_eq!(elems, [C]);
// Another way to express intersection
let e_intersection = e1 - (e1 - e2);
let elems: Vec<_> = e_intersection.iter().collect();
- assert_eq!([C], elems);
+ assert_eq!(elems, [C]);
let e_subtract = e1 - e2;
let elems: Vec<_> = e_subtract.iter().collect();
- assert_eq!([A], elems);
+ assert_eq!(elems, [A]);
// Bitwise XOR of two sets, aka symmetric difference
let e_symmetric_diff = e1 ^ e2;
let elems: Vec<_> = e_symmetric_diff.iter().collect();
- assert_eq!([A,B], elems);
+ assert_eq!(elems, [A,B]);
// Another way to express symmetric difference
let e_symmetric_diff = (e1 - e2) | (e2 - e1);
let elems: Vec<_> = e_symmetric_diff.iter().collect();
- assert_eq!([A,B], elems);
+ assert_eq!(elems, [A,B]);
// Yet another way to express symmetric difference
let e_symmetric_diff = (e1 | e2) - (e1 & e2);
let elems: Vec<_> = e_symmetric_diff.iter().collect();
- assert_eq!([A,B], elems);
+ assert_eq!(elems, [A,B]);
}
#[test]
#[test]
fn test_format() {
let s = fmt::format(format_args!("Hello, {}!", "world"));
- assert_eq!(s.as_slice(), "Hello, world!");
+ assert_eq!(s, "Hello, world!");
}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![allow(deprecated)]
#![feature(box_syntax)]
#![feature(collections)]
#![feature(core)]
#![feature(unicode)]
#![feature(unsafe_destructor)]
#![feature(into_cow)]
+#![feature(step_by)]
#![cfg_attr(test, feature(str_char))]
#[macro_use] extern crate log;
// Test on-heap from_elem.
v = vec![20; 6];
{
- let v = v.as_slice();
+ let v = &v[..];
assert_eq!(v[0], 20);
assert_eq!(v[1], 20);
assert_eq!(v[2], 20);
#[test]
fn test_slice_2() {
let v = vec![1, 2, 3, 4, 5];
- let v = v.slice(1, 3);
+ let v = &v[1..3];
assert_eq!(v.len(), 2);
assert_eq!(v[0], 2);
assert_eq!(v[1], 3);
fn test_into_bytes() {
let data = String::from_str("asdf");
let buf = data.into_bytes();
- assert_eq!(b"asdf", buf);
+ assert_eq!(buf, b"asdf");
}
#[test]
fn test_find_str() {
// byte positions
- assert_eq!("".find_str(""), Some(0));
- assert!("banana".find_str("apple pie").is_none());
+ assert_eq!("".find(""), Some(0));
+ assert!("banana".find("apple pie").is_none());
let data = "abcabc";
- assert_eq!(data[0..6].find_str("ab"), Some(0));
- assert_eq!(data[2..6].find_str("ab"), Some(3 - 2));
- assert!(data[2..4].find_str("ab").is_none());
+ assert_eq!(data[0..6].find("ab"), Some(0));
+ assert_eq!(data[2..6].find("ab"), Some(3 - 2));
+ assert!(data[2..4].find("ab").is_none());
let string = "ประเทศไทย中华Việt Nam";
let mut data = String::from_str(string);
data.push_str(string);
- assert!(data.find_str("ไท华").is_none());
- assert_eq!(data[0..43].find_str(""), Some(0));
- assert_eq!(data[6..43].find_str(""), Some(6 - 6));
+ assert!(data.find("ไท华").is_none());
+ assert_eq!(data[0..43].find(""), Some(0));
+ assert_eq!(data[6..43].find(""), Some(6 - 6));
- assert_eq!(data[0..43].find_str("ประ"), Some( 0));
- assert_eq!(data[0..43].find_str("ทศไ"), Some(12));
- assert_eq!(data[0..43].find_str("ย中"), Some(24));
- assert_eq!(data[0..43].find_str("iệt"), Some(34));
- assert_eq!(data[0..43].find_str("Nam"), Some(40));
+ assert_eq!(data[0..43].find("ประ"), Some( 0));
+ assert_eq!(data[0..43].find("ทศไ"), Some(12));
+ assert_eq!(data[0..43].find("ย中"), Some(24));
+ assert_eq!(data[0..43].find("iệt"), Some(34));
+ assert_eq!(data[0..43].find("Nam"), Some(40));
- assert_eq!(data[43..86].find_str("ประ"), Some(43 - 43));
- assert_eq!(data[43..86].find_str("ทศไ"), Some(55 - 43));
- assert_eq!(data[43..86].find_str("ย中"), Some(67 - 43));
- assert_eq!(data[43..86].find_str("iệt"), Some(77 - 43));
- assert_eq!(data[43..86].find_str("Nam"), Some(83 - 43));
+ assert_eq!(data[43..86].find("ประ"), Some(43 - 43));
+ assert_eq!(data[43..86].find("ทศไ"), Some(55 - 43));
+ assert_eq!(data[43..86].find("ย中"), Some(67 - 43));
+ assert_eq!(data[43..86].find("iệt"), Some(77 - 43));
+ assert_eq!(data[43..86].find("Nam"), Some(83 - 43));
}
#[test]
#[test]
fn test_slice() {
- assert_eq!("ab", "abc".slice(0, 2));
- assert_eq!("bc", "abc".slice(1, 3));
- assert_eq!("", "abc".slice(1, 1));
- assert_eq!("\u{65e5}", "\u{65e5}\u{672c}".slice(0, 3));
+ assert_eq!("ab", &"abc"[0..2]);
+ assert_eq!("bc", &"abc"[1..3]);
+ assert_eq!("", &"abc"[1..1]);
+ assert_eq!("\u{65e5}", &"\u{65e5}\u{672c}"[0..3]);
let data = "ประเทศไทย中华";
- assert_eq!("ป", data.slice(0, 3));
- assert_eq!("ร", data.slice(3, 6));
- assert_eq!("", data.slice(3, 3));
- assert_eq!("华", data.slice(30, 33));
+ assert_eq!("ป", &data[0..3]);
+ assert_eq!("ร", &data[3..6]);
+ assert_eq!("", &data[3..3]);
+ assert_eq!("华", &data[30..33]);
fn a_million_letter_x() -> String {
let mut i = 0;
}
let letters = a_million_letter_x();
assert!(half_a_million_letter_x() ==
- String::from_str(letters.slice(0, 3 * 500000)));
+ String::from_str(&letters[0..3 * 500000]));
}
#[test]
fn test_slice_2() {
let ss = "中华Việt Nam";
- assert_eq!("华", ss.slice(3, 6));
- assert_eq!("Việt Nam", ss.slice(6, 16));
+ assert_eq!("华", &ss[3..6]);
+ assert_eq!("Việt Nam", &ss[6..16]);
- assert_eq!("ab", "abc".slice(0, 2));
- assert_eq!("bc", "abc".slice(1, 3));
- assert_eq!("", "abc".slice(1, 1));
+ assert_eq!("ab", &"abc"[0..2]);
+ assert_eq!("bc", &"abc"[1..3]);
+ assert_eq!("", &"abc"[1..1]);
- assert_eq!("中", ss.slice(0, 3));
- assert_eq!("华V", ss.slice(3, 7));
- assert_eq!("", ss.slice(3, 3));
+ assert_eq!("中", &ss[0..3]);
+ assert_eq!("华V", &ss[3..7]);
+ assert_eq!("", &ss[3..3]);
/*0: 中
3: 华
6: V
#[test]
#[should_panic]
fn test_slice_fail() {
- "中华Việt Nam".slice(0, 2);
+ &"中华Việt Nam"[0..2];
}
#[test]
fn test_slice_from() {
- assert_eq!("abcd".slice_from(0), "abcd");
- assert_eq!("abcd".slice_from(2), "cd");
- assert_eq!("abcd".slice_from(4), "");
+ assert_eq!(&"abcd"[0..], "abcd");
+ assert_eq!(&"abcd"[2..], "cd");
+ assert_eq!(&"abcd"[4..], "");
}
#[test]
fn test_slice_to() {
- assert_eq!("abcd".slice_to(0), "");
- assert_eq!("abcd".slice_to(2), "ab");
- assert_eq!("abcd".slice_to(4), "abcd");
+ assert_eq!(&"abcd"[..0], "");
+ assert_eq!(&"abcd"[..2], "ab");
+ assert_eq!(&"abcd"[..4], "abcd");
}
#[test]
#[test]
fn test_contains_char() {
- assert!("abc".contains_char('b'));
- assert!("a".contains_char('a'));
- assert!(!"abc".contains_char('d'));
- assert!(!"".contains_char('a'));
+ assert!("abc".contains('b'));
+ assert!("a".contains('a'));
+ assert!(!"abc".contains('d'));
+ assert!(!"".contains('a'));
}
#[test]
}
#[test]
-fn test_split_strator() {
+fn test_splitator() {
fn t(s: &str, sep: &str, u: &[&str]) {
- let v: Vec<&str> = s.split_str(sep).collect();
+ let v: Vec<&str> = s.split(sep).collect();
assert_eq!(v, u);
}
t("--1233345--", "12345", &["--1233345--"]);
fn test_str_default() {
use std::default::Default;
- fn t<S: Default + Str>() {
+ fn t<S: Default + AsRef<str>>() {
let s: S = Default::default();
- assert_eq!(s.as_slice(), "");
+ assert_eq!(s.as_ref(), "");
}
t::<&str>();
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-use std::borrow::IntoCow;
+use std::borrow::{IntoCow, Cow};
use std::iter::repeat;
use std::str::Utf8Error;
-use std::string::{CowString, as_string};
+use std::string::as_string;
use test::Bencher;
#[test]
fn test_from_utf8_lossy() {
let xs = b"hello";
- let ys: CowString = "hello".into_cow();
+ let ys: Cow<str> = "hello".into_cow();
assert_eq!(String::from_utf8_lossy(xs), ys);
let xs = "ศไทย中华Việt Nam".as_bytes();
- let ys: CowString = "ศไทย中华Việt Nam".into_cow();
+ let ys: Cow<str> = "ศไทย中华Việt Nam".into_cow();
assert_eq!(String::from_utf8_lossy(xs), ys);
let xs = b"Hello\xC2 There\xFF Goodbye";
use self::Taggypar::*;
#[test]
-#[allow(deprecated)]
fn test_simple() {
let mut d = VecDeque::new();
assert_eq!(d.len(), 0);
let u: Vec<_> = deq.iter().cloned().collect();
assert_eq!(u, v);
- let seq = iter::count(0, 2).take(256);
+ let seq = (0..).step_by(2).take(256);
let deq: VecDeque<_> = seq.collect();
for (i, &x) in deq.iter().enumerate() {
assert_eq!(2*i, x);
let (left, right) = ring.as_slices();
let expected: Vec<_> = (0..i+1).collect();
- assert_eq!(left, expected);
+ assert_eq!(left, &expected[..]);
assert_eq!(right, []);
}
let (left, right) = ring.as_slices();
let expected_left: Vec<_> = (-last..j+1).rev().collect();
let expected_right: Vec<_> = (0..first).collect();
- assert_eq!(left, expected_left);
- assert_eq!(right, expected_right);
+ assert_eq!(left, &expected_left[..]);
+ assert_eq!(right, &expected_right[..]);
}
assert_eq!(ring.len() as i32, cap);
let (left, right) = ring.as_mut_slices();
let expected: Vec<_> = (0..i+1).collect();
- assert_eq!(left, expected);
+ assert_eq!(left, &expected[..]);
assert_eq!(right, []);
}
let (left, right) = ring.as_mut_slices();
let expected_left: Vec<_> = (-last..j+1).rev().collect();
let expected_right: Vec<_> = (0..first).collect();
- assert_eq!(left, expected_left);
- assert_eq!(right, expected_right);
+ assert_eq!(left, &expected_left[..]);
+ assert_eq!(right, &expected_right[..]);
}
assert_eq!(ring.len() as i32, cap);
impl TypeId {
/// Returns the `TypeId` of the type this generic function has been
/// instantiated with
- #[unstable(feature = "core",
- reason = "may grow a `Reflect` bound soon via marker traits")]
+ #[stable(feature = "rust1", since = "1.0.0")]
pub fn of<T: ?Sized + Any>() -> TypeId {
TypeId {
t: unsafe { intrinsics::type_id::<T>() },
}
}
}
-
-#[unstable(feature = "core")]
-#[deprecated(since = "1.0.0",
- reason = "renamed to AtomicIsize")]
-#[allow(missing_docs)]
-pub struct AtomicInt {
- v: UnsafeCell<isize>,
-}
-
-#[allow(deprecated)]
-unsafe impl Sync for AtomicInt {}
-
-#[unstable(feature = "core")]
-#[deprecated(since = "1.0.0",
- reason = "renamed to AtomicUsize")]
-#[allow(missing_docs)]
-pub struct AtomicUint {
- v: UnsafeCell<usize>,
-}
-
-#[allow(deprecated)]
-unsafe impl Sync for AtomicUint {}
-
-#[unstable(feature = "core")]
-#[deprecated(since = "1.0.0",
- reason = "use ATOMIC_ISIZE_INIT instead")]
-#[allow(missing_docs, deprecated)]
-pub const ATOMIC_INT_INIT: AtomicInt =
- AtomicInt { v: UnsafeCell { value: 0 } };
-#[unstable(feature = "core")]
-#[deprecated(since = "1.0.0",
- reason = "use ATOMIC_USIZE_INIT instead")]
-#[allow(missing_docs, deprecated)]
-pub const ATOMIC_UINT_INIT: AtomicUint =
- AtomicUint { v: UnsafeCell { value: 0, } };
-
-#[allow(missing_docs, deprecated)]
-impl AtomicInt {
- #[inline]
- pub fn new(v: isize) -> AtomicInt {
- AtomicInt {v: UnsafeCell::new(v)}
- }
-
- #[inline]
- pub fn load(&self, order: Ordering) -> isize {
- unsafe { atomic_load(self.v.get(), order) }
- }
-
- #[inline]
- pub fn store(&self, val: isize, order: Ordering) {
- unsafe { atomic_store(self.v.get(), val, order); }
- }
-
- #[inline]
- pub fn swap(&self, val: isize, order: Ordering) -> isize {
- unsafe { atomic_swap(self.v.get(), val, order) }
- }
-
- #[inline]
- pub fn compare_and_swap(&self, old: isize, new: isize, order: Ordering) -> isize {
- unsafe { atomic_compare_and_swap(self.v.get(), old, new, order) }
- }
-
- #[inline]
- pub fn fetch_add(&self, val: isize, order: Ordering) -> isize {
- unsafe { atomic_add(self.v.get(), val, order) }
- }
-
- #[inline]
- pub fn fetch_sub(&self, val: isize, order: Ordering) -> isize {
- unsafe { atomic_sub(self.v.get(), val, order) }
- }
-
- #[inline]
- pub fn fetch_and(&self, val: isize, order: Ordering) -> isize {
- unsafe { atomic_and(self.v.get(), val, order) }
- }
-
- #[inline]
- pub fn fetch_or(&self, val: isize, order: Ordering) -> isize {
- unsafe { atomic_or(self.v.get(), val, order) }
- }
-
- #[inline]
- pub fn fetch_xor(&self, val: isize, order: Ordering) -> isize {
- unsafe { atomic_xor(self.v.get(), val, order) }
- }
-}
-
-#[allow(missing_docs, deprecated)]
-impl AtomicUint {
- #[inline]
- pub fn new(v: usize) -> AtomicUint {
- AtomicUint { v: UnsafeCell::new(v) }
- }
-
- #[inline]
- pub fn load(&self, order: Ordering) -> usize {
- unsafe { atomic_load(self.v.get(), order) }
- }
-
- #[inline]
- pub fn store(&self, val: usize, order: Ordering) {
- unsafe { atomic_store(self.v.get(), val, order); }
- }
-
- #[inline]
- pub fn swap(&self, val: usize, order: Ordering) -> usize {
- unsafe { atomic_swap(self.v.get(), val, order) }
- }
-
- #[inline]
- pub fn compare_and_swap(&self, old: usize, new: usize, order: Ordering) -> usize {
- unsafe { atomic_compare_and_swap(self.v.get(), old, new, order) }
- }
-
- #[inline]
- pub fn fetch_add(&self, val: usize, order: Ordering) -> usize {
- unsafe { atomic_add(self.v.get(), val, order) }
- }
-
- #[inline]
- pub fn fetch_sub(&self, val: usize, order: Ordering) -> usize {
- unsafe { atomic_sub(self.v.get(), val, order) }
- }
-
- #[inline]
- pub fn fetch_and(&self, val: usize, order: Ordering) -> usize {
- unsafe { atomic_and(self.v.get(), val, order) }
- }
-
- #[inline]
- pub fn fetch_or(&self, val: usize, order: Ordering) -> usize {
- unsafe { atomic_or(self.v.get(), val, order) }
- }
-
- #[inline]
- pub fn fetch_xor(&self, val: usize, order: Ordering) -> usize {
- unsafe { atomic_xor(self.v.get(), val, order) }
- }
-}
}
}
- /// Attempts to immutably borrow the wrapped value.
- ///
- /// The borrow lasts until the returned `Ref` exits scope. Multiple
- /// immutable borrows can be taken out at the same time.
- ///
- /// Returns `None` if the value is currently mutably borrowed.
- #[unstable(feature = "core", reason = "may be renamed or removed")]
- #[deprecated(since = "1.0.0",
- reason = "dispatch on `cell.borrow_state()` instead")]
- #[inline]
- pub fn try_borrow<'a>(&'a self) -> Option<Ref<'a, T>> {
- match BorrowRef::new(&self.borrow) {
- Some(b) => Some(Ref { _value: unsafe { &*self.value.get() }, _borrow: b }),
- None => None,
- }
- }
-
/// Immutably borrows the wrapped value.
///
/// The borrow lasts until the returned `Ref` exits scope. Multiple
}
}
- /// Mutably borrows the wrapped value.
- ///
- /// The borrow lasts until the returned `RefMut` exits scope. The value
- /// cannot be borrowed while this borrow is active.
- ///
- /// Returns `None` if the value is currently borrowed.
- #[unstable(feature = "core", reason = "may be renamed or removed")]
- #[deprecated(since = "1.0.0",
- reason = "dispatch on `cell.borrow_state()` instead")]
- #[inline]
- pub fn try_borrow_mut<'a>(&'a self) -> Option<RefMut<'a, T>> {
- match BorrowRefMut::new(&self.borrow) {
- Some(b) => Some(RefMut { _value: unsafe { &mut *self.value.get() }, _borrow: b }),
- None => None,
- }
- }
-
/// Mutably borrows the wrapped value.
///
/// The borrow lasts until the returned `RefMut` exits scope. The value
/// inverse of `ne`; that is, `!(a == b)` if and only if `a != b`.
#[lang="eq"]
#[stable(feature = "rust1", since = "1.0.0")]
-#[old_orphan_check]
pub trait PartialEq<Rhs: ?Sized = Self> {
/// This method tests for `self` and `other` values to be equal, and is used by `==`.
#[stable(feature = "rust1", since = "1.0.0")]
/// Compare and return the minimum of two values.
///
+/// Returns the first argument if the comparison determines them to be equal.
+///
/// # Examples
///
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn min<T: Ord>(v1: T, v2: T) -> T {
- if v1 < v2 { v1 } else { v2 }
+ if v1 <= v2 { v1 } else { v2 }
}
/// Compare and return the maximum of two values.
///
+/// Returns the second argument if the comparison determines them to be equal.
+///
/// # Examples
///
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn max<T: Ord>(v1: T, v2: T) -> T {
- if v1 > v2 { v1 } else { v2 }
+ if v2 >= v1 { v2 } else { v1 }
}
/// Compare and return the minimum of two values if there is one.
/// Compare and return the maximum of two values if there is one.
///
-/// Returns the first argument if the comparison determines them to be equal.
+/// Returns the second argument if the comparison determines them to be equal.
///
/// # Examples
///
#[unstable(feature = "core")]
pub fn partial_max<T: PartialOrd>(v1: T, v2: T) -> Option<T> {
match v1.partial_cmp(&v2) {
- Some(Less) => Some(v2),
- Some(Equal) | Some(Greater) => Some(v1),
+ Some(Equal) | Some(Less) => Some(v2),
+ Some(Greater) => Some(v1),
None => None
}
}
#[macro_export]
macro_rules! __impl_slice_eq1 {
($Lhs: ty, $Rhs: ty) => {
+ __impl_slice_eq1! { $Lhs, $Rhs, Sized }
+ };
+ ($Lhs: ty, $Rhs: ty, $Bound: ident) => {
#[stable(feature = "rust1", since = "1.0.0")]
- impl<'a, 'b, A, B> PartialEq<$Rhs> for $Lhs where A: PartialEq<B> {
+ impl<'a, 'b, A: $Bound, B> PartialEq<$Rhs> for $Lhs where A: PartialEq<B> {
#[inline]
fn eq(&self, other: &$Rhs) -> bool { &self[..] == &other[..] }
#[inline]
__impl_slice_eq2! { $Lhs, $Rhs, Sized }
};
($Lhs: ty, $Rhs: ty, $Bound: ident) => {
- #[stable(feature = "rust1", since = "1.0.0")]
- impl<'a, 'b, A: $Bound, B> PartialEq<$Rhs> for $Lhs where A: PartialEq<B> {
- #[inline]
- fn eq(&self, other: &$Rhs) -> bool { &self[..] == &other[..] }
- #[inline]
- fn ne(&self, other: &$Rhs) -> bool { &self[..] != &other[..] }
- }
+ __impl_slice_eq1!($Lhs, $Rhs, $Bound);
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, 'b, A: $Bound, B> PartialEq<$Lhs> for $Rhs where B: PartialEq<A> {
//! conversions from one type to another. They follow the standard
//! Rust conventions of `as`/`to`/`into`/`from`.
-#![unstable(feature = "convert",
- reason = "recently added, experimental traits")]
+#![stable(feature = "rust1", since = "1.0.0")]
use marker::Sized;
/// A cheap, reference-to-reference conversion.
+#[stable(feature = "rust1", since = "1.0.0")]
pub trait AsRef<T: ?Sized> {
/// Perform the conversion.
+ #[stable(feature = "rust1", since = "1.0.0")]
fn as_ref(&self) -> &T;
}
/// A cheap, mutable reference-to-mutable reference conversion.
+#[stable(feature = "rust1", since = "1.0.0")]
pub trait AsMut<T: ?Sized> {
/// Perform the conversion.
+ #[stable(feature = "rust1", since = "1.0.0")]
fn as_mut(&mut self) -> &mut T;
}
/// A conversion that consumes `self`, which may or may not be
/// expensive.
+#[stable(feature = "rust1", since = "1.0.0")]
pub trait Into<T>: Sized {
/// Perform the conversion.
+ #[stable(feature = "rust1", since = "1.0.0")]
fn into(self) -> T;
}
/// Construct `Self` via a conversion.
+#[stable(feature = "rust1", since = "1.0.0")]
pub trait From<T> {
/// Perform the conversion.
+ #[stable(feature = "rust1", since = "1.0.0")]
fn from(T) -> Self;
}
// GENERIC IMPLS
////////////////////////////////////////////////////////////////////////////////
-// As implies Into
-impl<'a, T: ?Sized, U: ?Sized> Into<&'a U> for &'a T where T: AsRef<U> {
- fn into(self) -> &'a U {
- self.as_ref()
- }
-}
-
// As lifts over &
+#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, T: ?Sized, U: ?Sized> AsRef<U> for &'a T where T: AsRef<U> {
fn as_ref(&self) -> &U {
<T as AsRef<U>>::as_ref(*self)
}
// As lifts over &mut
+#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, T: ?Sized, U: ?Sized> AsRef<U> for &'a mut T where T: AsRef<U> {
fn as_ref(&self) -> &U {
<T as AsRef<U>>::as_ref(*self)
// }
// }
-// AsMut implies Into
-impl<'a, T: ?Sized, U: ?Sized> Into<&'a mut U> for &'a mut T where T: AsMut<U> {
- fn into(self) -> &'a mut U {
- (*self).as_mut()
- }
-}
-
// AsMut lifts over &mut
+#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, T: ?Sized, U: ?Sized> AsMut<U> for &'a mut T where T: AsMut<U> {
fn as_mut(&mut self) -> &mut U {
(*self).as_mut()
// }
// From implies Into
+#[stable(feature = "rust1", since = "1.0.0")]
impl<T, U> Into<U> for T where U: From<T> {
fn into(self) -> U {
U::from(self)
}
}
+// From (and thus Into) is reflexive
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<T> From<T> for T {
+ fn from(t: T) -> T { t }
+}
+
////////////////////////////////////////////////////////////////////////////////
// CONCRETE IMPLS
////////////////////////////////////////////////////////////////////////////////
+#[stable(feature = "rust1", since = "1.0.0")]
impl<T> AsRef<[T]> for [T] {
fn as_ref(&self) -> &[T] {
self
}
}
+#[stable(feature = "rust1", since = "1.0.0")]
impl<T> AsMut<[T]> for [T] {
fn as_mut(&mut self) -> &mut [T] {
self
}
}
+#[stable(feature = "rust1", since = "1.0.0")]
impl AsRef<str> for str {
fn as_ref(&self) -> &str {
self
//! high-level module to provide its own errors that do not commit to any
//! particular implementation, but also reveal some of its implementation for
//! debugging via `cause` chains.
-//!
-//! # The `FromError` trait
-//!
-//! `FromError` is a simple trait that expresses conversions between different
-//! error types. To provide maximum flexibility, it does not require either of
-//! the types to actually implement the `Error` trait, although this will be the
-//! common case.
-//!
-//! The main use of this trait is in the `try!` macro, which uses it to
-//! automatically convert a given error to the error specified in a function's
-//! return type.
-//!
-//! For example,
-//!
-//! ```
-//! #![feature(core)]
-//! use std::error::FromError;
-//! use std::{io, str};
-//! use std::fs::File;
-//!
-//! enum MyError {
-//! Io(io::Error),
-//! Utf8(str::Utf8Error),
-//! }
-//!
-//! impl FromError<io::Error> for MyError {
-//! fn from_error(err: io::Error) -> MyError { MyError::Io(err) }
-//! }
-//!
-//! impl FromError<str::Utf8Error> for MyError {
-//! fn from_error(err: str::Utf8Error) -> MyError { MyError::Utf8(err) }
-//! }
-//!
-//! #[allow(unused_variables)]
-//! fn open_and_map() -> Result<(), MyError> {
-//! let b = b"foo.txt";
-//! let s = try!(str::from_utf8(b));
-//! let f = try!(File::open(s));
-//!
-//! // do something interesting here...
-//! Ok(())
-//! }
-//! ```
#![stable(feature = "rust1", since = "1.0.0")]
#[stable(feature = "rust1", since = "1.0.0")]
fn cause(&self) -> Option<&Error> { None }
}
-
-/// A trait for types that can be converted from a given error type `E`.
-#[stable(feature = "rust1", since = "1.0.0")]
-pub trait FromError<E> {
- /// Perform the conversion.
- #[stable(feature = "rust1", since = "1.0.0")]
- fn from_error(err: E) -> Self;
-}
-
-// Any type is convertable from itself
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<E> FromError<E> for E {
- fn from_error(err: E) -> E {
- err
- }
-}
+++ /dev/null
-// Copyright 2013 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.
-
-//! The Finally trait provides a method, `finally` on
-//! stack closures that emulates Java-style try/finally blocks.
-//!
-//! Using the `finally` method is sometimes convenient, but the type rules
-//! prohibit any shared, mutable state between the "try" case and the
-//! "finally" case. For advanced cases, the `try_finally` function can
-//! also be used. See that function for more details.
-//!
-//! # Examples
-//!
-//! ```
-//! # #![feature(core)]
-//! # #![feature(unboxed_closures)]
-//!
-//! use std::finally::Finally;
-//!
-//! (|| {
-//! // ...
-//! }).finally(|| {
-//! // this code is always run
-//! })
-//! ```
-
-#![unstable(feature = "core")]
-#![deprecated(since = "1.0.0",
- reason = "It is unclear if this module is more robust than implementing \
- Drop on a custom type, and this module is being removed with no \
- replacement. Use a custom Drop implementation to regain existing \
- functionality.")]
-#![allow(deprecated)]
-
-use ops::{Drop, FnMut, FnOnce};
-
-/// A trait for executing a destructor unconditionally after a block of code,
-/// regardless of whether the blocked fails.
-pub trait Finally<T> {
- /// Executes this object, unconditionally running `dtor` after this block of
- /// code has run.
- fn finally<F>(&mut self, dtor: F) -> T where F: FnMut();
-}
-
-impl<T, F> Finally<T> for F where F: FnMut() -> T {
- fn finally<G>(&mut self, mut dtor: G) -> T where G: FnMut() {
- try_finally(&mut (), self, |_, f| (*f)(), |_| dtor())
- }
-}
-
-/// The most general form of the `finally` functions. The function
-/// `try_fn` will be invoked first; whether or not it panics, the
-/// function `finally_fn` will be invoked next. The two parameters
-/// `mutate` and `drop` are used to thread state through the two
-/// closures. `mutate` is used for any shared, mutable state that both
-/// closures require access to; `drop` is used for any state that the
-/// `try_fn` requires ownership of.
-///
-/// **WARNING:** While shared, mutable state between the try and finally
-/// function is often necessary, one must be very careful; the `try`
-/// function could have panicked at any point, so the values of the shared
-/// state may be inconsistent.
-///
-/// # Examples
-///
-/// ```
-/// # #![feature(core)]
-/// use std::finally::try_finally;
-///
-/// struct State<'a> { buffer: &'a mut [u8], len: usize }
-/// # let mut buf = [];
-/// let mut state = State { buffer: &mut buf, len: 0 };
-/// try_finally(
-/// &mut state, (),
-/// |state, ()| {
-/// // use state.buffer, state.len
-/// },
-/// |state| {
-/// // use state.buffer, state.len to cleanup
-/// })
-/// ```
-pub fn try_finally<T, U, R, F, G>(mutate: &mut T, drop: U, try_fn: F, finally_fn: G) -> R where
- F: FnOnce(&mut T, U) -> R,
- G: FnMut(&mut T),
-{
- let f = Finallyalizer {
- mutate: mutate,
- dtor: finally_fn,
- };
- try_fn(&mut *f.mutate, drop)
-}
-
-struct Finallyalizer<'a, A:'a, F> where F: FnMut(&mut A) {
- mutate: &'a mut A,
- dtor: F,
-}
-
-#[unsafe_destructor]
-impl<'a, A, F> Drop for Finallyalizer<'a, A, F> where F: FnMut(&mut A) {
- #[inline]
- fn drop(&mut self) {
- (self.dtor)(self.mutate);
- }
-}
state
}
- /// Returns the computed hash.
- #[unstable(feature = "hash")]
- #[deprecated(since = "1.0.0", reason = "renamed to finish")]
- pub fn result(&self) -> u64 { self.finish() }
-
fn reset(&mut self) {
self.length = 0;
self.v0 = self.k0 ^ 0x736f6d6570736575;
/// Rust moves to non-zeroing dynamic drop (and thus removes the
/// embedded drop flags that are being established by this
/// intrinsic).
- #[cfg(not(stage0))]
pub fn init_dropped<T>() -> T;
/// Create a value initialized to zero.
//!
//! # The `Iterator` trait
//!
-//! This module defines Rust's core iteration trait. The `Iterator` trait has one
-//! unimplemented method, `next`. All other methods are derived through default
-//! methods to perform operations such as `zip`, `chain`, `enumerate`, and `fold`.
+//! This module defines Rust's core iteration trait. The `Iterator` trait has
+//! one unimplemented method, `next`. All other methods are derived through
+//! default methods to perform operations such as `zip`, `chain`, `enumerate`,
+//! and `fold`.
//!
//! The goal of this module is to unify iteration across all containers in Rust.
-//! An iterator can be considered as a state machine which is used to track which
-//! element will be yielded next.
+//! An iterator can be considered as a state machine which is used to track
+//! which element will be yielded next.
//!
-//! There are various extensions also defined in this module to assist with various
-//! types of iteration, such as the `DoubleEndedIterator` for iterating in reverse,
-//! the `FromIterator` trait for creating a container from an iterator, and much
-//! more.
+//! There are various extensions also defined in this module to assist with
+//! various types of iteration, such as the `DoubleEndedIterator` for iterating
+//! in reverse, the `FromIterator` trait for creating a container from an
+//! iterator, and much more.
//!
//! ## Rust's `for` loop
//!
//! The special syntax used by rust's `for` loop is based around the `Iterator`
-//! trait defined in this module. For loops can be viewed as a syntactical expansion
-//! into a `loop`, for example, the `for` loop in this example is essentially
-//! translated to the `loop` below.
+//! trait defined in this module. For loops can be viewed as a syntactical
+//! expansion into a `loop`, for example, the `for` loop in this example is
+//! essentially translated to the `loop` below.
//!
//! ```
//! let values = vec![1, 2, 3];
use default::Default;
use marker;
use mem;
-use num::{Int, Zero, One, ToPrimitive};
-use ops::{Add, Sub, FnMut, RangeFrom};
-use option::Option;
-use option::Option::{Some, None};
+use num::{Int, Zero, One};
+use ops::{self, Add, Sub, FnMut, RangeFrom};
+use option::Option::{self, Some, None};
use marker::Sized;
use usize;
/// else.
#[lang="iterator"]
#[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_on_unimplemented = "`{Self}` is not an iterator; maybe try calling `.iter()` or a similar \
- method"]
+#[rustc_on_unimplemented = "`{Self}` is not an iterator; maybe try calling \
+ `.iter()` or a similar method"]
pub trait Iterator {
/// The type of the elements being iterated
#[stable(feature = "rust1", since = "1.0.0")]
type Item;
- /// Advance the iterator and return the next value. Return `None` when the end is reached.
+ /// Advance the iterator and return the next value. Return `None` when the
+ /// end is reached.
#[stable(feature = "rust1", since = "1.0.0")]
fn next(&mut self) -> Option<Self::Item>;
/// Returns a lower and upper bound on the remaining length of the iterator.
///
- /// An upper bound of `None` means either there is no known upper bound, or the upper bound
- /// does not fit within a `usize`.
+ /// An upper bound of `None` means either there is no known upper bound, or
+ /// the upper bound does not fit within a `usize`.
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
fn size_hint(&self) -> (usize, Option<usize>) { (0, None) }
/// iterator plus the current index of iteration.
///
/// `enumerate` keeps its count as a `usize`. If you want to count by a
- /// different sized integer, the `zip` function provides similar functionality.
+ /// different sized integer, the `zip` function provides similar
+ /// functionality.
///
/// # Examples
///
/// # #![feature(core)]
/// let xs = [2, 3];
/// let ys = [0, 1, 0, 1, 2];
- /// let it = xs.iter().flat_map(|&x| std::iter::count(0, 1).take(x));
+ /// let it = xs.iter().flat_map(|&x| (0..).take(x));
/// // Check that `it` has the same elements as `ys`
/// for (i, x) in it.enumerate() {
/// assert_eq!(x, ys[i]);
/// # Examples
///
/// ```
- /// # #![feature(core)]
- /// let a = [1, 2, 3, 4, 5];
- /// let b: Vec<_> = a.iter().cloned().collect();
- /// assert_eq!(a, b);
+ /// let expected = [1, 2, 3, 4, 5];
+ /// let actual: Vec<_> = expected.iter().cloned().collect();
+ /// assert_eq!(actual, expected);
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
/// assert_eq!(even, [2, 4]);
/// assert_eq!(odd, [1, 3]);
/// ```
- #[unstable(feature = "core",
- reason = "recently added as part of collections reform")]
+ #[stable(feature = "rust1", since = "1.0.0")]
fn partition<B, F>(self, mut f: F) -> (B, B) where
Self: Sized,
B: Default + Extend<Self::Item>,
true
}
- /// Tests whether any element of an iterator satisfies the specified predicate.
+ /// Tests whether any element of an iterator satisfies the specified
+ /// predicate.
///
/// Does not consume the iterator past the first found element.
///
/// let a = [1, 2, 3, 4, 5];
/// let mut it = a.iter();
/// assert!(it.any(|x| *x == 3));
- /// assert_eq!(it.as_slice(), [4, 5]);
+ /// assert_eq!(&it[..], [4, 5]);
///
/// ```
#[inline]
/// let a = [1, 2, 3, 4, 5];
/// let mut it = a.iter();
/// assert_eq!(it.find(|&x| *x == 3).unwrap(), &3);
- /// assert_eq!(it.as_slice(), [4, 5]);
+ /// assert_eq!(&it[..], [4, 5]);
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
fn find<P>(&mut self, mut predicate: P) -> Option<Self::Item> where
/// let a = [1, 2, 3, 4, 5];
/// let mut it = a.iter();
/// assert_eq!(it.position(|x| *x == 3).unwrap(), 2);
- /// assert_eq!(it.as_slice(), [4, 5]);
+ /// assert_eq!(&it[..], [4, 5]);
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
fn position<P>(&mut self, mut predicate: P) -> Option<usize> where
/// let a = [1, 2, 2, 4, 5];
/// let mut it = a.iter();
/// assert_eq!(it.rposition(|x| *x == 2).unwrap(), 2);
- /// assert_eq!(it.as_slice(), [1, 2]);
+ /// assert_eq!(&it[..], [1, 2]);
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
fn rposition<P>(&mut self, mut predicate: P) -> Option<usize> where
/// Consumes the entire iterator to return the maximum element.
///
+ /// Returns the rightmost element if the comparison determines two elements
+ /// to be equally maximum.
+ ///
/// # Examples
///
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
fn max(self) -> Option<Self::Item> where Self: Sized, Self::Item: Ord
{
- self.fold(None, |max, x| {
+ self.fold(None, |max, y| {
match max {
- None => Some(x),
- Some(y) => Some(cmp::max(x, y))
+ None => Some(y),
+ Some(x) => Some(cmp::max(x, y))
}
})
}
/// Consumes the entire iterator to return the minimum element.
///
+ /// Returns the leftmost element if the comparison determines two elements
+ /// to be equally minimum.
+ ///
/// # Examples
///
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
fn min(self) -> Option<Self::Item> where Self: Sized, Self::Item: Ord
{
- self.fold(None, |min, x| {
+ self.fold(None, |min, y| {
match min {
- None => Some(x),
- Some(y) => Some(cmp::min(x, y))
+ None => Some(y),
+ Some(x) => Some(cmp::min(x, y))
}
})
}
/// element in the iterator and all elements are equal.
///
/// On an iterator of length `n`, `min_max` does `1.5 * n` comparisons,
- /// and so is faster than calling `min` and `max` separately which does `2 * n` comparisons.
+ /// and so is faster than calling `min` and `max` separately which does `2 *
+ /// n` comparisons.
///
/// # Examples
///
Some(x) => {
match self.next() {
None => return OneElement(x),
- Some(y) => if x < y {(x, y)} else {(y,x)}
+ Some(y) => if x <= y {(x, y)} else {(y, x)}
}
}
};
loop {
- // `first` and `second` are the two next elements we want to look at.
- // We first compare `first` and `second` (#1). The smaller one is then compared to
- // current minimum (#2). The larger one is compared to current maximum (#3). This
- // way we do 3 comparisons for 2 elements.
+ // `first` and `second` are the two next elements we want to look
+ // at. We first compare `first` and `second` (#1). The smaller one
+ // is then compared to current minimum (#2). The larger one is
+ // compared to current maximum (#3). This way we do 3 comparisons
+ // for 2 elements.
let first = match self.next() {
None => break,
Some(x) => x
None => {
if first < min {
min = first;
- } else if first > max {
+ } else if first >= max {
max = first;
}
break;
}
Some(x) => x
};
- if first < second {
- if first < min {min = first;}
- if max < second {max = second;}
+ if first <= second {
+ if first < min { min = first }
+ if second >= max { max = second }
} else {
- if second < min {min = second;}
- if max < first {max = first;}
+ if second < min { min = second }
+ if first >= max { max = first }
}
}
/// Return the element that gives the maximum value from the
/// specified function.
///
+ /// Returns the rightmost element if the comparison determines two elements
+ /// to be equally maximum.
+ ///
/// # Examples
///
/// ```
Self: Sized,
F: FnMut(&Self::Item) -> B,
{
- self.fold(None, |max: Option<(Self::Item, B)>, x| {
- let x_val = f(&x);
+ self.fold(None, |max: Option<(Self::Item, B)>, y| {
+ let y_val = f(&y);
match max {
- None => Some((x, x_val)),
- Some((y, y_val)) => if x_val > y_val {
- Some((x, x_val))
- } else {
+ None => Some((y, y_val)),
+ Some((x, x_val)) => if y_val >= x_val {
Some((y, y_val))
+ } else {
+ Some((x, x_val))
}
}
}).map(|(x, _)| x)
/// Return the element that gives the minimum value from the
/// specified function.
///
+ /// Returns the leftmost element if the comparison determines two elements
+ /// to be equally minimum.
+ ///
/// # Examples
///
/// ```
Self: Sized,
F: FnMut(&Self::Item) -> B,
{
- self.fold(None, |min: Option<(Self::Item, B)>, x| {
- let x_val = f(&x);
+ self.fold(None, |min: Option<(Self::Item, B)>, y| {
+ let y_val = f(&y);
match min {
- None => Some((x, x_val)),
- Some((y, y_val)) => if x_val < y_val {
+ None => Some((y, y_val)),
+ Some((x, x_val)) => if x_val <= y_val {
Some((x, x_val))
} else {
Some((y, y_val))
/// # #![feature(core)]
/// let a = [(1, 2), (3, 4)];
/// let (left, right): (Vec<_>, Vec<_>) = a.iter().cloned().unzip();
- /// assert_eq!([1, 3], left);
- /// assert_eq!([2, 4], right);
+ /// assert_eq!(left, [1, 3]);
+ /// assert_eq!(right, [2, 4]);
/// ```
- #[unstable(feature = "core", reason = "recent addition")]
+ #[stable(feature = "rust1", since = "1.0.0")]
fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB) where
FromA: Default + Extend<A>,
FromB: Default + Extend<B>,
/// assert_eq!(colors_set.len(), 3);
/// ```
///
- /// `FromIterator` is more commonly used implicitly via the `Iterator::collect` method:
+ /// `FromIterator` is more commonly used implicitly via the
+ /// `Iterator::collect` method:
///
/// ```
/// use std::collections::HashSet;
/// An object implementing random access indexing by `usize`
///
-/// A `RandomAccessIterator` should be either infinite or a `DoubleEndedIterator`.
-/// Calling `next()` or `next_back()` on a `RandomAccessIterator`
-/// reduces the indexable range accordingly. That is, `it.idx(1)` will become `it.idx(0)`
-/// after `it.next()` is called.
+/// A `RandomAccessIterator` should be either infinite or a
+/// `DoubleEndedIterator`. Calling `next()` or `next_back()` on a
+/// `RandomAccessIterator` reduces the indexable range accordingly. That is,
+/// `it.idx(1)` will become `it.idx(0)` after `it.next()` is called.
#[unstable(feature = "core",
- reason = "not widely used, may be better decomposed into Index and ExactSizeIterator")]
+ reason = "not widely used, may be better decomposed into Index \
+ and ExactSizeIterator")]
pub trait RandomAccessIterator: Iterator {
/// Return the number of indexable elements. At most `std::usize::MAX`
/// elements are indexable, even if the iterator represents a longer range.
F: FnMut(&I::Item),
{}
#[stable(feature = "rust1", since = "1.0.0")]
-impl<I> ExactSizeIterator for Rev<I> where I: ExactSizeIterator + DoubleEndedIterator {}
+impl<I> ExactSizeIterator for Rev<I>
+ where I: ExactSizeIterator + DoubleEndedIterator {}
#[stable(feature = "rust1", since = "1.0.0")]
impl<B, I: ExactSizeIterator, F> ExactSizeIterator for Map<I, F> where
F: FnMut(I::Item) -> B,
{}
#[stable(feature = "rust1", since = "1.0.0")]
-impl<A, B> ExactSizeIterator for Zip<A, B> where A: ExactSizeIterator, B: ExactSizeIterator {}
+impl<A, B> ExactSizeIterator for Zip<A, B>
+ where A: ExactSizeIterator, B: ExactSizeIterator {}
/// An double-ended iterator with the direction inverted
#[derive(Clone)]
}
#[unstable(feature = "core", reason = "trait is experimental")]
-impl<I> RandomAccessIterator for Rev<I> where I: DoubleEndedIterator + RandomAccessIterator {
+impl<I> RandomAccessIterator for Rev<I>
+ where I: DoubleEndedIterator + RandomAccessIterator
+{
#[inline]
fn indexable(&self) -> usize { self.iter.indexable() }
#[inline]
///
/// ```
/// # #![feature(core)]
- /// use std::iter::{count, MultiplicativeIterator};
+ /// use std::iter::MultiplicativeIterator;
///
/// fn factorial(n: usize) -> usize {
- /// count(1, 1).take_while(|&i| i <= n).product()
+ /// (1..).take_while(|&i| i <= n).product()
/// }
/// assert!(factorial(0) == 1);
/// assert!(factorial(1) == 1);
impl_multiplicative! { f32, 1.0 }
impl_multiplicative! { f64, 1.0 }
-/// `MinMaxResult` is an enum returned by `min_max`. See `Iterator::min_max` for more detail.
+/// `MinMaxResult` is an enum returned by `min_max`. See `Iterator::min_max` for
+/// more detail.
#[derive(Clone, PartialEq, Debug)]
#[unstable(feature = "core",
reason = "unclear whether such a fine-grained result is widely useful")]
/// Iterator with one element, so the minimum and maximum are the same
OneElement(T),
- /// More than one element in the iterator, the first element is not larger than the second
+ /// More than one element in the iterator, the first element is not larger
+ /// than the second
MinMax(T, T)
}
impl<T: Clone> MinMaxResult<T> {
- /// `into_option` creates an `Option` of type `(T,T)`. The returned `Option` has variant
- /// `None` if and only if the `MinMaxResult` has variant `NoElements`. Otherwise variant
- /// `Some(x,y)` is returned where `x <= y`. If `MinMaxResult` has variant `OneElement(x)`,
- /// performing this operation will make one clone of `x`.
+ /// `into_option` creates an `Option` of type `(T,T)`. The returned `Option`
+ /// has variant `None` if and only if the `MinMaxResult` has variant
+ /// `NoElements`. Otherwise variant `Some(x,y)` is returned where `x <= y`.
+ /// If `MinMaxResult` has variant `OneElement(x)`, performing this operation
+ /// will make one clone of `x`.
///
/// # Examples
///
}
#[allow(deprecated)]
-impl<A: Step> ::ops::Range<A> {
+impl<A: Step> ops::Range<A> {
/// Creates an iterator with the same range, but stepping by the
/// given amount at each iteration.
///
}
}
-/// An infinite iterator starting at `start` and advancing by `step` with each
-/// iteration
-#[unstable(feature = "core",
- reason = "may be renamed or replaced by range notation adapters")]
-#[deprecated(since = "1.0.0-beta", reason = "use range notation and step_by")]
-pub type Counter<A> = StepBy<A, RangeFrom<A>>;
-
-/// Deprecated: use `(start..).step_by(step)` instead.
-#[inline]
-#[unstable(feature = "core",
- reason = "may be renamed or replaced by range notation adapters")]
-#[deprecated(since = "1.0.0-beta", reason = "use (start..).step_by(step) instead")]
-#[allow(deprecated)]
-pub fn count<A>(start: A, step: A) -> Counter<A> {
- StepBy {
- range: RangeFrom { start: start },
- step_by: step,
- }
-}
-
#[stable(feature = "rust1", since = "1.0.0")]
impl<A> Iterator for StepBy<A, RangeFrom<A>> where
A: Clone,
}
}
-/// An iterator over the range [start, stop)
-#[allow(deprecated)]
-#[derive(Clone)]
-#[unstable(feature = "core",
- reason = "will be replaced by range notation")]
-#[deprecated(since = "1.0.0-beta", reason = "use range notation")]
-pub struct Range<A> {
- state: A,
- stop: A,
- one: A,
-}
-
-/// Deprecated: use `(start..stop)` instead.
-#[inline]
-#[unstable(feature = "core", reason = "will be replaced by range notation")]
-#[deprecated(since = "1.0.0-beta", reason = "use (start..stop) instead")]
-#[allow(deprecated)]
-pub fn range<A: Int>(start: A, stop: A) -> Range<A> {
- Range {
- state: start,
- stop: stop,
- one: Int::one(),
- }
-}
-
-// FIXME: #10414: Unfortunate type bound
-#[unstable(feature = "core",
- reason = "will be replaced by range notation")]
-#[deprecated(since = "1.0.0-beta", reason = "use range notation")]
-#[allow(deprecated)]
-impl<A: Int + ToPrimitive> Iterator for Range<A> {
- type Item = A;
-
- #[inline]
- fn next(&mut self) -> Option<A> {
- if self.state < self.stop {
- let result = self.state.clone();
- self.state = self.state + self.one;
- Some(result)
- } else {
- None
- }
- }
-
- #[inline]
- fn size_hint(&self) -> (usize, Option<usize>) {
- // This first checks if the elements are representable as i64. If they aren't, try u64 (to
- // handle cases like range(huge, huger)). We don't use usize/isize because the difference of
- // the i64/u64 might lie within their range.
- let bound = match self.state.to_i64() {
- Some(a) => {
- let sz = self.stop.to_i64().map(|b| b.checked_sub(a));
- match sz {
- Some(Some(bound)) => bound.to_usize(),
- _ => None,
- }
- },
- None => match self.state.to_u64() {
- Some(a) => {
- let sz = self.stop.to_u64().map(|b| b.checked_sub(a));
- match sz {
- Some(Some(bound)) => bound.to_usize(),
- _ => None
- }
- },
- None => None
- }
- };
-
- match bound {
- Some(b) => (b, Some(b)),
- // Standard fallback for unbounded/unrepresentable bounds
- None => (0, None)
- }
- }
-}
-
-/// `Int` is required to ensure the range will be the same regardless of
-/// the direction it is consumed.
-#[unstable(feature = "core",
- reason = "will be replaced by range notation")]
-#[deprecated(since = "1.0.0-beta", reason = "use range notation")]
-#[allow(deprecated)]
-impl<A: Int + ToPrimitive> DoubleEndedIterator for Range<A> {
- #[inline]
- fn next_back(&mut self) -> Option<A> {
- if self.stop > self.state {
- self.stop = self.stop - self.one;
- Some(self.stop.clone())
- } else {
- None
- }
- }
-}
-
/// An iterator over the range [start, stop]
#[derive(Clone)]
#[unstable(feature = "core",
reason = "likely to be replaced by range notation and adapters")]
-#[allow(deprecated)]
pub struct RangeInclusive<A> {
- range: Range<A>,
+ range: ops::Range<A>,
done: bool,
}
#[inline]
#[unstable(feature = "core",
reason = "likely to be replaced by range notation and adapters")]
-#[allow(deprecated)]
-pub fn range_inclusive<A: Int>(start: A, stop: A) -> RangeInclusive<A> {
+pub fn range_inclusive<A>(start: A, stop: A) -> RangeInclusive<A>
+ where A: Step + One + Clone
+{
RangeInclusive {
- range: range(start, stop),
+ range: start..stop,
done: false,
}
}
#[unstable(feature = "core",
reason = "likely to be replaced by range notation and adapters")]
-#[allow(deprecated)]
-impl<A: Int + ToPrimitive> Iterator for RangeInclusive<A> {
+impl<A: Step + One + Clone> Iterator for RangeInclusive<A> {
type Item = A;
#[inline]
match self.range.next() {
Some(x) => Some(x),
None => {
- if !self.done && self.range.state == self.range.stop {
+ if !self.done && self.range.start == self.range.end {
self.done = true;
- Some(self.range.stop.clone())
+ Some(self.range.end.clone())
} else {
None
}
#[unstable(feature = "core",
reason = "likely to be replaced by range notation and adapters")]
-#[allow(deprecated)]
-impl<A: Int + ToPrimitive> DoubleEndedIterator for RangeInclusive<A> {
+impl<A> DoubleEndedIterator for RangeInclusive<A>
+ where A: Step + One + Clone,
+ for<'a> &'a A: Sub<Output=A>
+{
#[inline]
fn next_back(&mut self) -> Option<A> {
- if self.range.stop > self.range.state {
- let result = self.range.stop.clone();
- self.range.stop = self.range.stop - self.range.one;
+ if self.range.end > self.range.start {
+ let result = self.range.end.clone();
+ self.range.end = &self.range.end - &A::one();
Some(result)
- } else if !self.done && self.range.state == self.range.stop {
+ } else if !self.done && self.range.start == self.range.end {
self.done = true;
- Some(self.range.stop.clone())
+ Some(self.range.end.clone())
} else {
None
}
}
}
-/// An iterator over the range [start, stop) by `step`. It handles overflow by stopping.
-#[unstable(feature = "core",
- reason = "likely to be replaced by range notation and adapters")]
-#[deprecated(since = "1.0.0-beta", reason = "use range notation and step_by")]
-pub type RangeStep<A> = StepBy<A, ::ops::Range<A>>;
-
-/// Deprecated: use `(start..stop).step_by(step)` instead.
-#[inline]
-#[unstable(feature = "core",
- reason = "likely to be replaced by range notation and adapters")]
-#[deprecated(since = "1.0.0-beta",
- reason = "use `(start..stop).step_by(step)` instead")]
-#[allow(deprecated)]
-pub fn range_step<A: Int>(start: A, stop: A, step: A) -> RangeStep<A> {
- StepBy {
- step_by: step,
- range: ::ops::Range { start: start, end: stop },
- }
-}
-
#[stable(feature = "rust1", since = "1.0.0")]
#[allow(deprecated)]
-impl<A: Step + Zero + Clone> Iterator for StepBy<A, ::ops::Range<A>> {
+impl<A: Step + Zero + Clone> Iterator for StepBy<A, ops::Range<A>> {
type Item = A;
#[inline]
macro_rules! range_exact_iter_impl {
($($t:ty)*) => ($(
#[stable(feature = "rust1", since = "1.0.0")]
- impl ExactSizeIterator for ::ops::Range<$t> { }
+ impl ExactSizeIterator for ops::Range<$t> { }
)*)
}
#[stable(feature = "rust1", since = "1.0.0")]
#[allow(deprecated)]
-impl<A: Step + One + Clone> Iterator for ::ops::Range<A> {
+impl<A: Step + One + Clone> Iterator for ops::Range<A> {
type Item = A;
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
#[allow(deprecated)]
-impl<A: Step + One + Clone> DoubleEndedIterator for ::ops::Range<A> where
+impl<A: Step + One + Clone> DoubleEndedIterator for ops::Range<A> where
for<'a> &'a A: Sub<&'a A, Output = A>
{
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
#[allow(deprecated)]
-impl<A: Step + One> Iterator for ::ops::RangeFrom<A> {
+impl<A: Step + One> Iterator for ops::RangeFrom<A> {
type Item = A;
#[inline]
pub mod cell;
pub mod char;
pub mod panicking;
-pub mod finally;
pub mod iter;
pub mod option;
pub mod raw;
);
}
-/// Asserts that two expressions are equal to each other, testing equality in
-/// both directions.
+/// Asserts that two expressions are equal to each other.
///
-/// On panic, this macro will print the values of the expressions.
+/// On panic, this macro will print the values of the expressions with their
+/// debug representations.
///
/// # Examples
///
($left:expr , $right:expr) => ({
match (&($left), &($right)) {
(left_val, right_val) => {
- // check both directions of equality....
- if !((*left_val == *right_val) &&
- (*right_val == *left_val)) {
- panic!("assertion failed: `(left == right) && (right == left)` \
+ if !(*left_val == *right_val) {
+ panic!("assertion failed: `(left == right)` \
(left: `{:?}`, right: `{:?}`)", *left_val, *right_val)
}
}
/// Short circuiting evaluation on Err
///
-/// `libstd` contains a more general `try!` macro that uses `FromError`.
+/// `libstd` contains a more general `try!` macro that uses `From<E>`.
#[macro_export]
macro_rules! try {
($e:expr) => ({
/// ```
/// # #![feature(core)]
/// fn divide_by_three(x: u32) -> u32 { // one of the poorest implementations of x/3
-/// for i in std::iter::count(0, 1) {
+/// for i in 0.. {
/// if 3*i < i { panic!("u32 overflow"); }
/// if x < 3*i { return i-1; }
/// }
unsafe impl<'a, T: Send + ?Sized> Send for &'a mut T {}
}
-/// Old-style marker trait. Deprecated.
-#[unstable(feature = "core", reason = "deprecated")]
-#[deprecated(since = "1.0.0", reason = "Replace with `PhantomData<&'a ()>`")]
-#[lang="contravariant_lifetime"]
-pub struct ContravariantLifetime<'a>;
-
-/// Old-style marker trait. Deprecated.
-#[unstable(feature = "core", reason = "deprecated")]
-#[deprecated(since = "1.0.0", reason = "Replace with `PhantomData<fn(&'a ())>`")]
-#[lang="covariant_lifetime"]
-pub struct CovariantLifetime<'a>;
-
-/// Old-style marker trait. Deprecated.
-#[unstable(feature = "core", reason = "deprecated")]
-#[deprecated(since = "1.0.0", reason = "Replace with `PhantomData<Cell<&'a ()>>`")]
-#[lang="invariant_lifetime"]
-pub struct InvariantLifetime<'a>;
-
-/// Old-style marker trait. Deprecated.
-#[unstable(feature = "core", reason = "deprecated")]
-#[deprecated(since = "1.0.0", reason = "Replace with `PhantomData<fn(T)>`")]
-#[lang="contravariant_type"]
-pub struct ContravariantType<T>;
-
-/// Old-style marker trait. Deprecated.
-#[unstable(feature = "core", reason = "deprecated")]
-#[deprecated(since = "1.0.0", reason = "Replace with `PhantomData<T>`")]
-#[lang="covariant_type"]
-pub struct CovariantType<T>;
-
-/// Old-style marker trait. Deprecated.
-#[unstable(feature = "core", reason = "deprecated")]
-#[deprecated(since = "1.0.0", reason = "Replace with `PhantomData<Cell<T>>`")]
-#[lang="invariant_type"]
-pub struct InvariantType<T>;
-
/// A marker trait indicates a type that can be reflected over. This
/// trait is implemented for all types. Its purpose is to ensure that
/// when you write a generic function that will employ reflection,
pub trait Reflect : MarkerTrait {
}
-#[cfg(stage0)]
-impl<T> Reflect for T { }
-
-#[cfg(not(stage0))]
impl Reflect for .. { }
#[inline]
#[unstable(feature = "filling_drop")]
pub unsafe fn dropped<T>() -> T {
- #[cfg(stage0)]
- #[inline(always)]
- unsafe fn dropped_impl<T>() -> T { zeroed() }
-
- #[cfg(not(stage0))]
#[inline(always)]
unsafe fn dropped_impl<T>() -> T { intrinsics::init_dropped() }
// But having the sign bit set is a pain, so 0x1d is probably better.
//
// And of course, 0x00 brings back the old world of zero'ing on drop.
-#[cfg(not(stage0))] #[unstable(feature = "filling_drop")]
+#[unstable(feature = "filling_drop")]
pub const POST_DROP_U8: u8 = 0x1d;
-#[cfg(not(stage0))] #[unstable(feature = "filling_drop")]
+#[unstable(feature = "filling_drop")]
pub const POST_DROP_U32: u32 = repeat_u8_as_u32!(POST_DROP_U8);
-#[cfg(not(stage0))] #[unstable(feature = "filling_drop")]
+#[unstable(feature = "filling_drop")]
pub const POST_DROP_U64: u64 = repeat_u8_as_u64!(POST_DROP_U8);
#[cfg(target_pointer_width = "32")]
-#[cfg(not(stage0))] #[unstable(feature = "filling_drop")]
+#[unstable(feature = "filling_drop")]
pub const POST_DROP_USIZE: usize = POST_DROP_U32 as usize;
#[cfg(target_pointer_width = "64")]
-#[cfg(not(stage0))] #[unstable(feature = "filling_drop")]
+#[unstable(feature = "filling_drop")]
pub const POST_DROP_USIZE: usize = POST_DROP_U64 as usize;
-#[cfg(stage0)] #[unstable(feature = "filling_drop")]
-pub const POST_DROP_U8: u8 = 0;
-#[cfg(stage0)] #[unstable(feature = "filling_drop")]
-pub const POST_DROP_U32: u32 = 0;
-#[cfg(stage0)] #[unstable(feature = "filling_drop")]
-pub const POST_DROP_U64: u64 = 0;
-#[cfg(stage0)] #[unstable(feature = "filling_drop")]
-pub const POST_DROP_USIZE: usize = 0;
-
-/// Interprets `src` as `&U`, and then reads `src` without moving the contained value.
-///
-/// This function will unsafely assume the pointer `src` is valid for `sizeof(U)` bytes by
-/// transmuting `&T` to `&U` and then reading the `&U`. It will also unsafely create a copy of the
-/// contained value instead of moving out of `src`.
-///
-/// It is not a compile-time error if `T` and `U` have different sizes, but it is highly encouraged
-/// to only invoke this function where `T` and `U` have the same size. This function triggers
-/// undefined behavior if `U` is larger than `T`.
+/// Interprets `src` as `&U`, and then reads `src` without moving the contained
+/// value.
+///
+/// This function will unsafely assume the pointer `src` is valid for
+/// `sizeof(U)` bytes by transmuting `&T` to `&U` and then reading the `&U`. It
+/// will also unsafely create a copy of the contained value instead of moving
+/// out of `src`.
+///
+/// It is not a compile-time error if `T` and `U` have different sizes, but it
+/// is highly encouraged to only invoke this function where `T` and `U` have the
+/// same size. This function triggers undefined behavior if `U` is larger than
+/// `T`.
///
/// # Examples
///
/// intended to have wrapping semantics.
#[stable(feature = "rust1", since = "1.0.0")]
#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Debug)]
-pub struct Wrapping<T>(pub T);
+pub struct Wrapping<T>(#[stable(feature = "rust1", since = "1.0.0")] pub T);
#[unstable(feature = "core", reason = "may be removed or relocated")]
pub mod wrapping;
use ops::FnOnce;
use result::Result::{Ok, Err};
use result::Result;
-#[allow(deprecated)]
-use slice::AsSlice;
use slice;
// Note that this is not a lang item per se, but it has a hidden dependency on
// Trait implementations
/////////////////////////////////////////////////////////////////////////////
-#[unstable(feature = "core",
- reason = "waiting on the stability of the trait itself")]
-#[deprecated(since = "1.0.0",
- reason = "use the inherent method instead")]
-#[allow(deprecated)]
-impl<T> AsSlice<T> for Option<T> {
- /// Convert from `Option<T>` to `&[T]` (without copying)
- #[inline]
- fn as_slice<'a>(&'a self) -> &'a [T] {
- match *self {
- Some(ref x) => slice::ref_slice(x),
- None => {
- let result: &[_] = &[];
- result
- }
- }
- }
-}
-
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> Default for Option<T> {
#[inline]
pub use clone::Clone;
pub use cmp::{PartialEq, PartialOrd, Eq, Ord};
pub use convert::{AsRef, AsMut, Into, From};
-pub use iter::Extend;
-pub use iter::{Iterator, DoubleEndedIterator};
-pub use iter::{ExactSizeIterator};
+pub use iter::{Iterator, DoubleEndedIterator, Extend, ExactSizeIterator};
pub use option::Option::{self, Some, None};
pub use result::Result::{self, Ok, Err};
-pub use slice::{AsSlice, SliceExt};
-pub use str::{Str, StrExt};
+pub use slice::SliceExt;
+pub use str::StrExt;
+
+#[allow(deprecated)] pub use slice::AsSlice;
+#[allow(deprecated)] pub use str::Str;
#[stable(feature = "rust1", since = "1.0.0")]
pub fn null_mut<T>() -> *mut T { 0 as *mut T }
-/// Zeroes out `count * size_of::<T>` bytes of memory at `dst`. `count` may be
-/// `0`.
-///
-/// # Safety
-///
-/// Beyond accepting a raw pointer, this is unsafe because it will not drop the
-/// contents of `dst`, and may be used to create invalid instances of `T`.
-#[inline]
-#[unstable(feature = "core",
- reason = "may play a larger role in std::ptr future extensions")]
-#[deprecated(since = "1.0.0", reason = "use `write_bytes` instead")]
-pub unsafe fn zero_memory<T>(dst: *mut T, count: usize) {
- write_bytes(dst, 0, count);
-}
-
/// Swaps the values at two mutable locations of the same type, without
/// deinitialising either. They may overlap, unlike `mem::swap` which is
/// otherwise equivalent.
impl<T> Copy for Slice<T> {}
-/// The representation of an old closure.
-#[repr(C)]
-#[derive(Copy)]
-#[unstable(feature = "core")]
-#[deprecated(reason = "unboxed new closures do not have a universal representation; \
- `&Fn` (etc) trait objects should use `TraitObject` instead",
- since= "1.0.0")]
-#[allow(deprecated) /* for deriving Copy impl */]
-pub struct Closure {
- pub code: *mut (),
- pub env: *mut (),
-}
-
/// The representation of a trait object like `&SomeTrait`.
///
/// This struct has the same layout as types like `&SomeTrait` and
fn len(&self) -> usize;
fn is_empty(&self) -> bool { self.len() == 0 }
fn get_mut<'a>(&'a mut self, index: usize) -> Option<&'a mut Self::Item>;
- #[unstable(feature = "core",
- reason = "will be replaced by slice syntax")]
- #[deprecated(since = "1.0.0", reason = "use &mut s[..] instead")]
- fn as_mut_slice<'a>(&'a mut self) -> &'a mut [Self::Item];
fn iter_mut<'a>(&'a mut self) -> IterMut<'a, Self::Item>;
fn first_mut<'a>(&'a mut self) -> Option<&'a mut Self::Item>;
fn tail_mut<'a>(&'a mut self) -> &'a mut [Self::Item];
if index < self.len() { Some(&mut self[index]) } else { None }
}
- #[inline]
- #[unstable(feature = "core",
- reason = "will be replaced by slice syntax")]
- #[deprecated(since = "1.0.0", reason = "use &mut s[..] instead")]
- fn as_mut_slice(&mut self) -> &mut [T] { self }
-
#[inline]
fn split_at_mut(&mut self, mid: usize) -> (&mut [T], &mut [T]) {
unsafe {
transmute(RawSlice { data: p, len: len })
}
-/// Forms a slice from a pointer and a length.
-///
-/// The pointer given is actually a reference to the base of the slice. This
-/// reference is used to give a concrete lifetime to tie the returned slice to.
-/// Typically this should indicate that the slice is valid for as long as the
-/// pointer itself is valid.
-///
-/// The `len` argument is the number of **elements**, not the number of bytes.
-///
-/// This function is unsafe as there is no guarantee that the given pointer is
-/// valid for `len` elements, nor whether the lifetime provided is a suitable
-/// lifetime for the returned slice.
-///
-/// # Examples
-///
-/// ```
-/// #![feature(core)]
-/// use std::slice;
-///
-/// // manifest a slice out of thin air!
-/// let ptr = 0x1234 as *const usize;
-/// let amt = 10;
-/// unsafe {
-/// let slice = slice::from_raw_buf(&ptr, amt);
-/// }
-/// ```
-#[inline]
-#[unstable(feature = "core")]
-#[deprecated(since = "1.0.0",
- reason = "use from_raw_parts")]
-pub unsafe fn from_raw_buf<'a, T>(p: &'a *const T, len: usize) -> &'a [T] {
- transmute(RawSlice { data: *p, len: len })
-}
-
-/// Performs the same functionality as `from_raw_buf`, except that a mutable
-/// slice is returned.
-///
-/// This function is unsafe for the same reasons as `from_raw_buf`, as well as
-/// not being able to provide a non-aliasing guarantee of the returned mutable
-/// slice.
-#[inline]
-#[unstable(feature = "core")]
-#[deprecated(since = "1.0.0",
- reason = "use from_raw_parts_mut")]
-pub unsafe fn from_raw_mut_buf<'a, T>(p: &'a *mut T, len: usize) -> &'a mut [T] {
- transmute(RawSlice { data: *p, len: len })
-}
-
//
// Submodules
//
use iter::{Map, Iterator, DoubleEndedIterator};
use marker::Sized;
use mem;
-#[allow(deprecated)]
-use num::Int;
use ops::{Fn, FnMut, FnOnce};
use option::Option::{self, None, Some};
use raw::{Repr, Slice};
mem::transmute(v)
}
-/// Constructs a static string slice from a given raw pointer.
-///
-/// This function will read memory starting at `s` until it finds a 0, and then
-/// transmute the memory up to that point as a string slice, returning the
-/// corresponding `&'static str` value.
-///
-/// This function is unsafe because the caller must ensure the C string itself
-/// has the static lifetime and that the memory `s` is valid up to and including
-/// the first null byte.
-///
-/// # Panics
-///
-/// This function will panic if the string pointed to by `s` is not valid UTF-8.
-#[unstable(feature = "core")]
-#[deprecated(since = "1.0.0",
- reason = "use std::ffi::c_str_to_bytes + str::from_utf8")]
-pub unsafe fn from_c_str(s: *const i8) -> &'static str {
- let s = s as *const u8;
- let mut len: usize = 0;
- while *s.offset(len as isize) != 0 {
- len += 1;
- }
- let v: &'static [u8] = ::mem::transmute(Slice { data: s, len: len });
- from_utf8(v).ok().expect("from_c_str passed invalid utf-8 data")
-}
-
-/// Something that can be used to compare against a character
-#[unstable(feature = "core")]
-#[deprecated(since = "1.0.0",
- reason = "use `Pattern` instead")]
-// NB: Rather than removing it, make it private and move it into self::pattern
-pub trait CharEq {
- /// Determine if the splitter should split at the given character
- fn matches(&mut self, char) -> bool;
- /// Indicate if this is only concerned about ASCII characters,
- /// which can allow for a faster implementation.
- fn only_ascii(&self) -> bool;
-}
-
-#[allow(deprecated) /* for CharEq */ ]
-impl CharEq for char {
- #[inline]
- fn matches(&mut self, c: char) -> bool { *self == c }
-
- #[inline]
- fn only_ascii(&self) -> bool { (*self as u32) < 128 }
-}
-
-#[allow(deprecated) /* for CharEq */ ]
-impl<F> CharEq for F where F: FnMut(char) -> bool {
- #[inline]
- fn matches(&mut self, c: char) -> bool { (*self)(c) }
-
- #[inline]
- fn only_ascii(&self) -> bool { false }
-}
-
-#[allow(deprecated) /* for CharEq */ ]
-impl<'a> CharEq for &'a [char] {
- #[inline]
- #[allow(deprecated) /* for CharEq */ ]
- fn matches(&mut self, c: char) -> bool {
- self.iter().any(|&m| { let mut m = m; m.matches(c) })
- }
-
- #[inline]
- #[allow(deprecated) /* for CharEq */ ]
- fn only_ascii(&self) -> bool {
- self.iter().all(|m| m.only_ascii())
- }
-}
-
#[stable(feature = "rust1", since = "1.0.0")]
impl Error for Utf8Error {
fn description(&self) -> &str {
}
}
-/// An iterator over the substrings of a string separated by a given
-/// search string
-#[unstable(feature = "core")]
-#[deprecated(since = "1.0.0", reason = "use `Split` with a `&str`")]
-pub struct SplitStr<'a, P: Pattern<'a>>(Split<'a, P>);
-#[allow(deprecated)]
-impl<'a, P: Pattern<'a>> Iterator for SplitStr<'a, P> {
- type Item = &'a str;
-
- #[inline]
- #[allow(deprecated)]
- fn next(&mut self) -> Option<&'a str> {
- Iterator::next(&mut self.0)
- }
-}
-
impl<'a, 'b> OldMatchIndices<'a, 'b> {
#[inline]
#[allow(dead_code)]
fn rsplitn<'a, P: Pattern<'a>>(&'a self, count: usize, pat: P) -> RSplitN<'a, P>
where P::Searcher: ReverseSearcher<'a>;
fn match_indices<'a, P: Pattern<'a>>(&'a self, pat: P) -> MatchIndices<'a, P>;
- #[allow(deprecated) /* for SplitStr */]
- fn split_str<'a, P: Pattern<'a>>(&'a self, pat: P) -> SplitStr<'a, P>;
fn lines<'a>(&'a self) -> Lines<'a>;
fn lines_any<'a>(&'a self) -> LinesAny<'a>;
fn char_len(&self) -> usize;
MatchIndices(pat.into_searcher(self))
}
- #[inline]
- #[allow(deprecated) /* for SplitStr */ ]
- fn split_str<'a, P: Pattern<'a>>(&'a self, pat: P) -> SplitStr<'a, P> {
- SplitStr(self.split(pat))
- }
-
#[inline]
fn lines(&self) -> Lines {
Lines { inner: self.split_terminator('\n').0 }
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![allow(deprecated) /* for CharEq */ ]
-
use prelude::*;
-use super::CharEq;
// Pattern
// Impl for a CharEq wrapper
+#[doc(hidden)]
+trait CharEq {
+ fn matches(&mut self, char) -> bool;
+ fn only_ascii(&self) -> bool;
+}
+
+impl CharEq for char {
+ #[inline]
+ fn matches(&mut self, c: char) -> bool { *self == c }
+
+ #[inline]
+ fn only_ascii(&self) -> bool { (*self as u32) < 128 }
+}
+
+impl<F> CharEq for F where F: FnMut(char) -> bool {
+ #[inline]
+ fn matches(&mut self, c: char) -> bool { (*self)(c) }
+
+ #[inline]
+ fn only_ascii(&self) -> bool { false }
+}
+
+impl<'a> CharEq for &'a [char] {
+ #[inline]
+ fn matches(&mut self, c: char) -> bool {
+ self.iter().any(|&m| { let mut m = m; m.matches(c) })
+ }
+
+ #[inline]
+ fn only_ascii(&self) -> bool {
+ self.iter().all(|m| m.only_ascii())
+ }
+}
+
struct CharEqPattern<C: CharEq>(C);
struct CharEqSearcher<'a, C: CharEq> {
}
}
-macro_rules! associated_items {
- ($t:ty, $s:ident, $e:expr) => {
- // FIXME: #22463
- //type Searcher = $t;
-
- fn into_searcher(self, haystack: &'a str) -> $t {
- let $s = self;
- $e.into_searcher(haystack)
+macro_rules! char_eq_pattern_impl {
+ ($wrapper:ty, $wrapper_ident:ident) => {
+ fn into_searcher(self, haystack: &'a str) -> $wrapper {
+ $wrapper_ident(CharEqPattern(self).into_searcher(haystack))
}
-
#[inline]
fn is_contained_in(self, haystack: &'a str) -> bool {
- let $s = self;
- $e.is_contained_in(haystack)
+ CharEqPattern(self).is_contained_in(haystack)
}
-
#[inline]
fn is_prefix_of(self, haystack: &'a str) -> bool {
- let $s = self;
- $e.is_prefix_of(haystack)
+ CharEqPattern(self).is_prefix_of(haystack)
}
-
- // FIXME: #21750
- /*#[inline]
+ #[inline]
fn is_suffix_of(self, haystack: &'a str) -> bool
- where $t: ReverseSearcher<'a>
+ where $wrapper: ReverseSearcher<'a>
{
- let $s = self;
- $e.is_suffix_of(haystack)
- }*/
+ CharEqPattern(self).is_suffix_of(haystack)
+ }
}
}
-// CharEq delegation impls
+// Pattern for char
-/// Searches for chars that are equal to a given char
impl<'a> Pattern<'a> for char {
- type Searcher = <CharEqPattern<Self> as Pattern<'a>>::Searcher;
- associated_items!(<CharEqPattern<Self> as Pattern<'a>>::Searcher,
- s, CharEqPattern(s));
+ type Searcher = CharSearcher<'a>;
+ char_eq_pattern_impl!(CharSearcher<'a>, CharSearcher);
+}
+
+pub struct CharSearcher<'a>(CharEqSearcher<'a, char>);
+
+unsafe impl<'a> Searcher<'a> for CharSearcher<'a> {
+ #[inline]
+ fn haystack(&self) -> &'a str { self.0.haystack() }
+ #[inline]
+ fn next(&mut self) -> SearchStep { self.0.next() }
+}
+unsafe impl<'a> ReverseSearcher<'a> for CharSearcher<'a> {
+ #[inline]
+ fn next_back(&mut self) -> SearchStep { self.0.next_back() }
}
+impl<'a> DoubleEndedSearcher<'a> for CharSearcher<'a> {}
+
+// Pattern for &[char]
-/// Searches for chars that are equal to any of the chars in the array
impl<'a, 'b> Pattern<'a> for &'b [char] {
- type Searcher = <CharEqPattern<Self> as Pattern<'a>>::Searcher;
- associated_items!(<CharEqPattern<Self> as Pattern<'a>>::Searcher,
- s, CharEqPattern(s));
+ type Searcher = CharSliceSearcher<'a, 'b>;
+ char_eq_pattern_impl!(CharSliceSearcher<'a, 'b>, CharSliceSearcher);
}
-/// A convenience impl that delegates to the impl for `&str`
-impl<'a, 'b> Pattern<'a> for &'b &'b str {
- type Searcher = <&'b str as Pattern<'a>>::Searcher;
- associated_items!(<&'b str as Pattern<'a>>::Searcher,
- s, (*s));
+pub struct CharSliceSearcher<'a, 'b>(CharEqSearcher<'a, &'b [char]>);
+
+unsafe impl<'a, 'b> Searcher<'a> for CharSliceSearcher<'a, 'b> {
+ #[inline]
+ fn haystack(&self) -> &'a str { self.0.haystack() }
+ #[inline]
+ fn next(&mut self) -> SearchStep { self.0.next() }
+}
+unsafe impl<'a, 'b> ReverseSearcher<'a> for CharSliceSearcher<'a, 'b> {
+ #[inline]
+ fn next_back(&mut self) -> SearchStep { self.0.next_back() }
+}
+impl<'a, 'b> DoubleEndedSearcher<'a> for CharSliceSearcher<'a, 'b> {}
+
+// Pattern for predicates
+
+impl<'a, F: FnMut(char) -> bool> Pattern<'a> for F {
+ type Searcher = CharPredSearcher<'a, F>;
+ char_eq_pattern_impl!(CharPredSearcher<'a, F>, CharPredSearcher);
+}
+
+pub struct CharPredSearcher<'a, F: FnMut(char) -> bool>(CharEqSearcher<'a, F>);
+
+unsafe impl<'a, F> Searcher<'a> for CharPredSearcher<'a, F>
+ where F: FnMut(char) -> bool
+{
+ #[inline]
+ fn haystack(&self) -> &'a str { self.0.haystack() }
+ #[inline]
+ fn next(&mut self) -> SearchStep { self.0.next() }
+}
+unsafe impl<'a, F> ReverseSearcher<'a> for CharPredSearcher<'a, F>
+ where F: FnMut(char) -> bool
+{
+ #[inline]
+ fn next_back(&mut self) -> SearchStep { self.0.next_back() }
}
+impl<'a, F> DoubleEndedSearcher<'a> for CharPredSearcher<'a, F>
+ where F: FnMut(char) -> bool
+{}
-/// Searches for chars that match the given predicate
-impl<'a, F> Pattern<'a> for F where F: FnMut(char) -> bool {
- type Searcher = <CharEqPattern<Self> as Pattern<'a>>::Searcher;
- associated_items!(<CharEqPattern<Self> as Pattern<'a>>::Searcher,
- s, CharEqPattern(s));
+// Pattern for &&str
+
+impl<'a, 'b> Pattern<'a> for &'b &'b str {
+ type Searcher = <&'b str as Pattern<'a>>::Searcher;
+ #[inline]
+ fn into_searcher(self, haystack: &'a str)
+ -> <&'b str as Pattern<'a>>::Searcher {
+ (*self).into_searcher(haystack)
+ }
+ #[inline]
+ fn is_contained_in(self, haystack: &'a str) -> bool {
+ (*self).is_contained_in(haystack)
+ }
+ #[inline]
+ fn is_prefix_of(self, haystack: &'a str) -> bool {
+ (*self).is_prefix_of(haystack)
+ }
+ #[inline]
+ fn is_suffix_of(self, haystack: &'a str) -> bool {
+ (*self).is_suffix_of(haystack)
+ }
}
fn no_mut_then_imm_borrow() {
let x = RefCell::new(0);
let _b1 = x.borrow_mut();
- assert!(x.try_borrow().is_none());
assert_eq!(x.borrow_state(), BorrowState::Writing);
}
fn no_imm_then_borrow_mut() {
let x = RefCell::new(0);
let _b1 = x.borrow();
- assert!(x.try_borrow_mut().is_none());
assert_eq!(x.borrow_state(), BorrowState::Reading);
}
let x = RefCell::new(0);
assert_eq!(x.borrow_state(), BorrowState::Unused);
let _b1 = x.borrow_mut();
- assert!(x.try_borrow_mut().is_none());
assert_eq!(x.borrow_state(), BorrowState::Writing);
}
{
let _b2 = x.borrow();
}
- assert!(x.try_borrow_mut().is_none());
+ assert_eq!(x.borrow_state(), BorrowState::Reading);
}
#[test]
let x = RefCell::new(0);
{
let b1 = x.borrow();
- assert!(x.try_borrow_mut().is_none());
+ assert_eq!(x.borrow_state(), BorrowState::Reading);
{
let _b2 = clone_ref(&b1);
- assert!(x.try_borrow_mut().is_none());
+ assert_eq!(x.borrow_state(), BorrowState::Reading);
}
- assert!(x.try_borrow_mut().is_none());
+ assert_eq!(x.borrow_state(), BorrowState::Reading);
}
- assert!(x.try_borrow_mut().is_some());
+ assert_eq!(x.borrow_state(), BorrowState::Unused);
}
#[test]
+++ /dev/null
-// Copyright 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.
-
-#![allow(deprecated)]
-
-use core::finally::{try_finally, Finally};
-use std::thread;
-
-#[test]
-fn test_success() {
- let mut i = 0;
- try_finally(
- &mut i, (),
- |i, ()| {
- *i = 10;
- },
- |i| {
- assert!(!thread::panicking());
- assert_eq!(*i, 10);
- *i = 20;
- });
- assert_eq!(i, 20);
-}
-
-#[test]
-#[should_panic]
-fn test_fail() {
- let mut i = 0;
- try_finally(
- &mut i, (),
- |i, ()| {
- *i = 10;
- panic!();
- },
- |i| {
- assert!(thread::panicking());
- assert_eq!(*i, 10);
- })
-}
-
-#[test]
-fn test_retval() {
- let mut closure = || 10;
- // FIXME(#16640) `: i32` annotation shouldn't be necessary
- let i: i32 = closure.finally(|| { });
- assert_eq!(i, 10);
-}
-
-#[test]
-fn test_compact() {
- fn do_some_fallible_work() {}
- fn but_always_run_this_function() { }
- let mut f = do_some_fallible_work;
- f.finally(but_always_run_this_function);
-}
#[test]
fn test_counter_from_iter() {
- let it = count(0, 5).take(10);
+ let it = (0..).step_by(5).take(10);
let xs: Vec<isize> = FromIterator::from_iter(it);
assert_eq!(xs, [0, 5, 10, 15, 20, 25, 30, 35, 40, 45]);
}
}
assert_eq!(i, expected.len());
- let ys = count(30, 10).take(4);
+ let ys = (30..).step_by(10).take(4);
let it = xs.iter().cloned().chain(ys);
let mut i = 0;
for x in it {
#[test]
fn test_filter_map() {
- let it = count(0, 1).take(10)
+ let it = (0..).step_by(1).take(10)
.filter_map(|x| if x % 2 == 0 { Some(x*x) } else { None });
assert_eq!(it.collect::<Vec<usize>>(), [0*0, 2*2, 4*4, 6*6, 8*8]);
}
fn test_iterator_flat_map() {
let xs = [0, 3, 6];
let ys = [0, 1, 2, 3, 4, 5, 6, 7, 8];
- let it = xs.iter().flat_map(|&x| count(x, 1).take(3));
+ let it = xs.iter().flat_map(|&x| (x..).step_by(1).take(3));
let mut i = 0;
for x in it {
assert_eq!(x, ys[i]);
#[test]
fn test_cycle() {
let cycle_len = 3;
- let it = count(0, 1).take(cycle_len).cycle();
+ let it = (0..).step_by(1).take(cycle_len).cycle();
assert_eq!(it.size_hint(), (usize::MAX, None));
for (i, x) in it.take(100).enumerate() {
assert_eq!(i % cycle_len, x);
}
- let mut it = count(0, 1).take(0).cycle();
+ let mut it = (0..).step_by(1).take(0).cycle();
assert_eq!(it.size_hint(), (0, Some(0)));
assert_eq!(it.next(), None);
}
#[test]
fn test_iterator_size_hint() {
- let c = count(0, 1);
+ let c = (0..).step_by(1);
let v: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
let v2 = &[10, 11, 12];
let vi = v.iter();
mod cell;
mod char;
mod cmp;
-mod finally;
mod fmt;
mod hash;
mod iter;
}
unsafe {
- assert_eq!([76], transmute::<_, Vec<u8>>("L".to_string()));
+ assert_eq!(transmute::<_, Vec<u8>>("L".to_string()), [76]);
}
}
#[test]
fn contains_weird_cases() {
- assert!("* \t".contains_char(' '));
- assert!(!"* \t".contains_char('?'));
- assert!(!"* \t".contains_char('\u{1F4A9}'));
+ assert!("* \t".contains(' '));
+ assert!(!"* \t".contains('?'));
+ assert!(!"* \t".contains('\u{1F4A9}'));
}
#[test]
make_test!(chars_count, s, s.chars().count());
make_test!(contains_bang_str, s, s.contains("!"));
- make_test!(contains_bang_char, s, s.contains_char('!'));
+ make_test!(contains_bang_char, s, s.contains('!'));
make_test!(match_indices_a_str, s, s.match_indices("a").count());
- make_test!(split_str_a_str, s, s.split_str("a").count());
+ make_test!(split_a_str, s, s.split("a").count());
make_test!(trim_ascii_char, s, {
use std::ascii::AsciiExt;
make_test!(find_underscore_char, s, s.find('_'));
make_test!(rfind_underscore_char, s, s.rfind('_'));
- make_test!(find_underscore_str, s, s.find_str("_"));
+ make_test!(find_underscore_str, s, s.find("_"));
make_test!(find_zzz_char, s, s.find('\u{1F4A4}'));
make_test!(rfind_zzz_char, s, s.rfind('\u{1F4A4}'));
- make_test!(find_zzz_str, s, s.find_str("\u{1F4A4}"));
+ make_test!(find_zzz_str, s, s.find("\u{1F4A4}"));
make_test!(split_space_char, s, s.split(' ').count());
make_test!(split_terminator_space_char, s, s.split_terminator(' ').count());
make_test!(splitn_space_char, s, s.splitn(10, ' ').count());
make_test!(rsplitn_space_char, s, s.rsplitn(10, ' ').count());
- make_test!(split_str_space_str, s, s.split_str(" ").count());
- make_test!(split_str_ad_str, s, s.split_str("ad").count());
+ make_test!(split_space_str, s, s.split(" ").count());
+ make_test!(split_ad_str, s, s.split("ad").count());
}
fn same(fmt: &'static str, p: &[Piece<'static>]) {
let parser = Parser::new(fmt);
- assert!(p == parser.collect::<Vec<Piece<'static>>>());
+ assert!(parser.collect::<Vec<Piece<'static>>>() == p);
}
fn fmtdflt() -> FormatSpec<'static> {
//!
//! fn edges(&'a self) -> dot::Edges<'a,Ed> {
//! let &Edges(ref edges) = self;
-//! edges.as_slice().into_cow()
+//! (&edges[..]).into_cow()
//! }
//!
//! fn source(&self, e: &Ed) -> Nd { let &(s,_) = e; s }
for word in &mut key {
*word = other.gen();
}
- SeedableRng::from_seed(key.as_slice())
+ SeedableRng::from_seed(&key[..])
}
}
///
/// let mut v = [0; 13579];
/// thread_rng().fill_bytes(&mut v);
- /// println!("{:?}", v.as_slice());
+ /// println!("{:?}", &v[..]);
/// ```
fn fill_bytes(&mut self, dest: &mut [u8]) {
// this could, in theory, be done by transmuting dest to a
/// let mut rng = thread_rng();
/// let mut y = [1, 2, 3];
/// rng.shuffle(&mut y);
- /// println!("{:?}", y.as_slice());
+ /// println!("{:?}", y);
/// rng.shuffle(&mut y);
- /// println!("{:?}", y.as_slice());
+ /// println!("{:?}", y);
/// ```
fn shuffle<T>(&mut self, values: &mut [T]) {
let mut i = values.len();
#![feature(unsafe_destructor)]
#![feature(staged_api)]
#![feature(std_misc)]
-#![feature(io)]
#![feature(path_ext)]
#![feature(str_words)]
#![feature(str_char)]
-#![feature(convert)]
#![feature(into_cow)]
#![feature(slice_patterns)]
#![cfg_attr(test, feature(test))]
use std::fmt;
use std::hash::{Hash, SipHasher, Hasher};
use std::mem;
+use std::num::ToPrimitive;
use std::ops;
use std::rc::Rc;
use std::vec::IntoIter;
#[cfg(unix)]
pub fn path2cstr(p: &Path) -> CString {
use std::os::unix::prelude::*;
- use std::ffi::AsOsStr;
- CString::new(p.as_os_str().as_bytes()).unwrap()
+ use std::ffi::OsStr;
+ let p: &OsStr = p.as_ref();
+ CString::new(p.as_bytes()).unwrap()
}
#[cfg(windows)]
pub fn path2cstr(p: &Path) -> CString {
// except according to those terms.
use std::io;
+use std::env;
#[allow(deprecated)] use std::old_path::{self, GenericPath};
#[allow(deprecated)] use std::old_io;
use std::path::{Path, PathBuf};
#[allow(deprecated)]
fn old_realpath(original: &old_path::Path) -> old_io::IoResult<old_path::Path> {
use std::old_io::fs;
- use std::os;
const MAX_LINKS_FOLLOWED: usize = 256;
- let original = try!(os::getcwd()).join(original);
+ let original = old_path::Path::new(env::current_dir().unwrap()
+ .to_str().unwrap()).join(original);
// Right now lstat on windows doesn't work quite well
if cfg!(windows) {
#![feature(io)]
#![feature(old_io)]
#![feature(old_path)]
-#![feature(os)]
#![feature(rustc_private)]
#![feature(staged_api)]
#![feature(rand)]
#![feature(path_ext)]
-#![feature(std_misc)]
#![feature(step_by)]
-#![feature(convert)]
#![cfg_attr(test, feature(test, rand))]
extern crate syntax;
#![allow(deprecated)] // to_be32
-use std::iter::{range_step, repeat};
+use std::iter::repeat;
use std::num::Int;
use std::slice::bytes::{MutableByteVector, copy_memory};
use serialize::hex::ToHex;
// Putting the message schedule inside the same loop as the round calculations allows for
// the compiler to generate better code.
- for t in range_step(0, 48, 8) {
+ for t in (0..48).step_by(8) {
schedule_round!(t + 16);
schedule_round!(t + 17);
schedule_round!(t + 18);
sha2_round!(b, c, d, e, f, g, h, a, K32, t + 7);
}
- for t in range_step(48, 64, 8) {
+ for t in (48..64).step_by(8) {
sha2_round!(a, b, c, d, e, f, g, h, K32, t);
sha2_round!(h, a, b, c, d, e, f, g, K32, t + 1);
sha2_round!(g, h, a, b, c, d, e, f, K32, t + 2);
use std::env;
use std::io::{self, Error, ErrorKind};
use std::fs;
-use std::path::{self, PathBuf, AsPath};
+use std::path::{self, PathBuf, Path};
use std::rand::{thread_rng, Rng};
/// A wrapper for a path to temporary directory implementing automatic
///
/// 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> {
+ pub fn new_in<P: AsRef<Path>>(tmpdir: P, prefix: &str)
+ -> io::Result<TempDir> {
let storage;
- let mut tmpdir = tmpdir.as_path();
+ let mut tmpdir = tmpdir.as_ref();
if !tmpdir.is_absolute() {
let cur_dir = try!(env::current_dir());
storage = cur_dir.join(tmpdir);
#![feature(box_syntax)]
#![feature(collections)]
-#![feature(core)]
#![feature(libc)]
#![feature(quote)]
#![feature(rustc_diagnostic_macros)]
#![feature(io)]
#![feature(set_stdio)]
#![feature(unicode)]
-#![feature(convert)]
extern crate arena;
extern crate flate;
let tup2_ty = ty::mk_tup(tcx, vec!(tup1_ty, tup1_ty, uint_ty));
let uniq_ty = ty::mk_uniq(tcx, tup2_ty);
let walked: Vec<_> = uniq_ty.walk().collect();
- assert_eq!([uniq_ty,
- tup2_ty,
- tup1_ty, int_ty, uint_ty, int_ty, uint_ty,
- tup1_ty, int_ty, uint_ty, int_ty, uint_ty,
- uint_ty],
- walked);
+ assert_eq!(walked, [uniq_ty,
+ tup2_ty,
+ tup1_ty, int_ty, uint_ty, int_ty, uint_ty,
+ tup1_ty, int_ty, uint_ty, int_ty, uint_ty,
+ uint_ty]);
})
}
#[cfg(unix)]
fn path2cstr(p: &Path) -> CString {
use std::os::unix::prelude::*;
- use std::ffi::AsOsStr;
- CString::new(p.as_os_str().as_bytes()).unwrap()
+ use std::ffi::OsStr;
+ let p: &OsStr = p.as_ref();
+ CString::new(p.as_bytes()).unwrap()
}
#[cfg(windows)]
fn path2cstr(p: &Path) -> CString {
#![feature(libc)]
#![feature(link_args)]
#![feature(staged_api)]
-#![cfg_attr(unix, feature(std_misc))]
extern crate libc;
#[macro_use] #[no_link] extern crate rustc_bitflags;
#![feature(unicode)]
#![feature(path_ext)]
#![feature(fs)]
-#![feature(convert)]
#![feature(path_relative_from)]
#![allow(trivial_casts)]
use middle::lang_items::{LangItem, ExchangeMallocFnLangItem, StartFnLangItem};
use middle::weak_lang_items;
use middle::subst::{Subst, Substs};
-use middle::ty::{self, Ty, ClosureTyper};
+use middle::ty::{self, Ty, ClosureTyper, type_is_simd, simd_size};
use session::config::{self, NoDebugInfo};
use session::Session;
use trans::_match;
use trans::cleanup::CleanupMethods;
use trans::cleanup;
use trans::closure;
-use trans::common::{Block, C_bool, C_bytes_in_context, C_i32, C_integral};
+use trans::common::{Block, C_bool, C_bytes_in_context, C_i32, C_int, C_integral};
use trans::common::{C_null, C_struct_in_context, C_u64, C_u8, C_undef};
use trans::common::{CrateContext, ExternMap, FunctionContext};
use trans::common::{Result, NodeIdAndSpan};
let zero = C_integral(Type::uint_from_ty(cx.ccx(), t), 0, false);
(ICmp(cx, llvm::IntEQ, rhs, zero, debug_loc), false)
}
+ ty::ty_struct(_, _) if type_is_simd(cx.tcx(), rhs_t) => {
+ let mut res = C_bool(cx.ccx(), false);
+ for i in 0 .. simd_size(cx.tcx(), rhs_t) {
+ res = Or(cx, res,
+ IsNull(cx,
+ ExtractElement(cx, rhs, C_int(cx.ccx(), i as i64))), debug_loc);
+ }
+ (res, false)
+ }
_ => {
cx.sess().bug(&format!("fail-if-zero on unexpected type: {}",
ty_to_string(cx.tcx(), rhs_t)));
match traits::orphan_check(self.tcx, def_id) {
Ok(()) => { }
Err(traits::OrphanCheckErr::NoLocalInputType) => {
- if !ty::has_attr(self.tcx, trait_def_id, "old_orphan_check") {
- span_err!(
- self.tcx.sess, item.span, E0117,
- "the impl does not reference any \
- types defined in this crate; \
- only traits defined in the current crate can be \
- implemented for arbitrary types");
- return;
- }
+ span_err!(
+ self.tcx.sess, item.span, E0117,
+ "the impl does not reference any \
+ types defined in this crate; \
+ only traits defined in the current crate can be \
+ implemented for arbitrary types");
+ return;
}
Err(traits::OrphanCheckErr::UncoveredTy(param_ty)) => {
- if !ty::has_attr(self.tcx, trait_def_id, "old_orphan_check") {
- span_err!(self.tcx.sess, item.span, E0210,
- "type parameter `{}` must be used as the type parameter for \
- some local type (e.g. `MyStruct<T>`); only traits defined in \
- the current crate can be implemented for a type parameter",
- param_ty.user_string(self.tcx));
- return;
- }
+ span_err!(self.tcx.sess, item.span, E0210,
+ "type parameter `{}` must be used as the type parameter for \
+ some local type (e.g. `MyStruct<T>`); only traits defined in \
+ the current crate can be implemented for a type parameter",
+ param_ty.user_string(self.tcx));
+ return;
}
}
#[cfg(unix)]
mod imp {
- use std::ffi::{AsOsStr, CString};
+ use std::ffi::{CString, OsStr};
use std::os::unix::prelude::*;
use std::path::Path;
use std::io;
impl Lock {
pub fn new(p: &Path) -> Lock {
- let buf = CString::new(p.as_os_str().as_bytes()).unwrap();
+ let os: &OsStr = p.as_ref();
+ let buf = CString::new(os.as_bytes()).unwrap();
let fd = unsafe {
libc::open(buf.as_ptr(), libc::O_RDWR | libc::O_CREAT,
libc::S_IRWXU)
#[cfg(windows)]
mod imp {
use libc;
- use std::ffi::AsOsStr;
use std::io;
use std::mem;
+ use std::ffi::OsStr;
use std::os::windows::prelude::*;
use std::path::Path;
use std::ptr;
impl Lock {
pub fn new(p: &Path) -> Lock {
- let mut p_16: Vec<_> = p.as_os_str().encode_wide().collect();
+ let os: &OsStr = p.as_ref();
+ let mut p_16: Vec<_> = os.encode_wide().collect();
p_16.push(0);
let handle = unsafe {
libc::CreateFileW(p_16.as_ptr(),
#![feature(box_patterns)]
#![feature(box_syntax)]
#![feature(collections)]
-#![feature(core)]
#![feature(exit_status)]
#![feature(set_stdio)]
#![feature(libc)]
#![feature(file_path)]
#![feature(path_ext)]
#![feature(path_relative_from)]
-#![feature(convert)]
#![feature(slice_patterns)]
extern crate arena;
//! let encoded = json::encode(&object).unwrap();
//!
//! // Deserialize using `json::decode`
-//! let decoded: TestStruct = json::decode(encoded.as_slice()).unwrap();
+//! let decoded: TestStruct = json::decode(&encoded[..]).unwrap();
//! }
//! ```
//!
fn description(&self) -> &str { "encoder error" }
}
-impl std::error::FromError<fmt::Error> for EncoderError {
- fn from_error(err: fmt::Error) -> EncoderError { EncoderError::FmtError(err) }
+impl From<fmt::Error> for EncoderError {
+ fn from(err: fmt::Error) -> EncoderError { EncoderError::FmtError(err) }
}
pub type EncodeResult = Result<(), EncoderError>;
#![feature(std_misc)]
#![feature(unicode)]
#![feature(str_char)]
-#![feature(convert)]
#![cfg_attr(test, feature(test, old_io))]
// test harness access
}
}
- #[unstable(feature = "collections",
- reason = "matches entry v3 specification, waiting for dust to settle")]
+ #[stable(feature = "rust1", since = "1.0.0")]
/// Ensures a value is in the entry by inserting the default if empty, and returns
/// a mutable reference to the value in the entry.
pub fn or_insert(self, default: V) -> &'a mut V {
}
}
- #[unstable(feature = "collections",
- reason = "matches entry v3 specification, waiting for dust to settle")]
+ #[stable(feature = "rust1", since = "1.0.0")]
/// Ensures a value is in the entry by inserting the result of the default function if empty,
/// and returns a mutable reference to the value in the entry.
pub fn or_insert_with<F: FnOnce() -> V>(self, default: F) -> &'a mut V {
};
let v = hs.into_iter().collect::<Vec<char>>();
- assert!(['a', 'b'] == v || ['b', 'a'] == v);
+ assert!(v == ['a', 'b'] || v == ['b', 'a']);
}
#[test]
use clone::Clone;
use cmp;
use hash::{Hash, Hasher};
-use iter::{Iterator, ExactSizeIterator, count};
+use iter::{Iterator, ExactSizeIterator};
use marker::{Copy, Send, Sync, Sized, self};
use mem::{min_align_of, size_of};
use mem;
use prelude::v1::*;
use env;
-use ffi::{AsOsStr, CString, OsString};
+use ffi::{CString, OsString};
use mem;
use path::{Path, PathBuf};
use ffi::{CStr, OsStr};
use str;
use libc;
- use os::unix::prelude::*;
use ptr;
pub fn open(filename: Option<&OsStr>) -> Result<*mut u8, String> {
use iter::IntoIterator;
use error::Error;
-use ffi::{OsString, AsOsStr};
+use ffi::{OsStr, OsString};
use fmt;
use io;
use path::{Path, PathBuf};
/// }
/// ```
#[stable(feature = "env", since = "1.0.0")]
-pub fn var<K: ?Sized>(key: &K) -> Result<String, VarError> where K: AsOsStr {
+pub fn var<K: ?Sized>(key: &K) -> Result<String, VarError> where K: AsRef<OsStr> {
match var_os(key) {
Some(s) => s.into_string().map_err(VarError::NotUnicode),
None => Err(VarError::NotPresent)
/// }
/// ```
#[stable(feature = "env", since = "1.0.0")]
-pub fn var_os<K: ?Sized>(key: &K) -> Option<OsString> where K: AsOsStr {
+pub fn var_os<K: ?Sized>(key: &K) -> Option<OsString> where K: AsRef<OsStr> {
let _g = ENV_LOCK.lock();
- os_imp::getenv(key.as_os_str())
+ os_imp::getenv(key.as_ref())
}
/// Possible errors from the `env::var` method.
/// ```
#[stable(feature = "env", since = "1.0.0")]
pub fn set_var<K: ?Sized, V: ?Sized>(k: &K, v: &V)
- where K: AsOsStr, V: AsOsStr
+ where K: AsRef<OsStr>, V: AsRef<OsStr>
{
let _g = ENV_LOCK.lock();
- os_imp::setenv(k.as_os_str(), v.as_os_str())
+ os_imp::setenv(k.as_ref(), v.as_ref())
}
-/// Remove a variable from the environment entirely.
+/// Remove an environment variable from the environment of the currently running process.
+///
+/// # Examples
+///
+/// ```
+/// use std::env;
+///
+/// let key = "KEY";
+/// env::set_var(key, "VALUE");
+/// assert_eq!(env::var(key), Ok("VALUE".to_string()));
+///
+/// env::remove_var(key);
+/// assert!(env::var(key).is_err());
+/// ```
#[stable(feature = "env", since = "1.0.0")]
-pub fn remove_var<K: ?Sized>(k: &K) where K: AsOsStr {
+pub fn remove_var<K: ?Sized>(k: &K) where K: AsRef<OsStr> {
let _g = ENV_LOCK.lock();
- os_imp::unsetenv(k.as_os_str())
+ os_imp::unsetenv(k.as_ref())
}
/// An iterator over `Path` instances for parsing an environment variable
/// }
/// ```
#[stable(feature = "env", since = "1.0.0")]
-pub fn split_paths<T: AsOsStr + ?Sized>(unparsed: &T) -> SplitPaths {
- SplitPaths { inner: os_imp::split_paths(unparsed.as_os_str()) }
+pub fn split_paths<T: AsRef<OsStr> + ?Sized>(unparsed: &T) -> SplitPaths {
+ SplitPaths { inner: os_imp::split_paths(unparsed.as_ref()) }
}
#[stable(feature = "env", since = "1.0.0")]
/// # Examples
///
/// ```
-/// # #![feature(convert)]
/// use std::env;
/// use std::path::PathBuf;
///
/// ```
#[stable(feature = "env", since = "1.0.0")]
pub fn join_paths<I, T>(paths: I) -> Result<OsString, JoinPathsError>
- where I: IntoIterator<Item=T>, T: AsOsStr
+ where I: IntoIterator<Item=T>, T: AsRef<OsStr>
{
os_imp::join_paths(paths.into_iter()).map_err(|e| {
JoinPathsError { inner: e }
/// On Windows, returns the value of, in order, the 'TMP', 'TEMP',
/// 'USERPROFILE' environment variable if any are set and not the empty
/// string. Otherwise, tmpdir returns the path to the Windows directory.
+///
+/// ```
+/// use std::env;
+/// use std::fs::File;
+///
+/// # fn foo() -> std::io::Result<()> {
+/// let mut dir = env::temp_dir();
+/// dir.push("foo.txt");
+///
+/// let f = try!(File::create(dir));
+/// # Ok(())
+/// # }
+/// ```
#[stable(feature = "env", since = "1.0.0")]
pub fn temp_dir() -> PathBuf {
os_imp::temp_dir()
#[stable(feature = "env", since = "1.0.0")]
pub const ARCH: &'static str = super::arch::ARCH;
+ /// The family of the operating system. In this case, `unix`.
#[stable(feature = "env", since = "1.0.0")]
pub const FAMILY: &'static str = super::os::FAMILY;
let mut rng = rand::thread_rng();
let n = format!("TEST{}", rng.gen_ascii_chars().take(10)
.collect::<String>());
- let n = OsString::from_string(n);
+ let n = OsString::from(n);
assert!(var_os(&n).is_none());
n
}
#![unstable(feature = "std_misc")]
-use convert::Into;
+use convert::{Into, From};
use cmp::{PartialEq, Eq, PartialOrd, Ord, Ordering};
-use error::{Error, FromError};
+use error::Error;
use fmt;
use io;
use iter::Iterator;
#[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
-/// be converted to a vector of bytes.
-#[deprecated(since = "1.0.0", reason = "use std::convert::Into<Vec<u8>> instead")]
-#[unstable(feature = "std_misc")]
-pub trait IntoBytes {
- /// Consumes this container, returning a vector of bytes.
- fn into_bytes(self) -> Vec<u8>;
-}
-
impl CString {
/// Create a new C-compatible string from a container of bytes.
///
}
}
- /// Create a new C-compatible string from a byte slice.
- ///
- /// This method will copy the data of the slice provided into a new
- /// allocation, ensuring that there is a trailing 0 byte.
- ///
- /// # Examples
- ///
- /// ```no_run
- /// # #![feature(libc)]
- /// extern crate libc;
- /// use std::ffi::CString;
- ///
- /// extern { fn puts(s: *const libc::c_char); }
- ///
- /// fn main() {
- /// let to_print = CString::new("Hello!").unwrap();
- /// unsafe {
- /// puts(to_print.as_ptr());
- /// }
- /// }
- /// ```
- ///
- /// # Panics
- ///
- /// This function will panic if the provided slice contains any
- /// interior nul bytes.
- #[unstable(feature = "std_misc")]
- #[deprecated(since = "1.0.0", reason = "use CString::new instead")]
- #[allow(deprecated)]
- pub fn from_slice(v: &[u8]) -> CString {
- CString::from_vec(v.to_vec())
- }
-
- /// Create a C-compatible string from a byte vector.
- ///
- /// This method will consume ownership of the provided vector, appending a 0
- /// byte to the end after verifying that there are no interior 0 bytes.
- ///
- /// # Panics
- ///
- /// This function will panic if the provided slice contains any
- /// interior nul bytes.
- #[unstable(feature = "std_misc")]
- #[deprecated(since = "1.0.0", reason = "use CString::new instead")]
- pub fn from_vec(v: Vec<u8>) -> CString {
- match v.iter().position(|x| *x == 0) {
- Some(i) => panic!("null byte found in slice at: {}", i),
- None => unsafe { CString::from_vec_unchecked(v) },
- }
- }
-
/// Create a C-compatible string from a byte vector without checking for
/// interior 0 bytes.
///
}
#[stable(feature = "rust1", since = "1.0.0")]
-impl FromError<NulError> for io::Error {
- fn from_error(_: NulError) -> io::Error {
+impl From<NulError> for io::Error {
+ fn from(_: NulError) -> io::Error {
io::Error::new(io::ErrorKind::InvalidInput,
"data provided contains a nul byte", None)
}
#[stable(feature = "rust1", since = "1.0.0")]
#[allow(deprecated)]
-impl FromError<NulError> for old_io::IoError {
- fn from_error(_: NulError) -> old_io::IoError {
+impl From<NulError> for old_io::IoError {
+ fn from(_: NulError) -> old_io::IoError {
old_io::IoError {
kind: old_io::IoErrorKind::InvalidInput,
desc: "data provided contains a nul byte",
}
}
-/// Deprecated in favor of `CStr`
-#[unstable(feature = "std_misc")]
-#[deprecated(since = "1.0.0", reason = "use CStr::from_ptr(p).to_bytes() instead")]
-pub unsafe fn c_str_to_bytes<'a>(raw: &'a *const libc::c_char) -> &'a [u8] {
- let len = libc::strlen(*raw);
- slice::from_raw_parts(*(raw as *const _ as *const *const u8), len as usize)
-}
-
-/// Deprecated in favor of `CStr`
-#[unstable(feature = "std_misc")]
-#[deprecated(since = "1.0.0",
- reason = "use CStr::from_ptr(p).to_bytes_with_nul() instead")]
-pub unsafe fn c_str_to_bytes_with_nul<'a>(raw: &'a *const libc::c_char)
- -> &'a [u8] {
- let len = libc::strlen(*raw) + 1;
- slice::from_raw_parts(*(raw as *const _ as *const *const u8), len as usize)
-}
-
-#[allow(deprecated)]
-impl<'a> IntoBytes for &'a str {
- fn into_bytes(self) -> Vec<u8> { self.as_bytes().to_vec() }
-}
-#[allow(deprecated)]
-impl<'a> IntoBytes for &'a [u8] {
- fn into_bytes(self) -> Vec<u8> { self.to_vec() }
-}
-#[allow(deprecated)]
-impl IntoBytes for String {
- fn into_bytes(self) -> Vec<u8> { self.into_bytes() }
-}
-#[allow(deprecated)]
-impl IntoBytes for Vec<u8> {
- fn into_bytes(self) -> Vec<u8> { self }
-}
-
#[cfg(test)]
mod tests {
use prelude::v1::*;
#![stable(feature = "rust1", since = "1.0.0")]
#[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;
+pub use self::c_str::{CString, CStr, NulError};
#[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;
+pub use self::os_str::{OsString, OsStr};
mod c_str;
mod os_str;
//! for conversion to/from various other string types. Eventually these types
//! will offer a full-fledged string API.
-#![unstable(feature = "os",
+#![unstable(feature = "os_str",
reason = "recently added as part of path/io reform")]
use core::prelude::*;
use borrow::{Borrow, Cow, ToOwned};
+use ffi::CString;
use fmt::{self, Debug};
use mem;
use string::String;
use cmp;
use hash::{Hash, Hasher};
use old_path::{Path, GenericPath};
+use vec::Vec;
use sys::os_str::{Buf, Slice};
use sys_common::{AsInner, IntoInner, FromInner};
}
impl OsString {
- /// Constructs an `OsString` at no cost by consuming a `String`.
+ /// Constructs a new empty `OsString`.
#[stable(feature = "rust1", since = "1.0.0")]
- #[deprecated(since = "1.0.0", reason = "use `from` instead")]
- pub fn from_string(s: String) -> OsString {
- OsString::from(s)
+ pub fn new() -> OsString {
+ OsString { inner: Buf::from_string(String::new()) }
}
- /// Constructs an `OsString` by copying from a `&str` slice.
+ /// Construct an `OsString` from a byte sequence.
///
- /// Equivalent to: `OsString::from_string(String::from_str(s))`.
- #[stable(feature = "rust1", since = "1.0.0")]
- #[deprecated(since = "1.0.0", reason = "use `from` instead")]
- pub fn from_str(s: &str) -> OsString {
- OsString::from(s)
+ /// # Platform behavior
+ ///
+ /// On Unix systems, any byte sequence can be successfully
+ /// converted into an `OsString`.
+ ///
+ /// On Windows system, only UTF-8 byte sequences will successfully
+ /// convert; non UTF-8 data will produce `None`.
+ #[unstable(feature = "convert", reason = "recently added")]
+ pub fn from_bytes<B>(bytes: B) -> Option<OsString> where B: Into<Vec<u8>> {
+ #[cfg(unix)]
+ fn from_bytes_inner(vec: Vec<u8>) -> Option<OsString> {
+ use os::unix::ffi::OsStringExt;
+ Some(OsString::from_vec(vec))
+ }
+
+ #[cfg(windows)]
+ fn from_bytes_inner(vec: Vec<u8>) -> Option<OsString> {
+ String::from_utf8(vec).ok().map(OsString::from)
+ }
+
+ from_bytes_inner(bytes.into())
}
- /// Constructs a new empty `OsString`.
+ /// Convert to an `OsStr` slice.
#[stable(feature = "rust1", since = "1.0.0")]
- pub fn new() -> OsString {
- OsString { inner: Buf::from_string(String::new()) }
+ pub fn as_os_str(&self) -> &OsStr {
+ self
}
/// Convert the `OsString` into a `String` if it contains valid Unicode data.
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: AsRef<OsStr>>(&mut self, s: T) {
}
impl OsStr {
+ /// Coerce into an `OsStr` slice.
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub fn new<S: AsRef<OsStr> + ?Sized>(s: &S) -> &OsStr {
+ s.as_ref()
+ }
+
/// Coerce directly from a `&str` slice to a `&OsStr` slice.
#[stable(feature = "rust1", since = "1.0.0")]
+ #[deprecated(since = "1.0.0",
+ reason = "use `OsStr::new` instead")]
pub fn from_str(s: &str) -> &OsStr {
unsafe { mem::transmute(Slice::from_str(s)) }
}
OsString { inner: self.inner.to_owned() }
}
+ /// Yield this `OsStr` as a byte slice.
+ ///
+ /// # Platform behavior
+ ///
+ /// On Unix systems, this is a no-op.
+ ///
+ /// On Windows systems, this returns `None` unless the `OsStr` is
+ /// valid unicode, in which case it produces UTF-8-encoded
+ /// data. This may entail checking validity.
+ #[unstable(feature = "convert", reason = "recently added")]
+ pub fn to_bytes(&self) -> Option<&[u8]> {
+ if cfg!(windows) {
+ self.to_str().map(|s| s.as_bytes())
+ } else {
+ Some(self.bytes())
+ }
+ }
+
+ /// Create a `CString` containing this `OsStr` data.
+ ///
+ /// Fails if the `OsStr` contains interior nulls.
+ ///
+ /// This is a convenience for creating a `CString` from
+ /// `self.to_bytes()`, and inherits the platform behavior of the
+ /// `to_bytes` method.
+ #[unstable(feature = "convert", reason = "recently added")]
+ pub fn to_cstring(&self) -> Option<CString> {
+ self.to_bytes().and_then(|b| CString::new(b).ok())
+ }
+
/// Get the underlying byte representation.
///
/// Note: it is *crucial* that this API is private, to avoid
#[stable(feature = "rust1", since = "1.0.0")]
impl PartialEq<str> for OsStr {
fn eq(&self, other: &str) -> bool {
- *self == *OsStr::from_str(other)
+ *self == *OsStr::new(other)
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl PartialEq<OsStr> for str {
fn eq(&self, other: &OsStr) -> bool {
- *other == *OsStr::from_str(self)
+ *other == *OsStr::new(self)
}
}
impl PartialOrd<str> for OsStr {
#[inline]
fn partial_cmp(&self, other: &str) -> Option<cmp::Ordering> {
- self.partial_cmp(OsStr::from_str(other))
+ self.partial_cmp(OsStr::new(other))
}
}
#[deprecated(since = "1.0.0", reason = "trait is deprecated")]
impl AsOsStr for str {
fn as_os_str(&self) -> &OsStr {
- OsStr::from_str(self)
+ unsafe { mem::transmute(Slice::from_str(self)) }
}
}
#[deprecated(since = "1.0.0", reason = "trait is deprecated")]
impl AsOsStr for String {
fn as_os_str(&self) -> &OsStr {
- OsStr::from_str(&self[..])
+ unsafe { mem::transmute(Slice::from_str(self)) }
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl AsRef<OsStr> for str {
fn as_ref(&self) -> &OsStr {
- OsStr::from_str(self)
+ unsafe { mem::transmute(Slice::from_str(self)) }
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl AsRef<OsStr> for String {
fn as_ref(&self) -> &OsStr {
- OsStr::from_str(&self[..])
+ unsafe { mem::transmute(Slice::from_str(self)) }
}
}
--- /dev/null
+// 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.
+
+//! Filesystem manipulation operations
+//!
+//! This module contains basic methods to manipulate the contents of the local
+//! filesystem. All methods in this module represent cross-platform filesystem
+//! operations. Extra platform-specific functionality can be found in the
+//! extension traits of `std::os::$platform`.
+
+#![stable(feature = "rust1", since = "1.0.0")]
+
+use core::prelude::*;
+
+use io::{self, Error, ErrorKind, SeekFrom, Seek, Read, Write};
+use path::{Path, PathBuf};
+use sys::fs2 as fs_imp;
+use sys_common::{AsInnerMut, FromInner, AsInner};
+use vec::Vec;
+
+/// A reference to an open file on the filesystem.
+///
+/// An instance of a `File` can be read and/or written depending on what options
+/// it was opened with. Files also implement `Seek` to alter the logical cursor
+/// that the file contains internally.
+///
+/// # Examples
+///
+/// ```no_run
+/// use std::io::prelude::*;
+/// use std::fs::File;
+///
+/// # fn foo() -> std::io::Result<()> {
+/// let mut f = try!(File::create("foo.txt"));
+/// try!(f.write_all(b"Hello, world!"));
+///
+/// let mut f = try!(File::open("foo.txt"));
+/// let mut s = String::new();
+/// try!(f.read_to_string(&mut s));
+/// assert_eq!(s, "Hello, world!");
+/// # Ok(())
+/// # }
+/// ```
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct File {
+ inner: fs_imp::File,
+ path: Option<PathBuf>,
+}
+
+/// Metadata information about a 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.
+///
+/// This iterator is returned from the `read_dir` function of this module and
+/// will yield instances of `io::Result<DirEntry>`. Through a `DirEntry`
+/// information like the entry's path and possibly other metadata can be
+/// learned.
+///
+/// # Failure
+///
+/// This `io::Result` will be an `Err` if there's some sort of intermittent
+/// IO error during iteration.
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct ReadDir(fs_imp::ReadDir);
+
+/// Entries returned by the `ReadDir` iterator.
+///
+/// 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>>,
+}
+
+/// Options and flags which can be used to configure how a file is opened.
+///
+/// This builder exposes the ability to configure how a `File` is opened and
+/// what operations are permitted on the open file. The `File::open` and
+/// `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.
+///
+/// This module only currently provides one bit of information, `readonly`,
+/// which is exposed on all currently supported platforms. Unix-specific
+/// 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 {
+ /// Attempts to open a file in read-only mode.
+ ///
+ /// See the `OpenOptions::open` method for more details.
+ ///
+ /// # Errors
+ ///
+ /// This function will return an error if `path` does not already exist.
+ /// Other errors may also be returned according to `OpenOptions::open`.
+ ///
+ /// # Examples
+ ///
+ /// ```no_run
+ /// use std::fs::File;
+ ///
+ /// # fn foo() -> std::io::Result<()> {
+ /// let mut f = try!(File::open("foo.txt"));
+ /// # Ok(())
+ /// # }
+ /// ```
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub fn open<P: AsRef<Path>>(path: P) -> io::Result<File> {
+ OpenOptions::new().read(true).open(path)
+ }
+
+ /// Open a file in write-only mode.
+ ///
+ /// This function will create a file if it does not exist,
+ /// and will truncate it if it does.
+ ///
+ /// See the `OpenOptions::open` function for more details.
+ ///
+ /// # Examples
+ ///
+ /// ```no_run
+ /// use std::fs::File;
+ ///
+ /// # fn foo() -> std::io::Result<()> {
+ /// let mut f = try!(File::create("foo.txt"));
+ /// # Ok(())
+ /// # }
+ /// ```
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub fn create<P: AsRef<Path>>(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> {
+ self.path.as_ref().map(|p| &**p)
+ }
+
+ /// Attempt to sync all OS-internal metadata to disk.
+ ///
+ /// This function will attempt to ensure that all in-core data reaches the
+ /// filesystem before returning.
+ ///
+ /// # Examples
+ ///
+ /// ```no_run
+ /// use std::fs::File;
+ /// use std::io::prelude::*;
+ ///
+ /// # fn foo() -> std::io::Result<()> {
+ /// let mut f = try!(File::create("foo.txt"));
+ /// try!(f.write_all(b"Hello, world!"));
+ ///
+ /// try!(f.sync_all());
+ /// # Ok(())
+ /// # }
+ /// ```
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub fn sync_all(&self) -> io::Result<()> {
+ self.inner.fsync()
+ }
+
+ /// This function is similar to `sync_all`, except that it may not
+ /// synchronize file metadata to the filesystem.
+ ///
+ /// This is intended for use cases that must synchronize content, but don't
+ /// need the metadata on disk. The goal of this method is to reduce disk
+ /// operations.
+ ///
+ /// Note that some platforms may simply implement this in terms of
+ /// `sync_all`.
+ ///
+ /// # Examples
+ ///
+ /// ```no_run
+ /// use std::fs::File;
+ /// use std::io::prelude::*;
+ ///
+ /// # fn foo() -> std::io::Result<()> {
+ /// let mut f = try!(File::create("foo.txt"));
+ /// try!(f.write_all(b"Hello, world!"));
+ ///
+ /// try!(f.sync_data());
+ /// # Ok(())
+ /// # }
+ /// ```
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub fn sync_data(&self) -> io::Result<()> {
+ self.inner.datasync()
+ }
+
+ /// Truncates or extends the underlying file, updating the size of
+ /// this file to become `size`.
+ ///
+ /// If the `size` is less than the current file's size, then the file will
+ /// 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.
+ ///
+ /// # Examples
+ ///
+ /// ```no_run
+ /// use std::fs::File;
+ ///
+ /// # fn foo() -> std::io::Result<()> {
+ /// let mut f = try!(File::open("foo.txt"));
+ /// try!(f.set_len(0));
+ /// # Ok(())
+ /// # }
+ /// ```
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub fn set_len(&self, size: u64) -> io::Result<()> {
+ self.inner.truncate(size)
+ }
+
+ /// Queries metadata about the underlying file.
+ ///
+ /// # Examples
+ ///
+ /// ```no_run
+ /// use std::fs::File;
+ ///
+ /// # fn foo() -> std::io::Result<()> {
+ /// let mut f = try!(File::open("foo.txt"));
+ /// let metadata = try!(f.metadata());
+ /// # Ok(())
+ /// # }
+ /// ```
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub fn metadata(&self) -> io::Result<Metadata> {
+ self.inner.file_attr().map(Metadata)
+ }
+}
+
+impl AsInner<fs_imp::File> for File {
+ fn as_inner(&self) -> &fs_imp::File { &self.inner }
+}
+impl FromInner<fs_imp::File> for File {
+ fn from_inner(f: fs_imp::File) -> File {
+ File { inner: f, path: None }
+ }
+}
+
+#[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)
+ }
+}
+
+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())
+ }
+
+ /// Set the option for read access.
+ ///
+ /// 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
+ }
+
+ /// Set the option for write access.
+ ///
+ /// 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
+ }
+
+ /// Set the option for the append mode.
+ ///
+ /// 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
+ }
+
+ /// Set the option for truncating a previous file.
+ ///
+ /// 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
+ }
+
+ /// Set the option for creating a new file.
+ ///
+ /// 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
+ }
+
+ /// Open a file at `path` with the options specified by `self`.
+ ///
+ /// # Errors
+ ///
+ /// This function will return an error under a number of different
+ /// circumstances, to include but not limited to:
+ ///
+ /// * Opening a file that does not exist with read access.
+ /// * 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: AsRef<Path>>(&self, path: P) -> io::Result<File> {
+ let path = path.as_ref();
+ let inner = try!(fs_imp::File::open(path, &self.0));
+ Ok(File { path: Some(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())
+ }
+
+ /// 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)
+ }
+}
+
+impl FromInner<fs_imp::FilePermissions> for Permissions {
+ fn from_inner(f: fs_imp::FilePermissions) -> Permissions {
+ Permissions(f)
+ }
+}
+
+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>;
+
+ fn next(&mut self) -> Option<io::Result<DirEntry>> {
+ self.0.next().map(|entry| entry.map(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() }
+}
+
+/// Remove a file from the underlying filesystem.
+///
+/// # Examples
+///
+/// ```rust,no_run
+/// use std::fs;
+///
+/// fs::remove_file("/some/file/path.txt");
+/// ```
+///
+/// Note that, just because an unlink call was successful, it is not
+/// guaranteed that a file is immediately deleted (e.g. depending on
+/// platform, other open file descriptors may prevent immediate removal).
+///
+/// # Errors
+///
+/// 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: AsRef<Path>>(path: P) -> io::Result<()> {
+ fs_imp::unlink(path.as_ref())
+}
+
+/// Given a path, query the file system to get information about a file,
+/// directory, etc.
+///
+/// This function will traverse soft links to query information about the
+/// destination file.
+///
+/// # Examples
+///
+/// ```rust,no_run
+/// # fn foo() -> std::io::Result<()> {
+/// use std::fs;
+///
+/// let attr = try!(fs::metadata("/some/file/path.txt"));
+/// // inspect attr ...
+/// # Ok(())
+/// # }
+/// ```
+///
+/// # Errors
+///
+/// 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: AsRef<Path>>(path: P) -> io::Result<Metadata> {
+ fs_imp::stat(path.as_ref()).map(Metadata)
+}
+
+/// Rename a file or directory to a new name.
+///
+/// # Examples
+///
+/// ```rust,no_run
+/// use std::fs;
+///
+/// fs::rename("foo", "bar");
+/// ```
+///
+/// # Errors
+///
+/// This function will return an error if the provided `from` doesn't exist, if
+/// 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: AsRef<Path>, Q: AsRef<Path>>(from: P, to: Q) -> io::Result<()> {
+ fs_imp::rename(from.as_ref(), to.as_ref())
+}
+
+/// Copies the contents of one file to another. This function will also
+/// copy the permission bits of the original file to the destination file.
+///
+/// This function will **overwrite** the contents of `to`.
+///
+/// Note that if `from` and `to` both point to the same file, then the file
+/// will likely get truncated by this operation.
+///
+/// # Examples
+///
+/// ```
+/// use std::fs;
+///
+/// fs::copy("foo.txt", "bar.txt");
+/// ```
+///
+/// # Errors
+///
+/// This function will return an error in the following situations, but is not
+/// limited to just these cases:
+///
+/// * The `from` path is not a file
+/// * 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: AsRef<Path>, Q: AsRef<Path>>(from: P, to: Q) -> io::Result<u64> {
+ let from = from.as_ref();
+ let to = to.as_ref();
+ if !from.is_file() {
+ return Err(Error::new(ErrorKind::InvalidInput,
+ "the source path is not an existing file",
+ None))
+ }
+
+ let mut reader = try!(File::open(from));
+ let mut writer = try!(File::create(to));
+ let perm = try!(reader.metadata()).permissions();
+
+ let ret = try!(io::copy(&mut reader, &mut writer));
+ try!(set_permissions(to, perm));
+ Ok(ret)
+}
+
+/// Creates a new hard link on the filesystem.
+///
+/// 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: AsRef<Path>, Q: AsRef<Path>>(src: P, dst: Q) -> io::Result<()> {
+ fs_imp::link(src.as_ref(), dst.as_ref())
+}
+
+/// 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: AsRef<Path>, Q: AsRef<Path>>(src: P, dst: Q) -> io::Result<()> {
+ fs_imp::symlink(src.as_ref(), dst.as_ref())
+}
+
+/// Reads a soft link, returning the file that the link points to.
+///
+/// # Errors
+///
+/// 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: AsRef<Path>>(path: P) -> io::Result<PathBuf> {
+ fs_imp::readlink(path.as_ref())
+}
+
+/// Create a new, empty directory at the provided path
+///
+/// # Examples
+///
+/// ```
+/// use std::fs;
+///
+/// fs::create_dir("/some/dir");
+/// ```
+///
+/// # Errors
+///
+/// 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: AsRef<Path>>(path: P) -> io::Result<()> {
+ fs_imp::mkdir(path.as_ref())
+}
+
+/// Recursively create a directory and all of its parent components if they
+/// are missing.
+///
+/// # Errors
+///
+/// This function will fail if any directory in the path specified by `path`
+/// 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: AsRef<Path>>(path: P) -> io::Result<()> {
+ let path = path.as_ref();
+ if path == Path::new("") || path.is_dir() { return Ok(()) }
+ if let Some(p) = path.parent() { try!(create_dir_all(p)) }
+ create_dir(path)
+}
+
+/// Remove an existing, empty directory
+///
+/// # Examples
+///
+/// ```
+/// use std::fs;
+///
+/// fs::remove_dir("/some/dir");
+/// ```
+///
+/// # Errors
+///
+/// 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: AsRef<Path>>(path: P) -> io::Result<()> {
+ fs_imp::rmdir(path.as_ref())
+}
+
+/// Removes a directory at this path, after removing all its contents. Use
+/// carefully!
+///
+/// This function does **not** follow soft links and it will simply remove the
+/// soft link itself.
+///
+/// # Errors
+///
+/// See `file::remove_file` and `fs::remove_dir`
+#[stable(feature = "rust1", since = "1.0.0")]
+pub fn remove_dir_all<P: AsRef<Path>>(path: P) -> io::Result<()> {
+ let path = path.as_ref();
+ for child in try!(read_dir(path)) {
+ let child = try!(child).path();
+ let stat = try!(lstat(&*child));
+ if stat.is_dir() {
+ try!(remove_dir_all(&*child));
+ } else {
+ try!(remove_file(&*child));
+ }
+ }
+ return remove_dir(path);
+
+ #[cfg(unix)]
+ fn lstat(path: &Path) -> io::Result<fs_imp::FileAttr> { fs_imp::lstat(path) }
+ #[cfg(windows)]
+ fn lstat(path: &Path) -> io::Result<fs_imp::FileAttr> { fs_imp::stat(path) }
+}
+
+/// Returns an iterator over the entries within a directory.
+///
+/// The iterator will yield instances of `io::Result<DirEntry>`. New errors may
+/// be encountered after an iterator is initially constructed.
+///
+/// # Examples
+///
+/// ```
+/// # #![feature(path_ext)]
+/// use std::io;
+/// use std::fs::{self, PathExt, DirEntry};
+/// use std::path::Path;
+///
+/// // one possible implementation of fs::walk_dir only visiting files
+/// fn visit_dirs(dir: &Path, cb: &mut FnMut(DirEntry)) -> io::Result<()> {
+/// if dir.is_dir() {
+/// for entry in try!(fs::read_dir(dir)) {
+/// let entry = try!(entry);
+/// if entry.path().is_dir() {
+/// try!(visit_dirs(&entry.path(), cb));
+/// } else {
+/// cb(entry);
+/// }
+/// }
+/// }
+/// Ok(())
+/// }
+/// ```
+///
+/// # Errors
+///
+/// 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: AsRef<Path>>(path: P) -> io::Result<ReadDir> {
+ fs_imp::readdir(path.as_ref()).map(ReadDir)
+}
+
+/// Returns an iterator that will recursively walk the directory structure
+/// rooted at `path`.
+///
+/// The path given will not be iterated over, and this will perform iteration in
+/// some top-down order. The contents of unreadable subdirectories are ignored.
+///
+/// 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: AsRef<Path>>(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>;
+
+ fn next(&mut self) -> Option<io::Result<DirEntry>> {
+ loop {
+ if let Some(ref mut cur) = self.cur {
+ match cur.next() {
+ Some(Err(e)) => return Some(Err(e)),
+ Some(Ok(next)) => {
+ let path = next.path();
+ if path.is_dir() {
+ self.stack.push(read_dir(&*path));
+ }
+ return Some(Ok(next))
+ }
+ None => {}
+ }
+ }
+ self.cur = None;
+ match self.stack.pop() {
+ Some(Err(e)) => return Some(Err(e)),
+ Some(Ok(next)) => self.cur = Some(next),
+ None => return None,
+ }
+ }
+ }
+}
+
+/// 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.
+ ///
+ /// Consult the `fs::stat` documentation for more info.
+ ///
+ /// This call preserves identical runtime/error semantics with `file::stat`.
+ fn metadata(&self) -> io::Result<Metadata>;
+
+ /// Boolean value indicator whether the underlying file exists on the local
+ /// filesystem. Returns false in exactly the cases where `fs::stat` fails.
+ fn exists(&self) -> bool;
+
+ /// Whether the underlying implementation (be it a file path, or something
+ /// else) points at a "regular file" on the FS. Will return false for paths
+ /// to non-existent locations or directories or other non-regular files
+ /// (named pipes, etc). Follows links when making this determination.
+ fn is_file(&self) -> bool;
+
+ /// Whether the underlying implementation (be it a file path, or something
+ /// else) is pointing at a directory in the underlying FS. Will return
+ /// false for paths to non-existent locations or if the item is not a
+ /// directory (eg files, named pipes, etc). Follows links when making this
+ /// determination.
+ fn is_dir(&self) -> bool;
+}
+
+impl PathExt for Path {
+ fn metadata(&self) -> io::Result<Metadata> { metadata(self) }
+
+ fn exists(&self) -> bool { metadata(self).is_ok() }
+
+ fn is_file(&self) -> bool {
+ metadata(self).map(|s| s.is_file()).unwrap_or(false)
+ }
+ fn is_dir(&self) -> bool {
+ metadata(self).map(|s| s.is_dir()).unwrap_or(false)
+ }
+}
+
+/// Changes the timestamps for a file's last modification and access time.
+///
+/// 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: AsRef<Path>>(path: P, accessed: u64,
+ modified: u64) -> io::Result<()> {
+ fs_imp::utimes(path.as_ref(), accessed, modified)
+}
+
+/// Changes the permissions found on a file or a directory.
+///
+/// # Examples
+///
+/// ```
+/// # #![feature(fs)]
+/// # fn foo() -> std::io::Result<()> {
+/// use std::fs;
+///
+/// let mut perms = try!(fs::metadata("foo.txt")).permissions();
+/// perms.set_readonly(true);
+/// try!(fs::set_permissions("foo.txt", perms));
+/// # Ok(())
+/// # }
+/// ```
+///
+/// # Errors
+///
+/// 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: AsRef<Path>>(path: P, perm: Permissions) -> io::Result<()> {
+ fs_imp::set_perm(path.as_ref(), perm.0)
+}
+
+#[cfg(test)]
+mod tests {
+ #![allow(deprecated)] //rand
+
+ use prelude::v1::*;
+ use io::prelude::*;
+
+ use env;
+ use fs::{self, File, OpenOptions};
+ use io::{ErrorKind, SeekFrom};
+ use path::PathBuf;
+ use path::Path as Path2;
+ use os;
+ use rand::{self, StdRng, Rng};
+ use str;
+
+ macro_rules! check { ($e:expr) => (
+ match $e {
+ Ok(t) => t,
+ Err(e) => panic!("{} failed with: {}", stringify!($e), e),
+ }
+ ) }
+
+ macro_rules! error { ($e:expr, $s:expr) => (
+ match $e {
+ Ok(_) => panic!("Unexpected success. Should've been: {:?}", $s),
+ Err(ref err) => assert!(err.to_string().contains($s),
+ format!("`{}` did not contain `{}`", err, $s))
+ }
+ ) }
+
+ pub struct TempDir(PathBuf);
+
+ impl TempDir {
+ fn join(&self, path: &str) -> PathBuf {
+ let TempDir(ref p) = *self;
+ p.join(path)
+ }
+
+ fn path<'a>(&'a self) -> &'a Path2 {
+ let TempDir(ref p) = *self;
+ p
+ }
+ }
+
+ impl Drop for TempDir {
+ fn drop(&mut self) {
+ // Gee, seeing how we're testing the fs module I sure hope that we
+ // at least implement this correctly!
+ let TempDir(ref p) = *self;
+ check!(fs::remove_dir_all(p));
+ }
+ }
+
+ pub fn tmpdir() -> TempDir {
+ let p = env::temp_dir();
+ let ret = p.join(&format!("rust-{}", rand::random::<u32>()));
+ check!(fs::create_dir(&ret));
+ TempDir(ret)
+ }
+
+ #[test]
+ fn file_test_io_smoke_test() {
+ let message = "it's alright. have a good time";
+ let tmpdir = tmpdir();
+ let filename = &tmpdir.join("file_rt_io_file_test.txt");
+ {
+ let mut write_stream = check!(File::create(filename));
+ check!(write_stream.write(message.as_bytes()));
+ }
+ {
+ let mut read_stream = check!(File::open(filename));
+ let mut read_buf = [0; 1028];
+ let read_str = match check!(read_stream.read(&mut read_buf)) {
+ -1|0 => panic!("shouldn't happen"),
+ n => str::from_utf8(&read_buf[..n]).unwrap().to_string()
+ };
+ assert_eq!(read_str, message);
+ }
+ check!(fs::remove_file(filename));
+ }
+
+ #[test]
+ fn invalid_path_raises() {
+ let tmpdir = tmpdir();
+ let filename = &tmpdir.join("file_that_does_not_exist.txt");
+ let result = File::open(filename);
+
+ if cfg!(unix) {
+ error!(result, "o such file or directory");
+ }
+ // error!(result, "couldn't open path as file");
+ // error!(result, format!("path={}; mode=open; access=read", filename.display()));
+ }
+
+ #[test]
+ fn file_test_iounlinking_invalid_path_should_raise_condition() {
+ let tmpdir = tmpdir();
+ let filename = &tmpdir.join("file_another_file_that_does_not_exist.txt");
+
+ let result = fs::remove_file(filename);
+
+ if cfg!(unix) {
+ error!(result, "o such file or directory");
+ }
+ // error!(result, "couldn't unlink path");
+ // error!(result, format!("path={}", filename.display()));
+ }
+
+ #[test]
+ fn file_test_io_non_positional_read() {
+ let message: &str = "ten-four";
+ let mut read_mem = [0; 8];
+ let tmpdir = tmpdir();
+ let filename = &tmpdir.join("file_rt_io_file_test_positional.txt");
+ {
+ let mut rw_stream = check!(File::create(filename));
+ check!(rw_stream.write(message.as_bytes()));
+ }
+ {
+ let mut read_stream = check!(File::open(filename));
+ {
+ let read_buf = &mut read_mem[0..4];
+ check!(read_stream.read(read_buf));
+ }
+ {
+ let read_buf = &mut read_mem[4..8];
+ check!(read_stream.read(read_buf));
+ }
+ }
+ check!(fs::remove_file(filename));
+ let read_str = str::from_utf8(&read_mem).unwrap();
+ assert_eq!(read_str, message);
+ }
+
+ #[test]
+ fn file_test_io_seek_and_tell_smoke_test() {
+ let message = "ten-four";
+ let mut read_mem = [0; 4];
+ let set_cursor = 4 as u64;
+ let mut tell_pos_pre_read;
+ let mut tell_pos_post_read;
+ let tmpdir = tmpdir();
+ let filename = &tmpdir.join("file_rt_io_file_test_seeking.txt");
+ {
+ let mut rw_stream = check!(File::create(filename));
+ check!(rw_stream.write(message.as_bytes()));
+ }
+ {
+ let mut read_stream = check!(File::open(filename));
+ check!(read_stream.seek(SeekFrom::Start(set_cursor)));
+ tell_pos_pre_read = check!(read_stream.seek(SeekFrom::Current(0)));
+ check!(read_stream.read(&mut read_mem));
+ tell_pos_post_read = check!(read_stream.seek(SeekFrom::Current(0)));
+ }
+ check!(fs::remove_file(filename));
+ let read_str = str::from_utf8(&read_mem).unwrap();
+ assert_eq!(read_str, &message[4..8]);
+ assert_eq!(tell_pos_pre_read, set_cursor);
+ assert_eq!(tell_pos_post_read, message.len() as u64);
+ }
+
+ #[test]
+ fn file_test_io_seek_and_write() {
+ let initial_msg = "food-is-yummy";
+ let overwrite_msg = "-the-bar!!";
+ let final_msg = "foo-the-bar!!";
+ let seek_idx = 3;
+ let mut read_mem = [0; 13];
+ let tmpdir = tmpdir();
+ let filename = &tmpdir.join("file_rt_io_file_test_seek_and_write.txt");
+ {
+ let mut rw_stream = check!(File::create(filename));
+ check!(rw_stream.write(initial_msg.as_bytes()));
+ check!(rw_stream.seek(SeekFrom::Start(seek_idx)));
+ check!(rw_stream.write(overwrite_msg.as_bytes()));
+ }
+ {
+ let mut read_stream = check!(File::open(filename));
+ check!(read_stream.read(&mut read_mem));
+ }
+ check!(fs::remove_file(filename));
+ let read_str = str::from_utf8(&read_mem).unwrap();
+ assert!(read_str == final_msg);
+ }
+
+ #[test]
+ fn file_test_io_seek_shakedown() {
+ // 01234567890123
+ let initial_msg = "qwer-asdf-zxcv";
+ let chunk_one: &str = "qwer";
+ let chunk_two: &str = "asdf";
+ let chunk_three: &str = "zxcv";
+ let mut read_mem = [0; 4];
+ let tmpdir = tmpdir();
+ let filename = &tmpdir.join("file_rt_io_file_test_seek_shakedown.txt");
+ {
+ let mut rw_stream = check!(File::create(filename));
+ check!(rw_stream.write(initial_msg.as_bytes()));
+ }
+ {
+ let mut read_stream = check!(File::open(filename));
+
+ check!(read_stream.seek(SeekFrom::End(-4)));
+ check!(read_stream.read(&mut read_mem));
+ assert_eq!(str::from_utf8(&read_mem).unwrap(), chunk_three);
+
+ check!(read_stream.seek(SeekFrom::Current(-9)));
+ check!(read_stream.read(&mut read_mem));
+ assert_eq!(str::from_utf8(&read_mem).unwrap(), chunk_two);
+
+ check!(read_stream.seek(SeekFrom::Start(0)));
+ check!(read_stream.read(&mut read_mem));
+ assert_eq!(str::from_utf8(&read_mem).unwrap(), chunk_one);
+ }
+ check!(fs::remove_file(filename));
+ }
+
+ #[test]
+ fn file_test_stat_is_correct_on_is_file() {
+ let tmpdir = tmpdir();
+ let filename = &tmpdir.join("file_stat_correct_on_is_file.txt");
+ {
+ let mut opts = OpenOptions::new();
+ let mut fs = check!(opts.read(true).write(true)
+ .create(true).open(filename));
+ let msg = "hw";
+ fs.write(msg.as_bytes()).unwrap();
+
+ let fstat_res = check!(fs.metadata());
+ assert!(fstat_res.is_file());
+ }
+ let stat_res_fn = check!(fs::metadata(filename));
+ assert!(stat_res_fn.is_file());
+ let stat_res_meth = check!(filename.metadata());
+ assert!(stat_res_meth.is_file());
+ check!(fs::remove_file(filename));
+ }
+
+ #[test]
+ fn file_test_stat_is_correct_on_is_dir() {
+ let tmpdir = tmpdir();
+ let filename = &tmpdir.join("file_stat_correct_on_is_dir");
+ check!(fs::create_dir(filename));
+ let stat_res_fn = check!(fs::metadata(filename));
+ assert!(stat_res_fn.is_dir());
+ let stat_res_meth = check!(filename.metadata());
+ assert!(stat_res_meth.is_dir());
+ check!(fs::remove_dir(filename));
+ }
+
+ #[test]
+ fn file_test_fileinfo_false_when_checking_is_file_on_a_directory() {
+ let tmpdir = tmpdir();
+ let dir = &tmpdir.join("fileinfo_false_on_dir");
+ check!(fs::create_dir(dir));
+ assert!(dir.is_file() == false);
+ check!(fs::remove_dir(dir));
+ }
+
+ #[test]
+ fn file_test_fileinfo_check_exists_before_and_after_file_creation() {
+ let tmpdir = tmpdir();
+ let file = &tmpdir.join("fileinfo_check_exists_b_and_a.txt");
+ check!(check!(File::create(file)).write(b"foo"));
+ assert!(file.exists());
+ check!(fs::remove_file(file));
+ assert!(!file.exists());
+ }
+
+ #[test]
+ fn file_test_directoryinfo_check_exists_before_and_after_mkdir() {
+ let tmpdir = tmpdir();
+ let dir = &tmpdir.join("before_and_after_dir");
+ assert!(!dir.exists());
+ check!(fs::create_dir(dir));
+ assert!(dir.exists());
+ assert!(dir.is_dir());
+ check!(fs::remove_dir(dir));
+ assert!(!dir.exists());
+ }
+
+ #[test]
+ fn file_test_directoryinfo_readdir() {
+ let tmpdir = tmpdir();
+ let dir = &tmpdir.join("di_readdir");
+ check!(fs::create_dir(dir));
+ let prefix = "foo";
+ for n in 0..3 {
+ let f = dir.join(&format!("{}.txt", n));
+ let mut w = check!(File::create(&f));
+ let msg_str = format!("{}{}", prefix, n.to_string());
+ let msg = msg_str.as_bytes();
+ check!(w.write(msg));
+ }
+ let files = check!(fs::read_dir(dir));
+ let mut mem = [0; 4];
+ for f in files {
+ let f = f.unwrap().path();
+ {
+ let n = f.file_stem().unwrap();
+ check!(check!(File::open(&f)).read(&mut mem));
+ let read_str = str::from_utf8(&mem).unwrap();
+ let expected = format!("{}{}", prefix, n.to_str().unwrap());
+ assert_eq!(expected, read_str);
+ }
+ check!(fs::remove_file(&f));
+ }
+ check!(fs::remove_dir(dir));
+ }
+
+ #[test]
+ fn file_test_walk_dir() {
+ let tmpdir = tmpdir();
+ let dir = &tmpdir.join("walk_dir");
+ check!(fs::create_dir(dir));
+
+ let dir1 = &dir.join("01/02/03");
+ check!(fs::create_dir_all(dir1));
+ check!(File::create(&dir1.join("04")));
+
+ let dir2 = &dir.join("11/12/13");
+ check!(fs::create_dir_all(dir2));
+ check!(File::create(&dir2.join("14")));
+
+ let files = check!(fs::walk_dir(dir));
+ let mut cur = [0; 2];
+ for f in files {
+ let f = f.unwrap().path();
+ let stem = f.file_stem().unwrap().to_str().unwrap();
+ let root = stem.as_bytes()[0] - b'0';
+ let name = stem.as_bytes()[1] - b'0';
+ assert!(cur[root as usize] < name);
+ cur[root as usize] = name;
+ }
+
+ check!(fs::remove_dir_all(dir));
+ }
+
+ #[test]
+ fn mkdir_path_already_exists_error() {
+ let tmpdir = tmpdir();
+ let dir = &tmpdir.join("mkdir_error_twice");
+ check!(fs::create_dir(dir));
+ let e = fs::create_dir(dir).err().unwrap();
+ assert_eq!(e.kind(), ErrorKind::AlreadyExists);
+ }
+
+ #[test]
+ fn recursive_mkdir() {
+ let tmpdir = tmpdir();
+ let dir = tmpdir.join("d1/d2");
+ check!(fs::create_dir_all(&dir));
+ assert!(dir.is_dir())
+ }
+
+ #[test]
+ fn recursive_mkdir_failure() {
+ let tmpdir = tmpdir();
+ let dir = tmpdir.join("d1");
+ let file = dir.join("f1");
+
+ check!(fs::create_dir_all(&dir));
+ check!(File::create(&file));
+
+ let result = fs::create_dir_all(&file);
+
+ assert!(result.is_err());
+ // error!(result, "couldn't recursively mkdir");
+ // error!(result, "couldn't create directory");
+ // error!(result, "mode=0700");
+ // error!(result, format!("path={}", file.display()));
+ }
+
+ #[test]
+ fn recursive_mkdir_slash() {
+ check!(fs::create_dir_all(&Path2::new("/")));
+ }
+
+ // FIXME(#12795) depends on lstat to work on windows
+ #[cfg(not(windows))]
+ #[test]
+ fn recursive_rmdir() {
+ let tmpdir = tmpdir();
+ let d1 = tmpdir.join("d1");
+ let dt = d1.join("t");
+ let dtt = dt.join("t");
+ let d2 = tmpdir.join("d2");
+ let canary = d2.join("do_not_delete");
+ check!(fs::create_dir_all(&dtt));
+ check!(fs::create_dir_all(&d2));
+ check!(check!(File::create(&canary)).write(b"foo"));
+ check!(fs::soft_link(&d2, &dt.join("d2")));
+ check!(fs::remove_dir_all(&d1));
+
+ assert!(!d1.is_dir());
+ assert!(canary.exists());
+ }
+
+ #[test]
+ fn unicode_path_is_dir() {
+ assert!(Path2::new(".").is_dir());
+ assert!(!Path2::new("test/stdtest/fs.rs").is_dir());
+
+ let tmpdir = tmpdir();
+
+ let mut dirpath = tmpdir.path().to_path_buf();
+ dirpath.push(&format!("test-가一ー你好"));
+ check!(fs::create_dir(&dirpath));
+ assert!(dirpath.is_dir());
+
+ let mut filepath = dirpath;
+ filepath.push("unicode-file-\u{ac00}\u{4e00}\u{30fc}\u{4f60}\u{597d}.rs");
+ check!(File::create(&filepath)); // ignore return; touch only
+ assert!(!filepath.is_dir());
+ assert!(filepath.exists());
+ }
+
+ #[test]
+ fn unicode_path_exists() {
+ assert!(Path2::new(".").exists());
+ assert!(!Path2::new("test/nonexistent-bogus-path").exists());
+
+ let tmpdir = tmpdir();
+ let unicode = tmpdir.path();
+ let unicode = unicode.join(&format!("test-각丁ー再见"));
+ check!(fs::create_dir(&unicode));
+ assert!(unicode.exists());
+ assert!(!Path2::new("test/unicode-bogus-path-각丁ー再见").exists());
+ }
+
+ #[test]
+ fn copy_file_does_not_exist() {
+ let from = Path2::new("test/nonexistent-bogus-path");
+ let to = Path2::new("test/other-bogus-path");
+
+ match fs::copy(&from, &to) {
+ Ok(..) => panic!(),
+ Err(..) => {
+ assert!(!from.exists());
+ assert!(!to.exists());
+ }
+ }
+ }
+
+ #[test]
+ fn copy_file_ok() {
+ let tmpdir = tmpdir();
+ let input = tmpdir.join("in.txt");
+ let out = tmpdir.join("out.txt");
+
+ check!(check!(File::create(&input)).write(b"hello"));
+ check!(fs::copy(&input, &out));
+ let mut v = Vec::new();
+ check!(check!(File::open(&out)).read_to_end(&mut v));
+ assert_eq!(v, b"hello");
+
+ assert_eq!(check!(input.metadata()).permissions(),
+ check!(out.metadata()).permissions());
+ }
+
+ #[test]
+ fn copy_file_dst_dir() {
+ let tmpdir = tmpdir();
+ let out = tmpdir.join("out");
+
+ check!(File::create(&out));
+ match fs::copy(&*out, tmpdir.path()) {
+ Ok(..) => panic!(), Err(..) => {}
+ }
+ }
+
+ #[test]
+ fn copy_file_dst_exists() {
+ let tmpdir = tmpdir();
+ let input = tmpdir.join("in");
+ let output = tmpdir.join("out");
+
+ check!(check!(File::create(&input)).write("foo".as_bytes()));
+ check!(check!(File::create(&output)).write("bar".as_bytes()));
+ check!(fs::copy(&input, &output));
+
+ let mut v = Vec::new();
+ check!(check!(File::open(&output)).read_to_end(&mut v));
+ assert_eq!(v, b"foo".to_vec());
+ }
+
+ #[test]
+ fn copy_file_src_dir() {
+ let tmpdir = tmpdir();
+ let out = tmpdir.join("out");
+
+ match fs::copy(tmpdir.path(), &out) {
+ Ok(..) => panic!(), Err(..) => {}
+ }
+ assert!(!out.exists());
+ }
+
+ #[test]
+ fn copy_file_preserves_perm_bits() {
+ let tmpdir = tmpdir();
+ let input = tmpdir.join("in.txt");
+ let out = tmpdir.join("out.txt");
+
+ let attr = check!(check!(File::create(&input)).metadata());
+ let mut p = attr.permissions();
+ p.set_readonly(true);
+ 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?
+ #[test]
+ fn symlinks_work() {
+ let tmpdir = tmpdir();
+ let input = tmpdir.join("in.txt");
+ let out = tmpdir.join("out.txt");
+
+ check!(check!(File::create(&input)).write("foobar".as_bytes()));
+ check!(fs::soft_link(&input, &out));
+ // if cfg!(not(windows)) {
+ // assert_eq!(check!(lstat(&out)).kind, FileType::Symlink);
+ // assert_eq!(check!(out.lstat()).kind, FileType::Symlink);
+ // }
+ assert_eq!(check!(fs::metadata(&out)).len(),
+ check!(fs::metadata(&input)).len());
+ let mut v = Vec::new();
+ check!(check!(File::open(&out)).read_to_end(&mut v));
+ assert_eq!(v, b"foobar".to_vec());
+ }
+
+ #[cfg(not(windows))] // apparently windows doesn't like symlinks
+ #[test]
+ fn symlink_noexist() {
+ let tmpdir = tmpdir();
+ // symlinks can point to things that don't exist
+ check!(fs::soft_link(&tmpdir.join("foo"), &tmpdir.join("bar")));
+ assert_eq!(check!(fs::read_link(&tmpdir.join("bar"))),
+ tmpdir.join("foo"));
+ }
+
+ #[test]
+ fn readlink_not_symlink() {
+ let tmpdir = tmpdir();
+ match fs::read_link(tmpdir.path()) {
+ Ok(..) => panic!("wanted a failure"),
+ Err(..) => {}
+ }
+ }
+
+ #[test]
+ fn links_work() {
+ let tmpdir = tmpdir();
+ let input = tmpdir.join("in.txt");
+ let out = tmpdir.join("out.txt");
+
+ check!(check!(File::create(&input)).write("foobar".as_bytes()));
+ check!(fs::hard_link(&input, &out));
+ assert_eq!(check!(fs::metadata(&out)).len(),
+ check!(fs::metadata(&input)).len());
+ assert_eq!(check!(fs::metadata(&out)).len(),
+ check!(input.metadata()).len());
+ let mut v = Vec::new();
+ check!(check!(File::open(&out)).read_to_end(&mut v));
+ assert_eq!(v, b"foobar".to_vec());
+
+ // can't link to yourself
+ match fs::hard_link(&input, &input) {
+ Ok(..) => panic!("wanted a failure"),
+ Err(..) => {}
+ }
+ // can't link to something that doesn't exist
+ match fs::hard_link(&tmpdir.join("foo"), &tmpdir.join("bar")) {
+ Ok(..) => panic!("wanted a failure"),
+ Err(..) => {}
+ }
+ }
+
+ #[test]
+ fn chmod_works() {
+ let tmpdir = tmpdir();
+ let file = tmpdir.join("in.txt");
+
+ check!(File::create(&file));
+ let attr = check!(fs::metadata(&file));
+ assert!(!attr.permissions().readonly());
+ let mut p = attr.permissions();
+ p.set_readonly(true);
+ check!(fs::set_permissions(&file, p.clone()));
+ let attr = check!(fs::metadata(&file));
+ assert!(attr.permissions().readonly());
+
+ 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]
+ fn sync_doesnt_kill_anything() {
+ let tmpdir = tmpdir();
+ let path = tmpdir.join("in.txt");
+
+ let mut file = check!(File::create(&path));
+ check!(file.sync_all());
+ check!(file.sync_data());
+ check!(file.write(b"foo"));
+ check!(file.sync_all());
+ check!(file.sync_data());
+ }
+
+ #[test]
+ fn truncate_works() {
+ let tmpdir = tmpdir();
+ let path = tmpdir.join("in.txt");
+
+ let mut file = check!(File::create(&path));
+ check!(file.write(b"foo"));
+ check!(file.sync_all());
+
+ // Do some simple things with truncation
+ assert_eq!(check!(file.metadata()).len(), 3);
+ check!(file.set_len(10));
+ assert_eq!(check!(file.metadata()).len(), 10);
+ check!(file.write(b"bar"));
+ check!(file.sync_all());
+ assert_eq!(check!(file.metadata()).len(), 10);
+
+ let mut v = Vec::new();
+ check!(check!(File::open(&path)).read_to_end(&mut v));
+ assert_eq!(v, b"foobar\0\0\0\0".to_vec());
+
+ // Truncate to a smaller length, don't seek, and then write something.
+ // Ensure that the intermediate zeroes are all filled in (we have `seek`ed
+ // past the end of the file).
+ check!(file.set_len(2));
+ assert_eq!(check!(file.metadata()).len(), 2);
+ check!(file.write(b"wut"));
+ check!(file.sync_all());
+ assert_eq!(check!(file.metadata()).len(), 9);
+ let mut v = Vec::new();
+ check!(check!(File::open(&path)).read_to_end(&mut v));
+ assert_eq!(v, b"fo\0\0\0\0wut".to_vec());
+ }
+
+ #[test]
+ fn open_flavors() {
+ use fs::OpenOptions as OO;
+ fn c<T: Clone>(t: &T) -> T { t.clone() }
+
+ let tmpdir = tmpdir();
+
+ let mut r = OO::new(); r.read(true);
+ let mut w = OO::new(); w.write(true);
+ let mut rw = OO::new(); rw.write(true).read(true);
+
+ match r.open(&tmpdir.join("a")) {
+ Ok(..) => panic!(), Err(..) => {}
+ }
+
+ // Perform each one twice to make sure that it succeeds the second time
+ // (where the file exists)
+ check!(c(&w).create(true).open(&tmpdir.join("b")));
+ assert!(tmpdir.join("b").exists());
+ check!(c(&w).create(true).open(&tmpdir.join("b")));
+ check!(w.open(&tmpdir.join("b")));
+
+ check!(c(&rw).create(true).open(&tmpdir.join("c")));
+ assert!(tmpdir.join("c").exists());
+ check!(c(&rw).create(true).open(&tmpdir.join("c")));
+ check!(rw.open(&tmpdir.join("c")));
+
+ check!(c(&w).append(true).create(true).open(&tmpdir.join("d")));
+ assert!(tmpdir.join("d").exists());
+ check!(c(&w).append(true).create(true).open(&tmpdir.join("d")));
+ check!(c(&w).append(true).open(&tmpdir.join("d")));
+
+ check!(c(&rw).append(true).create(true).open(&tmpdir.join("e")));
+ assert!(tmpdir.join("e").exists());
+ check!(c(&rw).append(true).create(true).open(&tmpdir.join("e")));
+ check!(c(&rw).append(true).open(&tmpdir.join("e")));
+
+ check!(c(&w).truncate(true).create(true).open(&tmpdir.join("f")));
+ assert!(tmpdir.join("f").exists());
+ check!(c(&w).truncate(true).create(true).open(&tmpdir.join("f")));
+ check!(c(&w).truncate(true).open(&tmpdir.join("f")));
+
+ check!(c(&rw).truncate(true).create(true).open(&tmpdir.join("g")));
+ assert!(tmpdir.join("g").exists());
+ check!(c(&rw).truncate(true).create(true).open(&tmpdir.join("g")));
+ check!(c(&rw).truncate(true).open(&tmpdir.join("g")));
+
+ check!(check!(File::create(&tmpdir.join("h"))).write("foo".as_bytes()));
+ check!(r.open(&tmpdir.join("h")));
+ {
+ let mut f = check!(r.open(&tmpdir.join("h")));
+ assert!(f.write("wut".as_bytes()).is_err());
+ }
+ assert_eq!(check!(fs::metadata(&tmpdir.join("h"))).len(), 3);
+ {
+ let mut f = check!(c(&w).append(true).open(&tmpdir.join("h")));
+ check!(f.write("bar".as_bytes()));
+ }
+ assert_eq!(check!(fs::metadata(&tmpdir.join("h"))).len(), 6);
+ {
+ let mut f = check!(c(&w).truncate(true).open(&tmpdir.join("h")));
+ check!(f.write("bar".as_bytes()));
+ }
+ assert_eq!(check!(fs::metadata(&tmpdir.join("h"))).len(), 3);
+ }
+
+ #[test]
+ fn utime() {
+ let tmpdir = tmpdir();
+ let path = tmpdir.join("a");
+ check!(File::create(&path));
+ // These numbers have to be bigger than the time in the day to account
+ // for timezones Windows in particular will fail in certain timezones
+ // with small enough values
+ check!(fs::set_file_times(&path, 100000, 200000));
+ assert_eq!(check!(path.metadata()).accessed(), 100000);
+ assert_eq!(check!(path.metadata()).modified(), 200000);
+ }
+
+ #[test]
+ fn utime_noexist() {
+ let tmpdir = tmpdir();
+
+ match fs::set_file_times(&tmpdir.join("a"), 100, 200) {
+ Ok(..) => panic!(),
+ Err(..) => {}
+ }
+ }
+
+ #[test]
+ fn binary_file() {
+ let mut bytes = [0; 1024];
+ StdRng::new().unwrap().fill_bytes(&mut bytes);
+
+ let tmpdir = tmpdir();
+
+ check!(check!(File::create(&tmpdir.join("test"))).write(&bytes));
+ let mut v = Vec::new();
+ check!(check!(File::open(&tmpdir.join("test"))).read_to_end(&mut v));
+ assert!(v == &bytes[..]);
+ }
+
+ #[test]
+ #[cfg(not(windows))]
+ fn unlink_readonly() {
+ let tmpdir = tmpdir();
+ let path = tmpdir.join("file");
+ check!(File::create(&path));
+ let mut perm = check!(fs::metadata(&path)).permissions();
+ perm.set_readonly(true);
+ check!(fs::set_permissions(&path, perm));
+ check!(fs::remove_file(&path));
+ }
+
+ #[test]
+ fn mkdir_trailing_slash() {
+ let tmpdir = tmpdir();
+ let path = tmpdir.join("file");
+ check!(fs::create_dir_all(&path.join("a/")));
+ }
+}
+++ /dev/null
-// 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.
-
-//! Filesystem manipulation operations
-//!
-//! This module contains basic methods to manipulate the contents of the local
-//! filesystem. All methods in this module represent cross-platform filesystem
-//! operations. Extra platform-specific functionality can be found in the
-//! extension traits of `std::os::$platform`.
-
-#![stable(feature = "rust1", since = "1.0.0")]
-
-use core::prelude::*;
-
-use io::{self, Error, ErrorKind, SeekFrom, Seek, Read, Write};
-use path::{Path, PathBuf};
-use sys::fs2 as fs_imp;
-use sys_common::{AsInnerMut, FromInner, AsInner};
-use vec::Vec;
-
-#[allow(deprecated)]
-pub use self::tempdir::TempDir;
-
-mod tempdir;
-
-/// A reference to an open file on the filesystem.
-///
-/// An instance of a `File` can be read and/or written depending on what options
-/// it was opened with. Files also implement `Seek` to alter the logical cursor
-/// that the file contains internally.
-///
-/// # Examples
-///
-/// ```no_run
-/// use std::io::prelude::*;
-/// use std::fs::File;
-///
-/// # fn foo() -> std::io::Result<()> {
-/// let mut f = try!(File::create("foo.txt"));
-/// try!(f.write_all(b"Hello, world!"));
-///
-/// let mut f = try!(File::open("foo.txt"));
-/// let mut s = String::new();
-/// try!(f.read_to_string(&mut s));
-/// assert_eq!(s, "Hello, world!");
-/// # Ok(())
-/// # }
-/// ```
-#[stable(feature = "rust1", since = "1.0.0")]
-pub struct File {
- inner: fs_imp::File,
- path: PathBuf,
-}
-
-/// Metadata information about a 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.
-///
-/// This iterator is returned from the `read_dir` function of this module and
-/// will yield instances of `io::Result<DirEntry>`. Through a `DirEntry`
-/// information like the entry's path and possibly other metadata can be
-/// learned.
-///
-/// # Failure
-///
-/// This `io::Result` will be an `Err` if there's some sort of intermittent
-/// IO error during iteration.
-#[stable(feature = "rust1", since = "1.0.0")]
-pub struct ReadDir(fs_imp::ReadDir);
-
-/// Entries returned by the `ReadDir` iterator.
-///
-/// 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>>,
-}
-
-/// Options and flags which can be used to configure how a file is opened.
-///
-/// This builder exposes the ability to configure how a `File` is opened and
-/// what operations are permitted on the open file. The `File::open` and
-/// `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.
-///
-/// This module only currently provides one bit of information, `readonly`,
-/// which is exposed on all currently supported platforms. Unix-specific
-/// 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 {
- /// Attempts to open a file in read-only mode.
- ///
- /// See the `OpenOptions::open` method for more details.
- ///
- /// # Errors
- ///
- /// This function will return an error if `path` does not already exist.
- /// Other errors may also be returned according to `OpenOptions::open`.
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::fs::File;
- ///
- /// # fn foo() -> std::io::Result<()> {
- /// let mut f = try!(File::open("foo.txt"));
- /// # Ok(())
- /// # }
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- pub fn open<P: AsRef<Path>>(path: P) -> io::Result<File> {
- OpenOptions::new().read(true).open(path)
- }
-
- /// Open a file in write-only mode.
- ///
- /// This function will create a file if it does not exist,
- /// and will truncate it if it does.
- ///
- /// See the `OpenOptions::open` function for more details.
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::fs::File;
- ///
- /// # fn foo() -> std::io::Result<()> {
- /// let mut f = try!(File::create("foo.txt"));
- /// # Ok(())
- /// # }
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- pub fn create<P: AsRef<Path>>(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)
- }
-
- /// Attempt to sync all OS-internal metadata to disk.
- ///
- /// This function will attempt to ensure that all in-core data reaches the
- /// filesystem before returning.
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::fs::File;
- /// use std::io::prelude::*;
- ///
- /// # fn foo() -> std::io::Result<()> {
- /// let mut f = try!(File::create("foo.txt"));
- /// try!(f.write_all(b"Hello, world!"));
- ///
- /// try!(f.sync_all());
- /// # Ok(())
- /// # }
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- pub fn sync_all(&self) -> io::Result<()> {
- self.inner.fsync()
- }
-
- /// This function is similar to `sync_all`, except that it may not
- /// synchronize file metadata to the filesystem.
- ///
- /// This is intended for use cases that must synchronize content, but don't
- /// need the metadata on disk. The goal of this method is to reduce disk
- /// operations.
- ///
- /// Note that some platforms may simply implement this in terms of
- /// `sync_all`.
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::fs::File;
- /// use std::io::prelude::*;
- ///
- /// # fn foo() -> std::io::Result<()> {
- /// let mut f = try!(File::create("foo.txt"));
- /// try!(f.write_all(b"Hello, world!"));
- ///
- /// try!(f.sync_data());
- /// # Ok(())
- /// # }
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- pub fn sync_data(&self) -> io::Result<()> {
- self.inner.datasync()
- }
-
- /// Truncates or extends the underlying file, updating the size of
- /// this file to become `size`.
- ///
- /// If the `size` is less than the current file's size, then the file will
- /// 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.
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::fs::File;
- ///
- /// # fn foo() -> std::io::Result<()> {
- /// let mut f = try!(File::open("foo.txt"));
- /// try!(f.set_len(0));
- /// # Ok(())
- /// # }
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- pub fn set_len(&self, size: u64) -> io::Result<()> {
- self.inner.truncate(size)
- }
-
- /// Queries metadata about the underlying file.
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::fs::File;
- ///
- /// # fn foo() -> std::io::Result<()> {
- /// let mut f = try!(File::open("foo.txt"));
- /// let metadata = try!(f.metadata());
- /// # Ok(())
- /// # }
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- pub fn metadata(&self) -> io::Result<Metadata> {
- self.inner.file_attr().map(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)
- }
-}
-
-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())
- }
-
- /// Set the option for read access.
- ///
- /// 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
- }
-
- /// Set the option for write access.
- ///
- /// 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
- }
-
- /// Set the option for the append mode.
- ///
- /// 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
- }
-
- /// Set the option for truncating a previous file.
- ///
- /// 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
- }
-
- /// Set the option for creating a new file.
- ///
- /// 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
- }
-
- /// Open a file at `path` with the options specified by `self`.
- ///
- /// # Errors
- ///
- /// This function will return an error under a number of different
- /// circumstances, to include but not limited to:
- ///
- /// * Opening a file that does not exist with read access.
- /// * 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: AsRef<Path>>(&self, path: P) -> io::Result<File> {
- let path = path.as_ref();
- let inner = try!(fs_imp::File::open(path, &self.0));
- 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())
- }
-
- /// 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)
- }
-}
-
-impl FromInner<fs_imp::FilePermissions> for Permissions {
- fn from_inner(f: fs_imp::FilePermissions) -> Permissions {
- Permissions(f)
- }
-}
-
-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>;
-
- fn next(&mut self) -> Option<io::Result<DirEntry>> {
- self.0.next().map(|entry| entry.map(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() }
-}
-
-/// Remove a file from the underlying filesystem.
-///
-/// # Examples
-///
-/// ```rust,no_run
-/// use std::fs;
-///
-/// fs::remove_file("/some/file/path.txt");
-/// ```
-///
-/// Note that, just because an unlink call was successful, it is not
-/// guaranteed that a file is immediately deleted (e.g. depending on
-/// platform, other open file descriptors may prevent immediate removal).
-///
-/// # Errors
-///
-/// 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: AsRef<Path>>(path: P) -> io::Result<()> {
- fs_imp::unlink(path.as_ref())
-}
-
-/// Given a path, query the file system to get information about a file,
-/// directory, etc.
-///
-/// This function will traverse soft links to query information about the
-/// destination file.
-///
-/// # Examples
-///
-/// ```rust,no_run
-/// # fn foo() -> std::io::Result<()> {
-/// use std::fs;
-///
-/// let attr = try!(fs::metadata("/some/file/path.txt"));
-/// // inspect attr ...
-/// # Ok(())
-/// # }
-/// ```
-///
-/// # Errors
-///
-/// 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: AsRef<Path>>(path: P) -> io::Result<Metadata> {
- fs_imp::stat(path.as_ref()).map(Metadata)
-}
-
-/// Rename a file or directory to a new name.
-///
-/// # Examples
-///
-/// ```rust,no_run
-/// use std::fs;
-///
-/// fs::rename("foo", "bar");
-/// ```
-///
-/// # Errors
-///
-/// This function will return an error if the provided `from` doesn't exist, if
-/// 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: AsRef<Path>, Q: AsRef<Path>>(from: P, to: Q) -> io::Result<()> {
- fs_imp::rename(from.as_ref(), to.as_ref())
-}
-
-/// Copies the contents of one file to another. This function will also
-/// copy the permission bits of the original file to the destination file.
-///
-/// This function will **overwrite** the contents of `to`.
-///
-/// Note that if `from` and `to` both point to the same file, then the file
-/// will likely get truncated by this operation.
-///
-/// # Examples
-///
-/// ```
-/// use std::fs;
-///
-/// fs::copy("foo.txt", "bar.txt");
-/// ```
-///
-/// # Errors
-///
-/// This function will return an error in the following situations, but is not
-/// limited to just these cases:
-///
-/// * The `from` path is not a file
-/// * 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: AsRef<Path>, Q: AsRef<Path>>(from: P, to: Q) -> io::Result<u64> {
- let from = from.as_ref();
- let to = to.as_ref();
- if !from.is_file() {
- return Err(Error::new(ErrorKind::InvalidInput,
- "the source path is not an existing file",
- None))
- }
-
- let mut reader = try!(File::open(from));
- let mut writer = try!(File::create(to));
- let perm = try!(reader.metadata()).permissions();
-
- let ret = try!(io::copy(&mut reader, &mut writer));
- try!(set_permissions(to, perm));
- Ok(ret)
-}
-
-/// Creates a new hard link on the filesystem.
-///
-/// 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: AsRef<Path>, Q: AsRef<Path>>(src: P, dst: Q) -> io::Result<()> {
- fs_imp::link(src.as_ref(), dst.as_ref())
-}
-
-/// 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: AsRef<Path>, Q: AsRef<Path>>(src: P, dst: Q) -> io::Result<()> {
- fs_imp::symlink(src.as_ref(), dst.as_ref())
-}
-
-/// Reads a soft link, returning the file that the link points to.
-///
-/// # Errors
-///
-/// 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: AsRef<Path>>(path: P) -> io::Result<PathBuf> {
- fs_imp::readlink(path.as_ref())
-}
-
-/// Create a new, empty directory at the provided path
-///
-/// # Examples
-///
-/// ```
-/// use std::fs;
-///
-/// fs::create_dir("/some/dir");
-/// ```
-///
-/// # Errors
-///
-/// 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: AsRef<Path>>(path: P) -> io::Result<()> {
- fs_imp::mkdir(path.as_ref())
-}
-
-/// Recursively create a directory and all of its parent components if they
-/// are missing.
-///
-/// # Errors
-///
-/// This function will fail if any directory in the path specified by `path`
-/// 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: AsRef<Path>>(path: P) -> io::Result<()> {
- let path = path.as_ref();
- if path == Path::new("") || path.is_dir() { return Ok(()) }
- if let Some(p) = path.parent() { try!(create_dir_all(p)) }
- create_dir(path)
-}
-
-/// Remove an existing, empty directory
-///
-/// # Examples
-///
-/// ```
-/// use std::fs;
-///
-/// fs::remove_dir("/some/dir");
-/// ```
-///
-/// # Errors
-///
-/// 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: AsRef<Path>>(path: P) -> io::Result<()> {
- fs_imp::rmdir(path.as_ref())
-}
-
-/// Removes a directory at this path, after removing all its contents. Use
-/// carefully!
-///
-/// This function does **not** follow soft links and it will simply remove the
-/// soft link itself.
-///
-/// # Errors
-///
-/// See `file::remove_file` and `fs::remove_dir`
-#[stable(feature = "rust1", since = "1.0.0")]
-pub fn remove_dir_all<P: AsRef<Path>>(path: P) -> io::Result<()> {
- let path = path.as_ref();
- for child in try!(read_dir(path)) {
- let child = try!(child).path();
- let stat = try!(lstat(&*child));
- if stat.is_dir() {
- try!(remove_dir_all(&*child));
- } else {
- try!(remove_file(&*child));
- }
- }
- return remove_dir(path);
-
- #[cfg(unix)]
- fn lstat(path: &Path) -> io::Result<fs_imp::FileAttr> { fs_imp::lstat(path) }
- #[cfg(windows)]
- fn lstat(path: &Path) -> io::Result<fs_imp::FileAttr> { fs_imp::stat(path) }
-}
-
-/// Returns an iterator over the entries within a directory.
-///
-/// The iterator will yield instances of `io::Result<DirEntry>`. New errors may
-/// be encountered after an iterator is initially constructed.
-///
-/// # Examples
-///
-/// ```
-/// # #![feature(path_ext)]
-/// use std::io;
-/// use std::fs::{self, PathExt, DirEntry};
-/// use std::path::Path;
-///
-/// // one possible implementation of fs::walk_dir only visiting files
-/// fn visit_dirs(dir: &Path, cb: &mut FnMut(DirEntry)) -> io::Result<()> {
-/// if dir.is_dir() {
-/// for entry in try!(fs::read_dir(dir)) {
-/// let entry = try!(entry);
-/// if entry.path().is_dir() {
-/// try!(visit_dirs(&entry.path(), cb));
-/// } else {
-/// cb(entry);
-/// }
-/// }
-/// }
-/// Ok(())
-/// }
-/// ```
-///
-/// # Errors
-///
-/// 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: AsRef<Path>>(path: P) -> io::Result<ReadDir> {
- fs_imp::readdir(path.as_ref()).map(ReadDir)
-}
-
-/// Returns an iterator that will recursively walk the directory structure
-/// rooted at `path`.
-///
-/// The path given will not be iterated over, and this will perform iteration in
-/// some top-down order. The contents of unreadable subdirectories are ignored.
-///
-/// 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: AsRef<Path>>(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>;
-
- fn next(&mut self) -> Option<io::Result<DirEntry>> {
- loop {
- if let Some(ref mut cur) = self.cur {
- match cur.next() {
- Some(Err(e)) => return Some(Err(e)),
- Some(Ok(next)) => {
- let path = next.path();
- if path.is_dir() {
- self.stack.push(read_dir(&*path));
- }
- return Some(Ok(next))
- }
- None => {}
- }
- }
- self.cur = None;
- match self.stack.pop() {
- Some(Err(e)) => return Some(Err(e)),
- Some(Ok(next)) => self.cur = Some(next),
- None => return None,
- }
- }
- }
-}
-
-/// 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.
- ///
- /// Consult the `fs::stat` documentation for more info.
- ///
- /// This call preserves identical runtime/error semantics with `file::stat`.
- fn metadata(&self) -> io::Result<Metadata>;
-
- /// Boolean value indicator whether the underlying file exists on the local
- /// filesystem. Returns false in exactly the cases where `fs::stat` fails.
- fn exists(&self) -> bool;
-
- /// Whether the underlying implementation (be it a file path, or something
- /// else) points at a "regular file" on the FS. Will return false for paths
- /// to non-existent locations or directories or other non-regular files
- /// (named pipes, etc). Follows links when making this determination.
- fn is_file(&self) -> bool;
-
- /// Whether the underlying implementation (be it a file path, or something
- /// else) is pointing at a directory in the underlying FS. Will return
- /// false for paths to non-existent locations or if the item is not a
- /// directory (eg files, named pipes, etc). Follows links when making this
- /// determination.
- fn is_dir(&self) -> bool;
-}
-
-impl PathExt for Path {
- fn metadata(&self) -> io::Result<Metadata> { metadata(self) }
-
- fn exists(&self) -> bool { metadata(self).is_ok() }
-
- fn is_file(&self) -> bool {
- metadata(self).map(|s| s.is_file()).unwrap_or(false)
- }
- fn is_dir(&self) -> bool {
- metadata(self).map(|s| s.is_dir()).unwrap_or(false)
- }
-}
-
-/// Changes the timestamps for a file's last modification and access time.
-///
-/// 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: AsRef<Path>>(path: P, accessed: u64,
- modified: u64) -> io::Result<()> {
- fs_imp::utimes(path.as_ref(), accessed, modified)
-}
-
-/// Changes the permissions found on a file or a directory.
-///
-/// # Examples
-///
-/// ```
-/// # #![feature(fs)]
-/// # fn foo() -> std::io::Result<()> {
-/// use std::fs;
-///
-/// let mut perms = try!(fs::metadata("foo.txt")).permissions();
-/// perms.set_readonly(true);
-/// try!(fs::set_permissions("foo.txt", perms));
-/// # Ok(())
-/// # }
-/// ```
-///
-/// # Errors
-///
-/// 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: AsRef<Path>>(path: P, perm: Permissions) -> io::Result<()> {
- fs_imp::set_perm(path.as_ref(), perm.0)
-}
-
-#[cfg(test)]
-mod tests {
- #![allow(deprecated)] //rand
-
- use prelude::v1::*;
- use io::prelude::*;
-
- use env;
- use fs::{self, File, OpenOptions};
- use io::{ErrorKind, SeekFrom};
- use path::PathBuf;
- use path::Path as Path2;
- use os;
- use rand::{self, StdRng, Rng};
- use str;
-
- macro_rules! check { ($e:expr) => (
- match $e {
- Ok(t) => t,
- Err(e) => panic!("{} failed with: {}", stringify!($e), e),
- }
- ) }
-
- macro_rules! error { ($e:expr, $s:expr) => (
- match $e {
- Ok(_) => panic!("Unexpected success. Should've been: {:?}", $s),
- Err(ref err) => assert!(err.to_string().contains($s),
- format!("`{}` did not contain `{}`", err, $s))
- }
- ) }
-
- pub struct TempDir(PathBuf);
-
- impl TempDir {
- fn join(&self, path: &str) -> PathBuf {
- let TempDir(ref p) = *self;
- p.join(path)
- }
-
- fn path<'a>(&'a self) -> &'a Path2 {
- let TempDir(ref p) = *self;
- p
- }
- }
-
- impl Drop for TempDir {
- fn drop(&mut self) {
- // Gee, seeing how we're testing the fs module I sure hope that we
- // at least implement this correctly!
- let TempDir(ref p) = *self;
- check!(fs::remove_dir_all(p));
- }
- }
-
- pub fn tmpdir() -> TempDir {
- let p = env::temp_dir();
- let ret = p.join(&format!("rust-{}", rand::random::<u32>()));
- check!(fs::create_dir(&ret));
- TempDir(ret)
- }
-
- #[test]
- fn file_test_io_smoke_test() {
- let message = "it's alright. have a good time";
- let tmpdir = tmpdir();
- let filename = &tmpdir.join("file_rt_io_file_test.txt");
- {
- let mut write_stream = check!(File::create(filename));
- check!(write_stream.write(message.as_bytes()));
- }
- {
- let mut read_stream = check!(File::open(filename));
- let mut read_buf = [0; 1028];
- let read_str = match check!(read_stream.read(&mut read_buf)) {
- -1|0 => panic!("shouldn't happen"),
- n => str::from_utf8(&read_buf[..n]).unwrap().to_string()
- };
- assert_eq!(read_str, message);
- }
- check!(fs::remove_file(filename));
- }
-
- #[test]
- fn invalid_path_raises() {
- let tmpdir = tmpdir();
- let filename = &tmpdir.join("file_that_does_not_exist.txt");
- let result = File::open(filename);
-
- if cfg!(unix) {
- error!(result, "o such file or directory");
- }
- // error!(result, "couldn't open path as file");
- // error!(result, format!("path={}; mode=open; access=read", filename.display()));
- }
-
- #[test]
- fn file_test_iounlinking_invalid_path_should_raise_condition() {
- let tmpdir = tmpdir();
- let filename = &tmpdir.join("file_another_file_that_does_not_exist.txt");
-
- let result = fs::remove_file(filename);
-
- if cfg!(unix) {
- error!(result, "o such file or directory");
- }
- // error!(result, "couldn't unlink path");
- // error!(result, format!("path={}", filename.display()));
- }
-
- #[test]
- fn file_test_io_non_positional_read() {
- let message: &str = "ten-four";
- let mut read_mem = [0; 8];
- let tmpdir = tmpdir();
- let filename = &tmpdir.join("file_rt_io_file_test_positional.txt");
- {
- let mut rw_stream = check!(File::create(filename));
- check!(rw_stream.write(message.as_bytes()));
- }
- {
- let mut read_stream = check!(File::open(filename));
- {
- let read_buf = &mut read_mem[0..4];
- check!(read_stream.read(read_buf));
- }
- {
- let read_buf = &mut read_mem[4..8];
- check!(read_stream.read(read_buf));
- }
- }
- check!(fs::remove_file(filename));
- let read_str = str::from_utf8(&read_mem).unwrap();
- assert_eq!(read_str, message);
- }
-
- #[test]
- fn file_test_io_seek_and_tell_smoke_test() {
- let message = "ten-four";
- let mut read_mem = [0; 4];
- let set_cursor = 4 as u64;
- let mut tell_pos_pre_read;
- let mut tell_pos_post_read;
- let tmpdir = tmpdir();
- let filename = &tmpdir.join("file_rt_io_file_test_seeking.txt");
- {
- let mut rw_stream = check!(File::create(filename));
- check!(rw_stream.write(message.as_bytes()));
- }
- {
- let mut read_stream = check!(File::open(filename));
- check!(read_stream.seek(SeekFrom::Start(set_cursor)));
- tell_pos_pre_read = check!(read_stream.seek(SeekFrom::Current(0)));
- check!(read_stream.read(&mut read_mem));
- tell_pos_post_read = check!(read_stream.seek(SeekFrom::Current(0)));
- }
- check!(fs::remove_file(filename));
- let read_str = str::from_utf8(&read_mem).unwrap();
- assert_eq!(read_str, &message[4..8]);
- assert_eq!(tell_pos_pre_read, set_cursor);
- assert_eq!(tell_pos_post_read, message.len() as u64);
- }
-
- #[test]
- fn file_test_io_seek_and_write() {
- let initial_msg = "food-is-yummy";
- let overwrite_msg = "-the-bar!!";
- let final_msg = "foo-the-bar!!";
- let seek_idx = 3;
- let mut read_mem = [0; 13];
- let tmpdir = tmpdir();
- let filename = &tmpdir.join("file_rt_io_file_test_seek_and_write.txt");
- {
- let mut rw_stream = check!(File::create(filename));
- check!(rw_stream.write(initial_msg.as_bytes()));
- check!(rw_stream.seek(SeekFrom::Start(seek_idx)));
- check!(rw_stream.write(overwrite_msg.as_bytes()));
- }
- {
- let mut read_stream = check!(File::open(filename));
- check!(read_stream.read(&mut read_mem));
- }
- check!(fs::remove_file(filename));
- let read_str = str::from_utf8(&read_mem).unwrap();
- assert!(read_str == final_msg);
- }
-
- #[test]
- fn file_test_io_seek_shakedown() {
- // 01234567890123
- let initial_msg = "qwer-asdf-zxcv";
- let chunk_one: &str = "qwer";
- let chunk_two: &str = "asdf";
- let chunk_three: &str = "zxcv";
- let mut read_mem = [0; 4];
- let tmpdir = tmpdir();
- let filename = &tmpdir.join("file_rt_io_file_test_seek_shakedown.txt");
- {
- let mut rw_stream = check!(File::create(filename));
- check!(rw_stream.write(initial_msg.as_bytes()));
- }
- {
- let mut read_stream = check!(File::open(filename));
-
- check!(read_stream.seek(SeekFrom::End(-4)));
- check!(read_stream.read(&mut read_mem));
- assert_eq!(str::from_utf8(&read_mem).unwrap(), chunk_three);
-
- check!(read_stream.seek(SeekFrom::Current(-9)));
- check!(read_stream.read(&mut read_mem));
- assert_eq!(str::from_utf8(&read_mem).unwrap(), chunk_two);
-
- check!(read_stream.seek(SeekFrom::Start(0)));
- check!(read_stream.read(&mut read_mem));
- assert_eq!(str::from_utf8(&read_mem).unwrap(), chunk_one);
- }
- check!(fs::remove_file(filename));
- }
-
- #[test]
- fn file_test_stat_is_correct_on_is_file() {
- let tmpdir = tmpdir();
- let filename = &tmpdir.join("file_stat_correct_on_is_file.txt");
- {
- let mut opts = OpenOptions::new();
- let mut fs = check!(opts.read(true).write(true)
- .create(true).open(filename));
- let msg = "hw";
- fs.write(msg.as_bytes()).unwrap();
-
- let fstat_res = check!(fs.metadata());
- assert!(fstat_res.is_file());
- }
- let stat_res_fn = check!(fs::metadata(filename));
- assert!(stat_res_fn.is_file());
- let stat_res_meth = check!(filename.metadata());
- assert!(stat_res_meth.is_file());
- check!(fs::remove_file(filename));
- }
-
- #[test]
- fn file_test_stat_is_correct_on_is_dir() {
- let tmpdir = tmpdir();
- let filename = &tmpdir.join("file_stat_correct_on_is_dir");
- check!(fs::create_dir(filename));
- let stat_res_fn = check!(fs::metadata(filename));
- assert!(stat_res_fn.is_dir());
- let stat_res_meth = check!(filename.metadata());
- assert!(stat_res_meth.is_dir());
- check!(fs::remove_dir(filename));
- }
-
- #[test]
- fn file_test_fileinfo_false_when_checking_is_file_on_a_directory() {
- let tmpdir = tmpdir();
- let dir = &tmpdir.join("fileinfo_false_on_dir");
- check!(fs::create_dir(dir));
- assert!(dir.is_file() == false);
- check!(fs::remove_dir(dir));
- }
-
- #[test]
- fn file_test_fileinfo_check_exists_before_and_after_file_creation() {
- let tmpdir = tmpdir();
- let file = &tmpdir.join("fileinfo_check_exists_b_and_a.txt");
- check!(check!(File::create(file)).write(b"foo"));
- assert!(file.exists());
- check!(fs::remove_file(file));
- assert!(!file.exists());
- }
-
- #[test]
- fn file_test_directoryinfo_check_exists_before_and_after_mkdir() {
- let tmpdir = tmpdir();
- let dir = &tmpdir.join("before_and_after_dir");
- assert!(!dir.exists());
- check!(fs::create_dir(dir));
- assert!(dir.exists());
- assert!(dir.is_dir());
- check!(fs::remove_dir(dir));
- assert!(!dir.exists());
- }
-
- #[test]
- fn file_test_directoryinfo_readdir() {
- let tmpdir = tmpdir();
- let dir = &tmpdir.join("di_readdir");
- check!(fs::create_dir(dir));
- let prefix = "foo";
- for n in 0..3 {
- let f = dir.join(&format!("{}.txt", n));
- let mut w = check!(File::create(&f));
- let msg_str = format!("{}{}", prefix, n.to_string());
- let msg = msg_str.as_bytes();
- check!(w.write(msg));
- }
- let files = check!(fs::read_dir(dir));
- let mut mem = [0; 4];
- for f in files {
- let f = f.unwrap().path();
- {
- let n = f.file_stem().unwrap();
- check!(check!(File::open(&f)).read(&mut mem));
- let read_str = str::from_utf8(&mem).unwrap();
- let expected = format!("{}{}", prefix, n.to_str().unwrap());
- assert_eq!(expected, read_str);
- }
- check!(fs::remove_file(&f));
- }
- check!(fs::remove_dir(dir));
- }
-
- #[test]
- fn file_test_walk_dir() {
- let tmpdir = tmpdir();
- let dir = &tmpdir.join("walk_dir");
- check!(fs::create_dir(dir));
-
- let dir1 = &dir.join("01/02/03");
- check!(fs::create_dir_all(dir1));
- check!(File::create(&dir1.join("04")));
-
- let dir2 = &dir.join("11/12/13");
- check!(fs::create_dir_all(dir2));
- check!(File::create(&dir2.join("14")));
-
- let files = check!(fs::walk_dir(dir));
- let mut cur = [0; 2];
- for f in files {
- let f = f.unwrap().path();
- let stem = f.file_stem().unwrap().to_str().unwrap();
- let root = stem.as_bytes()[0] - b'0';
- let name = stem.as_bytes()[1] - b'0';
- assert!(cur[root as usize] < name);
- cur[root as usize] = name;
- }
-
- check!(fs::remove_dir_all(dir));
- }
-
- #[test]
- fn mkdir_path_already_exists_error() {
- let tmpdir = tmpdir();
- let dir = &tmpdir.join("mkdir_error_twice");
- check!(fs::create_dir(dir));
- let e = fs::create_dir(dir).err().unwrap();
- assert_eq!(e.kind(), ErrorKind::AlreadyExists);
- }
-
- #[test]
- fn recursive_mkdir() {
- let tmpdir = tmpdir();
- let dir = tmpdir.join("d1/d2");
- check!(fs::create_dir_all(&dir));
- assert!(dir.is_dir())
- }
-
- #[test]
- fn recursive_mkdir_failure() {
- let tmpdir = tmpdir();
- let dir = tmpdir.join("d1");
- let file = dir.join("f1");
-
- check!(fs::create_dir_all(&dir));
- check!(File::create(&file));
-
- let result = fs::create_dir_all(&file);
-
- assert!(result.is_err());
- // error!(result, "couldn't recursively mkdir");
- // error!(result, "couldn't create directory");
- // error!(result, "mode=0700");
- // error!(result, format!("path={}", file.display()));
- }
-
- #[test]
- fn recursive_mkdir_slash() {
- check!(fs::create_dir_all(&Path2::new("/")));
- }
-
- // FIXME(#12795) depends on lstat to work on windows
- #[cfg(not(windows))]
- #[test]
- fn recursive_rmdir() {
- let tmpdir = tmpdir();
- let d1 = tmpdir.join("d1");
- let dt = d1.join("t");
- let dtt = dt.join("t");
- let d2 = tmpdir.join("d2");
- let canary = d2.join("do_not_delete");
- check!(fs::create_dir_all(&dtt));
- check!(fs::create_dir_all(&d2));
- check!(check!(File::create(&canary)).write(b"foo"));
- check!(fs::soft_link(&d2, &dt.join("d2")));
- check!(fs::remove_dir_all(&d1));
-
- assert!(!d1.is_dir());
- assert!(canary.exists());
- }
-
- #[test]
- fn unicode_path_is_dir() {
- assert!(Path2::new(".").is_dir());
- assert!(!Path2::new("test/stdtest/fs.rs").is_dir());
-
- let tmpdir = tmpdir();
-
- let mut dirpath = tmpdir.path().to_path_buf();
- dirpath.push(&format!("test-가一ー你好"));
- check!(fs::create_dir(&dirpath));
- assert!(dirpath.is_dir());
-
- let mut filepath = dirpath;
- filepath.push("unicode-file-\u{ac00}\u{4e00}\u{30fc}\u{4f60}\u{597d}.rs");
- check!(File::create(&filepath)); // ignore return; touch only
- assert!(!filepath.is_dir());
- assert!(filepath.exists());
- }
-
- #[test]
- fn unicode_path_exists() {
- assert!(Path2::new(".").exists());
- assert!(!Path2::new("test/nonexistent-bogus-path").exists());
-
- let tmpdir = tmpdir();
- let unicode = tmpdir.path();
- let unicode = unicode.join(&format!("test-각丁ー再见"));
- check!(fs::create_dir(&unicode));
- assert!(unicode.exists());
- assert!(!Path2::new("test/unicode-bogus-path-각丁ー再见").exists());
- }
-
- #[test]
- fn copy_file_does_not_exist() {
- let from = Path2::new("test/nonexistent-bogus-path");
- let to = Path2::new("test/other-bogus-path");
-
- match fs::copy(&from, &to) {
- Ok(..) => panic!(),
- Err(..) => {
- assert!(!from.exists());
- assert!(!to.exists());
- }
- }
- }
-
- #[test]
- fn copy_file_ok() {
- let tmpdir = tmpdir();
- let input = tmpdir.join("in.txt");
- let out = tmpdir.join("out.txt");
-
- check!(check!(File::create(&input)).write(b"hello"));
- check!(fs::copy(&input, &out));
- let mut v = Vec::new();
- check!(check!(File::open(&out)).read_to_end(&mut v));
- assert_eq!(v.as_slice(), b"hello");
-
- assert_eq!(check!(input.metadata()).permissions(),
- check!(out.metadata()).permissions());
- }
-
- #[test]
- fn copy_file_dst_dir() {
- let tmpdir = tmpdir();
- let out = tmpdir.join("out");
-
- check!(File::create(&out));
- match fs::copy(&*out, tmpdir.path()) {
- Ok(..) => panic!(), Err(..) => {}
- }
- }
-
- #[test]
- fn copy_file_dst_exists() {
- let tmpdir = tmpdir();
- let input = tmpdir.join("in");
- let output = tmpdir.join("out");
-
- check!(check!(File::create(&input)).write("foo".as_bytes()));
- check!(check!(File::create(&output)).write("bar".as_bytes()));
- check!(fs::copy(&input, &output));
-
- let mut v = Vec::new();
- check!(check!(File::open(&output)).read_to_end(&mut v));
- assert_eq!(v, b"foo".to_vec());
- }
-
- #[test]
- fn copy_file_src_dir() {
- let tmpdir = tmpdir();
- let out = tmpdir.join("out");
-
- match fs::copy(tmpdir.path(), &out) {
- Ok(..) => panic!(), Err(..) => {}
- }
- assert!(!out.exists());
- }
-
- #[test]
- fn copy_file_preserves_perm_bits() {
- let tmpdir = tmpdir();
- let input = tmpdir.join("in.txt");
- let out = tmpdir.join("out.txt");
-
- let attr = check!(check!(File::create(&input)).metadata());
- let mut p = attr.permissions();
- p.set_readonly(true);
- 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?
- #[test]
- fn symlinks_work() {
- let tmpdir = tmpdir();
- let input = tmpdir.join("in.txt");
- let out = tmpdir.join("out.txt");
-
- check!(check!(File::create(&input)).write("foobar".as_bytes()));
- check!(fs::soft_link(&input, &out));
- // if cfg!(not(windows)) {
- // assert_eq!(check!(lstat(&out)).kind, FileType::Symlink);
- // assert_eq!(check!(out.lstat()).kind, FileType::Symlink);
- // }
- assert_eq!(check!(fs::metadata(&out)).len(),
- check!(fs::metadata(&input)).len());
- let mut v = Vec::new();
- check!(check!(File::open(&out)).read_to_end(&mut v));
- assert_eq!(v, b"foobar".to_vec());
- }
-
- #[cfg(not(windows))] // apparently windows doesn't like symlinks
- #[test]
- fn symlink_noexist() {
- let tmpdir = tmpdir();
- // symlinks can point to things that don't exist
- check!(fs::soft_link(&tmpdir.join("foo"), &tmpdir.join("bar")));
- assert_eq!(check!(fs::read_link(&tmpdir.join("bar"))),
- tmpdir.join("foo"));
- }
-
- #[test]
- fn readlink_not_symlink() {
- let tmpdir = tmpdir();
- match fs::read_link(tmpdir.path()) {
- Ok(..) => panic!("wanted a failure"),
- Err(..) => {}
- }
- }
-
- #[test]
- fn links_work() {
- let tmpdir = tmpdir();
- let input = tmpdir.join("in.txt");
- let out = tmpdir.join("out.txt");
-
- check!(check!(File::create(&input)).write("foobar".as_bytes()));
- check!(fs::hard_link(&input, &out));
- assert_eq!(check!(fs::metadata(&out)).len(),
- check!(fs::metadata(&input)).len());
- assert_eq!(check!(fs::metadata(&out)).len(),
- check!(input.metadata()).len());
- let mut v = Vec::new();
- check!(check!(File::open(&out)).read_to_end(&mut v));
- assert_eq!(v, b"foobar".to_vec());
-
- // can't link to yourself
- match fs::hard_link(&input, &input) {
- Ok(..) => panic!("wanted a failure"),
- Err(..) => {}
- }
- // can't link to something that doesn't exist
- match fs::hard_link(&tmpdir.join("foo"), &tmpdir.join("bar")) {
- Ok(..) => panic!("wanted a failure"),
- Err(..) => {}
- }
- }
-
- #[test]
- fn chmod_works() {
- let tmpdir = tmpdir();
- let file = tmpdir.join("in.txt");
-
- check!(File::create(&file));
- let attr = check!(fs::metadata(&file));
- assert!(!attr.permissions().readonly());
- let mut p = attr.permissions();
- p.set_readonly(true);
- check!(fs::set_permissions(&file, p.clone()));
- let attr = check!(fs::metadata(&file));
- assert!(attr.permissions().readonly());
-
- 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]
- fn sync_doesnt_kill_anything() {
- let tmpdir = tmpdir();
- let path = tmpdir.join("in.txt");
-
- let mut file = check!(File::create(&path));
- check!(file.sync_all());
- check!(file.sync_data());
- check!(file.write(b"foo"));
- check!(file.sync_all());
- check!(file.sync_data());
- }
-
- #[test]
- fn truncate_works() {
- let tmpdir = tmpdir();
- let path = tmpdir.join("in.txt");
-
- let mut file = check!(File::create(&path));
- check!(file.write(b"foo"));
- check!(file.sync_all());
-
- // Do some simple things with truncation
- assert_eq!(check!(file.metadata()).len(), 3);
- check!(file.set_len(10));
- assert_eq!(check!(file.metadata()).len(), 10);
- check!(file.write(b"bar"));
- check!(file.sync_all());
- assert_eq!(check!(file.metadata()).len(), 10);
-
- let mut v = Vec::new();
- check!(check!(File::open(&path)).read_to_end(&mut v));
- assert_eq!(v, b"foobar\0\0\0\0".to_vec());
-
- // Truncate to a smaller length, don't seek, and then write something.
- // Ensure that the intermediate zeroes are all filled in (we have `seek`ed
- // past the end of the file).
- check!(file.set_len(2));
- assert_eq!(check!(file.metadata()).len(), 2);
- check!(file.write(b"wut"));
- check!(file.sync_all());
- assert_eq!(check!(file.metadata()).len(), 9);
- let mut v = Vec::new();
- check!(check!(File::open(&path)).read_to_end(&mut v));
- assert_eq!(v, b"fo\0\0\0\0wut".to_vec());
- }
-
- #[test]
- fn open_flavors() {
- use fs::OpenOptions as OO;
- fn c<T: Clone>(t: &T) -> T { t.clone() }
-
- let tmpdir = tmpdir();
-
- let mut r = OO::new(); r.read(true);
- let mut w = OO::new(); w.write(true);
- let mut rw = OO::new(); rw.write(true).read(true);
-
- match r.open(&tmpdir.join("a")) {
- Ok(..) => panic!(), Err(..) => {}
- }
-
- // Perform each one twice to make sure that it succeeds the second time
- // (where the file exists)
- check!(c(&w).create(true).open(&tmpdir.join("b")));
- assert!(tmpdir.join("b").exists());
- check!(c(&w).create(true).open(&tmpdir.join("b")));
- check!(w.open(&tmpdir.join("b")));
-
- check!(c(&rw).create(true).open(&tmpdir.join("c")));
- assert!(tmpdir.join("c").exists());
- check!(c(&rw).create(true).open(&tmpdir.join("c")));
- check!(rw.open(&tmpdir.join("c")));
-
- check!(c(&w).append(true).create(true).open(&tmpdir.join("d")));
- assert!(tmpdir.join("d").exists());
- check!(c(&w).append(true).create(true).open(&tmpdir.join("d")));
- check!(c(&w).append(true).open(&tmpdir.join("d")));
-
- check!(c(&rw).append(true).create(true).open(&tmpdir.join("e")));
- assert!(tmpdir.join("e").exists());
- check!(c(&rw).append(true).create(true).open(&tmpdir.join("e")));
- check!(c(&rw).append(true).open(&tmpdir.join("e")));
-
- check!(c(&w).truncate(true).create(true).open(&tmpdir.join("f")));
- assert!(tmpdir.join("f").exists());
- check!(c(&w).truncate(true).create(true).open(&tmpdir.join("f")));
- check!(c(&w).truncate(true).open(&tmpdir.join("f")));
-
- check!(c(&rw).truncate(true).create(true).open(&tmpdir.join("g")));
- assert!(tmpdir.join("g").exists());
- check!(c(&rw).truncate(true).create(true).open(&tmpdir.join("g")));
- check!(c(&rw).truncate(true).open(&tmpdir.join("g")));
-
- check!(check!(File::create(&tmpdir.join("h"))).write("foo".as_bytes()));
- check!(r.open(&tmpdir.join("h")));
- {
- let mut f = check!(r.open(&tmpdir.join("h")));
- assert!(f.write("wut".as_bytes()).is_err());
- }
- assert_eq!(check!(fs::metadata(&tmpdir.join("h"))).len(), 3);
- {
- let mut f = check!(c(&w).append(true).open(&tmpdir.join("h")));
- check!(f.write("bar".as_bytes()));
- }
- assert_eq!(check!(fs::metadata(&tmpdir.join("h"))).len(), 6);
- {
- let mut f = check!(c(&w).truncate(true).open(&tmpdir.join("h")));
- check!(f.write("bar".as_bytes()));
- }
- assert_eq!(check!(fs::metadata(&tmpdir.join("h"))).len(), 3);
- }
-
- #[test]
- fn utime() {
- let tmpdir = tmpdir();
- let path = tmpdir.join("a");
- check!(File::create(&path));
- // These numbers have to be bigger than the time in the day to account
- // for timezones Windows in particular will fail in certain timezones
- // with small enough values
- check!(fs::set_file_times(&path, 100000, 200000));
- assert_eq!(check!(path.metadata()).accessed(), 100000);
- assert_eq!(check!(path.metadata()).modified(), 200000);
- }
-
- #[test]
- fn utime_noexist() {
- let tmpdir = tmpdir();
-
- match fs::set_file_times(&tmpdir.join("a"), 100, 200) {
- Ok(..) => panic!(),
- Err(..) => {}
- }
- }
-
- #[test]
- fn binary_file() {
- let mut bytes = [0; 1024];
- StdRng::new().unwrap().fill_bytes(&mut bytes);
-
- let tmpdir = tmpdir();
-
- check!(check!(File::create(&tmpdir.join("test"))).write(&bytes));
- let mut v = Vec::new();
- check!(check!(File::open(&tmpdir.join("test"))).read_to_end(&mut v));
- assert!(v == bytes.as_slice());
- }
-
- #[test]
- #[cfg(not(windows))]
- fn unlink_readonly() {
- let tmpdir = tmpdir();
- let path = tmpdir.join("file");
- check!(File::create(&path));
- let mut perm = check!(fs::metadata(&path)).permissions();
- perm.set_readonly(true);
- check!(fs::set_permissions(&path, perm));
- check!(fs::remove_file(&path));
- }
-
- #[test]
- fn mkdir_trailing_slash() {
- let tmpdir = tmpdir();
- let path = tmpdir.join("file");
- check!(fs::create_dir_all(&path.join("a/")));
- }
-}
+++ /dev/null
-// 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.
-
-#![unstable(feature = "tempdir", reason = "needs an RFC before stabilization")]
-#![deprecated(since = "1.0.0",
- reason = "use the `tempdir` crate from crates.io instead")]
-#![allow(deprecated)]
-
-use prelude::v1::*;
-
-use env;
-use io::{self, Error, ErrorKind};
-use fs;
-use path::{self, PathBuf};
-use 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: usize = 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: AsRef<path::Path>>(tmpdir: P, prefix: &str) -> io::Result<TempDir> {
- let storage;
- let mut tmpdir = tmpdir.as_ref();
- 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::AlreadyExists => {}
- Err(e) => return Err(e)
- }
- }
-
- Err(Error::new(ErrorKind::AlreadyExists,
- "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
use io::prelude::*;
use cmp;
-use error::{self, FromError};
+use error;
use fmt;
use io::{self, DEFAULT_BUF_SIZE, Error, ErrorKind};
use ptr;
}
#[stable(feature = "rust1", since = "1.0.0")]
-impl<W> FromError<IntoInnerError<W>> for Error {
- fn from_error(iie: IntoInnerError<W>) -> Error { iie.1 }
+impl<W> From<IntoInnerError<W>> for Error {
+ fn from(iie: IntoInnerError<W>) -> Error { iie.1 }
}
#[stable(feature = "rust1", since = "1.0.0")]
#[test]
fn test_slice_reader() {
let in_buf = vec![0, 1, 2, 3, 4, 5, 6, 7];
- let mut reader = &mut in_buf.as_slice();
+ let mut reader = &mut &in_buf[..];
let mut buf = [];
assert_eq!(reader.read(&mut buf), Ok(0));
let mut buf = [0];
assert_eq!(reader.read(&mut buf), Ok(1));
assert_eq!(reader.len(), 7);
let b: &[_] = &[0];
- assert_eq!(buf.as_slice(), b);
+ assert_eq!(&buf[..], b);
let mut buf = [0; 4];
assert_eq!(reader.read(&mut buf), Ok(4));
assert_eq!(reader.len(), 3);
let b: &[_] = &[1, 2, 3, 4];
- assert_eq!(buf.as_slice(), b);
+ assert_eq!(&buf[..], b);
assert_eq!(reader.read(&mut buf), Ok(3));
let b: &[_] = &[5, 6, 7];
assert_eq!(&buf[..3], b);
#[test]
fn test_buf_reader() {
let in_buf = vec![0, 1, 2, 3, 4, 5, 6, 7];
- let mut reader = Cursor::new(in_buf.as_slice());
+ let mut reader = Cursor::new(&in_buf[..]);
let mut buf = [];
assert_eq!(reader.read(&mut buf), Ok(0));
assert_eq!(reader.position(), 0);
// except according to those terms.
use boxed::Box;
-use clone::Clone;
use error;
use fmt;
use option::Option::{self, Some, None};
Repr::Custom(ref c) => c.kind,
}
}
-
- /// Returns a short description for this error message
- #[unstable(feature = "io")]
- #[deprecated(since = "1.0.0", reason = "use the Error trait's description \
- method instead")]
- pub fn description(&self) -> &str {
- match self.repr {
- Repr::Os(..) => "os error",
- Repr::Custom(ref c) => c.desc,
- }
- }
-
- /// Returns a detailed error message for this error (if one is available)
- #[unstable(feature = "io")]
- #[deprecated(since = "1.0.0", reason = "use the to_string() method instead")]
- pub fn detail(&self) -> Option<String> {
- match self.repr {
- Repr::Os(code) => Some(sys::os::error_string(code)),
- Repr::Custom(ref s) => s.detail.clone(),
- }
- }
}
#[stable(feature = "rust1", since = "1.0.0")]
///
/// The stream typically has a fixed size, allowing seeking relative to either
/// end or the current offset.
-#[unstable(feature = "io", reason = "the central `seek` method may be split \
- into multiple methods instead of taking \
- an enum as an argument")]
+#[stable(feature = "rust1", since = "1.0.0")]
pub trait Seek {
/// Seek to an offset, in bytes, in a stream
///
/// # Errors
///
/// Seeking to a negative offset is considered an error
+ #[stable(feature = "rust1", since = "1.0.0")]
fn seek(&mut self, pos: SeekFrom) -> Result<u64>;
}
/// Enumeration of possible methods to seek within an I/O object.
#[derive(Copy, PartialEq, Eq, Clone, Debug)]
-#[unstable(feature = "io", reason = "awaiting the stability of Seek")]
+#[stable(feature = "rust1", since = "1.0.0")]
pub enum SeekFrom {
/// Set the offset to the provided number of bytes.
+ #[stable(feature = "rust1", since = "1.0.0")]
Start(u64),
/// Set the offset to the size of this object plus the specified number of
///
/// It is possible to seek beyond the end of an object, but is an error to
/// seek before byte 0.
+ #[stable(feature = "rust1", since = "1.0.0")]
End(i64),
/// Set the offset to the current position plus the specified number of
///
/// It is possible to seek beyond the end of an object, but is an error to
/// seek before byte 0.
+ #[stable(feature = "rust1", since = "1.0.0")]
Current(i64),
}
//! lives in the [`vec`](vec/index.html) module. Contiguous, unsized regions
//! of memory, `[T]`, commonly called "slices", and their borrowed versions,
//! `&[T]`, commonly called "borrowed slices", are built-in types for which the
-//! for which the [`slice`](slice/index.html) module defines many methods.
+//! [`slice`](slice/index.html) module defines many methods.
//!
//! `&str`, a UTF-8 string, is a built-in type, and the standard library
//! defines methods for it on a variety of traits in the
#![feature(unsafe_no_drop_flag, filling_drop)]
#![feature(macro_reexport)]
#![feature(unique)]
-#![feature(convert)]
#![feature(allow_internal_unstable)]
#![feature(str_char)]
#![feature(into_cow)]
-#![feature(slice_patterns)]
#![feature(std_misc)]
+#![feature(slice_patterns)]
#![feature(debug_builders)]
#![cfg_attr(test, feature(test, rustc_private, std_misc))]
#[cfg(not(test))] pub use core::cmp;
pub use core::convert;
pub use core::default;
-#[allow(deprecated)]
-pub use core::finally;
pub use core::hash;
pub use core::intrinsics;
pub use core::iter;
($expr:expr) => (match $expr {
$crate::result::Result::Ok(val) => val,
$crate::result::Result::Err(err) => {
- return $crate::result::Result::Err($crate::error::FromError::from_error(err))
+ return $crate::result::Result::Err($crate::convert::From::from(err))
}
})
}
use io;
use net::{ToSocketAddrs, SocketAddr, Shutdown};
use sys_common::net2 as net_imp;
-use sys_common::AsInner;
+use sys_common::{AsInner, FromInner};
/// A structure which represents a TCP stream between a local socket and a
/// remote socket.
self.0.peer_addr()
}
- /// Returns the socket address of the local half of this TCP connection.
- #[unstable(feature = "net")]
- #[deprecated(since = "1.0.0", reason = "renamed to local_addr")]
- pub fn socket_addr(&self) -> io::Result<SocketAddr> {
- self.0.socket_addr()
- }
-
/// Returns the socket address of the local half of this TCP connection.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn local_addr(&self) -> io::Result<SocketAddr> {
fn as_inner(&self) -> &net_imp::TcpStream { &self.0 }
}
+impl FromInner<net_imp::TcpStream> for TcpStream {
+ fn from_inner(inner: net_imp::TcpStream) -> TcpStream { TcpStream(inner) }
+}
+
impl TcpListener {
/// Creates a new `TcpListener` which will be bound to the specified
/// address.
self.0.socket_addr()
}
- /// Deprecated, renamed to local_addr
- #[unstable(feature = "net")]
- #[deprecated(since = "1.0.0", reason = "renamed to local_addr")]
- pub fn socket_addr(&self) -> io::Result<SocketAddr> {
- self.0.socket_addr()
- }
-
/// Create a new independently owned handle to the underlying socket.
///
/// The returned `TcpListener` is a reference to the same socket that this
fn as_inner(&self) -> &net_imp::TcpListener { &self.0 }
}
+impl FromInner<net_imp::TcpListener> for TcpListener {
+ fn from_inner(inner: net_imp::TcpListener) -> TcpListener {
+ TcpListener(inner)
+ }
+}
+
#[cfg(test)]
mod tests {
use prelude::v1::*;
let _t = thread::spawn(move|| {
let mut stream = t!(TcpStream::connect(&addr));
t!(stream.write(&[99]));
- tx.send(t!(stream.socket_addr())).unwrap();
+ tx.send(t!(stream.local_addr())).unwrap();
});
let (mut stream, addr) = t!(acceptor.accept());
fn socket_and_peer_name_ip4() {
each_ip(&mut |addr| {
let listener = t!(TcpListener::bind(&addr));
- let so_name = t!(listener.socket_addr());
+ let so_name = t!(listener.local_addr());
assert_eq!(addr, so_name);
let _t = thread::spawn(move|| {
t!(listener.accept());
use io::{self, Error, ErrorKind};
use net::{ToSocketAddrs, SocketAddr, IpAddr};
use sys_common::net2 as net_imp;
-use sys_common::AsInner;
+use sys_common::{AsInner, FromInner};
/// A User Datagram Protocol socket.
///
}
}
- /// Returns the socket address that this socket was created from.
- #[unstable(feature = "net")]
- #[deprecated(since = "1.0.0", reason = "renamed to local_addr")]
- pub fn socket_addr(&self) -> io::Result<SocketAddr> {
- self.0.socket_addr()
- }
-
/// Returns the socket address that this socket was created from.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn local_addr(&self) -> io::Result<SocketAddr> {
fn as_inner(&self) -> &net_imp::UdpSocket { &self.0 }
}
+impl FromInner<net_imp::UdpSocket> for UdpSocket {
+ fn from_inner(inner: net_imp::UdpSocket) -> UdpSocket { UdpSocket(inner) }
+}
+
#[cfg(test)]
mod tests {
use prelude::v1::*;
fn socket_name_ip4() {
each_ip(&mut |addr, _| {
let server = t!(UdpSocket::bind(&addr));
- assert_eq!(addr, t!(server.socket_addr()));
+ assert_eq!(addr, t!(server.local_addr()));
})
}
let mut w = BufferedWriter::with_capacity(3, Vec::new());
w.write_all(&[0, 1]).unwrap();
let a: &[_] = &[];
- assert_eq!(a, &w.get_ref()[..]);
+ assert_eq!(&w.get_ref()[..], a);
let w = w.into_inner();
let a: &[_] = &[0, 1];
assert_eq!(a, &w[..]);
pub fn tmpdir() -> TempDir {
use os;
use rand;
- let ret = os::tmpdir().join(format!("rust-{}", rand::random::<u32>()));
+ let temp = Path::new(::env::temp_dir().to_str().unwrap());
+ let ret = temp.join(format!("rust-{}", rand::random::<u32>()));
check!(old_io::fs::mkdir(&ret, old_io::USER_RWX));
TempDir(ret)
}
check!(File::create(&tmpdir.join("test")).write(&bytes));
let actual = check!(File::open(&tmpdir.join("test")).read_to_end());
- assert!(actual == bytes.as_slice());
+ assert!(actual == &bytes[..]);
}
#[test]
mod test {
extern crate test as test_crate;
use old_io::{SeekSet, SeekCur, SeekEnd, Reader, Writer, Seek, Buffer};
- use prelude::v1::{Ok, Err, Vec, AsSlice};
+ use prelude::v1::{Ok, Err, Vec};
use prelude::v1::Iterator;
use old_io;
use iter::repeat;
wr.write(&[5; 10]).unwrap();
}
}
- assert_eq!(buf.as_slice(), [5; 100].as_slice());
+ assert_eq!(&buf[..], &[5; 100][..]);
});
}
use ops::FnOnce;
use option::Option;
use option::Option::{Some, None};
-use os;
+use sys::os;
use boxed::Box;
use result::Result;
use result::Result::{Ok, Err};
/// Some examples:
///
/// ```rust,no_run
-/// # #![feature(old_io, core)]
+/// # #![feature(old_io, core, convert)]
/// # #![allow(unused_must_use)]
///
/// use std::old_io::{TcpStream, TcpListener};
/// let tcp_l = TcpListener::bind("localhost:12345");
///
/// let mut udp_s = UdpSocket::bind(("127.0.0.1", 23451)).unwrap();
-/// udp_s.send_to([7, 7, 7].as_slice(), (Ipv4Addr(127, 0, 0, 1), 23451));
+/// udp_s.send_to([7, 7, 7].as_ref(), (Ipv4Addr(127, 0, 0, 1), 23451));
/// }
/// ```
pub trait ToSocketAddr {
use os;
use old_io::pipe::PipeStream;
- let os::Pipe { reader, writer } = unsafe { os::pipe().unwrap() };
- let out = PipeStream::open(writer);
- let mut input = PipeStream::open(reader);
+ let (reader, writer) = unsafe { ::sys::os::pipe().unwrap() };
+ let out = PipeStream::open(writer.unwrap());
+ let mut input = PipeStream::open(reader.unwrap());
let (tx, rx) = channel();
let _t = thread::spawn(move|| {
let mut out = out;
None => {
// if the env is currently just inheriting from the parent's,
// materialize the parent's env into a hashtable.
- self.env = Some(os::env_as_bytes().into_iter().map(|(k, v)| {
+ self.env = Some(::env::vars().map(|(k, v)| {
(EnvKey(CString::new(k).unwrap()),
CString::new(v).unwrap())
}).collect());
/// # Examples
///
/// ```
- /// # #![feature(old_io, core)]
+ /// # #![feature(old_io, core, convert)]
/// use std::old_io::Command;
///
/// let output = match Command::new("cat").arg("foot.txt").output() {
/// };
///
/// println!("status: {}", output.status);
- /// println!("stdout: {}", String::from_utf8_lossy(output.output.as_slice()));
- /// println!("stderr: {}", String::from_utf8_lossy(output.error.as_slice()));
+ /// println!("stdout: {}", String::from_utf8_lossy(output.output.as_ref()));
+ /// println!("stderr: {}", String::from_utf8_lossy(output.error.as_ref()));
/// ```
pub fn output(&self) -> IoResult<ProcessOutput> {
self.spawn().and_then(|p| p.wait_with_output())
#[cfg(test)]
mod tests {
+ use prelude::v1::*;
use old_io::{Truncate, Write, TimedOut, timer, process, FileNotFound};
use old_io::{Reader, Writer};
- use prelude::v1::{Ok, Err, drop, Some, None, Vec};
- use prelude::v1::{String, Clone};
- use prelude::v1::{Str, AsSlice, ToString};
use old_path::{GenericPath, Path};
use old_io::fs::PathExtensions;
use old_io::timer::*;
let prog = pwd_cmd().spawn().unwrap();
let output = String::from_utf8(prog.wait_with_output().unwrap().output).unwrap();
- let parent_dir = os::getcwd().unwrap();
+ let parent_dir = Path::new(::env::current_dir().unwrap().to_str().unwrap());
let child_dir = Path::new(output.trim());
let parent_stat = parent_dir.stat().unwrap();
use os;
// test changing to the parent of os::getcwd() because we know
// the path exists (and os::getcwd() is not expected to be root)
- let parent_dir = os::getcwd().unwrap().dir_path();
+ let parent_dir = Path::new(::env::current_dir().unwrap().to_str().unwrap());
let prog = pwd_cmd().cwd(&parent_dir).spawn().unwrap();
let output = String::from_utf8(prog.wait_with_output().unwrap().output).unwrap();
let prog = env_cmd().spawn().unwrap();
let output = String::from_utf8(prog.wait_with_output().unwrap().output).unwrap();
- let r = os::env();
- for &(ref k, ref v) in &r {
+ let r = ::env::vars();
+ for (k, v) in r {
// don't check windows magical empty-named variables
assert!(k.is_empty() ||
- output.contains(&format!("{}={}", *k, *v)),
+ output.contains(&format!("{}={}", k, v)),
"output doesn't contain `{}={}`\n{}",
k, v, output);
}
let mut prog = env_cmd().spawn().unwrap();
let output = String::from_utf8(prog.wait_with_output().unwrap().output).unwrap();
- let r = os::env();
- for &(ref k, ref v) in &r {
+ let r = env::vars();
+ for (k, v) in r {
// don't check android RANDOM variables
- if *k != "RANDOM".to_string() {
- assert!(output.contains(&format!("{}={}",
- *k,
- *v)) ||
- output.contains(&format!("{}=\'{}\'",
- *k,
- *v)));
+ if k != "RANDOM".to_string() {
+ assert!(output.contains(&format!("{}={}", k, v)) ||
+ output.contains(&format!("{}=\'{}\'", k, v)));
}
}
}
// PATH to our sub-process.
let path_val: String;
let mut new_env = vec![("RUN_TEST_NEW_ENV", "123")];
- match os::getenv("PATH") {
- None => {}
- Some(val) => {
+ match ::env::var("PATH") {
+ Err(..) => {}
+ Ok(val) => {
path_val = val;
new_env.push(("PATH", &path_val))
}
#[allow(deprecated)]
pub fn new_in(tmpdir: &Path, prefix: &str) -> IoResult<TempDir> {
if !tmpdir.is_absolute() {
- let cur_dir = try!(::os::getcwd());
+ let cur_dir = ::env::current_dir().unwrap();
+ let cur_dir = Path::new(cur_dir.to_str().unwrap());
return TempDir::new_in(&cur_dir.join(tmpdir), prefix);
}
/// If no directory can be created, `Err` is returned.
#[allow(deprecated)]
pub fn new(prefix: &str) -> IoResult<TempDir> {
- TempDir::new_in(&::os::tmpdir(), prefix)
+ let tmp = Path::new(::env::temp_dir().to_str().unwrap());
+ TempDir::new_in(&tmp, prefix)
}
/// Unwrap the wrapped `std::path::Path` from the `TempDir` wrapper.
pub fn next_test_unix() -> Path {
let string = next_test_unix_socket();
if cfg!(unix) {
- ::os::tmpdir().join(string)
+ Path::new(::env::temp_dir().to_str().unwrap()).join(string)
} else {
Path::new(format!("{}{}", r"\\.\pipe\", string))
}
// sysctl value, and bump the soft resource limit for maxfiles up to the sysctl value.
use ptr::null_mut;
use mem::size_of_val;
- use os::last_os_error;
+ use io;
// Fetch the kern.maxfilesperproc value
let mut mib: [libc::c_int; 2] = [CTL_KERN, KERN_MAXFILESPERPROC];
let mut size: libc::size_t = size_of_val(&maxfiles) as libc::size_t;
if sysctl(&mut mib[0], 2, &mut maxfiles as *mut libc::c_int as *mut libc::c_void, &mut size,
null_mut(), 0) != 0 {
- let err = last_os_error();
+ let err = io::Error::last_os_error();
panic!("raise_fd_limit: error calling sysctl: {}", err);
}
// Fetch the current resource limits
let mut rlim = rlimit{rlim_cur: 0, rlim_max: 0};
if getrlimit(RLIMIT_NOFILE, &mut rlim) != 0 {
- let err = last_os_error();
+ let err = io::Error::last_os_error();
panic!("raise_fd_limit: error calling getrlimit: {}", err);
}
// Set our newly-increased resource limit
if setrlimit(RLIMIT_NOFILE, &rlim) != 0 {
- let err = last_os_error();
+ let err = io::Error::last_os_error();
panic!("raise_fd_limit: error calling setrlimit: {}", err);
}
}
let mut r = MemReader::new(vec!(0, 1, 2));
{
let mut r = LimitReader::new(r.by_ref(), 4);
- assert_eq!([0, 1, 2], r.read_to_end().unwrap());
+ assert_eq!(r.read_to_end().unwrap(), [0, 1, 2]);
}
}
let mut r = MemReader::new(vec!(0, 1, 2));
{
let mut r = LimitReader::new(r.by_ref(), 2);
- assert_eq!([0, 1], r.read_to_end().unwrap());
+ assert_eq!(r.read_to_end().unwrap(), [0, 1]);
}
- assert_eq!([2], r.read_to_end().unwrap());
+ assert_eq!(r.read_to_end().unwrap(), [2]);
}
#[test]
assert_eq!(3, r.limit());
assert_eq!(0, r.read_byte().unwrap());
assert_eq!(2, r.limit());
- assert_eq!([1, 2], r.read_to_end().unwrap());
+ assert_eq!(r.read_to_end().unwrap(), [1, 2]);
assert_eq!(0, r.limit());
}
let mut r = MemReader::new(vec![0, 1, 2, 3, 4, 5]);
let mut r = LimitReader::new(r.by_ref(), 1);
r.consume(2);
- assert_eq!([], r.read_to_end().unwrap());
+ assert_eq!(r.read_to_end().unwrap(), []);
}
#[test]
let mut s = ZeroReader;
let mut buf = vec![1, 2, 3];
assert_eq!(s.read(&mut buf), Ok(3));
- assert_eq!([0, 0, 0], buf);
+ assert_eq!(buf, [0, 0, 0]);
}
#[test]
let rs = vec!(MemReader::new(vec!(0, 1)), MemReader::new(vec!()),
MemReader::new(vec!(2, 3)));
let mut r = ChainedReader::new(rs.into_iter());
- assert_eq!([0, 1, 2, 3], r.read_to_end().unwrap());
+ assert_eq!(r.read_to_end().unwrap(), [0, 1, 2, 3]);
}
#[test]
fn test_tee_reader() {
let mut r = TeeReader::new(MemReader::new(vec!(0, 1, 2)),
Vec::new());
- assert_eq!([0, 1, 2], r.read_to_end().unwrap());
+ assert_eq!(r.read_to_end().unwrap(), [0, 1, 2]);
let (_, w) = r.into_inner();
- assert_eq!([0, 1, 2], w);
+ assert_eq!(w, [0, 1, 2]);
}
#[test]
let mut r = MemReader::new(vec!(0, 1, 2, 3, 4));
let mut w = Vec::new();
copy(&mut r, &mut w).unwrap();
- assert_eq!([0, 1, 2, 3, 4], w);
+ assert_eq!(w, [0, 1, 2, 3, 4]);
}
#[test]
use core::marker::Sized;
use ffi::CString;
use clone::Clone;
+use borrow::Cow;
use fmt;
use iter::Iterator;
use option::Option;
use option::Option::{None, Some};
use str;
-use string::{String, CowString};
+use string::String;
use vec::Vec;
/// Typedef for POSIX file paths.
/// If the path is not UTF-8, invalid sequences will be replaced with the
/// Unicode replacement char. This involves allocation.
#[inline]
- pub fn as_cow(&self) -> CowString<'a> {
+ pub fn as_cow(&self) -> Cow<'a, str> {
String::from_utf8_lossy(if self.filename {
match self.path.filename() {
None => {
use marker::Sized;
use option::Option::{self, Some, None};
use result::Result::{self, Ok, Err};
-use slice::{AsSlice, Split, SliceConcatExt};
+use slice::{Split, SliceConcatExt};
use str::{self, FromStr};
use vec::Vec;
unsafe fn set_filename_unchecked<T: BytesContainer>(&mut self, filename: T) {
let filename = filename.container_as_bytes();
match self.sepidx {
- None if b".." == self.repr => {
+ None if self.repr == b".." => {
let mut v = Vec::with_capacity(3 + filename.len());
v.push_all(dot_dot_static);
v.push(SEP_BYTE);
fn dirname<'a>(&'a self) -> &'a [u8] {
match self.sepidx {
- None if b".." == self.repr => &self.repr,
+ None if self.repr == b".." => &self.repr,
None => dot_static,
Some(0) => &self.repr[..1],
Some(idx) if &self.repr[idx+1..] == b".." => &self.repr,
fn filename<'a>(&'a self) -> Option<&'a [u8]> {
match self.sepidx {
- None if b"." == self.repr ||
- b".." == self.repr => None,
+ None if self.repr == b"." || self.repr == b".." => None,
None => Some(&self.repr),
Some(idx) if &self.repr[idx+1..] == b".." => None,
Some(0) if self.repr[1..].is_empty() => None,
fn pop(&mut self) -> bool {
match self.sepidx {
- None if b"." == self.repr => false,
+ None if self.repr == b"." => false,
None => {
self.repr = vec![b'.'];
self.sepidx = None;
true
}
- Some(0) if b"/" == self.repr => false,
+ Some(0) if self.repr == b"/" => false,
Some(idx) => {
if idx == 0 {
self.repr.truncate(idx+1);
} else {
let mut ita = self.components();
let mut itb = other.components();
- if b"." == self.repr {
+ if self.repr == b"." {
return match itb.next() {
None => true,
Some(b) => b != b".."
/// Returns a normalized byte vector representation of a path, by removing all empty
/// components, and unnecessary . and .. components.
- fn normalize<V: ?Sized + AsSlice<u8>>(v: &V) -> Vec<u8> {
+ fn normalize(v: &[u8]) -> Vec<u8> {
// borrowck is being very picky
let val = {
- let is_abs = !v.as_slice().is_empty() && v.as_slice()[0] == SEP_BYTE;
- let v_ = if is_abs { &v.as_slice()[1..] } else { v.as_slice() };
+ let is_abs = !v.is_empty() && v[0] == SEP_BYTE;
+ let v_ = if is_abs { &v[1..] } else { v };
let comps = normalize_helper(v_, is_abs);
match comps {
None => None,
}
};
match val {
- None => v.as_slice().to_vec(),
+ None => v.to_vec(),
Some(val) => val
}
}
use clone::Clone;
use option::Option::{self, Some, None};
use old_path::GenericPath;
- use slice::AsSlice;
- use str::{self, Str};
+ use str;
use string::ToString;
use vec::Vec;
use iter::Iterator;
use iter::Iterator;
use option::Option::{self, Some, None};
use old_path::GenericPath;
- use slice::AsSlice;
- use str::Str;
use string::ToString;
use vec::Vec;
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-//! Higher-level interfaces to libc::* functions and operating system services.
-//!
-//! In general these take and return rust types, use rust idioms (enums,
-//! closures, vectors) rather than C idioms, and do more extensive safety
-//! checks.
-//!
-//! This module is not meant to only contain 1:1 mappings to libc entries; any
-//! os-interface code that is reasonably useful and broadly applicable can go
-//! here. Including utility routines that merely build on other os code.
-//!
-//! We assume the general case is that users do not care, and do not want to be
-//! made to care, which operating system they are on. While they may want to
-//! special case various special cases -- and so we will not _hide_ the facts of
-//! which OS the user is on -- they should be given the opportunity to write
-//! OS-ignorant code by default.
+//! OS-specific functionality
-#![unstable(feature = "os")]
-#![deprecated(since = "1.0.0", reason = "replaced with std::env APIs")]
-
-#![allow(missing_docs)]
-#![allow(non_snake_case)]
-#![allow(unused_imports)]
-#![allow(deprecated)]
-
-use self::MemoryMapKind::*;
-use self::MapOption::*;
-use self::MapError::*;
-
-use boxed::Box;
-use clone::Clone;
-use convert::From;
-use env;
-use error::{FromError, Error};
-use ffi::{OsString, OsStr};
-use fmt;
-use iter::Iterator;
-use libc::{c_void, c_int, c_char};
-use libc;
-use marker::{Copy, Send};
-use old_io::{IoResult, IoError};
-use ops::{Drop, FnOnce};
-use option::Option::{Some, None};
-use option::Option;
-use old_path::{Path, GenericPath, BytesContainer};
-use path::{self, PathBuf};
-use ptr;
-use result::Result::{Err, Ok};
-use result::Result;
-use slice::AsSlice;
-use str::Str;
-use str;
-use string::{String, ToString};
-use sync::atomic::{AtomicIsize, ATOMIC_ISIZE_INIT, Ordering};
-use sys::os as os_imp;
-use sys;
-use vec::Vec;
-
-#[cfg(unix)] use ffi::{self, CString};
+#![stable(feature = "os", since = "1.0.0")]
#[cfg(unix)] pub use sys::ext as unix;
#[cfg(windows)] pub use sys::ext as windows;
-
-fn err2old(new: ::io::Error) -> IoError {
- IoError {
- kind: ::old_io::OtherIoError,
- desc: "os error",
- detail: Some(new.to_string()),
- }
-}
-
-#[cfg(windows)]
-fn path2new(path: &Path) -> PathBuf {
- PathBuf::from(path.as_str().unwrap())
-}
-#[cfg(unix)]
-fn path2new(path: &Path) -> PathBuf {
- use os::unix::prelude::*;
- PathBuf::from(<OsStr as OsStrExt>::from_bytes(path.as_vec()))
-}
-
-#[cfg(unix)]
-fn path2old(path: &path::Path) -> Path {
- use os::unix::prelude::*;
- use ffi::AsOsStr;
- Path::new(path.as_os_str().as_bytes())
-}
-#[cfg(windows)]
-fn path2old(path: &path::Path) -> Path {
- Path::new(path.to_str().unwrap())
-}
-
-/// Get the number of cores available
-pub fn num_cpus() -> usize {
- unsafe {
- return rust_get_num_cpus() as usize;
- }
-
- extern {
- fn rust_get_num_cpus() -> libc::uintptr_t;
- }
-}
-
-pub const TMPBUF_SZ : usize = 1000;
-
-/// Returns the current working directory as a `Path`.
-///
-/// # Errors
-///
-/// Returns an `Err` if the current working directory value is invalid.
-/// Possible cases:
-///
-/// * Current directory does not exist.
-/// * There are insufficient permissions to access the current directory.
-/// * The internal buffer is not large enough to hold the path.
-///
-/// # Examples
-///
-/// ```
-/// # #![feature(os, old_path)]
-/// use std::os;
-/// use std::old_path::{Path, GenericPath};
-///
-/// // We assume that we are in a valid directory.
-/// let current_working_directory = os::getcwd().unwrap();
-/// println!("The current directory is {:?}", current_working_directory.display());
-/// ```
-#[unstable(feature = "os")]
-pub fn getcwd() -> IoResult<Path> {
- env::current_dir().map_err(err2old).map(|s| path2old(&s))
-}
-
-/// Returns a vector of (variable, value) pairs, for all the environment
-/// variables of the current process.
-///
-/// Invalid UTF-8 bytes are replaced with \uFFFD. See `String::from_utf8_lossy()`
-/// for details.
-///
-/// # Examples
-///
-/// ```
-/// # #![feature(os)]
-/// use std::os;
-///
-/// // We will iterate through the references to the element returned by os::env();
-/// for &(ref key, ref value) in os::env().iter() {
-/// println!("'{}': '{}'", key, value );
-/// }
-/// ```
-#[deprecated(since = "1.0.0", reason = "use env::vars instead")]
-#[unstable(feature = "os")]
-pub fn env() -> Vec<(String,String)> {
- env::vars_os().map(|(k, v)| {
- (k.to_string_lossy().into_owned(), v.to_string_lossy().into_owned())
- }).collect()
-}
-
-/// Returns a vector of (variable, value) byte-vector pairs for all the
-/// environment variables of the current process.
-#[deprecated(since = "1.0.0", reason = "use env::vars_os instead")]
-#[unstable(feature = "os")]
-pub fn env_as_bytes() -> Vec<(Vec<u8>, Vec<u8>)> {
- env::vars_os().map(|(k, v)| (byteify(k), byteify(v))).collect()
-}
-
-/// Fetches the environment variable `n` from the current process, returning
-/// None if the variable isn't set.
-///
-/// Any invalid UTF-8 bytes in the value are replaced by \uFFFD. See
-/// `String::from_utf8_lossy()` for details.
-///
-/// # Panics
-///
-/// Panics if `n` has any interior NULs.
-///
-/// # Examples
-///
-/// ```
-/// # #![feature(os)]
-/// use std::os;
-///
-/// let key = "HOME";
-/// match os::getenv(key) {
-/// Some(val) => println!("{}: {}", key, val),
-/// None => println!("{} is not defined in the environment.", key)
-/// }
-/// ```
-#[deprecated(since = "1.0.0", reason = "use env::var instead")]
-#[unstable(feature = "os")]
-pub fn getenv(n: &str) -> Option<String> {
- env::var(n).ok()
-}
-
-/// Fetches the environment variable `n` byte vector from the current process,
-/// returning None if the variable isn't set.
-///
-/// # Panics
-///
-/// Panics if `n` has any interior NULs.
-#[deprecated(since = "1.0.0", reason = "use env::var_os instead")]
-#[unstable(feature = "os")]
-pub fn getenv_as_bytes(n: &str) -> Option<Vec<u8>> {
- env::var_os(n).map(byteify)
-}
-
-#[cfg(unix)]
-fn byteify(s: OsString) -> Vec<u8> {
- use os::unix::prelude::*;
- s.into_vec()
-}
-#[cfg(windows)]
-fn byteify(s: OsString) -> Vec<u8> {
- s.to_string_lossy().as_bytes().to_vec()
-}
-
-/// Sets the environment variable `n` to the value `v` for the currently running
-/// process.
-///
-/// # Examples
-///
-/// ```
-/// # #![feature(os)]
-/// use std::os;
-///
-/// let key = "KEY";
-/// os::setenv(key, "VALUE");
-/// match os::getenv(key) {
-/// Some(ref val) => println!("{}: {}", key, val),
-/// None => println!("{} is not defined in the environment.", key)
-/// }
-/// ```
-#[deprecated(since = "1.0.0", reason = "renamed to env::set_var")]
-#[unstable(feature = "os")]
-pub fn setenv<T: BytesContainer>(n: &str, v: T) {
- #[cfg(unix)]
- fn _setenv(n: &str, v: &[u8]) {
- use os::unix::prelude::*;
- let v: OsString = OsStringExt::from_vec(v.to_vec());
- env::set_var(n, &v)
- }
-
- #[cfg(windows)]
- fn _setenv(n: &str, v: &[u8]) {
- let v = str::from_utf8(v).unwrap();
- env::set_var(n, v)
- }
-
- _setenv(n, v.container_as_bytes())
-}
-
-/// Remove a variable from the environment entirely.
-#[deprecated(since = "1.0.0", reason = "renamed to env::remove_var")]
-#[unstable(feature = "os")]
-pub fn unsetenv(n: &str) {
- env::remove_var(n)
-}
-
-/// Parses input according to platform conventions for the `PATH`
-/// environment variable.
-///
-/// # Examples
-///
-/// ```
-/// # #![feature(old_path, os)]
-/// use std::os;
-/// use std::old_path::{Path, GenericPath};
-///
-/// let key = "PATH";
-/// match os::getenv_as_bytes(key) {
-/// Some(paths) => {
-/// for path in os::split_paths(paths).iter() {
-/// println!("'{}'", path.display());
-/// }
-/// }
-/// None => println!("{} is not defined in the environment.", key)
-/// }
-/// ```
-#[unstable(feature = "os")]
-pub fn split_paths<T: BytesContainer>(unparsed: T) -> Vec<Path> {
- let b = unparsed.container_as_bytes();
- let s = str::from_utf8(b).unwrap();
- env::split_paths(s).map(|s| path2old(&s)).collect()
-}
-
-/// Joins a collection of `Path`s appropriately for the `PATH`
-/// environment variable.
-///
-/// Returns a `Vec<u8>` on success, since `Path`s are not utf-8
-/// encoded on all platforms.
-///
-/// Returns an `Err` (containing an error message) if one of the input
-/// `Path`s contains an invalid character for constructing the `PATH`
-/// variable (a double quote on Windows or a colon on Unix).
-///
-/// # Examples
-///
-/// ```
-/// # #![feature(os, old_path, core)]
-/// use std::os;
-/// use std::old_path::Path;
-///
-/// let key = "PATH";
-/// let mut paths = os::getenv_as_bytes(key).map_or(Vec::new(), os::split_paths);
-/// paths.push(Path::new("/home/xyz/bin"));
-/// os::setenv(key, os::join_paths(paths.as_slice()).unwrap());
-/// ```
-#[unstable(feature = "os")]
-pub fn join_paths<T: BytesContainer>(paths: &[T]) -> Result<Vec<u8>, &'static str> {
- env::join_paths(paths.iter().map(|s| {
- str::from_utf8(s.container_as_bytes()).unwrap()
- })).map(|s| {
- s.to_string_lossy().into_owned().into_bytes()
- }).map_err(|_| "failed to join paths")
-}
-
-/// A low-level OS in-memory pipe.
-#[derive(Copy)]
-pub struct Pipe {
- /// A file descriptor representing the reading end of the pipe. Data written
- /// on the `out` file descriptor can be read from this file descriptor.
- pub reader: c_int,
- /// A file descriptor representing the write end of the pipe. Data written
- /// to this file descriptor can be read from the `input` file descriptor.
- pub writer: c_int,
-}
-
-/// Creates a new low-level OS in-memory pipe.
-///
-/// This function can fail to succeed if there are no more resources available
-/// to allocate a pipe.
-///
-/// This function is also unsafe as there is no destructor associated with the
-/// `Pipe` structure will return. If it is not arranged for the returned file
-/// descriptors to be closed, the file descriptors will leak. For safe handling
-/// of this scenario, use `std::old_io::PipeStream` instead.
-pub unsafe fn pipe() -> IoResult<Pipe> {
- let (reader, writer) = try!(sys::os::pipe());
- Ok(Pipe {
- reader: reader.unwrap(),
- writer: writer.unwrap(),
- })
-}
-
-/// Returns the proper dll filename for the given basename of a file
-/// as a String.
-#[cfg(not(target_os="ios"))]
-#[deprecated(since = "1.0.0", reason = "this function will be removed, use the constants directly")]
-#[unstable(feature = "os")]
-#[allow(deprecated)]
-pub fn dll_filename(base: &str) -> String {
- format!("{}{}{}", consts::DLL_PREFIX, base, consts::DLL_SUFFIX)
-}
-
-/// Optionally returns the filesystem path to the current executable which is
-/// running but with the executable name.
-///
-/// # Examples
-///
-/// ```
-/// # #![feature(os, old_path)]
-/// use std::os;
-/// use std::old_path::{Path, GenericPath};
-///
-/// match os::self_exe_name() {
-/// Some(exe_path) => println!("Path of this executable is: {}", exe_path.display()),
-/// None => println!("Unable to get the path of this executable!")
-/// };
-/// ```
-#[unstable(feature = "os")]
-pub fn self_exe_name() -> Option<Path> {
- env::current_exe().ok().map(|p| path2old(&p))
-}
-
-/// Optionally returns the filesystem path to the current executable which is
-/// running.
-///
-/// Like self_exe_name() but without the binary's name.
-///
-/// # Examples
-///
-/// ```
-/// # #![feature(os, old_path)]
-/// use std::os;
-/// use std::old_path::{Path, GenericPath};
-///
-/// match os::self_exe_path() {
-/// Some(exe_path) => println!("Executable's Path is: {}", exe_path.display()),
-/// None => println!("Impossible to fetch the path of this executable.")
-/// };
-/// ```
-#[unstable(feature = "os")]
-pub fn self_exe_path() -> Option<Path> {
- env::current_exe().ok().map(|p| { let mut p = path2old(&p); p.pop(); p })
-}
-
-/// Optionally returns the path to the current user's home directory if known.
-///
-/// # Unix
-///
-/// Returns the value of the 'HOME' environment variable if it is set
-/// and not equal to the empty string.
-///
-/// # Windows
-///
-/// Returns the value of the 'HOME' environment variable if it is
-/// set and not equal to the empty string. Otherwise, returns the value of the
-/// 'USERPROFILE' environment variable if it is set and not equal to the empty
-/// string.
-///
-/// # Examples
-///
-/// ```
-/// # #![feature(os, old_path)]
-/// use std::os;
-/// use std::old_path::{Path, GenericPath};
-///
-/// match os::homedir() {
-/// Some(ref p) => println!("{}", p.display()),
-/// None => println!("Impossible to get your home dir!")
-/// }
-/// ```
-#[unstable(feature = "os")]
-#[allow(deprecated)]
-pub fn homedir() -> Option<Path> {
- #[inline]
- #[cfg(unix)]
- fn _homedir() -> Option<Path> {
- aux_homedir("HOME")
- }
-
- #[inline]
- #[cfg(windows)]
- fn _homedir() -> Option<Path> {
- aux_homedir("HOME").or(aux_homedir("USERPROFILE"))
- }
-
- #[inline]
- fn aux_homedir(home_name: &str) -> Option<Path> {
- match getenv_as_bytes(home_name) {
- Some(p) => {
- if p.is_empty() { None } else { Path::new_opt(p) }
- },
- _ => None
- }
- }
- _homedir()
-}
-
-/// Returns the path to a temporary directory.
-///
-/// On Unix, returns the value of the 'TMPDIR' environment variable if it is
-/// set, otherwise for non-Android it returns '/tmp'. If Android, since there
-/// is no global temporary folder (it is usually allocated per-app), we return
-/// '/data/local/tmp'.
-///
-/// On Windows, returns the value of, in order, the 'TMP', 'TEMP',
-/// 'USERPROFILE' environment variable if any are set and not the empty
-/// string. Otherwise, tmpdir returns the path to the Windows directory.
-#[unstable(feature = "os")]
-#[allow(deprecated)]
-pub fn tmpdir() -> Path {
- return lookup();
-
- fn getenv_nonempty(v: &str) -> Option<Path> {
- match getenv(v) {
- Some(x) =>
- if x.is_empty() {
- None
- } else {
- Path::new_opt(x)
- },
- _ => None
- }
- }
-
- #[cfg(unix)]
- fn lookup() -> Path {
- let default = if cfg!(target_os = "android") {
- Path::new("/data/local/tmp")
- } else {
- Path::new("/tmp")
- };
-
- getenv_nonempty("TMPDIR").unwrap_or(default)
- }
-
- #[cfg(windows)]
- fn lookup() -> Path {
- getenv_nonempty("TMP").or(
- getenv_nonempty("TEMP").or(
- getenv_nonempty("USERPROFILE").or(
- getenv_nonempty("WINDIR")))).unwrap_or(Path::new("C:\\Windows"))
- }
-}
-
-/// Convert a relative path to an absolute path
-///
-/// If the given path is relative, return it prepended with the current working
-/// directory. If the given path is already an absolute path, return it
-/// as is.
-///
-/// # Examples
-///
-/// ```
-/// # #![feature(os, old_path)]
-/// use std::os;
-/// use std::old_path::{Path, GenericPath};
-///
-/// // Assume we're in a path like /home/someuser
-/// let rel_path = Path::new("..");
-/// let abs_path = os::make_absolute(&rel_path).unwrap();
-/// println!("The absolute path is {}", abs_path.display());
-/// // Prints "The absolute path is /home"
-/// ```
-// NB: this is here rather than in path because it is a form of environment
-// querying; what it does depends on the process working directory, not just
-// the input paths.
-#[deprecated(since = "1.0.0", reason = "use env::current_dir + .join directly")]
-#[unstable(feature = "os")]
-pub fn make_absolute(p: &Path) -> IoResult<Path> {
- if p.is_absolute() {
- Ok(p.clone())
- } else {
- env::current_dir().map_err(err2old).map(|cwd| {
- let mut cwd = path2old(&cwd);
- cwd.push(p);
- cwd
- })
- }
-}
-
-/// Changes the current working directory to the specified path, returning
-/// whether the change was completed successfully or not.
-///
-/// # Examples
-///
-/// ```
-/// # #![feature(os, old_path)]
-/// use std::os;
-/// use std::old_path::{Path, GenericPath};
-///
-/// let root = Path::new("/");
-/// assert!(os::change_dir(&root).is_ok());
-/// println!("Successfully changed working directory to {}!", root.display());
-/// ```
-#[unstable(feature = "os")]
-pub fn change_dir(p: &Path) -> IoResult<()> {
- sys::os::chdir(&path2new(p)).map_err(err2old)
-}
-
-/// Returns the platform-specific value of errno
-pub fn errno() -> i32 {
- sys::os::errno() as i32
-}
-
-/// Return the string corresponding to an `errno()` value of `errnum`.
-///
-/// # Examples
-///
-/// ```
-/// # #![feature(os)]
-/// use std::os;
-///
-/// // Same as println!("{}", last_os_error());
-/// println!("{}", os::error_string(os::errno() as i32));
-/// ```
-pub fn error_string(errnum: i32) -> String {
- return sys::os::error_string(errnum);
-}
-
-/// Get a string representing the platform-dependent last error
-pub fn last_os_error() -> String {
- error_string(errno())
-}
-
-/// Sets the process exit code
-///
-/// Sets the exit code returned by the process if all supervised tasks
-/// terminate successfully (without panicking). If the current root task panics
-/// and is supervised by the scheduler then any user-specified exit status is
-/// ignored and the process exits with the default panic status.
-///
-/// Note that this is not synchronized against modifications of other threads.
-#[deprecated(since = "1.0.0", reason = "renamed to env::set_exit_status")]
-#[unstable(feature = "os")]
-pub fn set_exit_status(code: isize) {
- env::set_exit_status(code as i32)
-}
-
-/// Fetches the process's current exit code. This defaults to 0 and can change
-/// by calling `set_exit_status`.
-#[deprecated(since = "1.0.0", reason = "renamed to env::get_exit_status")]
-#[unstable(feature = "os")]
-pub fn get_exit_status() -> isize {
- env::get_exit_status() as isize
-}
-
-#[cfg(target_os = "macos")]
-unsafe fn load_argc_and_argv(argc: isize,
- argv: *const *const c_char) -> Vec<Vec<u8>> {
- use ffi::CStr;
-
- (0..argc).map(|i| {
- CStr::from_ptr(*argv.offset(i)).to_bytes().to_vec()
- }).collect()
-}
-
-/// Returns the command line arguments
-///
-/// Returns a list of the command line arguments.
-#[cfg(target_os = "macos")]
-fn real_args_as_bytes() -> Vec<Vec<u8>> {
- unsafe {
- let (argc, argv) = (*_NSGetArgc() as isize,
- *_NSGetArgv() as *const *const c_char);
- load_argc_and_argv(argc, argv)
- }
-}
-
-// As _NSGetArgc and _NSGetArgv aren't mentioned in iOS docs
-// and use underscores in their names - they're most probably
-// are considered private and therefore should be avoided
-// Here is another way to get arguments using Objective C
-// runtime
-//
-// In general it looks like:
-// res = Vec::new()
-// let args = [[NSProcessInfo processInfo] arguments]
-// for i in 0..[args count]
-// res.push([args objectAtIndex:i])
-// res
-#[cfg(target_os = "ios")]
-fn real_args_as_bytes() -> Vec<Vec<u8>> {
- use ffi::CStr;
- use iter::range;
- use mem;
-
- #[link(name = "objc")]
- extern {
- fn sel_registerName(name: *const libc::c_uchar) -> Sel;
- fn objc_msgSend(obj: NsId, sel: Sel, ...) -> NsId;
- fn objc_getClass(class_name: *const libc::c_uchar) -> NsId;
- }
-
- #[link(name = "Foundation", kind = "framework")]
- extern {}
-
- type Sel = *const libc::c_void;
- type NsId = *const libc::c_void;
-
- let mut res = Vec::new();
-
- unsafe {
- let processInfoSel = sel_registerName("processInfo\0".as_ptr());
- let argumentsSel = sel_registerName("arguments\0".as_ptr());
- let utf8Sel = sel_registerName("UTF8String\0".as_ptr());
- let countSel = sel_registerName("count\0".as_ptr());
- let objectAtSel = sel_registerName("objectAtIndex:\0".as_ptr());
-
- let klass = objc_getClass("NSProcessInfo\0".as_ptr());
- let info = objc_msgSend(klass, processInfoSel);
- let args = objc_msgSend(info, argumentsSel);
-
- let cnt: isize = mem::transmute(objc_msgSend(args, countSel));
- for i in 0..cnt {
- let tmp = objc_msgSend(args, objectAtSel, i);
- let utf_c_str: *const libc::c_char =
- mem::transmute(objc_msgSend(tmp, utf8Sel));
- res.push(CStr::from_ptr(utf_c_str).to_bytes().to_vec());
- }
- }
-
- res
-}
-
-#[cfg(any(target_os = "linux",
- target_os = "android",
- target_os = "freebsd",
- target_os = "dragonfly",
- target_os = "bitrig",
- target_os = "openbsd"))]
-fn real_args_as_bytes() -> Vec<Vec<u8>> {
- use rt;
- rt::args::clone().unwrap_or_else(|| vec![])
-}
-
-#[cfg(not(windows))]
-fn real_args() -> Vec<String> {
- real_args_as_bytes().into_iter()
- .map(|v| {
- String::from_utf8_lossy(&v).into_owned()
- }).collect()
-}
-
-#[cfg(windows)]
-fn real_args() -> Vec<String> {
- use slice;
- use iter::range;
-
- let mut nArgs: c_int = 0;
- let lpArgCount: *mut c_int = &mut nArgs;
- let lpCmdLine = unsafe { GetCommandLineW() };
- let szArgList = unsafe { CommandLineToArgvW(lpCmdLine, lpArgCount) };
-
- let args: Vec<_> = (0..nArgs as usize).map(|i| unsafe {
- // Determine the length of this argument.
- let ptr = *szArgList.offset(i as isize);
- let mut len = 0;
- while *ptr.offset(len as isize) != 0 { len += 1; }
-
- // Push it onto the list.
- let ptr = ptr as *const u16;
- let buf = slice::from_raw_parts(ptr, len);
- let opt_s = String::from_utf16(sys::truncate_utf16_at_nul(buf));
- opt_s.ok().expect("CommandLineToArgvW returned invalid UTF-16")
- }).collect();
-
- unsafe {
- LocalFree(szArgList as *mut c_void);
- }
-
- return args
-}
-
-#[cfg(windows)]
-fn real_args_as_bytes() -> Vec<Vec<u8>> {
- real_args().into_iter().map(|s| s.into_bytes()).collect()
-}
-
-type LPCWSTR = *const u16;
-
-#[cfg(windows)]
-#[link_name="kernel32"]
-extern "system" {
- fn GetCommandLineW() -> LPCWSTR;
- fn LocalFree(ptr: *mut c_void);
-}
-
-#[cfg(windows)]
-#[link_name="shell32"]
-extern "system" {
- fn CommandLineToArgvW(lpCmdLine: LPCWSTR,
- pNumArgs: *mut c_int) -> *mut *mut u16;
-}
-
-/// Returns the arguments which this program was started with (normally passed
-/// via the command line).
-///
-/// The first element is traditionally the path to the executable, but it can be
-/// set to arbitrary text, and it may not even exist, so this property should not
-/// be relied upon for security purposes.
-///
-/// The arguments are interpreted as utf-8, with invalid bytes replaced with \uFFFD.
-/// See `String::from_utf8_lossy` for details.
-/// # Examples
-///
-/// ```
-/// # #![feature(os)]
-/// use std::os;
-///
-/// // Prints each argument on a separate line
-/// for argument in os::args().iter() {
-/// println!("{}", argument);
-/// }
-/// ```
-#[deprecated(since = "1.0.0", reason = "use std::env::args() instead")]
-#[unstable(feature = "os")]
-pub fn args() -> Vec<String> {
- real_args()
-}
-
-/// Returns the arguments which this program was started with (normally passed
-/// via the command line) as byte vectors.
-#[deprecated(since = "1.0.0", reason = "use env::args_os instead")]
-#[unstable(feature = "os")]
-pub fn args_as_bytes() -> Vec<Vec<u8>> {
- real_args_as_bytes()
-}
-
-#[cfg(target_os = "macos")]
-extern {
- // These functions are in crt_externs.h.
- fn _NSGetArgc() -> *mut c_int;
- fn _NSGetArgv() -> *mut *mut *mut c_char;
-}
-
-/// Returns the page size of the current architecture in bytes.
-#[deprecated(since = "1.0.0", reason = "renamed to env::page_size")]
-#[unstable(feature = "os")]
-pub fn page_size() -> usize {
- sys::os::page_size()
-}
-
-/// A memory mapped file or chunk of memory. This is a very system-specific
-/// interface to the OS's memory mapping facilities (`mmap` on POSIX,
-/// `VirtualAlloc`/`CreateFileMapping` on Windows). It makes no attempt at
-/// abstracting platform differences, besides in error values returned. Consider
-/// yourself warned.
-///
-/// The memory map is released (unmapped) when the destructor is run, so don't
-/// let it leave scope by accident if you want it to stick around.
-pub struct MemoryMap {
- data: *mut u8,
- len: usize,
- kind: MemoryMapKind,
-}
-
-/// Type of memory map
-#[allow(raw_pointer_derive)]
-#[derive(Copy)]
-pub enum MemoryMapKind {
- /// Virtual memory map. Usually used to change the permissions of a given
- /// chunk of memory. Corresponds to `VirtualAlloc` on Windows.
- MapFile(*const u8),
- /// Virtual memory map. Usually used to change the permissions of a given
- /// chunk of memory, or for allocation. Corresponds to `VirtualAlloc` on
- /// Windows.
- MapVirtual
-}
-
-/// Options the memory map is created with
-#[allow(raw_pointer_derive)]
-#[derive(Copy)]
-pub enum MapOption {
- /// The memory should be readable
- MapReadable,
- /// The memory should be writable
- MapWritable,
- /// The memory should be executable
- MapExecutable,
- /// Create a map for a specific address range. Corresponds to `MAP_FIXED` on
- /// POSIX.
- MapAddr(*const u8),
- /// Create a memory mapping for a file with a given HANDLE.
- #[cfg(windows)]
- MapFd(libc::HANDLE),
- /// Create a memory mapping for a file with a given fd.
- #[cfg(not(windows))]
- MapFd(c_int),
- /// When using `MapFd`, the start of the map is `usize` bytes from the start
- /// of the file.
- MapOffset(usize),
- /// On POSIX, this can be used to specify the default flags passed to
- /// `mmap`. By default it uses `MAP_PRIVATE` and, if not using `MapFd`,
- /// `MAP_ANON`. This will override both of those. This is platform-specific
- /// (the exact values used) and ignored on Windows.
- MapNonStandardFlags(c_int),
-}
-
-/// Possible errors when creating a map.
-#[derive(Copy, Debug)]
-pub enum MapError {
- /// # The following are POSIX-specific
- ///
- /// fd was not open for reading or, if using `MapWritable`, was not open for
- /// writing.
- ErrFdNotAvail,
- /// fd was not valid
- ErrInvalidFd,
- /// Either the address given by `MapAddr` or offset given by `MapOffset` was
- /// not a multiple of `MemoryMap::granularity` (unaligned to page size).
- ErrUnaligned,
- /// With `MapFd`, the fd does not support mapping.
- ErrNoMapSupport,
- /// If using `MapAddr`, the address + `min_len` was outside of the process's
- /// address space. If using `MapFd`, the target of the fd didn't have enough
- /// resources to fulfill the request.
- ErrNoMem,
- /// A zero-length map was requested. This is invalid according to
- /// [POSIX](http://pubs.opengroup.org/onlinepubs/9699919799/functions/mmap.html).
- /// Not all platforms obey this, but this wrapper does.
- ErrZeroLength,
- /// Unrecognized error. The inner value is the unrecognized errno.
- ErrUnknown(isize),
- /// # The following are Windows-specific
- ///
- /// Unsupported combination of protection flags
- /// (`MapReadable`/`MapWritable`/`MapExecutable`).
- ErrUnsupProt,
- /// When using `MapFd`, `MapOffset` was given (Windows does not support this
- /// at all)
- ErrUnsupOffset,
- /// When using `MapFd`, there was already a mapping to the file.
- ErrAlreadyExists,
- /// Unrecognized error from `VirtualAlloc`. The inner value is the return
- /// value of GetLastError.
- ErrVirtualAlloc(i32),
- /// Unrecognized error from `CreateFileMapping`. The inner value is the
- /// return value of `GetLastError`.
- ErrCreateFileMappingW(i32),
- /// Unrecognized error from `MapViewOfFile`. The inner value is the return
- /// value of `GetLastError`.
- ErrMapViewOfFile(i32)
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl fmt::Display for MapError {
- fn fmt(&self, out: &mut fmt::Formatter) -> fmt::Result {
- let str = match *self {
- ErrFdNotAvail => "fd not available for reading or writing",
- ErrInvalidFd => "Invalid fd",
- ErrUnaligned => {
- "Unaligned address, invalid flags, negative length or \
- unaligned offset"
- }
- ErrNoMapSupport=> "File doesn't support mapping",
- ErrNoMem => "Invalid address, or not enough available memory",
- ErrUnsupProt => "Protection mode unsupported",
- ErrUnsupOffset => "Offset in virtual memory mode is unsupported",
- ErrAlreadyExists => "File mapping for specified file already exists",
- ErrZeroLength => "Zero-length mapping not allowed",
- ErrUnknown(code) => {
- return write!(out, "Unknown error = {}", code)
- },
- ErrVirtualAlloc(code) => {
- return write!(out, "VirtualAlloc failure = {}", code)
- },
- ErrCreateFileMappingW(code) => {
- return write!(out, "CreateFileMappingW failure = {}", code)
- },
- ErrMapViewOfFile(code) => {
- return write!(out, "MapViewOfFile failure = {}", code)
- }
- };
- write!(out, "{}", str)
- }
-}
-
-impl Error for MapError {
- fn description(&self) -> &str { "memory map error" }
-}
-
-// Round up `from` to be divisible by `to`
-fn round_up(from: usize, to: usize) -> usize {
- let r = if from % to == 0 {
- from
- } else {
- from + to - (from % to)
- };
- if r == 0 {
- to
- } else {
- r
- }
-}
-
-#[cfg(unix)]
-impl MemoryMap {
- /// Create a new mapping with the given `options`, at least `min_len` bytes
- /// long. `min_len` must be greater than zero; see the note on
- /// `ErrZeroLength`.
- pub fn new(min_len: usize, options: &[MapOption]) -> Result<MemoryMap, MapError> {
- use libc::off_t;
-
- if min_len == 0 {
- return Err(ErrZeroLength)
- }
- let mut addr: *const u8 = ptr::null();
- let mut prot = 0;
- let mut flags = libc::MAP_PRIVATE;
- let mut fd = -1;
- let mut offset = 0;
- let mut custom_flags = false;
- let len = round_up(min_len, env::page_size());
-
- for &o in options {
- match o {
- MapReadable => { prot |= libc::PROT_READ; },
- MapWritable => { prot |= libc::PROT_WRITE; },
- MapExecutable => { prot |= libc::PROT_EXEC; },
- MapAddr(addr_) => {
- flags |= libc::MAP_FIXED;
- addr = addr_;
- },
- MapFd(fd_) => {
- flags |= libc::MAP_FILE;
- fd = fd_;
- },
- MapOffset(offset_) => { offset = offset_ as off_t; },
- MapNonStandardFlags(f) => { custom_flags = true; flags = f },
- }
- }
- if fd == -1 && !custom_flags { flags |= libc::MAP_ANON; }
-
- let r = unsafe {
- libc::mmap(addr as *mut c_void, len as libc::size_t, prot, flags,
- fd, offset)
- };
- if r == libc::MAP_FAILED {
- Err(match errno() as c_int {
- libc::EACCES => ErrFdNotAvail,
- libc::EBADF => ErrInvalidFd,
- libc::EINVAL => ErrUnaligned,
- libc::ENODEV => ErrNoMapSupport,
- libc::ENOMEM => ErrNoMem,
- code => ErrUnknown(code as isize)
- })
- } else {
- Ok(MemoryMap {
- data: r as *mut u8,
- len: len,
- kind: if fd == -1 {
- MapVirtual
- } else {
- MapFile(ptr::null())
- }
- })
- }
- }
-
- /// Granularity that the offset or address must be for `MapOffset` and
- /// `MapAddr` respectively.
- pub fn granularity() -> usize {
- env::page_size()
- }
-}
-
-#[cfg(unix)]
-impl Drop for MemoryMap {
- /// Unmap the mapping. Panics the task if `munmap` panics.
- fn drop(&mut self) {
- if self.len == 0 { /* workaround for dummy_stack */ return; }
-
- unsafe {
- // `munmap` only panics due to logic errors
- libc::munmap(self.data as *mut c_void, self.len as libc::size_t);
- }
- }
-}
-
-#[cfg(windows)]
-impl MemoryMap {
- /// Create a new mapping with the given `options`, at least `min_len` bytes long.
- pub fn new(min_len: usize, options: &[MapOption]) -> Result<MemoryMap, MapError> {
- use libc::types::os::arch::extra::{LPVOID, DWORD, SIZE_T, HANDLE};
-
- let mut lpAddress: LPVOID = ptr::null_mut();
- let mut readable = false;
- let mut writable = false;
- let mut executable = false;
- let mut handle: HANDLE = libc::INVALID_HANDLE_VALUE;
- let mut offset: usize = 0;
- let len = round_up(min_len, env::page_size());
-
- for &o in options {
- match o {
- MapReadable => { readable = true; },
- MapWritable => { writable = true; },
- MapExecutable => { executable = true; }
- MapAddr(addr_) => { lpAddress = addr_ as LPVOID; },
- MapFd(handle_) => { handle = handle_; },
- MapOffset(offset_) => { offset = offset_; },
- MapNonStandardFlags(..) => {}
- }
- }
-
- let flProtect = match (executable, readable, writable) {
- (false, false, false) if handle == libc::INVALID_HANDLE_VALUE => libc::PAGE_NOACCESS,
- (false, true, false) => libc::PAGE_READONLY,
- (false, true, true) => libc::PAGE_READWRITE,
- (true, false, false) if handle == libc::INVALID_HANDLE_VALUE => libc::PAGE_EXECUTE,
- (true, true, false) => libc::PAGE_EXECUTE_READ,
- (true, true, true) => libc::PAGE_EXECUTE_READWRITE,
- _ => return Err(ErrUnsupProt)
- };
-
- if handle == libc::INVALID_HANDLE_VALUE {
- if offset != 0 {
- return Err(ErrUnsupOffset);
- }
- let r = unsafe {
- libc::VirtualAlloc(lpAddress,
- len as SIZE_T,
- libc::MEM_COMMIT | libc::MEM_RESERVE,
- flProtect)
- };
- match r as usize {
- 0 => Err(ErrVirtualAlloc(errno())),
- _ => Ok(MemoryMap {
- data: r as *mut u8,
- len: len,
- kind: MapVirtual
- })
- }
- } else {
- let dwDesiredAccess = match (executable, readable, writable) {
- (false, true, false) => libc::FILE_MAP_READ,
- (false, true, true) => libc::FILE_MAP_WRITE,
- (true, true, false) => libc::FILE_MAP_READ | libc::FILE_MAP_EXECUTE,
- (true, true, true) => libc::FILE_MAP_WRITE | libc::FILE_MAP_EXECUTE,
- _ => return Err(ErrUnsupProt) // Actually, because of the check above,
- // we should never get here.
- };
- unsafe {
- let hFile = handle;
- let mapping = libc::CreateFileMappingW(hFile,
- ptr::null_mut(),
- flProtect,
- 0,
- 0,
- ptr::null());
- if mapping == ptr::null_mut() {
- return Err(ErrCreateFileMappingW(errno()));
- }
- if errno() as c_int == libc::ERROR_ALREADY_EXISTS {
- return Err(ErrAlreadyExists);
- }
- let r = libc::MapViewOfFile(mapping,
- dwDesiredAccess,
- ((len as u64) >> 32) as DWORD,
- (offset & 0xffff_ffff) as DWORD,
- 0);
- match r as usize {
- 0 => Err(ErrMapViewOfFile(errno())),
- _ => Ok(MemoryMap {
- data: r as *mut u8,
- len: len,
- kind: MapFile(mapping as *const u8)
- })
- }
- }
- }
- }
-
- /// Granularity of MapAddr() and MapOffset() parameter values.
- /// This may be greater than the value returned by page_size().
- pub fn granularity() -> usize {
- use mem;
- unsafe {
- let mut info = mem::zeroed();
- libc::GetSystemInfo(&mut info);
-
- return info.dwAllocationGranularity as usize;
- }
- }
-}
-
-#[cfg(windows)]
-impl Drop for MemoryMap {
- /// Unmap the mapping. Panics the task if any of `VirtualFree`,
- /// `UnmapViewOfFile`, or `CloseHandle` fail.
- fn drop(&mut self) {
- use libc::types::os::arch::extra::{LPCVOID, HANDLE};
- use libc::consts::os::extra::FALSE;
- if self.len == 0 { return }
-
- unsafe {
- match self.kind {
- MapVirtual => {
- if libc::VirtualFree(self.data as *mut c_void, 0,
- libc::MEM_RELEASE) == 0 {
- println!("VirtualFree failed: {}", errno());
- }
- },
- MapFile(mapping) => {
- if libc::UnmapViewOfFile(self.data as LPCVOID) == FALSE {
- println!("UnmapViewOfFile failed: {}", errno());
- }
- if libc::CloseHandle(mapping as HANDLE) == FALSE {
- println!("CloseHandle failed: {}", errno());
- }
- }
- }
- }
- }
-}
-
-impl MemoryMap {
- /// Returns the pointer to the memory created or modified by this map.
- pub fn data(&self) -> *mut u8 { self.data }
- /// Returns the number of bytes this map applies to.
- pub fn len(&self) -> usize { self.len }
- /// Returns the type of mapping this represents.
- pub fn kind(&self) -> MemoryMapKind { self.kind }
-}
-
-#[cfg(target_os = "linux")]
-#[deprecated(since = "1.0.0", reason = "renamed to env::consts")]
-#[unstable(feature = "os")]
-pub mod consts {
- pub use os::arch_consts::ARCH;
-
- pub const FAMILY: &'static str = "unix";
-
- /// A string describing the specific operating system in use: in this
- /// case, `linux`.
- pub const SYSNAME: &'static str = "linux";
-
- /// Specifies the filename prefix used for shared libraries on this
- /// platform: in this case, `lib`.
- pub const DLL_PREFIX: &'static str = "lib";
-
- /// Specifies the filename suffix used for shared libraries on this
- /// platform: in this case, `.so`.
- pub const DLL_SUFFIX: &'static str = ".so";
-
- /// Specifies the file extension used for shared libraries on this
- /// platform that goes after the dot: in this case, `so`.
- pub const DLL_EXTENSION: &'static str = "so";
-
- /// Specifies the filename suffix used for executable binaries on this
- /// platform: in this case, the empty string.
- pub const EXE_SUFFIX: &'static str = "";
-
- /// Specifies the file extension, if any, used for executable binaries
- /// on this platform: in this case, the empty string.
- pub const EXE_EXTENSION: &'static str = "";
-}
-
-#[cfg(target_os = "macos")]
-#[deprecated(since = "1.0.0", reason = "renamed to env::consts")]
-#[unstable(feature = "os")]
-pub mod consts {
- pub use os::arch_consts::ARCH;
-
- pub const FAMILY: &'static str = "unix";
-
- /// A string describing the specific operating system in use: in this
- /// case, `macos`.
- pub const SYSNAME: &'static str = "macos";
-
- /// Specifies the filename prefix used for shared libraries on this
- /// platform: in this case, `lib`.
- pub const DLL_PREFIX: &'static str = "lib";
-
- /// Specifies the filename suffix used for shared libraries on this
- /// platform: in this case, `.dylib`.
- pub const DLL_SUFFIX: &'static str = ".dylib";
-
- /// Specifies the file extension used for shared libraries on this
- /// platform that goes after the dot: in this case, `dylib`.
- pub const DLL_EXTENSION: &'static str = "dylib";
-
- /// Specifies the filename suffix used for executable binaries on this
- /// platform: in this case, the empty string.
- pub const EXE_SUFFIX: &'static str = "";
-
- /// Specifies the file extension, if any, used for executable binaries
- /// on this platform: in this case, the empty string.
- pub const EXE_EXTENSION: &'static str = "";
-}
-
-#[cfg(target_os = "ios")]
-#[deprecated(since = "1.0.0", reason = "renamed to env::consts")]
-#[unstable(feature = "os")]
-pub mod consts {
- pub use os::arch_consts::ARCH;
-
- pub const FAMILY: &'static str = "unix";
-
- /// A string describing the specific operating system in use: in this
- /// case, `ios`.
- pub const SYSNAME: &'static str = "ios";
-
- /// Specifies the filename suffix used for executable binaries on this
- /// platform: in this case, the empty string.
- pub const EXE_SUFFIX: &'static str = "";
-
- /// Specifies the file extension, if any, used for executable binaries
- /// on this platform: in this case, the empty string.
- pub const EXE_EXTENSION: &'static str = "";
-}
-
-#[cfg(target_os = "freebsd")]
-#[deprecated(since = "1.0.0", reason = "renamed to env::consts")]
-#[unstable(feature = "os")]
-pub mod consts {
- pub use os::arch_consts::ARCH;
-
- pub const FAMILY: &'static str = "unix";
-
- /// A string describing the specific operating system in use: in this
- /// case, `freebsd`.
- pub const SYSNAME: &'static str = "freebsd";
-
- /// Specifies the filename prefix used for shared libraries on this
- /// platform: in this case, `lib`.
- pub const DLL_PREFIX: &'static str = "lib";
-
- /// Specifies the filename suffix used for shared libraries on this
- /// platform: in this case, `.so`.
- pub const DLL_SUFFIX: &'static str = ".so";
-
- /// Specifies the file extension used for shared libraries on this
- /// platform that goes after the dot: in this case, `so`.
- pub const DLL_EXTENSION: &'static str = "so";
-
- /// Specifies the filename suffix used for executable binaries on this
- /// platform: in this case, the empty string.
- pub const EXE_SUFFIX: &'static str = "";
-
- /// Specifies the file extension, if any, used for executable binaries
- /// on this platform: in this case, the empty string.
- pub const EXE_EXTENSION: &'static str = "";
-}
-
-#[cfg(target_os = "dragonfly")]
-#[deprecated(since = "1.0.0", reason = "renamed to env::consts")]
-#[unstable(feature = "os")]
-pub mod consts {
- pub use os::arch_consts::ARCH;
-
- pub const FAMILY: &'static str = "unix";
-
- /// A string describing the specific operating system in use: in this
- /// case, `dragonfly`.
- pub const SYSNAME: &'static str = "dragonfly";
-
- /// Specifies the filename prefix used for shared libraries on this
- /// platform: in this case, `lib`.
- pub const DLL_PREFIX: &'static str = "lib";
-
- /// Specifies the filename suffix used for shared libraries on this
- /// platform: in this case, `.so`.
- pub const DLL_SUFFIX: &'static str = ".so";
-
- /// Specifies the file extension used for shared libraries on this
- /// platform that goes after the dot: in this case, `so`.
- pub const DLL_EXTENSION: &'static str = "so";
-
- /// Specifies the filename suffix used for executable binaries on this
- /// platform: in this case, the empty string.
- pub const EXE_SUFFIX: &'static str = "";
-
- /// Specifies the file extension, if any, used for executable binaries
- /// on this platform: in this case, the empty string.
- pub const EXE_EXTENSION: &'static str = "";
-}
-
-#[cfg(target_os = "bitrig")]
-#[deprecated(since = "1.0.0", reason = "renamed to env::consts")]
-#[unstable(feature = "os")]
-pub mod consts {
- pub use os::arch_consts::ARCH;
-
- pub const FAMILY: &'static str = "unix";
-
- /// A string describing the specific operating system in use: in this
- /// case, `bitrig`.
- pub const SYSNAME: &'static str = "bitrig";
-
- /// Specifies the filename prefix used for shared libraries on this
- /// platform: in this case, `lib`.
- pub const DLL_PREFIX: &'static str = "lib";
-
- /// Specifies the filename suffix used for shared libraries on this
- /// platform: in this case, `.so`.
- pub const DLL_SUFFIX: &'static str = ".so";
-
- /// Specifies the file extension used for shared libraries on this
- /// platform that goes after the dot: in this case, `so`.
- pub const DLL_EXTENSION: &'static str = "so";
-
- /// Specifies the filename suffix used for executable binaries on this
- /// platform: in this case, the empty string.
- pub const EXE_SUFFIX: &'static str = "";
-
- /// Specifies the file extension, if any, used for executable binaries
- /// on this platform: in this case, the empty string.
- pub const EXE_EXTENSION: &'static str = "";
-}
-
-#[cfg(target_os = "openbsd")]
-#[deprecated(since = "1.0.0", reason = "renamed to env::consts")]
-#[unstable(feature = "os")]
-pub mod consts {
- pub use os::arch_consts::ARCH;
-
- pub const FAMILY: &'static str = "unix";
-
- /// A string describing the specific operating system in use: in this
- /// case, `openbsd`.
- pub const SYSNAME: &'static str = "openbsd";
-
- /// Specifies the filename prefix used for shared libraries on this
- /// platform: in this case, `lib`.
- pub const DLL_PREFIX: &'static str = "lib";
-
- /// Specifies the filename suffix used for shared libraries on this
- /// platform: in this case, `.so`.
- pub const DLL_SUFFIX: &'static str = ".so";
-
- /// Specifies the file extension used for shared libraries on this
- /// platform that goes after the dot: in this case, `so`.
- pub const DLL_EXTENSION: &'static str = "so";
-
- /// Specifies the filename suffix used for executable binaries on this
- /// platform: in this case, the empty string.
- pub const EXE_SUFFIX: &'static str = "";
-
- /// Specifies the file extension, if any, used for executable binaries
- /// on this platform: in this case, the empty string.
- pub const EXE_EXTENSION: &'static str = "";
-}
-
-#[cfg(target_os = "android")]
-#[deprecated(since = "1.0.0", reason = "renamed to env::consts")]
-#[unstable(feature = "os")]
-pub mod consts {
- pub use os::arch_consts::ARCH;
-
- pub const FAMILY: &'static str = "unix";
-
- /// A string describing the specific operating system in use: in this
- /// case, `android`.
- pub const SYSNAME: &'static str = "android";
-
- /// Specifies the filename prefix used for shared libraries on this
- /// platform: in this case, `lib`.
- pub const DLL_PREFIX: &'static str = "lib";
-
- /// Specifies the filename suffix used for shared libraries on this
- /// platform: in this case, `.so`.
- pub const DLL_SUFFIX: &'static str = ".so";
-
- /// Specifies the file extension used for shared libraries on this
- /// platform that goes after the dot: in this case, `so`.
- pub const DLL_EXTENSION: &'static str = "so";
-
- /// Specifies the filename suffix used for executable binaries on this
- /// platform: in this case, the empty string.
- pub const EXE_SUFFIX: &'static str = "";
-
- /// Specifies the file extension, if any, used for executable binaries
- /// on this platform: in this case, the empty string.
- pub const EXE_EXTENSION: &'static str = "";
-}
-
-#[cfg(target_os = "windows")]
-#[deprecated(since = "1.0.0", reason = "renamed to env::consts")]
-#[unstable(feature = "os")]
-pub mod consts {
- pub use os::arch_consts::ARCH;
-
- pub const FAMILY: &'static str = "windows";
-
- /// A string describing the specific operating system in use: in this
- /// case, `windows`.
- pub const SYSNAME: &'static str = "windows";
-
- /// Specifies the filename prefix used for shared libraries on this
- /// platform: in this case, the empty string.
- pub const DLL_PREFIX: &'static str = "";
-
- /// Specifies the filename suffix used for shared libraries on this
- /// platform: in this case, `.dll`.
- pub const DLL_SUFFIX: &'static str = ".dll";
-
- /// Specifies the file extension used for shared libraries on this
- /// platform that goes after the dot: in this case, `dll`.
- pub const DLL_EXTENSION: &'static str = "dll";
-
- /// Specifies the filename suffix used for executable binaries on this
- /// platform: in this case, `.exe`.
- pub const EXE_SUFFIX: &'static str = ".exe";
-
- /// Specifies the file extension, if any, used for executable binaries
- /// on this platform: in this case, `exe`.
- pub const EXE_EXTENSION: &'static str = "exe";
-}
-
-#[cfg(target_arch = "x86")]
-mod arch_consts {
- pub const ARCH: &'static str = "x86";
-}
-
-#[cfg(target_arch = "x86_64")]
-mod arch_consts {
- pub const ARCH: &'static str = "x86_64";
-}
-
-#[cfg(target_arch = "arm")]
-mod arch_consts {
- pub const ARCH: &'static str = "arm";
-}
-
-#[cfg(target_arch = "aarch64")]
-mod arch_consts {
- pub const ARCH: &'static str = "aarch64";
-}
-
-#[cfg(target_arch = "mips")]
-mod arch_consts {
- pub const ARCH: &'static str = "mips";
-}
-
-#[cfg(target_arch = "mipsel")]
-mod arch_consts {
- pub const ARCH: &'static str = "mipsel";
-}
-
-#[cfg(target_arch = "powerpc")]
-mod arch_consts {
- pub const ARCH: &'static str = "powerpc";
-}
-
-#[cfg(test)]
-mod tests {
- #![allow(deprecated)] // rand
-
- use prelude::v1::*;
-
- use iter::repeat;
- use os::{env, getcwd, getenv, make_absolute};
- use os::{split_paths, join_paths, setenv, unsetenv};
- use os;
- use rand::Rng;
- use rand;
- use old_path::{Path, GenericPath};
- use old_io::{Reader, Writer, Seek};
-
- #[test]
- pub fn last_os_error() {
- debug!("{}", os::last_os_error());
- }
-
- fn make_rand_name() -> String {
- let mut rng = rand::thread_rng();
- let n = format!("TEST{}", rng.gen_ascii_chars().take(10)
- .collect::<String>());
- assert!(getenv(&n).is_none());
- n
- }
-
- #[test]
- fn test_num_cpus() {
- assert!(os::num_cpus() > 0);
- }
-
- #[test]
- fn test_setenv() {
- let n = make_rand_name();
- setenv(&n, "VALUE");
- assert_eq!(getenv(&n), Some("VALUE".to_string()));
- }
-
- #[test]
- fn test_unsetenv() {
- let n = make_rand_name();
- setenv(&n, "VALUE");
- unsetenv(&n);
- assert_eq!(getenv(&n), None);
- }
-
- #[test]
- #[ignore]
- fn test_setenv_overwrite() {
- let n = make_rand_name();
- setenv(&n, "1");
- setenv(&n, "2");
- assert_eq!(getenv(&n), Some("2".to_string()));
- setenv(&n, "");
- assert_eq!(getenv(&n), Some("".to_string()));
- }
-
- // Windows GetEnvironmentVariable requires some extra work to make sure
- // the buffer the variable is copied into is the right size
- #[test]
- #[ignore]
- fn test_getenv_big() {
- let mut s = "".to_string();
- let mut i = 0;
- while i < 100 {
- s.push_str("aaaaaaaaaa");
- i += 1;
- }
- let n = make_rand_name();
- setenv(&n, &s);
- debug!("{}", s.clone());
- assert_eq!(getenv(&n), Some(s));
- }
-
- #[test]
- fn test_self_exe_name() {
- let path = os::self_exe_name();
- assert!(path.is_some());
- let path = path.unwrap();
- debug!("{}", path.display());
-
- // Hard to test this function
- assert!(path.is_absolute());
- }
-
- #[test]
- fn test_self_exe_path() {
- let path = os::self_exe_path();
- assert!(path.is_some());
- let path = path.unwrap();
- debug!("{}", path.display());
-
- // Hard to test this function
- assert!(path.is_absolute());
- }
-
- #[test]
- #[ignore]
- fn test_env_getenv() {
- let e = env();
- assert!(e.len() > 0);
- for p in &e {
- let (n, v) = (*p).clone();
- debug!("{}", n);
- let v2 = getenv(&n);
- // MingW seems to set some funky environment variables like
- // "=C:=C:\MinGW\msys\1.0\bin" and "!::=::\" that are returned
- // from env() but not visible from getenv().
- assert!(v2.is_none() || v2 == Some(v));
- }
- }
-
- #[test]
- fn test_env_set_get_huge() {
- let n = make_rand_name();
- let s = repeat("x").take(10000).collect::<String>();
- setenv(&n, &s);
- assert_eq!(getenv(&n), Some(s));
- unsetenv(&n);
- assert_eq!(getenv(&n), None);
- }
-
- #[test]
- fn test_env_setenv() {
- let n = make_rand_name();
-
- let mut e = env();
- setenv(&n, "VALUE");
- assert!(!e.contains(&(n.clone(), "VALUE".to_string())));
-
- e = env();
- assert!(e.contains(&(n, "VALUE".to_string())));
- }
-
- #[test]
- fn test() {
- assert!((!Path::new("test-path").is_absolute()));
-
- let cwd = getcwd().unwrap();
- debug!("Current working directory: {}", cwd.display());
-
- debug!("{}", make_absolute(&Path::new("test-path")).unwrap().display());
- debug!("{}", make_absolute(&Path::new("/usr/bin")).unwrap().display());
- }
-
- #[test]
- #[cfg(unix)]
- fn homedir() {
- let oldhome = getenv("HOME");
-
- setenv("HOME", "/home/MountainView");
- assert!(os::homedir() == Some(Path::new("/home/MountainView")));
-
- setenv("HOME", "");
- assert!(os::homedir().is_none());
-
- if let Some(s) = oldhome {
- setenv("HOME", s);
- }
- }
-
- #[test]
- #[cfg(windows)]
- fn homedir() {
-
- let oldhome = getenv("HOME");
- let olduserprofile = getenv("USERPROFILE");
-
- setenv("HOME", "");
- setenv("USERPROFILE", "");
-
- assert!(os::homedir().is_none());
-
- setenv("HOME", "/home/MountainView");
- assert!(os::homedir() == Some(Path::new("/home/MountainView")));
-
- setenv("HOME", "");
-
- setenv("USERPROFILE", "/home/MountainView");
- assert!(os::homedir() == Some(Path::new("/home/MountainView")));
-
- setenv("HOME", "/home/MountainView");
- setenv("USERPROFILE", "/home/PaloAlto");
- assert!(os::homedir() == Some(Path::new("/home/MountainView")));
-
- if let Some(s) = oldhome {
- setenv("HOME", &s);
- }
- if let Some(s) = olduserprofile {
- setenv("USERPROFILE", &s);
- }
- }
-
- #[test]
- fn memory_map_rw() {
- use result::Result::{Ok, Err};
-
- let chunk = match os::MemoryMap::new(16, &[
- os::MapOption::MapReadable,
- os::MapOption::MapWritable
- ]) {
- Ok(chunk) => chunk,
- Err(msg) => panic!("{:?}", msg)
- };
- assert!(chunk.len >= 16);
-
- unsafe {
- *chunk.data = 0xBE;
- assert!(*chunk.data == 0xBE);
- }
- }
-
- #[test]
- fn memory_map_file() {
- use libc;
- use os::*;
- use old_io::fs::{File, unlink};
- use old_io::SeekStyle::SeekSet;
- use old_io::FileMode::Open;
- use old_io::FileAccess::ReadWrite;
-
- #[cfg(not(windows))]
- fn get_fd(file: &File) -> libc::c_int {
- use os::unix::prelude::*;
- file.as_raw_fd()
- }
-
- #[cfg(windows)]
- fn get_fd(file: &File) -> libc::HANDLE {
- use os::windows::prelude::*;
- file.as_raw_handle()
- }
-
- let mut path = tmpdir();
- path.push("mmap_file.tmp");
- let size = MemoryMap::granularity() * 2;
- let mut file = File::open_mode(&path, Open, ReadWrite).unwrap();
- file.seek(size as i64, SeekSet).unwrap();
- file.write_u8(0).unwrap();
-
- let chunk = MemoryMap::new(size / 2, &[
- MapOption::MapReadable,
- MapOption::MapWritable,
- MapOption::MapFd(get_fd(&file)),
- MapOption::MapOffset(size / 2)
- ]).unwrap();
- assert!(chunk.len > 0);
-
- unsafe {
- *chunk.data = 0xbe;
- assert!(*chunk.data == 0xbe);
- }
- drop(chunk);
-
- unlink(&path).unwrap();
- }
-
- #[test]
- #[cfg(windows)]
- fn split_paths_windows() {
- fn check_parse(unparsed: &str, parsed: &[&str]) -> bool {
- split_paths(unparsed) ==
- parsed.iter().map(|s| Path::new(*s)).collect::<Vec<_>>()
- }
-
- assert!(check_parse("", &mut [""]));
- assert!(check_parse(r#""""#, &mut [""]));
- assert!(check_parse(";;", &mut ["", "", ""]));
- assert!(check_parse(r"c:\", &mut [r"c:\"]));
- assert!(check_parse(r"c:\;", &mut [r"c:\", ""]));
- assert!(check_parse(r"c:\;c:\Program Files\",
- &mut [r"c:\", r"c:\Program Files\"]));
- assert!(check_parse(r#"c:\;c:\"foo"\"#, &mut [r"c:\", r"c:\foo\"]));
- assert!(check_parse(r#"c:\;c:\"foo;bar"\;c:\baz"#,
- &mut [r"c:\", r"c:\foo;bar\", r"c:\baz"]));
- }
-
- #[test]
- #[cfg(unix)]
- fn split_paths_unix() {
- fn check_parse(unparsed: &str, parsed: &[&str]) -> bool {
- split_paths(unparsed) ==
- parsed.iter().map(|s| Path::new(*s)).collect::<Vec<_>>()
- }
-
- assert!(check_parse("", &mut [""]));
- assert!(check_parse("::", &mut ["", "", ""]));
- assert!(check_parse("/", &mut ["/"]));
- assert!(check_parse("/:", &mut ["/", ""]));
- assert!(check_parse("/:/usr/local", &mut ["/", "/usr/local"]));
- }
-
- #[test]
- #[cfg(unix)]
- fn join_paths_unix() {
- fn test_eq(input: &[&str], output: &str) -> bool {
- join_paths(input).unwrap() == output.as_bytes()
- }
-
- assert!(test_eq(&[], ""));
- assert!(test_eq(&["/bin", "/usr/bin", "/usr/local/bin"],
- "/bin:/usr/bin:/usr/local/bin"));
- assert!(test_eq(&["", "/bin", "", "", "/usr/bin", ""],
- ":/bin:::/usr/bin:"));
- assert!(join_paths(&["/te:st"]).is_err());
- }
-
- #[test]
- #[cfg(windows)]
- fn join_paths_windows() {
- fn test_eq(input: &[&str], output: &str) -> bool {
- join_paths(input).unwrap() == output.as_bytes()
- }
-
- assert!(test_eq(&[], ""));
- assert!(test_eq(&[r"c:\windows", r"c:\"],
- r"c:\windows;c:\"));
- assert!(test_eq(&["", r"c:\windows", "", "", r"c:\", ""],
- r";c:\windows;;;c:\;"));
- assert!(test_eq(&[r"c:\te;st", r"c:\"],
- r#""c:\te;st";c:\"#));
- assert!(join_paths(&[r#"c:\te"st"#]).is_err());
- }
-
- // More recursive_mkdir tests are in extra::tempfile
-}
//! To build or modify paths, use `PathBuf`:
//!
//! ```rust
-//! # #![feature(convert)]
//! use std::path::PathBuf;
//!
//! let mut path = PathBuf::from("c:\\");
pub fn as_os_str(self) -> &'a OsStr {
match self {
Component::Prefix(p) => p.as_os_str(),
- Component::RootDir => OsStr::from_str(MAIN_SEP_STR),
- Component::CurDir => OsStr::from_str("."),
- Component::ParentDir => OsStr::from_str(".."),
+ Component::RootDir => OsStr::new(MAIN_SEP_STR),
+ Component::CurDir => OsStr::new("."),
+ Component::ParentDir => OsStr::new(".."),
Component::Normal(path) => path,
}
}
/// # Examples
///
/// ```
-/// # #![feature(convert)]
/// use std::path::PathBuf;
///
/// let mut path = PathBuf::from("c:\\");
PathBuf { inner: OsString::new() }
}
+ /// Coerce to a `Path` slice.
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub fn as_path(&self) -> &Path {
+ self
+ }
+
/// Extend `self` with `path`.
///
/// If `path` is absolute, it replaces the current path.
/// # Examples
///
/// ```
- /// # #![feature(convert)]
/// use std::path::PathBuf;
///
/// let mut buf = PathBuf::from("/");
#[stable(feature = "rust1", since = "1.0.0")]
pub fn file_name(&self) -> Option<&OsStr> {
self.components().next_back().and_then(|p| match p {
- Component::Normal(p) => Some(p.as_os_str()),
+ Component::Normal(p) => Some(p.as_ref()),
_ => None
})
}
#[stable(feature = "rust1", since = "1.0.0")]
#[doc(no_inline)] pub use result::Result::{self, Ok, Err};
#[stable(feature = "rust1", since = "1.0.0")]
-#[allow(deprecated)]
-#[doc(no_inline)] pub use slice::{SliceConcatExt, AsSlice};
-#[stable(feature = "rust1", since = "1.0.0")]
-#[allow(deprecated)]
-#[doc(no_inline)] pub use str::Str;
+#[doc(no_inline)] pub use slice::SliceConcatExt;
#[stable(feature = "rust1", since = "1.0.0")]
#[doc(no_inline)] pub use string::{String, ToString};
#[stable(feature = "rust1", since = "1.0.0")]
#[doc(no_inline)] pub use vec::Vec;
+
+#[allow(deprecated)] pub use slice::AsSlice;
+#[allow(deprecated)] pub use str::Str;
use prelude::v1::*;
use io::prelude::*;
-use ffi::AsOsStr;
+use ffi::OsStr;
use fmt;
use io::{self, Error, ErrorKind};
use libc;
use path;
use sync::mpsc::{channel, Receiver};
use sys::pipe2::{self, AnonPipe};
-use sys::process2::Process as ProcessImp;
use sys::process2::Command as CommandImp;
+use sys::process2::Process as ProcessImp;
use sys::process2::ExitStatus as ExitStatusImp;
use sys_common::{AsInner, AsInnerMut};
use thread;
/// Builder methods are provided to change these defaults and
/// otherwise configure the process.
#[stable(feature = "process", since = "1.0.0")]
- pub fn new<S: AsOsStr>(program: S) -> Command {
+ pub fn new<S: AsRef<OsStr>>(program: S) -> Command {
Command {
- inner: CommandImp::new(program.as_os_str()),
+ inner: CommandImp::new(program.as_ref()),
stdin: None,
stdout: None,
stderr: None,
/// Add an argument to pass to the program.
#[stable(feature = "process", since = "1.0.0")]
- pub fn arg<S: AsOsStr>(&mut self, arg: S) -> &mut Command {
- self.inner.arg(arg.as_os_str());
+ pub fn arg<S: AsRef<OsStr>>(&mut self, arg: S) -> &mut Command {
+ self.inner.arg(arg.as_ref());
self
}
/// Add multiple arguments to pass to the program.
#[stable(feature = "process", since = "1.0.0")]
- pub fn args<S: AsOsStr>(&mut self, args: &[S]) -> &mut Command {
- self.inner.args(args.iter().map(AsOsStr::as_os_str));
+ pub fn args<S: AsRef<OsStr>>(&mut self, args: &[S]) -> &mut Command {
+ self.inner.args(args.iter().map(AsRef::as_ref));
self
}
/// and case-sensitive on all other platforms.
#[stable(feature = "process", since = "1.0.0")]
pub fn env<K, V>(&mut self, key: K, val: V) -> &mut Command
- where K: AsOsStr, V: AsOsStr
+ where K: AsRef<OsStr>, V: AsRef<OsStr>
{
- self.inner.env(key.as_os_str(), val.as_os_str());
+ self.inner.env(key.as_ref(), val.as_ref());
self
}
/// Removes an environment variable mapping.
#[stable(feature = "process", since = "1.0.0")]
- pub fn env_remove<K: AsOsStr>(&mut self, key: K) -> &mut Command {
- self.inner.env_remove(key.as_os_str());
+ pub fn env_remove<K: AsRef<OsStr>>(&mut self, key: K) -> &mut Command {
+ self.inner.env_remove(key.as_ref());
self
}
/// Set the working directory for the child process.
#[stable(feature = "process", since = "1.0.0")]
pub fn current_dir<P: AsRef<path::Path>>(&mut self, dir: P) -> &mut Command {
- self.inner.cwd(dir.as_ref().as_os_str());
+ self.inner.cwd(dir.as_ref().as_ref());
self
}
}
impl Stdio {
- /// A new pipe should be arranged to connect the parent and child processes.
- #[unstable(feature = "process_capture")]
- #[deprecated(since = "1.0.0", reason = "renamed to `Stdio::piped`")]
- pub fn capture() -> Stdio { Stdio::piped() }
-
/// A new pipe should be arranged to connect the parent and child processes.
#[stable(feature = "process", since = "1.0.0")]
pub fn piped() -> Stdio { Stdio(StdioImp::Piped) }
}
}
+/// Terminates the current process with the specified exit code.
+///
+/// This function will never return and will immediately terminate the current
+/// process. The exit code is passed through to the underlying OS and will be
+/// available for consumption by another process.
+///
+/// Note that because this function never returns, and that it terminates the
+/// process, no destructors on the current stack or any other thread's stack
+/// will be run. If a clean shutdown is needed it is recommended to only call
+/// this function at a known point where there are no more destructors left
+/// to run.
+#[stable(feature = "rust1", since = "1.0.0")]
+pub fn exit(code: i32) -> ! {
+ ::sys::os::exit(code)
+}
+
#[cfg(test)]
mod tests {
- use io::ErrorKind;
+ use prelude::v1::*;
use io::prelude::*;
- use prelude::v1::{Ok, Err, drop, Some, Vec};
- use prelude::v1::{String, Clone};
- use prelude::v1::{Str, AsSlice, ToString};
+
+ use io::ErrorKind;
use old_path::{self, GenericPath};
use old_io::fs::PathExtensions;
use rt::running_on_valgrind;
fn test_process_output_output() {
let Output {status, stdout, stderr}
= Command::new("echo").arg("hello").output().unwrap();
- let output_str = str::from_utf8(stdout.as_slice()).unwrap();
+ let output_str = str::from_utf8(&stdout).unwrap();
assert!(status.success());
assert_eq!(output_str.trim().to_string(), "hello");
let prog = Command::new("echo").arg("hello").stdout(Stdio::piped())
.spawn().unwrap();
let Output {status, stdout, stderr} = prog.wait_with_output().unwrap();
- let output_str = str::from_utf8(stdout.as_slice()).unwrap();
+ let output_str = str::from_utf8(&stdout).unwrap();
assert!(status.success());
assert_eq!(output_str.trim().to_string(), "hello");
let prog = pwd_cmd().spawn().unwrap();
let output = String::from_utf8(prog.wait_with_output().unwrap().stdout).unwrap();
- let parent_dir = os::getcwd().unwrap();
+ let parent_dir = ::env::current_dir().unwrap().to_str().unwrap().to_string();
+ let parent_dir = old_path::Path::new(parent_dir);
let child_dir = old_path::Path::new(output.trim());
let parent_stat = parent_dir.stat().unwrap();
use os;
// test changing to the parent of os::getcwd() because we know
// the path exists (and os::getcwd() is not expected to be root)
- let parent_dir = os::getcwd().unwrap().dir_path();
+ let parent_dir = ::env::current_dir().unwrap().to_str().unwrap().to_string();
+ let parent_dir = old_path::Path::new(parent_dir).dir_path();
let result = pwd_cmd().current_dir(parent_dir.as_str().unwrap()).output().unwrap();
let output = String::from_utf8(result.stdout).unwrap();
cmd.env("PATH", &p);
}
let result = cmd.output().unwrap();
- let output = String::from_utf8_lossy(result.stdout.as_slice()).to_string();
+ let output = String::from_utf8_lossy(&result.stdout).to_string();
assert!(output.contains("RUN_TEST_NEW_ENV=123"),
"didn't find RUN_TEST_NEW_ENV inside of:\n\n{}", output);
#[test]
fn test_add_to_env() {
let result = env_cmd().env("RUN_TEST_NEW_ENV", "123").output().unwrap();
- let output = String::from_utf8_lossy(result.stdout.as_slice()).to_string();
+ let output = String::from_utf8_lossy(&result.stdout).to_string();
assert!(output.contains("RUN_TEST_NEW_ENV=123"),
"didn't find RUN_TEST_NEW_ENV inside of:\n\n{}", output);
#[cfg(all(unix, not(target_os = "ios")))]
mod imp {
- extern crate libc;
-
+ use prelude::v1::*;
use self::OsRngInner::*;
+ use libc;
+ use mem;
use old_io::{IoResult, File};
use old_path::Path;
use rand::Rng;
use rand::reader::ReaderRng;
- use result::Result::Ok;
- use mem;
- use os::errno;
+ use sys::os::errno;
#[cfg(all(target_os = "linux",
any(target_arch = "x86_64",
#[cfg(target_os = "ios")]
mod imp {
- extern crate libc;
+ use prelude::v1::*;
- use old_io::{IoResult};
+ use old_io::IoResult;
use mem;
use os;
use rand::Rng;
- use result::Result::{Ok};
- use self::libc::{c_int, size_t};
+ use libc::{c_int, size_t};
/// A random number generator that retrieves randomness straight from
/// the operating system. Platform sources:
#[cfg(windows)]
mod imp {
- extern crate libc;
+ use prelude::v1::*;
- use old_io::{IoResult, IoError};
+ use io;
use mem;
- use ops::Drop;
- use os;
+ use old_io::{IoResult, IoError};
use rand::Rng;
- use result::Result::{Ok, Err};
- use self::libc::{DWORD, BYTE, LPCSTR, BOOL};
- use self::libc::types::os::arch::extra::{LONG_PTR};
+ use libc::types::os::arch::extra::{LONG_PTR};
+ use libc::{DWORD, BYTE, LPCSTR, BOOL};
type HCRYPTPROV = LONG_PTR;
v.as_mut_ptr())
};
if ret == 0 {
- panic!("couldn't generate random bytes: {}", os::last_os_error());
+ panic!("couldn't generate random bytes: {}",
+ io::Error::last_os_error());
}
}
}
CryptReleaseContext(self.hcryptprov, 0)
};
if ret == 0 {
- panic!("couldn't release context: {}", os::last_os_error());
+ panic!("couldn't release context: {}",
+ io::Error::last_os_error());
}
}
}
#[cfg(test)]
mod tests {
use prelude::v1::*;
- use finally::Finally;
use super::*;
assert!(take() == Some(expected.clone()));
assert!(take() == None);
- (|| {
- }).finally(|| {
- // Restore the actual global state.
- match saved_value {
- Some(ref args) => put(args.clone()),
- None => ()
- }
- })
+ // Restore the actual global state.
+ match saved_value {
+ Some(ref args) => put(args.clone()),
+ None => ()
+ }
}
}
}
pub use self::poison::{PoisonError, TryLockError, TryLockResult, LockResult};
pub use self::future::Future;
-#[allow(deprecated)]
-pub use self::task_pool::TaskPool;
pub mod mpsc;
mod poison;
mod rwlock;
mod semaphore;
-mod task_pool;
//! ```
//!
//! Reading from a channel with a timeout requires to use a Timer together
-//! with the channel. You can use the select! macro to select either and
+//! with the channel. You can use the `select!` macro to select either and
//! handle the timeout case. This first example will break out of the loop
//! after 10 seconds no matter what:
//!
use prelude::v1::*;
use cell::UnsafeCell;
-use error::{Error, FromError};
+use error::{Error};
use fmt;
use thread;
PoisonError { guard: guard }
}
- /// Consumes this error indicating that a lock is poisoned, returning the
- /// underlying guard to allow access regardless.
- #[unstable(feature = "std_misc")]
- #[deprecated(since = "1.0.0", reason = "renamed to into_inner")]
- pub fn into_guard(self) -> T { self.guard }
-
/// Consumes this error indicating that a lock is poisoned, returning the
/// underlying guard to allow access regardless.
#[unstable(feature = "std_misc")]
pub fn get_mut(&mut self) -> &mut T { &mut self.guard }
}
-impl<T> FromError<PoisonError<T>> for TryLockError<T> {
- fn from_error(err: PoisonError<T>) -> TryLockError<T> {
+impl<T> From<PoisonError<T>> for TryLockError<T> {
+ fn from(err: PoisonError<T>) -> TryLockError<T> {
TryLockError::Poisoned(err)
}
}
+++ /dev/null
-// Copyright 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.
-
-//! Abstraction of a thread pool for basic parallelism.
-
-#![deprecated(since = "1.0.0",
- reason = "This kind of API needs some time to bake in \
- crates.io. This functionality is available through \
- https://crates.io/crates/threadpool")]
-#![unstable(feature = "std_misc")]
-
-#![allow(deprecated)]
-
-use core::prelude::*;
-
-use sync::{Arc, Mutex};
-use sync::mpsc::{channel, Sender, Receiver};
-use thread;
-use thunk::Thunk;
-
-struct Sentinel<'a> {
- jobs: &'a Arc<Mutex<Receiver<Thunk<'static>>>>,
- active: bool
-}
-
-impl<'a> Sentinel<'a> {
- fn new(jobs: &'a Arc<Mutex<Receiver<Thunk<'static>>>>) -> Sentinel<'a> {
- Sentinel {
- jobs: jobs,
- active: true
- }
- }
-
- // Cancel and destroy this sentinel.
- fn cancel(mut self) {
- self.active = false;
- }
-}
-
-#[unsafe_destructor]
-impl<'a> Drop for Sentinel<'a> {
- fn drop(&mut self) {
- if self.active {
- spawn_in_pool(self.jobs.clone())
- }
- }
-}
-
-/// A thread pool used to execute functions in parallel.
-///
-/// Spawns `n` worker threads and replenishes the pool if any worker threads
-/// panic.
-///
-/// # Examples
-///
-/// ```
-/// # #![feature(std_misc, core)]
-/// use std::sync::TaskPool;
-/// use std::iter::AdditiveIterator;
-/// use std::sync::mpsc::channel;
-///
-/// let pool = TaskPool::new(4);
-///
-/// let (tx, rx) = channel();
-/// for _ in 0..8 {
-/// let tx = tx.clone();
-/// pool.execute(move|| {
-/// tx.send(1_u32).unwrap();
-/// });
-/// }
-///
-/// assert_eq!(rx.iter().take(8).sum(), 8);
-/// ```
-pub struct TaskPool {
- // How the threadpool communicates with subthreads.
- //
- // This is the only such Sender, so when it is dropped all subthreads will
- // quit.
- jobs: Sender<Thunk<'static>>
-}
-
-impl TaskPool {
- /// Spawns a new thread pool with `threads` threads.
- ///
- /// # Panics
- ///
- /// This function will panic if `threads` is 0.
- pub fn new(threads: usize) -> TaskPool {
- assert!(threads >= 1);
-
- let (tx, rx) = channel::<Thunk>();
- let rx = Arc::new(Mutex::new(rx));
-
- // Threadpool threads
- for _ in 0..threads {
- spawn_in_pool(rx.clone());
- }
-
- TaskPool { jobs: tx }
- }
-
- /// Executes the function `job` on a thread in the pool.
- pub fn execute<F>(&self, job: F)
- where F : FnOnce(), F : Send + 'static
- {
- self.jobs.send(Thunk::new(job)).unwrap();
- }
-}
-
-fn spawn_in_pool(jobs: Arc<Mutex<Receiver<Thunk<'static>>>>) {
- thread::spawn(move || {
- // Will spawn a new thread on panic unless it is cancelled.
- let sentinel = Sentinel::new(&jobs);
-
- loop {
- let message = {
- // Only lock jobs for the time it takes
- // to get a job, not run it.
- let lock = jobs.lock().unwrap();
- lock.recv()
- };
-
- match message {
- Ok(job) => job.invoke(()),
-
- // The Taskpool was dropped.
- Err(..) => break
- }
- }
-
- sentinel.cancel();
- });
-}
-
-#[cfg(test)]
-mod test {
- use prelude::v1::*;
- use super::*;
- use sync::mpsc::channel;
-
- const TEST_TASKS: usize = 4;
-
- #[test]
- fn test_works() {
- use iter::AdditiveIterator;
-
- let pool = TaskPool::new(TEST_TASKS);
-
- let (tx, rx) = channel();
- for _ in 0..TEST_TASKS {
- let tx = tx.clone();
- pool.execute(move|| {
- tx.send(1).unwrap();
- });
- }
-
- assert_eq!(rx.iter().take(TEST_TASKS).sum(), TEST_TASKS);
- }
-
- #[test]
- #[should_panic]
- fn test_zero_tasks_panic() {
- TaskPool::new(0);
- }
-
- #[test]
- fn test_recovery_from_subtask_panic() {
- use iter::AdditiveIterator;
-
- let pool = TaskPool::new(TEST_TASKS);
-
- // Panic all the existing threads.
- for _ in 0..TEST_TASKS {
- pool.execute(move|| -> () { panic!() });
- }
-
- // Ensure new threads were spawned to compensate.
- let (tx, rx) = channel();
- for _ in 0..TEST_TASKS {
- let tx = tx.clone();
- pool.execute(move|| {
- tx.send(1).unwrap();
- });
- }
-
- assert_eq!(rx.iter().take(TEST_TASKS).sum(), TEST_TASKS);
- }
-
- #[test]
- fn test_should_not_panic_on_drop_if_subtasks_panic_after_drop() {
- use sync::{Arc, Barrier};
-
- let pool = TaskPool::new(TEST_TASKS);
- let waiter = Arc::new(Barrier::new(TEST_TASKS + 1));
-
- // Panic all the existing threads in a bit.
- for _ in 0..TEST_TASKS {
- let waiter = waiter.clone();
- pool.execute(move|| {
- waiter.wait();
- panic!();
- });
- }
-
- drop(pool);
-
- // Kick off the failure.
- waiter.wait();
- }
-}
}
}
+impl FromInner<Socket> for TcpStream {
+ fn from_inner(socket: Socket) -> TcpStream {
+ TcpStream { inner: socket }
+ }
+}
+
////////////////////////////////////////////////////////////////////////////////
// TCP listeners
////////////////////////////////////////////////////////////////////////////////
}
}
+impl FromInner<Socket> for TcpListener {
+ fn from_inner(socket: Socket) -> TcpListener {
+ TcpListener { inner: socket }
+ }
+}
+
////////////////////////////////////////////////////////////////////////////////
// UDP
////////////////////////////////////////////////////////////////////////////////
self.inner.duplicate().map(|s| UdpSocket { inner: s })
}
}
+
+impl FromInner<Socket> for UdpSocket {
+ fn from_inner(socket: Socket) -> UdpSocket {
+ UdpSocket { inner: socket }
+ }
+}
fn print(w: &mut Write, idx: isize, addr: *mut libc::c_void,
symaddr: *mut libc::c_void) -> io::Result<()> {
use env;
- use ffi::AsOsStr;
use os::unix::prelude::*;
use ptr;
#![stable(feature = "rust1", since = "1.0.0")]
/// Unix-specific extensions to general I/O primitives
-#[unstable(feature = "io_ext",
- reason = "may want a slightly different organization or a more \
- general file descriptor primitive")]
+#[stable(feature = "rust1", since = "1.0.0")]
pub mod io {
#[allow(deprecated)] use old_io;
use fs;
use libc;
use net;
- use sys_common::AsInner;
+ use sys_common::{net2, AsInner, FromInner};
+ use sys;
/// Raw file descriptors.
- pub type Fd = libc::c_int;
-
- /// Extract raw file descriptor
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub type RawFd = libc::c_int;
+
+ /// A trait to extract the raw unix file descriptor from an underlying
+ /// object.
+ ///
+ /// This is only available on unix platforms and must be imported in order
+ /// to call the method. Windows platforms have a corresponding `AsRawHandle`
+ /// and `AsRawSocket` set of traits.
+ #[stable(feature = "rust1", since = "1.0.0")]
pub trait AsRawFd {
- /// Extract the raw file descriptor, without taking any ownership.
- fn as_raw_fd(&self) -> Fd;
+ /// Extract the raw file descriptor.
+ ///
+ /// This method does **not** pass ownership of the raw file descriptor
+ /// to the caller. The descriptor is only guarantee to be valid while
+ /// the original object has not yet been destroyed.
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn as_raw_fd(&self) -> RawFd;
+ }
+
+ /// A trait to express the ability to construct an object from a raw file
+ /// descriptor.
+ #[unstable(feature = "from_raw_os",
+ reason = "recent addition to std::os::unix::io")]
+ pub trait FromRawFd {
+ /// Constructs a new instances of `Self` from the given raw file
+ /// descriptor.
+ ///
+ /// This function **consumes ownership** of the specified file
+ /// descriptor. The returned object will take responsibility for closing
+ /// it when the object goes out of scope.
+ ///
+ /// Callers should normally only pass in a valid file descriptor to this
+ /// method or otherwise methods will return errors.
+ fn from_raw_fd(fd: RawFd) -> Self;
}
#[allow(deprecated)]
+ #[stable(feature = "rust1", since = "1.0.0")]
impl AsRawFd for old_io::fs::File {
- fn as_raw_fd(&self) -> Fd {
+ fn as_raw_fd(&self) -> RawFd {
self.as_inner().fd()
}
}
+ #[stable(feature = "rust1", since = "1.0.0")]
impl AsRawFd for fs::File {
- fn as_raw_fd(&self) -> Fd {
+ fn as_raw_fd(&self) -> RawFd {
self.as_inner().fd().raw()
}
}
+ #[unstable(feature = "from_raw_os", reason = "trait is unstable")]
+ impl FromRawFd for fs::File {
+ fn from_raw_fd(fd: RawFd) -> fs::File {
+ fs::File::from_inner(sys::fs2::File::from_inner(fd))
+ }
+ }
#[allow(deprecated)]
+ #[stable(feature = "rust1", since = "1.0.0")]
impl AsRawFd for old_io::pipe::PipeStream {
- fn as_raw_fd(&self) -> Fd {
+ fn as_raw_fd(&self) -> RawFd {
self.as_inner().fd()
}
}
#[allow(deprecated)]
+ #[stable(feature = "rust1", since = "1.0.0")]
impl AsRawFd for old_io::net::pipe::UnixStream {
- fn as_raw_fd(&self) -> Fd {
+ fn as_raw_fd(&self) -> RawFd {
self.as_inner().fd()
}
}
#[allow(deprecated)]
+ #[stable(feature = "rust1", since = "1.0.0")]
impl AsRawFd for old_io::net::pipe::UnixListener {
- fn as_raw_fd(&self) -> Fd {
+ fn as_raw_fd(&self) -> RawFd {
self.as_inner().fd()
}
}
#[allow(deprecated)]
+ #[stable(feature = "rust1", since = "1.0.0")]
impl AsRawFd for old_io::net::pipe::UnixAcceptor {
- fn as_raw_fd(&self) -> Fd {
+ fn as_raw_fd(&self) -> RawFd {
self.as_inner().fd()
}
}
+ #[stable(feature = "rust1", since = "1.0.0")]
#[allow(deprecated)]
impl AsRawFd for old_io::net::tcp::TcpStream {
- fn as_raw_fd(&self) -> Fd {
+ fn as_raw_fd(&self) -> RawFd {
self.as_inner().fd()
}
}
+ #[stable(feature = "rust1", since = "1.0.0")]
#[allow(deprecated)]
impl AsRawFd for old_io::net::tcp::TcpListener {
- fn as_raw_fd(&self) -> Fd {
+ fn as_raw_fd(&self) -> RawFd {
self.as_inner().fd()
}
}
+ #[stable(feature = "rust1", since = "1.0.0")]
#[allow(deprecated)]
impl AsRawFd for old_io::net::tcp::TcpAcceptor {
- fn as_raw_fd(&self) -> Fd {
+ fn as_raw_fd(&self) -> RawFd {
self.as_inner().fd()
}
}
#[allow(deprecated)]
+ #[stable(feature = "rust1", since = "1.0.0")]
impl AsRawFd for old_io::net::udp::UdpSocket {
- fn as_raw_fd(&self) -> Fd {
+ fn as_raw_fd(&self) -> RawFd {
self.as_inner().fd()
}
}
+ #[stable(feature = "rust1", since = "1.0.0")]
impl AsRawFd for net::TcpStream {
- fn as_raw_fd(&self) -> Fd { *self.as_inner().socket().as_inner() }
+ fn as_raw_fd(&self) -> RawFd { *self.as_inner().socket().as_inner() }
}
+ #[stable(feature = "rust1", since = "1.0.0")]
impl AsRawFd for net::TcpListener {
- fn as_raw_fd(&self) -> Fd { *self.as_inner().socket().as_inner() }
+ fn as_raw_fd(&self) -> RawFd { *self.as_inner().socket().as_inner() }
}
+ #[stable(feature = "rust1", since = "1.0.0")]
impl AsRawFd for net::UdpSocket {
- fn as_raw_fd(&self) -> Fd { *self.as_inner().socket().as_inner() }
+ fn as_raw_fd(&self) -> RawFd { *self.as_inner().socket().as_inner() }
+ }
+
+ #[unstable(feature = "from_raw_os", reason = "trait is unstable")]
+ impl FromRawFd for net::TcpStream {
+ fn from_raw_fd(fd: RawFd) -> net::TcpStream {
+ let socket = sys::net::Socket::from_inner(fd);
+ net::TcpStream::from_inner(net2::TcpStream::from_inner(socket))
+ }
+ }
+ #[unstable(feature = "from_raw_os", reason = "trait is unstable")]
+ impl FromRawFd for net::TcpListener {
+ fn from_raw_fd(fd: RawFd) -> net::TcpListener {
+ let socket = sys::net::Socket::from_inner(fd);
+ net::TcpListener::from_inner(net2::TcpListener::from_inner(socket))
+ }
+ }
+ #[unstable(feature = "from_raw_os", reason = "trait is unstable")]
+ impl FromRawFd for net::UdpSocket {
+ fn from_raw_fd(fd: RawFd) -> net::UdpSocket {
+ let socket = sys::net::Socket::from_inner(fd);
+ net::UdpSocket::from_inner(net2::UdpSocket::from_inner(socket))
+ }
}
}
/// Unix-specific extension to the primitives in the `std::ffi` module
#[stable(feature = "rust1", since = "1.0.0")]
pub mod ffi {
- use ffi::{CString, NulError, OsStr, OsString};
+ use ffi::{OsStr, OsString};
use mem;
use prelude::v1::*;
use sys::os_str::Buf;
/// Get the underlying byte view of the `OsStr` slice.
#[stable(feature = "rust1", since = "1.0.0")]
fn as_bytes(&self) -> &[u8];
-
- /// Convert the `OsStr` slice into a `CString`.
- #[stable(feature = "rust1", since = "1.0.0")]
- fn to_cstring(&self) -> Result<CString, NulError>;
}
#[stable(feature = "rust1", since = "1.0.0")]
fn as_bytes(&self) -> &[u8] {
&self.as_inner().inner
}
- fn to_cstring(&self) -> Result<CString, NulError> {
- CString::new(self.as_bytes())
- }
}
}
#[stable(feature = "rust1", since = "1.0.0")]
pub mod prelude {
#[doc(no_inline)]
- pub use super::io::{Fd, AsRawFd};
+ pub use super::io::{RawFd, AsRawFd};
#[doc(no_inline)] #[stable(feature = "rust1", since = "1.0.0")]
pub use super::ffi::{OsStrExt, OsStringExt};
#[doc(no_inline)]
fn test_file_desc() {
// Run this test with some pipes so we don't have to mess around with
// opening or closing files.
- let os::Pipe { reader, writer } = unsafe { os::pipe().unwrap() };
- let mut reader = FileDesc::new(reader, true);
- let mut writer = FileDesc::new(writer, true);
+ let (mut reader, mut writer) = unsafe { ::sys::os::pipe().unwrap() };
writer.write(b"test").unwrap();
let mut buf = [0; 4];
use io::prelude::*;
use os::unix::prelude::*;
-use ffi::{CString, CStr, OsString, AsOsStr, OsStr};
+use ffi::{CString, CStr, OsString, OsStr};
use io::{self, Error, SeekFrom};
use libc::{self, c_int, size_t, off_t, c_char, mode_t};
use mem;
}
fn cstr(path: &Path) -> io::Result<CString> {
- let cstring = try!(path.as_os_str().to_cstring());
- Ok(cstring)
+ path.as_os_str().to_cstring().ok_or(
+ io::Error::new(io::ErrorKind::InvalidInput, "path contained a null", None))
+}
+
+impl FromInner<c_int> for File {
+ fn from_inner(fd: c_int) -> File {
+ File(FileDesc::new(fd))
+ }
}
pub fn mkdir(p: &Path) -> io::Result<()> {
#![allow(deprecated)]
use libc;
-use os;
+use sys::os;
use sys::fs::FileDesc;
pub type signal = libc::c_int;
pub fn new() -> (signal, signal) {
- let os::Pipe { reader, writer } = unsafe { os::pipe().unwrap() };
- (reader, writer)
+ let (a, b) = unsafe { os::pipe().unwrap() };
+ (a.unwrap(), b.unwrap())
}
pub fn signal(fd: libc::c_int) {
use sys::c;
use net::SocketAddr;
use sys::fd::FileDesc;
-use sys_common::AsInner;
+use sys_common::{AsInner, FromInner};
pub use sys::{cvt, cvt_r};
impl AsInner<c_int> for Socket {
fn as_inner(&self) -> &c_int { self.0.as_inner() }
}
+
+impl FromInner<c_int> for Socket {
+ fn from_inner(fd: c_int) -> Socket { Socket(FileDesc::new(fd)) }
+}
use os::unix::prelude::*;
use error::Error as StdError;
-use ffi::{CString, CStr, OsString, OsStr, AsOsStr};
+use ffi::{CString, CStr, OsString, OsStr};
use fmt;
use io;
use iter;
}
pub fn chdir(p: &path::Path) -> io::Result<()> {
- let p = try!(CString::new(p.as_os_str().as_bytes()));
+ let p: &OsStr = p.as_ref();
+ let p = try!(CString::new(p.as_bytes()));
unsafe {
match libc::chdir(p.as_ptr()) == (0 as c_int) {
true => Ok(()),
pub struct JoinPathsError;
pub fn join_paths<I, T>(paths: I) -> Result<OsString, JoinPathsError>
- where I: Iterator<Item=T>, T: AsOsStr
+ where I: Iterator<Item=T>, T: AsRef<OsStr>
{
let mut joined = Vec::new();
let sep = b':';
for (i, path) in paths.enumerate() {
- let path = path.as_os_str().as_bytes();
+ let path = path.as_ref().as_bytes();
if i > 0 { joined.push(sep) }
if path.contains(&sep) {
return Err(JoinPathsError)
}
pub fn temp_dir() -> PathBuf {
- getenv("TMPDIR".as_os_str()).map(os2path).unwrap_or_else(|| {
+ getenv("TMPDIR".as_ref()).map(os2path).unwrap_or_else(|| {
if cfg!(target_os = "android") {
PathBuf::from("/data/local/tmp")
} else {
}
pub fn home_dir() -> Option<PathBuf> {
- return getenv("HOME".as_os_str()).or_else(|| unsafe {
+ return getenv("HOME".as_ref()).or_else(|| unsafe {
fallback()
}).map(os2path);
}
}
}
+
+pub fn exit(code: i32) -> ! {
+ unsafe { libc::exit(code as c_int) }
+}
use old_io::process::{ProcessExit, ExitStatus, ExitSignal};
use old_io::{IoResult, EndOfFile};
use libc::{self, pid_t, c_void, c_int};
+use io;
use mem;
-use os;
+use sys::os;
use old_path::BytesContainer;
use ptr;
use sync::mpsc::{channel, Sender, Receiver};
n if n > 0 => { ret = true; }
0 => return true,
-1 if wouldblock() => return ret,
- n => panic!("bad read {:?} ({:?})", os::last_os_error(), n),
+ n => panic!("bad read {} ({})",
+ io::Error::last_os_error(), n),
}
}
}
self.args.push(arg.to_cstring().unwrap())
}
pub fn args<'a, I: Iterator<Item = &'a OsStr>>(&mut self, args: I) {
- self.args.extend(args.map(|s| OsStrExt::to_cstring(s).unwrap()))
+ self.args.extend(args.map(|s| s.to_cstring().unwrap()))
}
fn init_env_map(&mut self) {
if self.env.is_none() {
use old_io::IoResult;
use libc;
use mem;
-use os;
+use sys::os;
+use io;
use ptr;
use sync::atomic::{self, Ordering};
use sync::mpsc::{channel, Sender, Receiver, TryRecvError};
-1 if os::errno() == libc::EINTR as i32 => {}
n => panic!("helper thread failed in select() with error: {} ({})",
- n, os::last_os_error())
+ n, io::Error::last_os_error())
}
}
}
TokenHandle: *mut libc::HANDLE) -> libc::BOOL;
pub fn GetCurrentProcess() -> libc::HANDLE;
pub fn GetStdHandle(which: libc::DWORD) -> libc::HANDLE;
+ pub fn ExitProcess(uExitCode: libc::UINT) -> !;
}
#[link(name = "userenv")]
#![stable(feature = "rust1", since = "1.0.0")]
-#[unstable(feature = "io_ext",
- reason = "organization may change slightly and the primitives \
- provided may be tweaked")]
+#[stable(feature = "rust1", since = "1.0.0")]
pub mod io {
use fs;
use libc;
use net;
- use sys_common::AsInner;
+ use sys_common::{net2, AsInner, FromInner};
+ use sys;
#[allow(deprecated)]
use old_io;
/// Raw HANDLEs.
- pub type Handle = libc::HANDLE;
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub type RawHandle = libc::HANDLE;
/// Raw SOCKETs.
- pub type Socket = libc::SOCKET;
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub type RawSocket = libc::SOCKET;
/// Extract raw handles.
+ #[stable(feature = "rust1", since = "1.0.0")]
pub trait AsRawHandle {
/// Extract the raw handle, without taking any ownership.
- fn as_raw_handle(&self) -> Handle;
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn as_raw_handle(&self) -> RawHandle;
+ }
+
+ /// Construct I/O objects from raw handles.
+ #[unstable(feature = "from_raw_os",
+ reason = "recent addition to the std::os::windows::io module")]
+ pub trait FromRawHandle {
+ /// Construct a new I/O object from the specified raw handle.
+ ///
+ /// This function will **consume ownership** of the handle given,
+ /// passing responsibility for closing the handle to the returned
+ /// object.
+ fn from_raw_handle(handle: RawHandle) -> Self;
}
#[allow(deprecated)]
+ #[stable(feature = "rust1", since = "1.0.0")]
impl AsRawHandle for old_io::fs::File {
- fn as_raw_handle(&self) -> Handle {
+ fn as_raw_handle(&self) -> RawHandle {
self.as_inner().handle()
}
}
+ #[stable(feature = "rust1", since = "1.0.0")]
impl AsRawHandle for fs::File {
- fn as_raw_handle(&self) -> Handle {
+ fn as_raw_handle(&self) -> RawHandle {
self.as_inner().handle().raw()
}
}
+ #[unstable(feature = "from_raw_os", reason = "trait is unstable")]
+ impl FromRawHandle for fs::File {
+ fn from_raw_handle(handle: RawHandle) -> fs::File {
+ fs::File::from_inner(sys::fs2::File::from_inner(handle))
+ }
+ }
+
#[allow(deprecated)]
+ #[stable(feature = "rust1", since = "1.0.0")]
impl AsRawHandle for old_io::pipe::PipeStream {
- fn as_raw_handle(&self) -> Handle {
+ fn as_raw_handle(&self) -> RawHandle {
self.as_inner().handle()
}
}
#[allow(deprecated)]
+ #[stable(feature = "rust1", since = "1.0.0")]
impl AsRawHandle for old_io::net::pipe::UnixStream {
- fn as_raw_handle(&self) -> Handle {
+ fn as_raw_handle(&self) -> RawHandle {
self.as_inner().handle()
}
}
#[allow(deprecated)]
+ #[stable(feature = "rust1", since = "1.0.0")]
impl AsRawHandle for old_io::net::pipe::UnixListener {
- fn as_raw_handle(&self) -> Handle {
+ fn as_raw_handle(&self) -> RawHandle {
self.as_inner().handle()
}
}
#[allow(deprecated)]
+ #[stable(feature = "rust1", since = "1.0.0")]
impl AsRawHandle for old_io::net::pipe::UnixAcceptor {
- fn as_raw_handle(&self) -> Handle {
+ fn as_raw_handle(&self) -> RawHandle {
self.as_inner().handle()
}
}
/// Extract raw sockets.
+ #[stable(feature = "rust1", since = "1.0.0")]
pub trait AsRawSocket {
- fn as_raw_socket(&self) -> Socket;
+ /// Extract the underlying raw socket from this object.
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn as_raw_socket(&self) -> RawSocket;
+ }
+
+ /// Create I/O objects from raw sockets.
+ #[unstable(feature = "from_raw_os", reason = "recent addition to module")]
+ pub trait FromRawSocket {
+ /// Creates a new I/O object from the given raw socket.
+ ///
+ /// This function will **consume ownership** of the socket provided and
+ /// it will be closed when the returned object goes out of scope.
+ fn from_raw_socket(sock: RawSocket) -> Self;
}
#[allow(deprecated)]
+ #[stable(feature = "rust1", since = "1.0.0")]
impl AsRawSocket for old_io::net::tcp::TcpStream {
- fn as_raw_socket(&self) -> Socket {
+ fn as_raw_socket(&self) -> RawSocket {
self.as_inner().fd()
}
}
#[allow(deprecated)]
+ #[stable(feature = "rust1", since = "1.0.0")]
impl AsRawSocket for old_io::net::tcp::TcpListener {
- fn as_raw_socket(&self) -> Socket {
+ fn as_raw_socket(&self) -> RawSocket {
self.as_inner().socket()
}
}
#[allow(deprecated)]
+ #[stable(feature = "rust1", since = "1.0.0")]
impl AsRawSocket for old_io::net::tcp::TcpAcceptor {
- fn as_raw_socket(&self) -> Socket {
+ fn as_raw_socket(&self) -> RawSocket {
self.as_inner().socket()
}
}
#[allow(deprecated)]
+ #[stable(feature = "rust1", since = "1.0.0")]
impl AsRawSocket for old_io::net::udp::UdpSocket {
- fn as_raw_socket(&self) -> Socket {
+ fn as_raw_socket(&self) -> RawSocket {
self.as_inner().fd()
}
}
+ #[stable(feature = "rust1", since = "1.0.0")]
impl AsRawSocket for net::TcpStream {
- fn as_raw_socket(&self) -> Socket { *self.as_inner().socket().as_inner() }
+ fn as_raw_socket(&self) -> RawSocket {
+ *self.as_inner().socket().as_inner()
+ }
}
+ #[stable(feature = "rust1", since = "1.0.0")]
impl AsRawSocket for net::TcpListener {
- fn as_raw_socket(&self) -> Socket { *self.as_inner().socket().as_inner() }
+ fn as_raw_socket(&self) -> RawSocket {
+ *self.as_inner().socket().as_inner()
+ }
}
+ #[stable(feature = "rust1", since = "1.0.0")]
impl AsRawSocket for net::UdpSocket {
- fn as_raw_socket(&self) -> Socket { *self.as_inner().socket().as_inner() }
+ fn as_raw_socket(&self) -> RawSocket {
+ *self.as_inner().socket().as_inner()
+ }
+ }
+
+ #[unstable(feature = "from_raw_os", reason = "trait is unstable")]
+ impl FromRawSocket for net::TcpStream {
+ fn from_raw_socket(sock: RawSocket) -> net::TcpStream {
+ let sock = sys::net::Socket::from_inner(sock);
+ net::TcpStream::from_inner(net2::TcpStream::from_inner(sock))
+ }
+ }
+ #[unstable(feature = "from_raw_os", reason = "trait is unstable")]
+ impl FromRawSocket for net::TcpListener {
+ fn from_raw_socket(sock: RawSocket) -> net::TcpListener {
+ let sock = sys::net::Socket::from_inner(sock);
+ net::TcpListener::from_inner(net2::TcpListener::from_inner(sock))
+ }
+ }
+ #[unstable(feature = "from_raw_os", reason = "trait is unstable")]
+ impl FromRawSocket for net::UdpSocket {
+ fn from_raw_socket(sock: RawSocket) -> net::UdpSocket {
+ let sock = sys::net::Socket::from_inner(sock);
+ net::UdpSocket::from_inner(net2::UdpSocket::from_inner(sock))
+ }
}
}
#[stable(feature = "rust1", since = "1.0.0")]
pub mod prelude {
#[doc(no_inline)]
- pub use super::io::{Socket, Handle, AsRawSocket, AsRawHandle};
+ pub use super::io::{RawSocket, RawHandle, AsRawSocket, AsRawHandle};
#[doc(no_inline)] #[stable(feature = "rust1", since = "1.0.0")]
pub use super::ffi::{OsStrExt, OsStringExt};
#[doc(no_inline)]
_ => Err(super::last_error()),
}
}
-
- /// Extract the actual filedescriptor without closing it.
- pub fn unwrap(self) -> fd_t {
- let fd = self.fd;
- unsafe { mem::forget(self) };
- fd
- }
}
impl Drop for FileDesc {
use path::{Path, PathBuf};
use ptr;
use sync::Arc;
-use sys::handle::Handle as RawHandle;
+use sys::handle::Handle;
use sys::{c, cvt};
+use sys_common::FromInner;
use vec::Vec;
-pub struct File { handle: RawHandle }
+pub struct File { handle: Handle }
pub struct FileAttr { data: c::WIN32_FILE_ATTRIBUTE_DATA }
pub struct ReadDir {
if handle == libc::INVALID_HANDLE_VALUE {
Err(Error::last_os_error())
} else {
- Ok(File { handle: RawHandle::new(handle) })
+ Ok(File { handle: Handle::new(handle) })
}
}
Ok(newpos as u64)
}
- pub fn handle(&self) -> &RawHandle { &self.handle }
+ pub fn handle(&self) -> &Handle { &self.handle }
+}
+
+impl FromInner<libc::HANDLE> for File {
+ fn from_inner(handle: libc::HANDLE) -> File {
+ File { handle: Handle::new(handle) }
+ }
}
pub fn to_utf16(s: &Path) -> Vec<u16> {
use rt;
use sync::{Once, ONCE_INIT};
use sys::c;
-use sys_common::AsInner;
+use sys_common::{AsInner, FromInner};
pub type wrlen_t = i32;
impl Drop for Socket {
fn drop(&mut self) {
- unsafe { cvt(libc::closesocket(self.0)).unwrap(); }
+ let _ = unsafe { libc::closesocket(self.0) };
}
}
impl AsInner<libc::SOCKET> for Socket {
fn as_inner(&self) -> &libc::SOCKET { &self.0 }
}
+
+impl FromInner<libc::SOCKET> for Socket {
+ fn from_inner(sock: libc::SOCKET) -> Socket { Socket(sock) }
+}
use os::windows::prelude::*;
use error::Error as StdError;
-use ffi::{OsString, OsStr, AsOsStr};
+use ffi::{OsString, OsStr};
use fmt;
use io;
use libc::types::os::arch::extra::LPWCH;
use slice;
use sys::c;
use sys::fs::FileDesc;
-use sys::handle::Handle as RawHandle;
+use sys::handle::Handle;
use libc::funcs::extra::kernel32::{
GetEnvironmentStringsW,
pub struct JoinPathsError;
pub fn join_paths<I, T>(paths: I) -> Result<OsString, JoinPathsError>
- where I: Iterator<Item=T>, T: AsOsStr
+ where I: Iterator<Item=T>, T: AsRef<OsStr>
{
let mut joined = Vec::new();
let sep = b';' as u16;
for (i, path) in paths.enumerate() {
- let path = path.as_os_str();
+ let path = path.as_ref();
if i > 0 { joined.push(sep) }
let v = path.encode_wide().collect::<Vec<u16>>();
if v.contains(&(b'"' as u16)) {
}
pub fn chdir(p: &path::Path) -> io::Result<()> {
- let mut p = p.as_os_str().encode_wide().collect::<Vec<_>>();
+ let p: &OsStr = p.as_ref();
+ let mut p = p.encode_wide().collect::<Vec<_>>();
p.push(0);
unsafe {
}
pub fn home_dir() -> Option<PathBuf> {
- getenv("HOME".as_os_str()).or_else(|| {
- getenv("USERPROFILE".as_os_str())
+ getenv("HOME".as_ref()).or_else(|| {
+ getenv("USERPROFILE".as_ref())
}).map(PathBuf::from).or_else(|| unsafe {
let me = c::GetCurrentProcess();
let mut token = ptr::null_mut();
if c::OpenProcessToken(me, c::TOKEN_READ, &mut token) == 0 {
return None
}
- let _handle = RawHandle::new(token);
+ let _handle = Handle::new(token);
super::fill_utf16_buf_new(|buf, mut sz| {
match c::GetUserProfileDirectoryW(token, buf, &mut sz) {
0 if libc::GetLastError() != 0 => 0,
}, super::os2path).ok()
})
}
+
+pub fn exit(code: i32) -> ! {
+ unsafe { libc::ExitProcess(code as libc::UINT) }
+}
use old_io::process::{ProcessExit, ExitStatus};
use old_io::{IoResult, IoError};
use old_io;
-use os;
+use fs::PathExt;
use old_path::{BytesContainer, GenericPath};
use ptr;
use str;
let program = cfg.env().and_then(|env| {
for (key, v) in env {
if b"PATH" != key.container_as_bytes() { continue }
+ let v = match ::str::from_utf8(v.container_as_bytes()) {
+ Ok(s) => s,
+ Err(..) => continue,
+ };
// Split the value and test each path to see if the
// program exists.
- for path in os::split_paths(v.container_as_bytes()) {
- let path = path.join(cfg.program().as_bytes())
+ for path in ::env::split_paths(v) {
+ let program = str::from_utf8(cfg.program().as_bytes()).unwrap();
+ let path = path.join(program)
.with_extension(env::consts::EXE_EXTENSION);
if path.exists() {
- return Some(CString::from_slice(path.as_vec()))
+ return Some(CString::new(path.to_str().unwrap()).unwrap())
}
}
break
#[test]
fn test_make_command_line() {
fn test_wrapper(prog: &str, args: &[&str]) -> String {
- make_command_line(&CString::from_slice(prog.as_bytes()),
+ make_command_line(&CString::new(prog),
&args.iter()
- .map(|a| CString::from_slice(a.as_bytes()))
+ .map(|a| CString::new(a))
.collect::<Vec<CString>>())
}
}
}
}
-
- /// Deprecated
- #[unstable(feature = "std_misc")]
- #[deprecated(since = "1.0.0",
- reason = "function renamed to state() and returns more info")]
- pub fn destroyed(&'static self) -> bool { self.state() == LocalKeyState::Destroyed }
}
#[cfg(all(any(target_os = "macos", target_os = "linux"), not(target_arch = "aarch64")))]
use thunk::Thunk;
use time::Duration;
-#[allow(deprecated)] use old_io::Writer;
-
////////////////////////////////////////////////////////////////////////////////
// Thread-local storage
////////////////////////////////////////////////////////////////////////////////
self
}
- /// Redirect thread-local stdout.
- #[unstable(feature = "std_misc",
- reason = "Will likely go away after proc removal")]
- #[deprecated(since = "1.0.0",
- reason = "the old I/O module is deprecated and this function \
- will be removed with no replacement")]
- #[allow(deprecated)]
- pub fn stdout(self, _stdout: Box<Writer + Send + 'static>) -> Builder {
- self
- }
-
- /// Redirect thread-local stderr.
- #[unstable(feature = "std_misc",
- reason = "Will likely go away after proc removal")]
- #[deprecated(since = "1.0.0",
- reason = "the old I/O module is deprecated and this function \
- will be removed with no replacement")]
- #[allow(deprecated)]
- pub fn stderr(self, _stderr: Box<Writer + Send + 'static>) -> Builder {
- self
- }
-
/// Spawn a new thread, and return a join handle for it.
///
/// The child thread may outlive the parent (unless the parent thread
}
}
- /// Deprecated: use module-level free function.
- #[deprecated(since = "1.0.0", reason = "use module-level free function")]
- #[unstable(feature = "std_misc",
- reason = "may change with specifics of new Send semantics")]
- pub fn spawn<F>(f: F) -> Thread where F: FnOnce(), F: Send + 'static {
- Builder::new().spawn(f).unwrap().thread().clone()
- }
-
- /// Deprecated: use module-level free function.
- #[deprecated(since = "1.0.0", reason = "use module-level free function")]
- #[unstable(feature = "std_misc",
- reason = "may change with specifics of new Send semantics")]
- pub fn scoped<'a, T, F>(f: F) -> JoinGuard<'a, T> where
- T: Send + 'a, F: FnOnce() -> T, F: Send + 'a
- {
- Builder::new().scoped(f).unwrap()
- }
-
- /// Deprecated: use module-level free function.
- #[deprecated(since = "1.0.0", reason = "use module-level free function")]
- #[stable(feature = "rust1", since = "1.0.0")]
- pub fn current() -> Thread {
- thread_info::current_thread()
- }
-
- /// Deprecated: use module-level free function.
- #[deprecated(since = "1.0.0", reason = "use module-level free function")]
- #[unstable(feature = "std_misc", reason = "name may change")]
- pub fn yield_now() {
- unsafe { imp::yield_now() }
- }
-
- /// Deprecated: use module-level free function.
- #[deprecated(since = "1.0.0", reason = "use module-level free function")]
- #[inline]
- #[stable(feature = "rust1", since = "1.0.0")]
- pub fn panicking() -> bool {
- unwind::panicking()
- }
-
- /// Deprecated: use module-level free function.
- #[deprecated(since = "1.0.0", reason = "use module-level free function")]
- #[unstable(feature = "std_misc", reason = "recently introduced")]
- pub fn park() {
- let thread = current();
- let mut guard = thread.inner.lock.lock().unwrap();
- while !*guard {
- guard = thread.inner.cvar.wait(guard).unwrap();
- }
- *guard = false;
- }
-
- /// Deprecated: use module-level free function.
- #[deprecated(since = "1.0.0", reason = "use module-level free function")]
- #[unstable(feature = "std_misc", reason = "recently introduced")]
- pub fn park_timeout(duration: Duration) {
- let thread = current();
- let mut guard = thread.inner.lock.lock().unwrap();
- if !*guard {
- let (g, _) = thread.inner.cvar.wait_timeout(guard, duration).unwrap();
- guard = g;
- }
- *guard = false;
- }
-
/// Atomically makes the handle's token available if it is not already.
///
/// See the module doc for more detail.
&self.inner.thread
}
- /// Wait for the associated thread to finish, returning the result of the thread's
- /// calculation.
+ /// Wait for the associated thread to finish, returning the result of the
+ /// thread's calculation.
///
/// # Panics
///
}
}
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<T: Send> JoinGuard<'static, T> {
- /// Detaches the child thread, allowing it to outlive its parent.
- #[deprecated(since = "1.0.0", reason = "use spawn instead")]
- #[unstable(feature = "std_misc")]
- pub fn detach(mut self) {
- unsafe { imp::detach(self.inner.native) };
- self.inner.joined = true; // avoid joining in the destructor
- }
-}
-
#[unsafe_destructor]
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, T: Send + 'a> Drop for JoinGuard<'a, T> {
use any::Any;
use sync::mpsc::{channel, Sender};
- use boxed::BoxAny;
use result;
use std::old_io::{ChanReader, ChanWriter};
use super::{Builder};
("main", "1.0.0", Active),
// Deprecate after snapshot
- // SNAP a923278
+ // SNAP 5520801
("unsafe_destructor", "1.0.0", Active),
// A temporary feature gate used to enable parser extensions needed
// A way to temporarily opt out of opt in copy. This will *never* be accepted.
("opt_out_copy", "1.0.0", Removed),
- // A way to temporarily opt out of the new orphan rules. This will *never* be accepted.
- ("old_orphan_check", "1.0.0", Deprecated),
-
// OIBIT specific features
("optin_builtin_traits", "1.0.0", Active),
/// currently being considered for addition/removal.
Active,
- /// Represents a feature gate that is temporarily enabling deprecated behavior.
- /// This gate will never be accepted.
- Deprecated,
-
/// Represents a feature which has since been removed (it was once Active)
Removed,
("stable", Whitelisted),
("unstable", Whitelisted),
- // FIXME: #19470 this shouldn't be needed forever
- ("old_orphan_check", Whitelisted),
-
("rustc_paren_sugar", Gated("unboxed_closures",
"unboxed_closures are still evolving")),
("rustc_reflect_like", Gated("reflect",
pub allow_trace_macros: bool,
pub allow_internal_unstable: bool,
pub allow_custom_derive: bool,
- pub old_orphan_check: bool,
pub simd_ffi: bool,
pub unmarked_api: bool,
/// spans of #![feature] attrs for stable language features. for error reporting
allow_trace_macros: false,
allow_internal_unstable: false,
allow_custom_derive: false,
- old_orphan_check: false,
simd_ffi: false,
unmarked_api: false,
declared_stable_lang_features: Vec::new(),
},
_ => {}
}
-
- if attr::contains_name(&i.attrs[..],
- "old_orphan_check") {
- self.gate_feature(
- "old_orphan_check",
- i.span,
- "the new orphan check rules will eventually be strictly enforced");
- }
}
_ => {}
Some(&(name, _, Active)) => {
cx.features.push(name);
}
- Some(&(name, _, Deprecated)) => {
- cx.features.push(name);
- span_handler.span_warn(
- mi.span,
- "feature is deprecated and will only be available \
- for a limited time, please rewrite code that relies on it");
- }
Some(&(_, _, Removed)) => {
span_handler.span_err(mi.span, "feature has been removed");
}
allow_trace_macros: cx.has_feature("trace_macros"),
allow_internal_unstable: cx.has_feature("allow_internal_unstable"),
allow_custom_derive: cx.has_feature("custom_derive"),
- old_orphan_check: cx.has_feature("old_orphan_check"),
simd_ffi: cx.has_feature("simd_ffi"),
unmarked_api: cx.has_feature("unmarked_api"),
declared_stable_lang_features: accepted_features,
#![feature(unicode)]
#![feature(path_ext)]
#![feature(str_char)]
-#![feature(convert)]
#![feature(into_cow)]
#![feature(slice_patterns)]
let base = 10;
// find the integer representing the name
- self.scan_digits(base);
- let encoded_name: u32 = self.with_str_from(start_bpos, |s| {
+ self.scan_digits(base, base);
+ let encoded_name : u32 = self.with_str_from(start_bpos, |s| {
u32::from_str_radix(s, 10).unwrap_or_else(|_| {
panic!("expected digits representing a name, got {:?}, {}, range [{:?},{:?}]",
s, whence, start_bpos, self.last_pos);
// find the integer representing the ctxt
let start_bpos = self.last_pos;
- self.scan_digits(base);
+ self.scan_digits(base, base);
let encoded_ctxt : ast::SyntaxContext = self.with_str_from(start_bpos, |s| {
u32::from_str_radix(s, 10).unwrap_or_else(|_| {
panic!("expected digits representing a ctxt, got {:?}, {}", s, whence);
ctxt: encoded_ctxt, }
}
- /// Scan through any digits (base `radix`) or underscores, and return how
- /// many digits there were.
- fn scan_digits(&mut self, radix: u32) -> usize {
+ /// Scan through any digits (base `scan_radix`) or underscores,
+ /// and return how many digits there were.
+ ///
+ /// `real_radix` represents the true radix of the number we're
+ /// interested in, and errors will be emitted for any digits
+ /// between `real_radix` and `scan_radix`.
+ fn scan_digits(&mut self, real_radix: u32, scan_radix: u32) -> usize {
+ assert!(real_radix <= scan_radix);
let mut len = 0;
loop {
let c = self.curr;
if c == Some('_') { debug!("skipping a _"); self.bump(); continue; }
- match c.and_then(|cc| cc.to_digit(radix)) {
+ match c.and_then(|cc| cc.to_digit(scan_radix)) {
Some(_) => {
debug!("{:?} in scan_digits", c);
+ // check that the hypothetical digit is actually
+ // in range for the true radix
+ if c.unwrap().to_digit(real_radix).is_none() {
+ self.err_span_(self.last_pos, self.pos,
+ &format!("invalid digit for a base {} literal",
+ real_radix));
+ }
len += 1;
self.bump();
}
if c == '0' {
match self.curr.unwrap_or('\0') {
- 'b' => { self.bump(); base = 2; num_digits = self.scan_digits(2); }
- 'o' => { self.bump(); base = 8; num_digits = self.scan_digits(8); }
- 'x' => { self.bump(); base = 16; num_digits = self.scan_digits(16); }
+ 'b' => { self.bump(); base = 2; num_digits = self.scan_digits(2, 10); }
+ 'o' => { self.bump(); base = 8; num_digits = self.scan_digits(8, 10); }
+ 'x' => { self.bump(); base = 16; num_digits = self.scan_digits(16, 16); }
'0'...'9' | '_' | '.' => {
- num_digits = self.scan_digits(10) + 1;
+ num_digits = self.scan_digits(10, 10) + 1;
}
_ => {
// just a 0
}
}
} else if c.is_digit(10) {
- num_digits = self.scan_digits(10) + 1;
+ num_digits = self.scan_digits(10, 10) + 1;
} else {
num_digits = 0;
}
// with a number
self.bump();
if self.curr.unwrap_or('\0').is_digit(10) {
- self.scan_digits(10);
+ self.scan_digits(10, 10);
self.scan_float_exponent();
}
let last_pos = self.last_pos;
if self.curr_is('-') || self.curr_is('+') {
self.bump();
}
- if self.scan_digits(10) == 0 {
+ if self.scan_digits(10, 10) == 0 {
self.err_span_(self.last_pos, self.pos, "expected at least one digit in exponent")
}
}
let res = match u64::from_str_radix(s, base).ok() {
Some(r) => r,
- None => { sd.span_err(sp, "int literal is too large"); 0 }
+ None => {
+ // small bases are lexed as if they were base 10, e.g, the string
+ // might be `0b10201`. This will cause the conversion above to fail,
+ // but these cases have errors in the lexer: we don't want to emit
+ // two errors, and we especially don't want to emit this error since
+ // it isn't necessarily true.
+ let already_errored = base < 10 &&
+ s.chars().any(|c| c.to_digit(10).map_or(false, |d| d >= base));
+
+ if !already_errored {
+ sd.span_err(sp, "int literal is too large");
+ }
+ 0
+ }
};
// adjust the sign
fn test_move_iter() {
let v = SmallVector::zero();
let v: Vec<isize> = v.into_iter().collect();
- assert_eq!(Vec::new(), v);
+ assert_eq!(v, Vec::new());
let v = SmallVector::one(1);
- assert_eq!([1], v.into_iter().collect::<Vec<_>>());
+ assert_eq!(v.into_iter().collect::<Vec<_>>(), [1]);
let v = SmallVector::many(vec![1, 2, 3]);
- assert_eq!([1, 2, 3], v.into_iter().collect::<Vec<_>>());
+ assert_eq!(v.into_iter().collect::<Vec<_>>(), [1, 2, 3]);
}
#[test]
#![feature(std_misc)]
#![feature(str_char)]
#![feature(path_ext)]
-#![feature(convert)]
#![cfg_attr(windows, feature(libc))]
#[macro_use] extern crate log;
#![feature(std_misc)]
#![feature(libc)]
#![feature(set_stdio)]
-#![feature(os)]
-#![feature(convert)]
#![cfg_attr(test, feature(old_io))]
extern crate getopts;
if std::rt::util::limit_thread_creation_due_to_osx_and_valgrind() {
1
} else {
- std::os::num_cpus()
+ extern { fn rust_get_num_cpus() -> libc::uintptr_t; }
+ unsafe { rust_get_num_cpus() as usize }
}
}
}
#![feature(rustdoc)]
#![feature(rustc_private)]
#![feature(path_relative_from)]
-#![feature(convert)]
extern crate rustdoc;
extern crate rustc_back;
+S 2015-03-27 5520801
+ bitrig-x86_64 41de2c7a69a1ac648d3fa3b65e96a29bdc122163
+ freebsd-x86_64 0910bbad35e213f679d0433884fd51398eb3bc8d
+ linux-i386 1ef82402ed16f5a6d2f87a9a62eaa83170e249ec
+ linux-x86_64 ef2154372e97a3cb687897d027fd51c8f2c5f349
+ macos-i386 0310b1a970f2da7e61770fd14dbbbdca3b518234
+ macos-x86_64 5f35d9c920b8083a7420ef8cf5b00d5ef3085dfa
+ winnt-i386 808b7961f85872f04ec15ad0d3e9e23ae9bc0c3b
+ winnt-x86_64 903a99a58f57a9bd9848cc68a2445dda881f1ee8
+
S 2015-03-25 a923278
bitrig-x86_64 41de2c7a69a1ac648d3fa3b65e96a29bdc122163
freebsd-x86_64 cd02c86a9218da73b2a45aff293787010d33bf3e
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
-#![feature(rustc_private, core)]
+#![feature(rustc_private, core, step_by)]
extern crate arena;
-use std::iter::range_step;
use std::thread;
use arena::TypedArena;
let long_lived_arena = TypedArena::new();
let long_lived_tree = bottom_up_tree(&long_lived_arena, 0, max_depth);
- let messages = range_step(min_depth, max_depth + 1, 2).map(|depth| {
+ let messages = (min_depth..max_depth + 1).step_by(2).map(|depth| {
use std::num::Int;
let iterations = 2.pow((max_depth - depth + min_depth) as u32);
thread::scoped(move || inner(depth, iterations))
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
-#![feature(core)]
+#![feature(step_by)]
-use std::{cmp, iter, mem};
+use std::{cmp, mem};
use std::thread;
fn rotate(x: &mut [i32]) {
let mut futures = vec![];
let k = perm.max() / N;
- for (_, j) in (0..N).zip(iter::count(0, k)) {
+ for (_, j) in (0..N).zip((0..).step_by(k)) {
let max = cmp::min(j+k, perm.max());
futures.push(thread::scoped(move|| {
// start processing if this is the one
('>', false) => {
- match line[1..].find_str("THREE") {
+ match line[1..].find("THREE") {
Some(_) => { proc_mode = true; }
None => { }
}
fn parallel<'a,T, F>(v: &mut [T], ref f: F)
where T: Send + Sync + 'a,
F: Fn(usize, &mut [T]) + Sync + 'a {
- let size = v.len() / os::num_cpus() + 1;
+ // FIXME: pick a more appropriate parallel factor
+ let parallelism = 4;
+ let size = v.len() / parallelism + 1;
v.chunks_mut(size).enumerate().map(|(i, chunk)| {
thread::scoped(move|| {
f(i * size, chunk)
mod s {
#![allow(unstable)]
- use std::sync::atomic::{AtomicUint, ATOMIC_UINT_INIT, Ordering};
+ use std::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering};
- static S_COUNT: AtomicUint = ATOMIC_UINT_INIT;
+ static S_COUNT: AtomicUsize = ATOMIC_USIZE_INIT;
pub fn next_count() -> usize {
S_COUNT.fetch_add(1, Ordering::SeqCst) + 1
mod s {
#![allow(unstable)]
- use std::sync::atomic::{AtomicUint, ATOMIC_UINT_INIT, Ordering};
+ use std::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering};
- static S_COUNT: AtomicUint = ATOMIC_UINT_INIT;
+ static S_COUNT: AtomicUsize = ATOMIC_USIZE_INIT;
pub fn next_count() -> usize {
S_COUNT.fetch_add(1, Ordering::SeqCst) + 1
mod s {
#![allow(unstable)]
- use std::sync::atomic::{AtomicUint, ATOMIC_UINT_INIT, Ordering};
+ use std::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering};
- static S_COUNT: AtomicUint = ATOMIC_UINT_INIT;
+ static S_COUNT: AtomicUsize = ATOMIC_USIZE_INIT;
pub fn next_count() -> usize {
S_COUNT.fetch_add(1, Ordering::SeqCst) + 1
fn has_slice(x: &str) {
wants_uniq(x); //~ ERROR mismatched types
- wants_slice(x.as_slice());
+ wants_slice(x);
}
fn main() {
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-use std::iter::{Range,range};
+use std::ops::Range;
trait Itble<'r, T, I: Iterator<Item=T>> { fn iter(&'r self) -> I; }
impl<'r> Itble<'r, usize, Range<usize>> for (usize, usize) {
fn iter(&'r self) -> Range<usize> {
let &(min, max) = self;
- range(min, max)
+ min..max
}
}
fn main() {
// FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
- (|| Box::new(*[0].as_slice()))();
+ (|| Box::new(*(&[0][..])))();
//~^ ERROR the trait `core::marker::Sized` is not implemented for the type `[_]`
}
// ignore-tidy-linelength
-use std::iter::{Range,range};
+use std::ops::Range;
trait Itble<'r, T, I: Iterator<Item=T>> { fn iter(&'r self) -> I; }
impl<'r> Itble<'r, usize, Range<usize>> for (usize, usize) {
fn iter(&'r self) -> Range<usize> {
let &(min, max) = self;
- range(min, max)
+ min..max
}
}
+++ /dev/null
-// 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.
-
-// Test that the deprecated markers still have their old effect.
-
-#![feature(rustc_attrs)]
-
-use std::marker;
-
-#[rustc_variance]
-struct A<T>(marker::CovariantType<T>); //~ ERROR types=[[+];[];[]]
-
-#[rustc_variance]
-struct B<T>(marker::ContravariantType<T>); //~ ERROR types=[[-];[];[]]
-
-#[rustc_variance]
-struct C<T>(marker::InvariantType<T>); //~ ERROR types=[[o];[];[]]
-
-#[rustc_variance]
-struct D<'a>(marker::CovariantLifetime<'a>); //~ ERROR regions=[[+];[];[]]
-
-#[rustc_variance]
-struct E<'a>(marker::ContravariantLifetime<'a>); //~ ERROR regions=[[-];[];[]]
-
-#[rustc_variance]
-struct F<'a>(marker::InvariantLifetime<'a>); //~ ERROR regions=[[o];[];[]]
-
-fn main() { }
mod s {
#![allow(unstable)]
- use std::sync::atomic::{AtomicUint, ATOMIC_UINT_INIT, Ordering};
+ use std::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering};
- static S_COUNT: AtomicUint = ATOMIC_UINT_INIT;
+ static S_COUNT: AtomicUsize = ATOMIC_USIZE_INIT;
/// generates globally unique count (global across the current
/// process, that is)
v.push(&x); //~ ERROR `x` does not live long enough
v.push(&y); //~ ERROR `y` does not live long enough
- assert_eq!(v.as_slice(), [&3, &4]);
+ assert_eq!(v, [&3, &4]);
}
// error-pattern:no valid digits found for number
fn main() {
- log(error, 0b42);
+ log(error, 0b);
}
--- /dev/null
+// Copyright 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.
+
+fn main() {
+ 0b121; //~ ERROR invalid digit for a base 2 literal
+ 0b10_10301; //~ ERROR invalid digit for a base 2 literal
+ 0b30; //~ ERROR invalid digit for a base 2 literal
+ 0b41; //~ ERROR invalid digit for a base 2 literal
+ 0b5; //~ ERROR invalid digit for a base 2 literal
+ 0b6; //~ ERROR invalid digit for a base 2 literal
+ 0b7; //~ ERROR invalid digit for a base 2 literal
+ 0b8; //~ ERROR invalid digit for a base 2 literal
+ 0b9; //~ ERROR invalid digit for a base 2 literal
+}
--- /dev/null
+// Copyright 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.
+
+fn main() {
+ 0o18; //~ ERROR invalid digit for a base 8 literal
+ 0o1234_9_5670; //~ ERROR invalid digit for a base 8 literal
+}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-// error-pattern:assertion failed: `(left == right) && (right == left)` (left: `14`, right: `15`)
+// error-pattern:assertion failed: `(left == right)` (left: `14`, right: `15`)
fn main() {
assert_eq!(14,15);
// error-pattern:whatever
-#![feature(os, rustc_private)]
+#![feature(exit_status, rustc_private)]
#[macro_use] extern crate log;
-use std::os;
+use std::env;
fn main() {
error!("whatever");
// Setting the exit status only works when the scheduler terminates
// normally. In this case we're going to panic, so instead of
// returning 50 the process will return the typical rt failure code.
- os::set_exit_status(50);
+ env::set_exit_status(50);
panic!();
}
// error-pattern:whatever
-#![feature(os, rustc_private)]
+#![feature(exit_status, rustc_private)]
#[macro_use] extern crate log;
-use std::os;
+use std::env;
use std::thread;
struct r {
// runtime's exit code
impl Drop for r {
fn drop(&mut self) {
- os::set_exit_status(50);
+ env::set_exit_status(50);
}
}
// error-pattern:whatever
-#![feature(rustc_private, os)]
+#![feature(rustc_private, exit_status)]
#[macro_use] extern crate log;
-use std::os;
+use std::env;
fn main() {
error!("whatever");
// 101 is the code the runtime uses on task panic and the value
// compiletest expects run-fail tests to return.
- os::set_exit_status(101);
+ env::set_exit_status(101);
}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(libc, os)]
+#![feature(libc, exit_status)]
extern crate libc;
};
if result != 1 {
- std::os::set_exit_status(255);
+ std::env::set_exit_status(255);
}
}
let expected_span = format!("\n{}^{}\n",
repeat(" ").take(offset + 7).collect::<String>(),
repeat("~").take(8).collect::<String>());
- assert!(err.contains(expected_span.as_slice()));
+ assert!(err.contains(&expected_span));
// Second snake is 8 ~s long, with 36 preceding spaces
let expected_span = format!("\n{}^{}\n",
repeat(" ").take(offset + 36).collect::<String>(),
repeat("~").take(8).collect::<String>());
- assert!(err.contains(expected_span.as_slice()));
+ assert!(err.contains(&expected_span));
}
let mut tc = TestCalls { count: 1 };
// we should never get use this filename, but lets make sure they are valid args.
let args = vec!["compiler-calls".to_string(), "foo.rs".to_string()];
- rustc_driver::run_compiler(args.as_slice(), &mut tc);
+ rustc_driver::run_compiler(&args, &mut tc);
assert!(tc.count == 30);
}
--- /dev/null
+// 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.
+
+#![feature(rustc_private)]
+
+extern crate rustc_back;
+
+use std::env;
+use std::fs;
+use rustc_back::tempdir::TempDir;
+
+fn main() {
+ let td = TempDir::new("create-dir-all-bare").unwrap();
+ env::set_current_dir(td.path()).unwrap();
+ fs::create_dir_all("create-dir-all-bare").unwrap();
+}
--- /dev/null
+// 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.
+
+// This test can't be a unit test in std,
+// because it needs TempDir, which is in extra
+
+// pretty-expanded FIXME #23616
+
+#![feature(rustc_private, path_ext)]
+
+extern crate rustc_back;
+
+use std::ffi::CString;
+use std::fs::{self, File, PathExt};
+use rustc_back::tempdir::TempDir;
+
+fn rename_directory() {
+ let tmpdir = TempDir::new("rename_directory").ok().expect("rename_directory failed");
+ let tmpdir = tmpdir.path();
+ let old_path = tmpdir.join("foo/bar/baz");
+ fs::create_dir_all(&old_path).unwrap();
+ let test_file = &old_path.join("temp.txt");
+
+ File::create(test_file).unwrap();
+
+ let new_path = tmpdir.join("quux/blat");
+ fs::create_dir_all(&new_path).unwrap();
+ fs::rename(&old_path, &new_path.join("newdir"));
+ assert!(new_path.join("newdir").is_dir());
+ assert!(new_path.join("newdir/temp.txt").exists());
+}
+
+pub fn main() { rename_directory() }
let s = str::from_utf8(&out.error).unwrap();
let mut i = 0;
for _ in 0..2 {
- i += s[i + 10..].find_str("stack backtrace").unwrap() + 10;
+ i += s[i + 10..].find("stack backtrace").unwrap() + 10;
}
- assert!(s[i + 10..].find_str("stack backtrace").is_none(),
+ assert!(s[i + 10..].find("stack backtrace").is_none(),
"bad output4: {}", s);
}
use std::sync::mpsc::channel;
use std::fmt;
use std::old_io::{ChanReader, ChanWriter, Reader, Writer};
-use std::thread::Thread;
+use std::thread;
struct MyWriter(ChanWriter);
fn main() {
let (tx, rx) = channel();
let (mut r, w) = (ChanReader::new(rx), ChanWriter::new(tx));
- let _t = Thread::spawn(move|| {
+ let _t = thread::scoped(move|| {
set_logger(box MyWriter(w) as Box<Logger+Send>);
debug!("debug");
info!("info");
#![feature(std_misc)]
-use std::thread::Thread;
+use std::thread;
fn child2(_s: String) { }
pub fn main() {
- let _x = Thread::spawn(move|| child2("hi".to_string()));
+ let _x = thread::spawn(move|| child2("hi".to_string()));
}
#![allow(unknown_features)]
#![feature(box_syntax, std_misc)]
-use std::thread::Thread;
+use std::thread;
struct Pair {
a: isize,
pub fn main() {
let z: Box<_> = box Pair { a : 10, b : 12};
- let _t = Thread::spawn(move|| {
+ let _t = thread::scoped(move|| {
assert_eq!(z.a, 10);
assert_eq!(z.b, 12);
});
#![feature(std_misc)]
-use std::thread::Thread;
+use std::thread;
use std::sync::mpsc::{channel, Sender};
pub fn main() {
let (tx, rx) = channel();
- let _t = Thread::spawn(move|| { child(&tx) });
+ let _t = thread::scoped(move|| { child(&tx) });
let y = rx.recv().unwrap();
println!("received");
println!("{}", y);
use std::time::Duration;
use std::str;
use std::sync::mpsc::channel;
-use std::thread::Thread;
+use std::thread;
macro_rules! succeed { ($e:expr) => (
match $e { Ok(..) => {}, Err(e) => panic!("panic: {}", e) }
let (tx, rx1) = channel();
let mut t = timer::Timer::new().unwrap();
let rx2 = t.oneshot(Duration::milliseconds(1000));
- Thread::spawn(move|| {
+ thread::spawn(move|| {
select! {
_ = rx2.recv() => unsafe { libc::exit(1) },
_ = rx1.recv() => {}
+++ /dev/null
-// 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.
-
-#![feature(tempdir)]
-
-use std::env;
-use std::fs::{self, TempDir};
-
-fn main() {
- let td = TempDir::new("create-dir-all-bare").unwrap();
- env::set_current_dir(td.path()).unwrap();
- fs::create_dir_all("create-dir-all-bare").unwrap();
-}
#![allow(unknown_features)]
#![feature(box_syntax)]
-#![feature(old_orphan_check, rustc_private)]
+#![feature(rustc_private)]
extern crate serialize;
// pretty-expanded FIXME #23616
-#![feature(old_orphan_check, rustc_private)]
+#![feature(rustc_private)]
extern crate serialize;
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(old_orphan_check, rand, rustc_private)]
+#![feature(rand, rustc_private)]
extern crate serialize;
extern crate rand;
fn main() {
let args = vec!("foobie", "asdf::asdf");
- let arr: Vec<&str> = args[1].split_str("::").collect();
+ let arr: Vec<&str> = args[1].split("::").collect();
assert_eq!(arr[0], "asdf");
assert_eq!(arr[0], "asdf");
}
// pretty-expanded FIXME #23616
#![feature(path)]
-#![feature(convert)]
use std::env::*;
use std::path::PathBuf;
#![feature(libc, std_misc)]
extern crate libc;
-use std::thread::Thread;
+use std::thread;
mod rustrt {
extern crate libc;
pub fn main() {
// Make sure we're on a task with small Rust stacks (main currently
// has a large stack)
- let _t = Thread::spawn(move|| {
+ let _t = thread::scoped(move|| {
let result = count(12);
println!("result = {}", result);
assert_eq!(result, 2048);
use std::collections::HashMap;
use std::sync::mpsc::{channel, Sender};
use std::str;
- use std::thread::Thread;
+ use std::thread;
pub type putter<'a> = Box<FnMut(String, String) + 'a>;
for i in &inputs {
let ctrl = ctrl.clone();
let i = i.clone();
- Thread::spawn(move|| map_task(ctrl.clone(), i.clone()) );
+ thread::spawn(move|| map_task(ctrl.clone(), i.clone()) );
}
}
#![feature(intrinsics, std_misc)]
-use std::thread::Thread;
+use std::thread;
extern "rust-intrinsic" {
pub fn init<T>() -> T;
fn main() {
// do the test in a new thread to avoid (spurious?) stack overflows
- let _ = Thread::scoped(|| {
+ let _ = thread::scoped(|| {
let _memory: [u8; SIZE] = unsafe { init() };
}).join();
}
// pretty-expanded FIXME #23616
-#![feature(old_orphan_check, rustc_private, old_io)]
+#![feature(rustc_private, old_io)]
extern crate rbml;
extern crate serialize;
fn parent() {
let args: Vec<String> = env::args().collect();
let mut p = Command::new(&args[0]).arg("child")
- .stdout(Stdio::capture())
- .stdin(Stdio::capture())
+ .stdout(Stdio::piped())
+ .stdin(Stdio::piped())
.spawn().unwrap();
p.stdin.as_mut().unwrap().write_all(b"test1\ntest2\ntest3").unwrap();
let out = p.wait_with_output().unwrap();
#![feature(std_misc)]
use std::sync::mpsc::{channel, Sender, Receiver};
-use std::thread::Thread;
+use std::thread;
fn helper(rx: Receiver<Sender<()>>) {
for tx in rx.iter() {
fn main() {
let (tx, rx) = channel();
- let _t = Thread::spawn(move|| { helper(rx) });
+ let _t = thread::scoped(move|| { helper(rx) });
let (snd, rcv) = channel::<isize>();
for _ in 1..100000 {
snd.send(1).unwrap();
_ = rcv.recv() => ()
}
}
+ drop(tx);
}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(old_orphan_check, rustc_private)]
+#![feature(rustc_private)]
extern crate serialize;
fn test() {
let args: Vec<String> = env::args().collect();
let mut p = Command::new(&args[0]).arg("child")
- .stdin(Stdio::capture())
- .stdout(Stdio::capture())
- .stderr(Stdio::capture())
+ .stdin(Stdio::piped())
+ .stdout(Stdio::piped())
+ .stderr(Stdio::piped())
.spawn().unwrap();
assert!(p.wait().unwrap().success());
}
// pretty-expanded FIXME #23616
-#![feature(old_orphan_check, core)]
+#![feature(core)]
use std::ops::Index;
#![feature(core)]
+trait Str { fn foo(&self) {} }
+impl Str for str {}
+impl<'a, S: ?Sized> Str for &'a S where S: Str {}
+
fn main() {
let _: &Str = &"x";
}
use std::thread;
-fn main() {
- thread::Thread::spawn(move || { // no need for -> ()
+fn _foo() {
+ let _t = thread::scoped(move || { // no need for -> ()
loop {
println!("hello");
}
});
}
+
+fn main() {}
// pretty-expanded FIXME #23616
-#![feature(convert)]
-
use std::default::Default;
use std::io;
use std::fs;
use std::mem::{forget, transmute};
use std::mem::{replace, swap};
use std::mem;
- use std::thread::Thread;
+ use std::thread;
use std::marker::Send;
pub struct Stuff<T> {
let old_state = swap_state_acq(&mut (*p).state,
blocked);
match old_state {
- empty | blocked => { Thread::yield_now(); }
+ empty | blocked => { thread::yield_now(); }
full => {
let payload = replace(&mut p.payload, None);
return Some(payload.unwrap())
#![allow(unknown_features)]
#![feature(std_misc)]
-use std::thread::Thread;
+use std::thread;
use std::sync::mpsc::Sender;
use std::thunk::Invoke;
}
fn foo(name: String, samples_chan: Sender<Msg>) {
- let _t = Thread::spawn(move|| {
+ let _t = thread::scoped(move|| {
let mut samples_chan = samples_chan;
// FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
// If `Mul` used an associated type for its output, this test would
// work more smoothly.
-#![feature(old_orphan_check)]
use std::ops::Mul;
#![feature(std_misc)]
-use std::thread::Thread;
+use std::thread;
use std::sync::mpsc::{channel, Receiver};
fn periodical(n: isize) -> Receiver<bool> {
let (chan, port) = channel();
- Thread::spawn(move|| {
+ thread::spawn(move|| {
loop {
for _ in 1..n {
match chan.send(false) {
fn integers() -> Receiver<isize> {
let (chan, port) = channel();
- Thread::spawn(move|| {
+ thread::spawn(move|| {
let mut i = 1;
loop {
match chan.send(i) {
use std::sync::mpsc::{TryRecvError, channel};
use std::old_io::timer::Timer;
-use std::thread::Thread;
+use std::thread;
use std::time::Duration;
pub fn main() {
let (tx, rx) = channel();
- let _t = Thread::scoped(move||{
+ let _t = thread::scoped(move||{
let mut timer = Timer::new().unwrap();
timer.sleep(Duration::milliseconds(10));
tx.send(()).unwrap();
#![feature(std_misc)]
-use std::thread::Thread;
+use std::thread;
use std::sync::mpsc::{channel, Sender};
fn producer(tx: &Sender<Vec<u8>>) {
pub fn main() {
let (tx, rx) = channel::<Vec<u8>>();
- let _prod = Thread::spawn(move|| {
+ let _prod = thread::scoped(move|| {
producer(&tx)
});
#![feature(std_misc)]
-use std::thread::Thread;
+use std::thread;
fn user(_i: isize) {}
// Here, i is *copied* into the proc (heap closure).
// Requires allocation. The proc's copy is not mutable.
let mut i = 0;
- let _t = Thread::spawn(move|| {
+ let _t = thread::scoped(move|| {
user(i);
println!("spawned {}", i)
});
// mutable outside of the proc.
let mut i = 0;
while i < 10 {
- let _t = Thread::spawn(move|| {
+ let _t = thread::scoped(move|| {
user(i);
});
i += 1;
// Here, i must be shadowed in the proc to be mutable.
let mut i = 0;
while i < 10 {
- let _t = Thread::spawn(move|| {
+ let _t = thread::scoped(move|| {
let mut i = i;
i += 1;
user(i);
#![feature(std_misc)]
-use std::thread::Thread;
+use std::thread;
macro_rules! expr { ($e: expr) => { $e } }
macro_rules! spawn {
($($code: tt)*) => {
- expr!(Thread::spawn(move|| {$($code)*}))
+ expr!(thread::spawn(move|| {$($code)*}))
}
}
fn main() {
let x: [isize; 4] = [1,2,3,4];
- let xptr = x.as_slice() as *const [isize];
+ let xptr = &x[..] as *const [isize];
xptr.foo();
}
--- /dev/null
+// 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.
+
+#![feature(core)]
+use std::fmt::Debug;
+use std::cmp::{self, PartialOrd, Ordering};
+use std::iter::MinMaxResult::MinMax;
+
+#[derive(Debug, Copy, Clone, PartialEq, Eq)]
+struct Foo {
+ n: u8,
+ name: &'static str
+}
+
+impl PartialOrd for Foo {
+ fn partial_cmp(&self, other: &Foo) -> Option<Ordering> {
+ Some(self.cmp(other))
+ }
+}
+
+impl Ord for Foo {
+ fn cmp(&self, other: &Foo) -> Ordering {
+ self.n.cmp(&other.n)
+ }
+}
+
+fn main() {
+ let a = Foo { n: 4, name: "a" };
+ let b = Foo { n: 4, name: "b" };
+ let c = Foo { n: 8, name: "c" };
+ let d = Foo { n: 8, name: "d" };
+ let e = Foo { n: 22, name: "e" };
+ let f = Foo { n: 22, name: "f" };
+
+ let data = [a, b, c, d, e, f];
+
+ // `min` should return the left when the values are equal
+ assert_eq!(data.iter().min(), Some(&a));
+ assert_eq!(data.iter().min_by(|a| a.n), Some(&a));
+ assert_eq!(cmp::min(a, b), a);
+ assert_eq!(cmp::min(b, a), b);
+ assert_eq!(cmp::partial_min(a, b), Some(a));
+ assert_eq!(cmp::partial_min(b, a), Some(b));
+
+ // `max` should return the right when the values are equal
+ assert_eq!(data.iter().max(), Some(&f));
+ assert_eq!(data.iter().max_by(|a| a.n), Some(&f));
+ assert_eq!(cmp::max(e, f), f);
+ assert_eq!(cmp::max(f, e), e);
+ assert_eq!(cmp::partial_max(e, f), Some(f));
+ assert_eq!(cmp::partial_max(f, e), Some(e));
+
+ // Similar for `min_max`
+ assert_eq!(data.iter().min_max(), MinMax(&a, &f));
+ assert_eq!(data[1..5].iter().min_max(), MinMax(&b, &e));
+ assert_eq!(data[2..4].iter().min_max(), MinMax(&c, &d));
+
+ let mut presorted = data.to_vec();
+ presorted.sort();
+ assert_stable(&presorted);
+
+ let mut presorted = data.to_vec();
+ presorted.sort_by(|a, b| a.cmp(b));
+ assert_stable(&presorted);
+
+ // Assert that sorted and min/max are the same
+ fn assert_stable<T: Ord + Debug>(presorted: &[T]) {
+ for slice in presorted.windows(2) {
+ let a = &slice[0];
+ let b = &slice[1];
+
+ assert_eq!(a, cmp::min(a, b));
+ assert_eq!(b, cmp::max(a, b));
+ }
+ }
+}
#![feature(std_misc)]
-use std::thread::Thread;
+use std::thread;
pub fn main() {
let x = "Hello world!".to_string();
- let _t = Thread::spawn(move|| {
+ let _t = thread::scoped(move|| {
println!("{}", x);
});
}
pub fn main() {
let thing = "{{ f }}";
- let f = thing.find_str("{{");
+ let f = thing.find("{{");
if f.is_none() {
println!("None!");
use std::old_io::process::Command;
use std::env;
-use std::thread::Thread;
+use std::thread;
// lifted from the test module
// Inlining to avoid llvm turning the recursive functions into tail calls,
fn main() {
let args: Vec<String> = env::args().collect();
if args.len() > 1 && args[1] == "recurse" {
- let _t = Thread::scoped(recurse);
+ let _t = thread::scoped(recurse);
} else {
let recurse = Command::new(&args[0]).arg("recurse").output().unwrap();
assert!(!recurse.status.success());
--- /dev/null
+// 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::process::{self, Command, Stdio};
+
+fn main() {
+ let args: Vec<String> = env::args().collect();
+ if args.len() > 1 && args[1] == "child" {
+ child();
+ } else {
+ parent();
+ }
+}
+
+fn parent() {
+ let args: Vec<String> = env::args().collect();
+ let status = Command::new(&args[0]).arg("child").status().unwrap();
+ assert_eq!(status.code(), Some(2));
+}
+
+fn child() -> i32 {
+ process::exit(2);
+}
// supposed to match the lifetime `'a`) ...
fn foo<'a>(map: RefCell<HashMap<&'static str, &'a [u8]>>) {
let one = [1];
- assert_eq!(map.borrow().get("one"), Some(&one.as_slice()));
+ assert_eq!(map.borrow().get("one"), Some(&&one[..]));
}
#[cfg(all(not(cannot_use_this_yet),not(cannot_use_this_yet_either)))]
+++ /dev/null
-// 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.
-
-// This test can't be a unit test in std,
-// because it needs TempDir, which is in extra
-
-// pretty-expanded FIXME #23616
-
-#![feature(tempdir, path_ext)]
-
-use std::ffi::CString;
-use std::fs::{self, TempDir, File, PathExt};
-
-fn rename_directory() {
- let tmpdir = TempDir::new("rename_directory").ok().expect("rename_directory failed");
- let tmpdir = tmpdir.path();
- let old_path = tmpdir.join("foo/bar/baz");
- fs::create_dir_all(&old_path).unwrap();
- let test_file = &old_path.join("temp.txt");
-
- File::create(test_file).unwrap();
-
- let new_path = tmpdir.join("quux/blat");
- fs::create_dir_all(&new_path).unwrap();
- fs::rename(&old_path, &new_path.join("newdir"));
- assert!(new_path.join("newdir").is_dir());
- assert!(new_path.join("newdir/temp.txt").exists());
-}
-
-pub fn main() { rename_directory() }
#![feature(start, os, std_misc, old_io)]
-use std::ffi;
+use std::ffi::CStr;
use std::old_io::process::{Command, ProcessOutput};
use std::os;
use std::rt::unwind::try;
let args = unsafe {
(0..argc as usize).map(|i| {
let ptr = *argv.offset(i as isize) as *const _;
- ffi::c_str_to_bytes(&ptr).to_vec()
+ CStr::from_ptr(ptr).to_bytes().to_vec()
}).collect::<Vec<_>>()
};
let me = &*args[0];
extern crate log;
use std::sync::mpsc::{channel, Sender, Receiver};
-use std::thread::Thread;
+use std::thread;
pub struct ChannelLogger {
tx: Sender<String>
pub fn main() {
let (logger, rx) = ChannelLogger::new();
- let _t = Thread::spawn(move|| {
+ let _t = thread::scoped(move|| {
log::set_logger(logger);
info!("foo");
// pretty-expanded FIXME #23616
#![feature(core, std_misc)]
-use std::thread::Thread;
+use std::thread;
use std::sync::Mutex;
fn par_for<I, F>(iter: I, f: F)
{
let f = &f;
let _guards: Vec<_> = iter.map(|elem| {
- Thread::scoped(move || {
+ thread::scoped(move || {
f(elem)
})
}).collect();
#![feature(std_misc)]
-use std::thread::Thread;
+use std::thread;
use std::sync::mpsc::channel;
struct test {
pub fn main() {
let (tx, rx) = channel();
- let _t = Thread::spawn(move|| {
+ let _t = thread::scoped(move|| {
let (tx2, rx2) = channel();
tx.send(tx2).unwrap();
assert!(eq_u32x4(u32x4(1, 2, 3, 4) + u32x4(4, 3, 2, 1), u32x4(5, 5, 5, 5)));
assert!(eq_u32x4(u32x4(4, 5, 6, 7) - u32x4(4, 3, 2, 1), u32x4(0, 2, 4, 6)));
assert!(eq_u32x4(u32x4(1, 2, 3, 4) * u32x4(4, 3, 2, 1), u32x4(4, 6, 6, 4)));
+ assert!(eq_u32x4(u32x4(1, 2, 3, 4) / u32x4(4, 3, 2, 1), u32x4(0, 0, 1, 4)));
assert!(eq_u32x4(u32x4(1, 2, 3, 4) & u32x4(4, 3, 2, 1), u32x4(0, 2, 2, 0)));
assert!(eq_u32x4(u32x4(1, 2, 3, 4) | u32x4(4, 3, 2, 1), u32x4(5, 3, 3, 5)));
assert!(eq_u32x4(u32x4(1, 2, 3, 4) ^ u32x4(4, 3, 2, 1), u32x4(5, 1, 1, 5)));
assert!(eq_i32x4(i32x4(1, 2, 3, 4) + i32x4(4, 3, 2, 1), i32x4(5, 5, 5, 5)));
assert!(eq_i32x4(i32x4(1, 2, 3, 4) - i32x4(4, 3, 2, 1), i32x4(-3, -1, 1, 3)));
assert!(eq_i32x4(i32x4(1, 2, 3, 4) * i32x4(4, 3, 2, 1), i32x4(4, 6, 6, 4)));
+ assert!(eq_i32x4(i32x4(1, 2, 3, 4) / i32x4(4, 3, 2, 1), i32x4(0, 0, 1, 4)));
assert!(eq_i32x4(i32x4(1, 2, 3, 4) & i32x4(4, 3, 2, 1), i32x4(0, 2, 2, 0)));
assert!(eq_i32x4(i32x4(1, 2, 3, 4) | i32x4(4, 3, 2, 1), i32x4(5, 3, 3, 5)));
assert!(eq_i32x4(i32x4(1, 2, 3, 4) ^ i32x4(4, 3, 2, 1), i32x4(5, 1, 1, 5)));
+++ /dev/null
-// Copyright 2012-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.
-
-// pretty-expanded FIXME #23616
-
-#![feature(tempdir, path_ext)]
-
-use std::fs::{File, TempDir};
-use std::io::prelude::*;
-
-pub fn main() {
- let dir = TempDir::new_in(".", "").unwrap();
- let path = dir.path().join("file");
-
- {
- match File::create(&path) {
- Err(..) => unreachable!(),
- Ok(f) => {
- let mut f = f;
- for _ in 0..1000 {
- f.write(&[0]);
- }
- }
- }
- }
-
- assert!(path.exists());
- assert_eq!(path.metadata().unwrap().len(), 1000);
-}
assert!(
include_str!("syntax-extension-source-utils-files/includeme.\
fragment").to_string()
- .as_slice()
.starts_with("/* this is for "));
assert!(
include_bytes!("syntax-extension-source-utils-files/includeme.fragment")
// The Windows tests are wrapped in an extra module for some reason
assert!((m1::m2::where_am_i().ends_with("m1::m2")));
- assert!(match (47, "( 2 * 3 ) + 5") {
- (line!(), stringify!((2*3) + 5)) => true,
- _ => false
- })
+ assert_eq!((46, "( 2 * 3 ) + 5"), (line!(), stringify!((2*3) + 5)));
}
#![feature(std_misc)]
-use std::thread::Thread;
+use std::thread;
use std::sync::mpsc::{channel, Sender};
pub fn main() { test05(); }
fn test05() {
let (tx, rx) = channel();
- let _t = Thread::spawn(move|| { test05_start(&tx) });
+ let _t = thread::scoped(move|| { test05_start(&tx) });
let mut value: isize = rx.recv().unwrap();
println!("{}", value);
value = rx.recv().unwrap();
#![feature(std_misc)]
-use std::thread::Thread;
+use std::thread;
pub fn main() { test00(); }
fn start() { println!("Started / Finished task."); }
fn test00() {
- let _ = Thread::scoped(move|| start() ).join();
+ let _ = thread::scoped(move|| start() ).join();
println!("Completing.");
}
#![feature(std_misc)]
-use std::thread::Thread;
+use std::thread;
use std::sync::mpsc::{channel, Sender};
fn start(tx: &Sender<Sender<String>>) {
pub fn main() {
let (tx, rx) = channel();
- let _child = Thread::spawn(move|| { start(&tx) });
+ let _child = thread::scoped(move|| { start(&tx) });
let mut c = rx.recv().unwrap();
c.send("A".to_string()).unwrap();
c.send("B".to_string()).unwrap();
- Thread::yield_now();
+ thread::yield_now();
}
#![feature(std_misc)]
use std::sync::mpsc::{channel, Sender};
-use std::thread::Thread;
+use std::thread;
fn start(tx: &Sender<Sender<isize>>) {
let (tx2, _rx) = channel();
pub fn main() {
let (tx, rx) = channel();
- let _child = Thread::spawn(move|| {
+ let _child = thread::scoped(move|| {
start(&tx)
});
let _tx = rx.recv().unwrap();
#![feature(std_misc)]
-use std::thread::Thread;
+use std::thread;
pub fn main() { test00(); }
fn test00() {
let i: isize = 0;
- let mut result = Thread::scoped(move|| {
+ let mut result = thread::scoped(move|| {
start(i)
});
// Sleep long enough for the task to finish.
let mut i = 0_usize;
while i < 10000 {
- Thread::yield_now();
+ thread::yield_now();
i += 1;
}
#![feature(std_misc)]
use std::sync::mpsc::{channel, Sender};
-use std::thread::Thread;
+use std::thread;
fn start(tx: &Sender<isize>, start: isize, number_of_messages: isize) {
let mut i: isize = 0;
pub fn main() {
println!("Check that we don't deadlock.");
let (tx, rx) = channel();
- let _ = Thread::scoped(move|| { start(&tx, 0, 10) }).join();
+ let _t = thread::scoped(move|| { start(&tx, 0, 10) }).join();
println!("Joined task");
}
#![feature(std_misc)]
use std::sync::mpsc::{channel, Sender};
-use std::thread::Thread;
+use std::thread;
pub fn main() {
let (tx, rx) = channel();
while (i > 0) {
println!("{}", i);
let tx = tx.clone();
- Thread::spawn({let i = i; move|| { child(i, &tx) }});
+ thread::scoped({let i = i; move|| { child(i, &tx) }});
i = i - 1;
}
#![feature(std_misc)]
use std::sync::mpsc::{channel, Sender};
-use std::thread::Thread;
+use std::thread;
fn start(tx: &Sender<isize>, i0: isize) {
let mut i = i0;
// the child's point of view the receiver may die. We should
// drop messages on the floor in this case, and not crash!
let (tx, rx) = channel();
- let _t = Thread::spawn(move|| {
+ let _t = thread::scoped(move|| {
start(&tx, 10)
});
rx.recv();
// This test is specifically about spawning temporary closures.
-use std::thread::Thread;
+use std::thread;
fn f() {
}
pub fn main() {
- let _t = Thread::scoped(move|| f() ).join();
+ let _t = thread::scoped(move|| f() ).join();
}
// no-pretty-expanded FIXME #15189
-use std::thread::Thread;
+use std::thread;
use std::sync::mpsc::{channel, Sender};
pub fn main() { println!("===== WITHOUT THREADS ====="); test00(); }
let mut results = Vec::new();
while i < number_of_tasks {
let tx = tx.clone();
- results.push(Thread::scoped({
+ results.push(thread::scoped({
let i = i;
move|| {
test00_start(&tx, i, number_of_messages)
#![allow(dead_assignment)]
use std::sync::mpsc::{channel, Sender};
-use std::thread::Thread;
+use std::thread;
pub fn main() { test00(); }
let number_of_messages: isize = 10;
let tx2 = tx.clone();
- let _t = Thread::spawn(move|| {
+ let _t = thread::scoped(move|| {
test00_start(&tx2, number_of_messages * 0, number_of_messages);
});
let tx2 = tx.clone();
- let _t = Thread::spawn(move|| {
+ let _t = thread::scoped(move|| {
test00_start(&tx2, number_of_messages * 1, number_of_messages);
});
let tx2 = tx.clone();
- let _t = Thread::spawn(move|| {
+ let _t = thread::scoped(move|| {
test00_start(&tx2, number_of_messages * 2, number_of_messages);
});
let tx2 = tx.clone();
- let _t = Thread::spawn(move|| {
+ let _t = thread::scoped(move|| {
test00_start(&tx2, number_of_messages * 3, number_of_messages);
});
#![feature(std_misc)]
-use std::thread::Thread;
+use std::thread;
use std::sync::mpsc::{channel, Sender};
pub fn main() { test00(); }
let (tx, rx) = channel();
let number_of_messages: isize = 10;
- let result = Thread::scoped(move|| {
+ let result = thread::scoped(move|| {
test00_start(&tx, number_of_messages);
});
#![feature(std_misc)]
-use std::thread::Thread;
+use std::thread;
pub fn main() {
- let _t = Thread::spawn(move|| child("Hello".to_string()) );
+ let _t = thread::scoped(move|| child("Hello".to_string()) );
}
fn child(_s: String) {
#![allow(unknown_features)]
#![feature(box_syntax, std_misc)]
-use std::thread::Thread;
+use std::thread;
use std::sync::mpsc::channel;
pub fn main() {
let x: Box<isize> = box 1;
let x_in_parent = &(*x) as *const isize as usize;
- let _t = Thread::spawn(move || {
+ let _t = thread::scoped(move || {
let x_in_child = &(*x) as *const isize as usize;
tx.send(x_in_child).unwrap();
});
use std::sync::Arc;
use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::mpsc::channel;
-use std::thread::Thread;
+use std::thread;
static N: usize = 8;
static M: usize = 20;
let a = a.clone();
let cnt = cnt.clone();
let srv_tx = srv_tx.clone();
- Thread::scoped(move|| {
+ thread::scoped(move|| {
let mut a = a;
loop {
match a.accept() {
let _t = (0..N).map(|_| {
let cli_tx = cli_tx.clone();
- Thread::scoped(move|| {
+ thread::scoped(move|| {
for _ in 0..M {
let _s = TcpStream::connect(addr).unwrap();
}
use std::old_io;
use std::time::Duration;
use std::sync::mpsc::channel;
-use std::thread::Thread;
+use std::thread;
#[cfg_attr(target_os = "freebsd", ignore)]
fn eventual_timeout() {
let (tx1, rx1) = channel();
let (_tx2, rx2) = channel::<()>();
- let _t = Thread::spawn(move|| {
+ let _t = thread::scoped(move|| {
let _l = TcpListener::bind(addr).unwrap().listen();
tx1.send(()).unwrap();
let _ = rx2.recv();
use std::old_io::fs::PathExtensions;
use std::old_io::{fs, TempDir};
use std::old_io;
-use std::os;
+use std::env;
use std::sync::mpsc::channel;
use std::thread;
// to depend on std
fn recursive_mkdir_rel() {
let path = Path::new("frob");
- let cwd = os::getcwd().unwrap();
+ let cwd = Path::new(env::current_dir().unwrap().to_str().unwrap());
println!("recursive_mkdir_rel: Making: {} in cwd {} [{}]", path.display(),
cwd.display(), path.exists());
fs::mkdir_recursive(&path, old_io::USER_RWX);
fn recursive_mkdir_rel_2() {
let path = Path::new("./frob/baz");
- let cwd = os::getcwd().unwrap();
+ let cwd = Path::new(env::current_dir().unwrap().to_str().unwrap());
println!("recursive_mkdir_rel_2: Making: {} in cwd {} [{}]", path.display(),
cwd.display(), path.exists());
fs::mkdir_recursive(&path, old_io::USER_RWX);
fn in_tmpdir<F>(f: F) where F: FnOnce() {
let tmpdir = TempDir::new("test").ok().expect("can't make tmpdir");
- assert!(os::change_dir(tmpdir.path()).is_ok());
+ assert!(env::set_current_dir(tmpdir.path().as_str().unwrap()).is_ok());
f();
}
#![feature(std_misc)]
-use std::thread::Thread;
+use std::thread;
pub fn main() {
let mut i = 10;
while i > 0 {
- Thread::scoped({let i = i; move|| child(i)});
+ thread::scoped({let i = i; move|| child(i)});
i = i - 1;
}
println!("main thread exiting");
use std::sync::Arc;
use std::sync::mpsc::channel;
-use std::thread::Thread;
+use std::thread;
trait Pet {
fn name(&self, blk: Box<FnMut(&str)>);
box dogge2 as Box<Pet+Sync+Send>));
let (tx1, rx1) = channel();
let arc1 = arc.clone();
- let _t1 = Thread::spawn(move|| { check_legs(arc1); tx1.send(()); });
+ let _t1 = thread::scoped(move|| { check_legs(arc1); tx1.send(()); });
let (tx2, rx2) = channel();
let arc2 = arc.clone();
- let _t2 = Thread::spawn(move|| { check_names(arc2); tx2.send(()); });
+ let _t2 = thread::scoped(move|| { check_names(arc2); tx2.send(()); });
let (tx3, rx3) = channel();
let arc3 = arc.clone();
- let _t3 = Thread::spawn(move|| { check_pedigree(arc3); tx3.send(()); });
+ let _t3 = thread::scoped(move|| { check_pedigree(arc3); tx3.send(()); });
rx1.recv();
rx2.recv();
rx3.recv();
#![feature(alloc)]
-use std::boxed::BoxAny;
use std::thread;
struct Foo;
extern crate libc;
-use std::ffi::{self, CString};
+use std::ffi::{CStr, CString};
use libc::{c_char, c_int};
unsafe fn check<T, F>(expected: &str, f: F) where F: FnOnce(*mut c_char) -> T {
let mut x = [0 as c_char; 50];
f(&mut x[0] as *mut c_char);
- assert_eq!(expected.as_bytes(), ffi::c_str_to_bytes(&x.as_ptr()));
+ assert_eq!(expected.as_bytes(), CStr::from_ptr(x.as_ptr()).to_bytes());
}
pub fn main() {