Removes all unstable and deprecated APIs prior to the 1.8 release. All APIs that
are deprecated in the 1.8 release are sticking around for the rest of this
cycle.
Some notable changes are:
* The `dynamic_lib` module was moved into `rustc_back` as the compiler still
relies on a few bits and pieces.
* The `DebugTuple` formatter now special-cases an empty struct name with only
one field to append a trailing comma.
#![crate_type = "bin"]
#![feature(box_syntax)]
-#![feature(dynamic_lib)]
#![feature(libc)]
#![feature(rustc_private)]
#![feature(str_char)]
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![allow(deprecated)]
-
-use std::dynamic_lib::DynamicLibrary;
+use std::env;
+use std::ffi::OsString;
use std::io::prelude::*;
use std::path::PathBuf;
use std::process::{ExitStatus, Command, Child, Output, Stdio};
fn add_target_env(cmd: &mut Command, lib_path: &str, aux_path: Option<&str>) {
// Need to be sure to put both the lib_path and the aux path in the dylib
// search path for the child.
- let mut path = DynamicLibrary::search_path();
+ let var = if cfg!(windows) {
+ "PATH"
+ } else if cfg!(target_os = "macos") {
+ "DYLD_LIBRARY_PATH"
+ } else {
+ "LD_LIBRARY_PATH"
+ };
+ let mut path = env::split_paths(&env::var_os(var).unwrap_or(OsString::new()))
+ .collect::<Vec<_>>();
if let Some(p) = aux_path {
path.insert(0, PathBuf::from(p))
}
path.insert(0, PathBuf::from(lib_path));
// Add the new dylib search path var
- let var = DynamicLibrary::envvar();
- let newpath = DynamicLibrary::create_path(&path);
+ let newpath = env::join_paths(&path).unwrap();
cmd.env(var, newpath);
}
#![feature(alloc)]
#![feature(core_intrinsics)]
#![feature(heap_api)]
-#![feature(raw)]
#![feature(heap_api)]
#![feature(staged_api)]
#![feature(dropck_parametricity)]
use std::marker::{PhantomData, Send};
use std::mem;
use std::ptr;
-use std::slice;
use alloc::heap;
use alloc::raw_vec::RawVec;
-struct Chunk {
- data: RawVec<u8>,
- /// Index of the first unused byte.
- fill: Cell<usize>,
- /// Indicates whether objects with destructors are stored in this chunk.
- is_copy: Cell<bool>,
-}
-
-impl Chunk {
- fn new(size: usize, is_copy: bool) -> Chunk {
- Chunk {
- data: RawVec::with_capacity(size),
- fill: Cell::new(0),
- is_copy: Cell::new(is_copy),
- }
- }
-
- fn capacity(&self) -> usize {
- self.data.cap()
- }
-
- unsafe fn as_ptr(&self) -> *const u8 {
- self.data.ptr()
- }
-
- // Walk down a chunk, running the destructors for any objects stored
- // in it.
- unsafe fn destroy(&self) {
- let mut idx = 0;
- let buf = self.as_ptr();
- let fill = self.fill.get();
-
- while idx < fill {
- let tydesc_data = buf.offset(idx as isize) as *const usize;
- let (tydesc, is_done) = un_bitpack_tydesc_ptr(*tydesc_data);
- let (size, align) = ((*tydesc).size, (*tydesc).align);
-
- let after_tydesc = idx + mem::size_of::<*const TyDesc>();
-
- let start = round_up(after_tydesc, align);
-
- if is_done {
- ((*tydesc).drop_glue)(buf.offset(start as isize) as *const i8);
- }
-
- // Find where the next tydesc lives
- idx = round_up(start + size, mem::align_of::<*const TyDesc>());
- }
- }
-}
-
-/// A slower reflection-based arena that can allocate objects of any type.
-///
-/// This arena uses `RawVec<u8>` as a backing store to allocate objects from.
-/// For each allocated object, the arena stores a pointer to the type descriptor
-/// followed by the object (potentially with alignment padding after each
-/// element). When the arena is destroyed, it iterates through all of its
-/// chunks, and uses the tydesc information to trace through the objects,
-/// calling the destructors on them. One subtle point that needs to be
-/// addressed is how to handle panics while running the user provided
-/// initializer function. It is important to not run the destructor on
-/// uninitialized objects, but how to detect them is somewhat subtle. Since
-/// `alloc()` can be invoked recursively, it is not sufficient to simply exclude
-/// the most recent object. To solve this without requiring extra space, we
-/// use the low order bit of the tydesc pointer to encode whether the object
-/// it describes has been fully initialized.
-///
-/// As an optimization, objects with destructors are stored in different chunks
-/// than objects without destructors. This reduces overhead when initializing
-/// plain-old-data (`Copy` types) and means we don't need to waste time running
-/// their destructors.
-#[unstable(feature = "rustc_private",
- reason = "Private to rustc", issue = "0")]
-#[rustc_deprecated(since = "1.6.0-dev", reason =
-"The reflection-based arena is superseded by the any-arena crate")]
-pub struct Arena<'longer_than_self> {
- // The heads are separated out from the list as a unbenchmarked
- // microoptimization, to avoid needing to case on the list to access a head.
- head: RefCell<Chunk>,
- copy_head: RefCell<Chunk>,
- chunks: RefCell<Vec<Chunk>>,
- _marker: PhantomData<*mut &'longer_than_self ()>,
-}
-
-impl<'a> Arena<'a> {
- /// Allocates a new Arena with 32 bytes preallocated.
- pub fn new() -> Arena<'a> {
- Arena::new_with_size(32)
- }
-
- /// Allocates a new Arena with `initial_size` bytes preallocated.
- pub fn new_with_size(initial_size: usize) -> Arena<'a> {
- Arena {
- head: RefCell::new(Chunk::new(initial_size, false)),
- copy_head: RefCell::new(Chunk::new(initial_size, true)),
- chunks: RefCell::new(Vec::new()),
- _marker: PhantomData,
- }
- }
-}
-
-impl<'longer_than_self> Drop for Arena<'longer_than_self> {
- fn drop(&mut self) {
- unsafe {
- self.head.borrow().destroy();
- for chunk in self.chunks.borrow().iter() {
- if !chunk.is_copy.get() {
- chunk.destroy();
- }
- }
- }
- }
-}
-
-#[inline]
-fn round_up(base: usize, align: usize) -> usize {
- (base.checked_add(align - 1)).unwrap() & !(align - 1)
-}
-
-// We encode whether the object a tydesc describes has been
-// initialized in the arena in the low bit of the tydesc pointer. This
-// is necessary in order to properly do cleanup if a panic occurs
-// during an initializer.
-#[inline]
-fn bitpack_tydesc_ptr(p: *const TyDesc, is_done: bool) -> usize {
- p as usize | (is_done as usize)
-}
-#[inline]
-fn un_bitpack_tydesc_ptr(p: usize) -> (*const TyDesc, bool) {
- ((p & !1) as *const TyDesc, p & 1 == 1)
-}
-
-// HACK(eddyb) TyDesc replacement using a trait object vtable.
-// This could be replaced in the future with a custom DST layout,
-// or `&'static (drop_glue, size, align)` created by a `const fn`.
-// Requirements:
-// * rvalue promotion (issue #1056)
-// * mem::{size_of, align_of} must be const fns
-struct TyDesc {
- drop_glue: fn(*const i8),
- size: usize,
- align: usize,
-}
-
-trait AllTypes {
- fn dummy(&self) {}
-}
-
-impl<T: ?Sized> AllTypes for T {}
-
-unsafe fn get_tydesc<T>() -> *const TyDesc {
- use std::raw::TraitObject;
-
- let ptr = &*(heap::EMPTY as *const T);
-
- // Can use any trait that is implemented for all types.
- let obj = mem::transmute::<&AllTypes, TraitObject>(ptr);
- obj.vtable as *const TyDesc
-}
-
-impl<'longer_than_self> Arena<'longer_than_self> {
- // Grows a given chunk and returns `false`, or replaces it with a bigger
- // chunk and returns `true`.
- // This method is shared by both parts of the arena.
- #[cold]
- fn alloc_grow(&self, head: &mut Chunk, used_cap: usize, n_bytes: usize) -> bool {
- if head.data.reserve_in_place(used_cap, n_bytes) {
- // In-place reallocation succeeded.
- false
- } else {
- // Allocate a new chunk.
- let new_min_chunk_size = cmp::max(n_bytes, head.capacity());
- let new_chunk = Chunk::new((new_min_chunk_size + 1).next_power_of_two(), false);
- let old_chunk = mem::replace(head, new_chunk);
- if old_chunk.fill.get() != 0 {
- self.chunks.borrow_mut().push(old_chunk);
- }
- true
- }
- }
-
- // Functions for the copyable part of the arena.
-
- #[inline]
- fn alloc_copy_inner(&self, n_bytes: usize, align: usize) -> *const u8 {
- let mut copy_head = self.copy_head.borrow_mut();
- let fill = copy_head.fill.get();
- let mut start = round_up(fill, align);
- let mut end = start + n_bytes;
-
- if end > copy_head.capacity() {
- if self.alloc_grow(&mut *copy_head, fill, end - fill) {
- // Continuing with a newly allocated chunk
- start = 0;
- end = n_bytes;
- copy_head.is_copy.set(true);
- }
- }
-
- copy_head.fill.set(end);
-
- unsafe { copy_head.as_ptr().offset(start as isize) }
- }
-
- #[inline]
- fn alloc_copy<T, F>(&self, op: F) -> &mut T
- where F: FnOnce() -> T
- {
- unsafe {
- let ptr = self.alloc_copy_inner(mem::size_of::<T>(), mem::align_of::<T>());
- let ptr = ptr as *mut T;
- ptr::write(&mut (*ptr), op());
- &mut *ptr
- }
- }
-
- // Functions for the non-copyable part of the arena.
-
- #[inline]
- fn alloc_noncopy_inner(&self, n_bytes: usize, align: usize) -> (*const u8, *const u8) {
- let mut head = self.head.borrow_mut();
- let fill = head.fill.get();
-
- let mut tydesc_start = fill;
- let after_tydesc = fill + mem::size_of::<*const TyDesc>();
- let mut start = round_up(after_tydesc, align);
- let mut end = round_up(start + n_bytes, mem::align_of::<*const TyDesc>());
-
- if end > head.capacity() {
- if self.alloc_grow(&mut *head, tydesc_start, end - tydesc_start) {
- // Continuing with a newly allocated chunk
- tydesc_start = 0;
- start = round_up(mem::size_of::<*const TyDesc>(), align);
- end = round_up(start + n_bytes, mem::align_of::<*const TyDesc>());
- }
- }
-
- head.fill.set(end);
-
- unsafe {
- let buf = head.as_ptr();
- (buf.offset(tydesc_start as isize),
- buf.offset(start as isize))
- }
- }
-
- #[inline]
- fn alloc_noncopy<T, F>(&self, op: F) -> &mut T
- where F: FnOnce() -> T
- {
- unsafe {
- let tydesc = get_tydesc::<T>();
- let (ty_ptr, ptr) = self.alloc_noncopy_inner(mem::size_of::<T>(), mem::align_of::<T>());
- let ty_ptr = ty_ptr as *mut usize;
- let ptr = ptr as *mut T;
- // Write in our tydesc along with a bit indicating that it
- // has *not* been initialized yet.
- *ty_ptr = bitpack_tydesc_ptr(tydesc, false);
- // Actually initialize it
- ptr::write(&mut (*ptr), op());
- // Now that we are done, update the tydesc to indicate that
- // the object is there.
- *ty_ptr = bitpack_tydesc_ptr(tydesc, true);
-
- &mut *ptr
- }
- }
-
- /// Allocates a new item in the arena, using `op` to initialize the value,
- /// and returns a reference to it.
- #[inline]
- pub fn alloc<T: 'longer_than_self, F>(&self, op: F) -> &mut T
- where F: FnOnce() -> T
- {
- unsafe {
- if intrinsics::needs_drop::<T>() {
- self.alloc_noncopy(op)
- } else {
- self.alloc_copy(op)
- }
- }
- }
-
- /// Allocates a slice of bytes of requested length. The bytes are not guaranteed to be zero
- /// if the arena has previously been cleared.
- ///
- /// # Panics
- ///
- /// Panics if the requested length is too large and causes overflow.
- pub fn alloc_bytes(&self, len: usize) -> &mut [u8] {
- unsafe {
- // Check for overflow.
- self.copy_head.borrow().fill.get().checked_add(len).expect("length overflow");
- let ptr = self.alloc_copy_inner(len, 1);
- intrinsics::assume(!ptr.is_null());
- slice::from_raw_parts_mut(ptr as *mut _, len)
- }
- }
-
- /// Clears the arena. Deallocates all but the longest chunk which may be reused.
- pub fn clear(&mut self) {
- unsafe {
- self.head.borrow().destroy();
- self.head.borrow().fill.set(0);
- self.copy_head.borrow().fill.set(0);
- for chunk in self.chunks.borrow().iter() {
- if !chunk.is_copy.get() {
- chunk.destroy();
- }
- }
- self.chunks.borrow_mut().clear();
- }
- }
-}
-
/// A faster arena that can hold objects of only one type.
pub struct TypedArena<T> {
/// A pointer to the next object to be allocated.
mod tests {
extern crate test;
use self::test::Bencher;
- use super::{Arena, TypedArena};
+ use super::TypedArena;
use std::cell::Cell;
- use std::rc::Rc;
#[allow(dead_code)]
#[derive(Debug, Eq, PartialEq)]
})
}
- #[bench]
- pub fn bench_copy_old_arena(b: &mut Bencher) {
- let arena = Arena::new();
- b.iter(|| arena.alloc(|| Point { x: 1, y: 2, z: 3 }))
- }
-
#[allow(dead_code)]
struct Noncopy {
string: String,
}
}
- #[test]
- pub fn test_arena_zero_sized() {
- let arena = Arena::new();
- let mut points = vec![];
- for _ in 0..1000 {
- for _ in 0..100 {
- arena.alloc(|| ());
- }
- let point = arena.alloc(|| Point { x: 1, y: 2, z: 3 });
- points.push(point);
- }
- for point in &points {
- assert_eq!(**point, Point { x: 1, y: 2, z: 3 });
- }
- }
-
#[test]
pub fn test_typed_arena_clear() {
let mut arena = TypedArena::new();
}
}
- #[test]
- pub fn test_arena_clear() {
- let mut arena = Arena::new();
- for _ in 0..10 {
- arena.clear();
- for _ in 0..10000 {
- arena.alloc(|| Point { x: 1, y: 2, z: 3 });
- arena.alloc(|| {
- Noncopy {
- string: "hello world".to_string(),
- array: vec![],
- }
- });
- }
- }
- }
-
- #[test]
- pub fn test_arena_alloc_bytes() {
- let arena = Arena::new();
- for i in 0..10000 {
- arena.alloc(|| Point { x: 1, y: 2, z: 3 });
- for byte in arena.alloc_bytes(i % 42).iter_mut() {
- *byte = i as u8;
- }
- }
- }
-
- #[test]
- fn test_arena_destructors() {
- let arena = Arena::new();
- for i in 0..10 {
- // Arena allocate something with drop glue to make sure it
- // doesn't leak.
- arena.alloc(|| Rc::new(i));
- // Allocate something with funny size and alignment, to keep
- // things interesting.
- arena.alloc(|| [0u8, 1u8, 2u8]);
- }
- }
-
- #[test]
- #[should_panic]
- fn test_arena_destructors_fail() {
- let arena = Arena::new();
- // Put some stuff in the arena.
- for i in 0..10 {
- // Arena allocate something with drop glue to make sure it
- // doesn't leak.
- arena.alloc(|| Rc::new(i));
- // Allocate something with funny size and alignment, to keep
- // things interesting.
- arena.alloc(|| [0u8, 1, 2]);
- }
- // Now, panic while allocating
- arena.alloc::<Rc<i32>, _>(|| {
- panic!();
- });
- }
-
// Drop tests
struct DropCounter<'a> {
}
}
- #[test]
- fn test_arena_drop_count() {
- let counter = Cell::new(0);
- {
- let arena = Arena::new();
- for _ in 0..100 {
- // Allocate something with drop glue to make sure it doesn't leak.
- arena.alloc(|| DropCounter { count: &counter });
- // Allocate something with funny size and alignment, to keep
- // things interesting.
- arena.alloc(|| [0u8, 1u8, 2u8]);
- }
- // dropping
- };
- assert_eq!(counter.get(), 100);
- }
-
- #[test]
- fn test_arena_drop_on_clear() {
- let counter = Cell::new(0);
- for i in 0..10 {
- let mut arena = Arena::new();
- for _ in 0..100 {
- // Allocate something with drop glue to make sure it doesn't leak.
- arena.alloc(|| DropCounter { count: &counter });
- // Allocate something with funny size and alignment, to keep
- // things interesting.
- arena.alloc(|| [0u8, 1u8, 2u8]);
- }
- arena.clear();
- assert_eq!(counter.get(), i * 100 + 100);
- }
- }
-
#[test]
fn test_typed_arena_drop_count() {
let counter = Cell::new(0);
}
}
- #[test]
- fn test_arena_drop_small_count() {
- DROP_COUNTER.with(|c| c.set(0));
- {
- let arena = Arena::new();
- for _ in 0..10 {
- for _ in 0..10 {
- // Allocate something with drop glue to make sure it doesn't leak.
- arena.alloc(|| SmallDroppable);
- }
- // Allocate something with funny size and alignment, to keep
- // things interesting.
- arena.alloc(|| [0u8, 1u8, 2u8]);
- }
- // dropping
- };
- assert_eq!(DROP_COUNTER.with(|c| c.get()), 100);
- }
-
#[test]
fn test_typed_arena_drop_small_count() {
DROP_COUNTER.with(|c| c.set(0));
});
})
}
-
- #[bench]
- pub fn bench_noncopy_old_arena(b: &mut Bencher) {
- let arena = Arena::new();
- b.iter(|| {
- arena.alloc(|| {
- Noncopy {
- string: "hello world".to_string(),
- array: vec![1, 2, 3, 4, 5],
- }
- })
- })
- }
}
}
}
-/// Trait for moving into a `Cow`.
-#[unstable(feature = "into_cow", reason = "may be replaced by `convert::Into`",
- issue = "27735")]
-#[rustc_deprecated(since = "1.7.0",
- reason = "conflicts with Into, may return with specialization")]
-pub trait IntoCow<'a, B: ?Sized> where B: ToOwned {
- /// Moves `self` into `Cow`
- fn into_cow(self) -> Cow<'a, B>;
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-#[allow(deprecated)]
-impl<'a, B: ?Sized> IntoCow<'a, B> for Cow<'a, B> where B: ToOwned {
- fn into_cow(self) -> Cow<'a, B> {
- self
- }
-}
-
#[stable(feature = "rust1", since = "1.0.0")]
#[allow(deprecated)]
impl<'a, T: ?Sized + ToOwned> AsRef<T> for Cow<'a, T> {
fn from_usize(usize) -> Self;
}
-#[allow(deprecated)]
fn bit<E: CLike>(e: &E) -> usize {
- use core::usize;
+ use core::mem;
let value = e.to_usize();
- assert!(value < usize::BITS,
+ let bits = mem::size_of::<usize>() * 8;
+ assert!(value < bits,
"EnumSet only supports up to {} variants.",
- usize::BITS - 1);
+ bits - 1);
1 << value
}
pub use core::fmt::Error;
#[stable(feature = "rust1", since = "1.0.0")]
pub use core::fmt::{ArgumentV1, Arguments, write};
-#[unstable(feature = "fmt_radix", issue = "27728")]
-#[rustc_deprecated(since = "1.7.0", reason = "not used enough to stabilize")]
-#[allow(deprecated)]
-pub use core::fmt::{radix, Radix, RadixFmt};
#[stable(feature = "rust1", since = "1.0.0")]
pub use core::fmt::{DebugList, DebugMap, DebugSet, DebugStruct, DebugTuple};
#![feature(decode_utf16)]
#![feature(dropck_parametricity)]
#![feature(fmt_internals)]
-#![feature(fmt_radix)]
#![feature(heap_api)]
#![feature(inclusive_range)]
#![feature(iter_arith)]
#![feature(lang_items)]
#![feature(nonzero)]
-#![feature(num_bits_bytes)]
#![feature(pattern)]
#![feature(placement_in)]
#![feature(placement_new_protocol)]
#![feature(shared)]
-#![feature(slice_bytes)]
#![feature(slice_patterns)]
#![feature(staged_api)]
#![feature(step_by)]
m.append(&mut n);
check_links(&m);
let mut sum = v;
- sum.push_all(&u);
+ sum.extend_from_slice(&u);
assert_eq!(sum.len(), m.len());
for elt in sum {
assert_eq!(m.pop_front(), Some(elt))
pub use core::slice::{SplitMut, ChunksMut, Split};
#[stable(feature = "rust1", since = "1.0.0")]
pub use core::slice::{SplitN, RSplitN, SplitNMut, RSplitNMut};
-#[unstable(feature = "slice_bytes", issue = "27740")]
-#[allow(deprecated)]
-pub use core::slice::bytes;
#[stable(feature = "rust1", since = "1.0.0")]
pub use core::slice::{from_raw_parts, from_raw_parts_mut};
use rustc_unicode::char::{decode_utf16, REPLACEMENT_CHARACTER};
use rustc_unicode::str as unicode_str;
-#[allow(deprecated)]
-use borrow::{Cow, IntoCow};
+use borrow::Cow;
use range::RangeArgument;
use str::{self, FromStr, Utf8Error, Chars};
use vec::Vec;
}
}
-#[unstable(feature = "into_cow", reason = "may be replaced by `convert::Into`",
- issue= "27735")]
-#[allow(deprecated)]
-impl IntoCow<'static, str> for String {
- #[inline]
- fn into_cow(self) -> Cow<'static, str> {
- Cow::Owned(self)
- }
-}
-
-#[unstable(feature = "into_cow", reason = "may be replaced by `convert::Into`",
- issue = "27735")]
-#[allow(deprecated)]
-impl<'a> IntoCow<'a, str> for &'a str {
- #[inline]
- fn into_cow(self) -> Cow<'a, str> {
- Cow::Borrowed(self)
- }
-}
-
#[stable(feature = "rust1", since = "1.0.0")]
impl fmt::Write for String {
#[inline]
use alloc::heap::EMPTY;
use alloc::raw_vec::RawVec;
use borrow::ToOwned;
+use borrow::Cow;
use core::cmp::Ordering;
use core::fmt;
use core::hash::{self, Hash};
use core::ptr;
use core::slice;
-#[allow(deprecated)]
-use borrow::{Cow, IntoCow};
-
use super::range::RangeArgument;
/// A contiguous growable array type, written `Vec<T>` but pronounced 'vector.'
}
}
- #[allow(missing_docs)]
- #[inline]
- #[unstable(feature = "vec_push_all",
- reason = "likely to be replaced by a more optimized extend",
- issue = "27744")]
- #[rustc_deprecated(reason = "renamed to extend_from_slice",
- since = "1.6.0")]
- pub fn push_all(&mut self, other: &[T]) {
- self.extend_from_slice(other)
- }
-
/// Appends all elements in a slice to the `Vec`.
///
/// Iterates over the slice `other`, clones each element, and then appends
}
}
-#[stable(feature = "rust1", since = "1.0.0")]
-#[allow(deprecated)]
-impl<'a, T: 'a> IntoCow<'a, [T]> for Vec<T> where T: Clone {
- fn into_cow(self) -> Cow<'a, [T]> {
- Cow::Owned(self)
- }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-#[allow(deprecated)]
-impl<'a, T> IntoCow<'a, [T]> for &'a [T] where T: Clone {
- fn into_cow(self) -> Cow<'a, [T]> {
- Cow::Borrowed(self)
- }
-}
-
////////////////////////////////////////////////////////////////////////////////
// Iterators
////////////////////////////////////////////////////////////////////////////////
#![feature(pattern)]
#![feature(rand)]
#![feature(set_recovery)]
-#![feature(slice_bytes)]
#![feature(step_by)]
#![feature(str_char)]
#![feature(str_escape)]
t!(Vec<i32>);
}
-#[test]
-#[allow(deprecated)]
-fn test_bytes_set_memory() {
- use std::slice::bytes::MutableByteVector;
-
- let mut values = [1,2,3,4,5];
- values[0..5].set_memory(0xAB);
- assert!(values == [0xAB, 0xAB, 0xAB, 0xAB, 0xAB]);
- values[2..4].set_memory(0xFF);
- assert!(values == [0xAB, 0xAB, 0xFF, 0xFF, 0xAB]);
-}
-
#[test]
#[should_panic]
fn test_overflow_does_not_cause_segfault() {
pub struct DebugTuple<'a, 'b: 'a> {
fmt: &'a mut fmt::Formatter<'b>,
result: fmt::Result,
- has_fields: bool,
+ fields: usize,
+ empty_name: bool,
}
pub fn debug_tuple_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>, name: &str) -> DebugTuple<'a, 'b> {
DebugTuple {
fmt: fmt,
result: result,
- has_fields: false,
+ fields: 0,
+ empty_name: name.is_empty(),
}
}
#[stable(feature = "debug_builders", since = "1.2.0")]
pub fn field(&mut self, value: &fmt::Debug) -> &mut DebugTuple<'a, 'b> {
self.result = self.result.and_then(|_| {
- let (prefix, space) = if self.has_fields {
+ let (prefix, space) = if self.fields > 0 {
(",", " ")
} else {
("(", "")
}
});
- self.has_fields = true;
+ self.fields += 1;
self
}
/// Finishes output and returns any error encountered.
#[stable(feature = "debug_builders", since = "1.2.0")]
pub fn finish(&mut self) -> fmt::Result {
- if self.has_fields {
+ if self.fields > 0 {
self.result = self.result.and_then(|_| {
if self.is_pretty() {
- self.fmt.write_str("\n)")
- } else {
- self.fmt.write_str(")")
+ try!(self.fmt.write_str("\n"));
+ }
+ if self.fields == 1 && self.empty_name {
+ try!(self.fmt.write_str(","));
}
+ self.fmt.write_str(")")
});
}
self.result
fn is_pretty(&self) -> bool {
self.fmt.flags() & (1 << (FlagV1::Alternate as usize)) != 0
}
-
- /// Returns the wrapped `Formatter`.
- #[unstable(feature = "debug_builder_formatter", reason = "recently added",
- issue = "27782")]
- #[rustc_deprecated(since = "1.7.0", reason = "will be removed")]
- pub fn formatter(&mut self) -> &mut fmt::Formatter<'b> {
- &mut self.fmt
- }
}
struct DebugInner<'a, 'b: 'a> {
Unknown,
}
-#[unstable(feature = "fmt_radix", issue = "27728")]
-#[rustc_deprecated(since = "1.7.0", reason = "not used enough to stabilize")]
-#[allow(deprecated)]
-pub use self::num::radix;
-#[unstable(feature = "fmt_radix", issue = "27728")]
-#[rustc_deprecated(since = "1.7.0", reason = "not used enough to stabilize")]
-#[allow(deprecated)]
-pub use self::num::Radix;
-#[unstable(feature = "fmt_radix", issue = "27728")]
-#[rustc_deprecated(since = "1.7.0", reason = "not used enough to stabilize")]
-#[allow(deprecated)]
-pub use self::num::RadixFmt;
#[stable(feature = "debug_builders", since = "1.2.0")]
pub use self::builders::{DebugStruct, DebugTuple, DebugSet, DebugList, DebugMap};
fn fmt(&self, f: &mut Formatter) -> Result {
let mut builder = f.debug_tuple("");
let ($(ref $name,)*) = *self;
- let mut n = 0;
$(
builder.field($name);
- n += 1;
)*
- if n == 1 {
- try!(write!(builder.formatter(), ","));
- }
-
builder.finish()
}
}
radix! { UpperHex, 16, "0x", x @ 0 ... 9 => b'0' + x,
x @ 10 ... 15 => b'A' + (x - 10) }
-/// A radix with in the range of `2..36`.
-#[derive(Clone, Copy, PartialEq)]
-#[unstable(feature = "fmt_radix",
- reason = "may be renamed or move to a different module",
- issue = "27728")]
-#[rustc_deprecated(since = "1.7.0", reason = "not used enough to stabilize")]
-pub struct Radix {
- base: u8,
-}
-
-impl Radix {
- fn new(base: u8) -> Radix {
- assert!(2 <= base && base <= 36,
- "the base must be in the range of 2..36: {}",
- base);
- Radix { base: base }
- }
-}
-
-impl GenericRadix for Radix {
- fn base(&self) -> u8 {
- self.base
- }
- fn digit(&self, x: u8) -> u8 {
- match x {
- x @ 0 ... 9 => b'0' + x,
- x if x < self.base() => b'a' + (x - 10),
- x => panic!("number not in the range 0..{}: {}", self.base() - 1, x),
- }
- }
-}
-
-/// A helper type for formatting radixes.
-#[unstable(feature = "fmt_radix",
- reason = "may be renamed or move to a different module",
- issue = "27728")]
-#[rustc_deprecated(since = "1.7.0", reason = "not used enough to stabilize")]
-#[derive(Copy, Clone)]
-pub struct RadixFmt<T, R>(T, R);
-
-/// Constructs a radix formatter in the range of `2..36`.
-///
-/// # Examples
-///
-/// ```
-/// #![feature(fmt_radix)]
-///
-/// use std::fmt::radix;
-/// assert_eq!(format!("{}", radix(55, 36)), "1j".to_string());
-/// ```
-#[unstable(feature = "fmt_radix",
- reason = "may be renamed or move to a different module",
- issue = "27728")]
-#[rustc_deprecated(since = "1.7.0", reason = "not used enough to stabilize")]
-pub fn radix<T>(x: T, base: u8) -> RadixFmt<T, Radix> {
- RadixFmt(x, Radix::new(base))
-}
-
-macro_rules! radix_fmt {
- ($T:ty as $U:ty, $fmt:ident) => {
- #[stable(feature = "rust1", since = "1.0.0")]
- impl fmt::Debug for RadixFmt<$T, Radix> {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- fmt::Display::fmt(self, f)
- }
- }
- #[stable(feature = "rust1", since = "1.0.0")]
- impl fmt::Display for RadixFmt<$T, Radix> {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- match *self { RadixFmt(ref x, radix) => radix.$fmt(*x as $U, f) }
- }
- }
- }
-}
-
macro_rules! int_base {
($Trait:ident for $T:ident as $U:ident -> $Radix:ident) => {
#[stable(feature = "rust1", since = "1.0.0")]
int_base! { Octal for $Int as $Uint -> Octal }
int_base! { LowerHex for $Int as $Uint -> LowerHex }
int_base! { UpperHex for $Int as $Uint -> UpperHex }
- radix_fmt! { $Int as $Int, fmt_int }
debug! { $Int }
int_base! { Binary for $Uint as $Uint -> Binary }
int_base! { Octal for $Uint as $Uint -> Octal }
int_base! { LowerHex for $Uint as $Uint -> LowerHex }
int_base! { UpperHex for $Uint as $Uint -> UpperHex }
- radix_fmt! { $Uint as $Uint, fmt_int }
debug! { $Uint }
}
}
}
}
-// The HashState trait is super deprecated, but it's here to have the blanket
-// impl that goes from HashState -> BuildHasher
-
-/// Deprecated, renamed to `BuildHasher`
-#[unstable(feature = "hashmap_hasher", reason = "hasher stuff is unclear",
- issue = "27713")]
-#[rustc_deprecated(since = "1.7.0", reason = "support moved to std::hash and \
- renamed to BuildHasher")]
-pub trait HashState {
- /// Type of the hasher that will be created.
- type Hasher: Hasher;
-
- /// Creates a new hasher based on the given state of this object.
- fn hasher(&self) -> Self::Hasher;
-}
-
-#[unstable(feature = "hashmap_hasher", reason = "hasher stuff is unclear",
- issue = "27713")]
-#[allow(deprecated)]
-impl<T: HashState> BuildHasher for T {
- type Hasher = T::Hasher;
- fn build_hasher(&self) -> T::Hasher { self.hasher() }
-}
-
//////////////////////////////////////////////////////////////////////////////
mod impls {
.map(|(_, x)| x)
}
- #[allow(missing_docs)]
- #[inline]
- #[unstable(feature = "iter_cmp",
- reason = "may want to produce an Ordering directly; see #15311",
- issue = "27724")]
- #[rustc_deprecated(reason = "renamed to max_by_key", since = "1.6.0")]
- fn max_by<B: Ord, F>(self, f: F) -> Option<Self::Item> where
- Self: Sized,
- F: FnMut(&Self::Item) -> B,
- {
- self.max_by_key(f)
- }
-
/// Returns the element that gives the maximum value from the
/// specified function.
///
.map(|(_, x)| x)
}
- #[inline]
- #[allow(missing_docs)]
- #[unstable(feature = "iter_cmp",
- reason = "may want to produce an Ordering directly; see #15311",
- issue = "27724")]
- #[rustc_deprecated(reason = "renamed to min_by_key", since = "1.6.0")]
- fn min_by<B: Ord, F>(self, f: F) -> Option<Self::Item> where
- Self: Sized,
- F: FnMut(&Self::Item) -> B,
- {
- self.min_by_key(f)
- }
-
/// Returns the element that gives the minimum value from the
/// specified function.
///
macro_rules! int_module { ($T:ty, $bits:expr) => (
-// FIXME(#11621): Should be deprecated once CTFE is implemented in favour of
-// calling the `mem::size_of` function.
-#[unstable(feature = "num_bits_bytes",
- reason = "may want to be an associated function",
- issue = "27753")]
-#[rustc_deprecated(since = "1.7.0",
- reason = "will be replaced via const fn or associated constants")]
-#[allow(missing_docs)]
-pub const BITS : usize = $bits;
-// FIXME(#11621): Should be deprecated once CTFE is implemented in favour of
-// calling the `mem::size_of` function.
-#[unstable(feature = "num_bits_bytes",
- reason = "may want to be an associated function",
- issue = "27753")]
-#[rustc_deprecated(since = "1.7.0",
- reason = "will be replaced via const fn or associated constants")]
-#[allow(missing_docs)]
-pub const BYTES : usize = ($bits / 8);
-
// FIXME(#11621): Should be deprecated once CTFE is implemented in favour of
// calling the `Bounded::min_value` function.
#[stable(feature = "rust1", since = "1.0.0")]
#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Debug, Default)]
pub struct Wrapping<T>(#[stable(feature = "rust1", since = "1.0.0")] pub T);
-pub mod wrapping;
+mod wrapping;
// All these modules are technically private and only exposed for libcoretest:
pub mod flt2dec;
macro_rules! uint_module { ($T:ty, $bits:expr) => (
-#[unstable(feature = "num_bits_bytes",
- reason = "may want to be an associated function",
- issue = "27753")]
-#[rustc_deprecated(since = "1.7.0",
- reason = "will be replaced via const fn or associated constants")]
-#[allow(missing_docs)]
-pub const BITS : usize = $bits;
-#[unstable(feature = "num_bits_bytes",
- reason = "may want to be an associated function",
- issue = "27753")]
-#[rustc_deprecated(since = "1.7.0",
- reason = "will be replaced via const fn or associated constants")]
-#[allow(missing_docs)]
-pub const BYTES : usize = ($bits / 8);
-
#[stable(feature = "rust1", since = "1.0.0")]
#[allow(missing_docs)]
pub const MIN: $T = 0 as $T;
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![allow(missing_docs)]
-#![unstable(feature = "old_wrapping", reason = "may be removed or relocated",
- issue = "27755")]
-
-use intrinsics::{add_with_overflow, sub_with_overflow, mul_with_overflow};
-
use super::Wrapping;
use ops::*;
-use ::{i8, i16, i32, i64, isize};
-
-#[unstable(feature = "old_wrapping", reason = "may be removed or relocated",
- issue = "27755")]
-#[rustc_deprecated(since = "1.7.0", reason = "moved to inherent methods")]
-pub trait OverflowingOps {
- fn overflowing_add(self, rhs: Self) -> (Self, bool);
- fn overflowing_sub(self, rhs: Self) -> (Self, bool);
- fn overflowing_mul(self, rhs: Self) -> (Self, bool);
-
- fn overflowing_div(self, rhs: Self) -> (Self, bool);
- fn overflowing_rem(self, rhs: Self) -> (Self, bool);
- fn overflowing_neg(self) -> (Self, bool);
-
- fn overflowing_shl(self, rhs: u32) -> (Self, bool);
- fn overflowing_shr(self, rhs: u32) -> (Self, bool);
-}
-
macro_rules! sh_impl_signed {
($t:ident, $f:ident) => (
#[stable(feature = "rust1", since = "1.0.0")]
pub const u64: u32 = i64;
pub use self::platform::usize;
}
-
-macro_rules! signed_overflowing_impl {
- ($($t:ident)*) => ($(
- #[allow(deprecated)]
- impl OverflowingOps for $t {
- #[inline(always)]
- fn overflowing_add(self, rhs: $t) -> ($t, bool) {
- unsafe {
- add_with_overflow(self, rhs)
- }
- }
- #[inline(always)]
- fn overflowing_sub(self, rhs: $t) -> ($t, bool) {
- unsafe {
- sub_with_overflow(self, rhs)
- }
- }
- #[inline(always)]
- fn overflowing_mul(self, rhs: $t) -> ($t, bool) {
- unsafe {
- mul_with_overflow(self, rhs)
- }
- }
-
- #[inline(always)]
- fn overflowing_div(self, rhs: $t) -> ($t, bool) {
- if self == $t::MIN && rhs == -1 {
- (self, true)
- } else {
- (self/rhs, false)
- }
- }
- #[inline(always)]
- fn overflowing_rem(self, rhs: $t) -> ($t, bool) {
- if self == $t::MIN && rhs == -1 {
- (0, true)
- } else {
- (self % rhs, false)
- }
- }
-
- #[inline(always)]
- fn overflowing_shl(self, rhs: u32) -> ($t, bool) {
- (self << (rhs & self::shift_max::$t),
- (rhs > self::shift_max::$t))
- }
- #[inline(always)]
- fn overflowing_shr(self, rhs: u32) -> ($t, bool) {
- (self >> (rhs & self::shift_max::$t),
- (rhs > self::shift_max::$t))
- }
-
- #[inline(always)]
- fn overflowing_neg(self) -> ($t, bool) {
- if self == $t::MIN {
- ($t::MIN, true)
- } else {
- (-self, false)
- }
- }
- }
- )*)
-}
-
-macro_rules! unsigned_overflowing_impl {
- ($($t:ident)*) => ($(
- #[allow(deprecated)]
- impl OverflowingOps for $t {
- #[inline(always)]
- fn overflowing_add(self, rhs: $t) -> ($t, bool) {
- unsafe {
- add_with_overflow(self, rhs)
- }
- }
- #[inline(always)]
- fn overflowing_sub(self, rhs: $t) -> ($t, bool) {
- unsafe {
- sub_with_overflow(self, rhs)
- }
- }
- #[inline(always)]
- fn overflowing_mul(self, rhs: $t) -> ($t, bool) {
- unsafe {
- mul_with_overflow(self, rhs)
- }
- }
-
- #[inline(always)]
- fn overflowing_div(self, rhs: $t) -> ($t, bool) {
- (self/rhs, false)
- }
- #[inline(always)]
- fn overflowing_rem(self, rhs: $t) -> ($t, bool) {
- (self % rhs, false)
- }
-
- #[inline(always)]
- fn overflowing_shl(self, rhs: u32) -> ($t, bool) {
- (self << (rhs & self::shift_max::$t),
- (rhs > self::shift_max::$t))
- }
- #[inline(always)]
- fn overflowing_shr(self, rhs: u32) -> ($t, bool) {
- (self >> (rhs & self::shift_max::$t),
- (rhs > self::shift_max::$t))
- }
-
- #[inline(always)]
- fn overflowing_neg(self) -> ($t, bool) {
- ((!self).wrapping_add(1), true)
- }
- }
- )*)
-}
-
-signed_overflowing_impl! { i8 i16 i32 i64 isize }
-unsigned_overflowing_impl! { u8 u16 u32 u64 usize }
mem::transmute(RawSlice { data: p, len: len })
}
-//
-// Submodules
-//
-
-/// Operations on `[u8]`.
-#[unstable(feature = "slice_bytes", reason = "needs review",
- issue = "27740")]
-#[rustc_deprecated(reason = "unidiomatic functions not pulling their weight",
- since = "1.6.0")]
-#[allow(deprecated)]
-pub mod bytes {
- use ptr;
- use slice::SliceExt;
-
- /// A trait for operations on mutable `[u8]`s.
- pub trait MutableByteVector {
- /// Sets all bytes of the receiver to the given value.
- fn set_memory(&mut self, value: u8);
- }
-
- impl MutableByteVector for [u8] {
- #[inline]
- fn set_memory(&mut self, value: u8) {
- unsafe { ptr::write_bytes(self.as_mut_ptr(), value, self.len()) };
- }
- }
-
- /// Copies data from `src` to `dst`
- ///
- /// Panics if the length of `dst` is less than the length of `src`.
- #[inline]
- pub fn copy_memory(src: &[u8], dst: &mut [u8]) {
- let len_src = src.len();
- assert!(dst.len() >= len_src);
- // `dst` is unaliasable, so we know statically it doesn't overlap
- // with `src`.
- unsafe {
- ptr::copy_nonoverlapping(src.as_ptr(),
- dst.as_mut_ptr(),
- len_src);
- }
- }
-}
-
-
-
//
// Boilerplate traits
//
assert!(format!("{}", i32::MIN) == "-2147483648");
assert!(format!("{}", i64::MIN) == "-9223372036854775808");
}
-
-#[test]
-#[allow(deprecated)]
-fn test_format_radix() {
- use core::fmt::radix;
- assert!(format!("{:04}", radix(3, 2)) == "0011");
- assert!(format!("{}", radix(55, 36)) == "1j");
-}
-
-#[test]
-#[should_panic]
-#[allow(deprecated)]
-fn test_radix_base_too_large() {
- use core::fmt::radix;
- let _ = radix(55, 37);
-}
-
-#[allow(deprecated)]
-mod u32 {
- use test::Bencher;
- use core::fmt::radix;
- use std::__rand::{thread_rng, Rng};
- use std::io::{Write, sink};
-
- #[bench]
- fn format_bin(b: &mut Bencher) {
- let mut rng = thread_rng();
- b.iter(|| { write!(&mut sink(), "{:b}", rng.gen::<u32>()) })
- }
-
- #[bench]
- fn format_oct(b: &mut Bencher) {
- let mut rng = thread_rng();
- b.iter(|| { write!(&mut sink(), "{:o}", rng.gen::<u32>()) })
- }
-
- #[bench]
- fn format_dec(b: &mut Bencher) {
- let mut rng = thread_rng();
- b.iter(|| { write!(&mut sink(), "{}", rng.gen::<u32>()) })
- }
-
- #[bench]
- fn format_hex(b: &mut Bencher) {
- let mut rng = thread_rng();
- b.iter(|| { write!(&mut sink(), "{:x}", rng.gen::<u32>()) })
- }
-
- #[bench]
- fn format_show(b: &mut Bencher) {
- let mut rng = thread_rng();
- b.iter(|| { write!(&mut sink(), "{:?}", rng.gen::<u32>()) })
- }
-
- #[bench]
- fn format_base_36(b: &mut Bencher) {
- let mut rng = thread_rng();
- b.iter(|| { write!(&mut sink(), "{}", radix(rng.gen::<u32>(), 36)) })
- }
-}
-
-#[allow(deprecated)]
-mod i32 {
- use test::Bencher;
- use core::fmt::radix;
- use std::__rand::{thread_rng, Rng};
- use std::io::{Write, sink};
-
- #[bench]
- fn format_bin(b: &mut Bencher) {
- let mut rng = thread_rng();
- b.iter(|| { write!(&mut sink(), "{:b}", rng.gen::<i32>()) })
- }
-
- #[bench]
- fn format_oct(b: &mut Bencher) {
- let mut rng = thread_rng();
- b.iter(|| { write!(&mut sink(), "{:o}", rng.gen::<i32>()) })
- }
-
- #[bench]
- fn format_dec(b: &mut Bencher) {
- let mut rng = thread_rng();
- b.iter(|| { write!(&mut sink(), "{}", rng.gen::<i32>()) })
- }
-
- #[bench]
- fn format_hex(b: &mut Bencher) {
- let mut rng = thread_rng();
- b.iter(|| { write!(&mut sink(), "{:x}", rng.gen::<i32>()) })
- }
-
- #[bench]
- fn format_show(b: &mut Bencher) {
- let mut rng = thread_rng();
- b.iter(|| { write!(&mut sink(), "{:?}", rng.gen::<i32>()) })
- }
-
- #[bench]
- fn format_base_36(b: &mut Bencher) {
- let mut rng = thread_rng();
- b.iter(|| { write!(&mut sink(), "{}", radix(rng.gen::<i32>(), 36)) })
- }
-}
#![feature(fixed_size_array)]
#![feature(float_extras)]
#![feature(flt2dec)]
-#![feature(fmt_radix)]
-#![feature(iter_arith)]
#![feature(iter_arith)]
#![feature(libc)]
#![feature(nonzero)]
#![feature(libc)]
#![feature(staged_api)]
#![feature(unique)]
-#![cfg_attr(test, feature(rustc_private, rand, vec_push_all))]
+#![cfg_attr(test, feature(rustc_private, rand))]
#[cfg(test)]
#[macro_use]
for _ in 0..20 {
let mut input = vec![];
for _ in 0..2000 {
- input.push_all(r.choose(&words).unwrap());
+ input.extend_from_slice(r.choose(&words).unwrap());
}
debug!("de/inflate of {} bytes of random word-sequences",
input.len());
issue = "27703")]
#![feature(core_float)]
#![feature(core_intrinsics)]
-#![feature(num_bits_bytes)]
#![feature(staged_api)]
#![feature(step_by)]
#![feature(custom_attribute)]
//! The implementations of `Rand` for the built-in types.
use core::char;
-use core::isize;
-use core::usize;
+use core::mem;
use {Rand, Rng};
impl Rand for isize {
#[inline]
fn rand<R: Rng>(rng: &mut R) -> isize {
- if isize::BITS == 32 {
+ if mem::size_of::<isize>() == 4 {
rng.gen::<i32>() as isize
} else {
rng.gen::<i64>() as isize
impl Rand for usize {
#[inline]
fn rand<R: Rng>(rng: &mut R) -> usize {
- if usize::BITS == 32 {
+ if mem::size_of::<usize>() == 4 {
rng.gen::<u32>() as usize
} else {
rng.gen::<u64>() as usize
--- /dev/null
+// Copyright 2013-2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Dynamic library facilities.
+//!
+//! A simple wrapper over the platform's dynamic library facilities
+
+use std::env;
+use std::ffi::{CString, OsString};
+use std::path::{Path, PathBuf};
+
+pub struct DynamicLibrary {
+ handle: *mut u8
+}
+
+impl Drop for DynamicLibrary {
+ fn drop(&mut self) {
+ unsafe {
+ dl::close(self.handle)
+ }
+ }
+}
+
+impl DynamicLibrary {
+ /// Lazily open a dynamic library. When passed None it gives a
+ /// handle to the calling process
+ pub fn open(filename: Option<&Path>) -> Result<DynamicLibrary, String> {
+ let maybe_library = dl::open(filename.map(|path| path.as_os_str()));
+
+ // The dynamic library must not be constructed if there is
+ // an error opening the library so the destructor does not
+ // run.
+ match maybe_library {
+ Err(err) => Err(err),
+ Ok(handle) => Ok(DynamicLibrary { handle: handle })
+ }
+ }
+
+ /// Prepends a path to this process's search path for dynamic libraries
+ pub fn prepend_search_path(path: &Path) {
+ let mut search_path = DynamicLibrary::search_path();
+ search_path.insert(0, path.to_path_buf());
+ env::set_var(DynamicLibrary::envvar(), &DynamicLibrary::create_path(&search_path));
+ }
+
+ /// From a slice of paths, create a new vector which is suitable to be an
+ /// environment variable for this platforms dylib search path.
+ pub fn create_path(path: &[PathBuf]) -> OsString {
+ let mut newvar = OsString::new();
+ for (i, path) in path.iter().enumerate() {
+ if i > 0 { newvar.push(DynamicLibrary::separator()); }
+ newvar.push(path);
+ }
+ return newvar;
+ }
+
+ /// Returns the environment variable for this process's dynamic library
+ /// search path
+ pub fn envvar() -> &'static str {
+ if cfg!(windows) {
+ "PATH"
+ } else if cfg!(target_os = "macos") {
+ "DYLD_LIBRARY_PATH"
+ } else {
+ "LD_LIBRARY_PATH"
+ }
+ }
+
+ fn separator() -> &'static str {
+ if cfg!(windows) { ";" } else { ":" }
+ }
+
+ /// Returns the current search path for dynamic libraries being used by this
+ /// process
+ pub fn search_path() -> Vec<PathBuf> {
+ match env::var_os(DynamicLibrary::envvar()) {
+ Some(var) => env::split_paths(&var).collect(),
+ None => Vec::new(),
+ }
+ }
+
+ /// Accesses the value at the symbol of the dynamic library.
+ pub unsafe fn symbol<T>(&self, symbol: &str) -> Result<*mut T, String> {
+ // This function should have a lifetime constraint of 'a on
+ // T but that feature is still unimplemented
+
+ let raw_string = CString::new(symbol).unwrap();
+ let maybe_symbol_value = dl::symbol(self.handle, raw_string.as_ptr());
+
+ // The value must not be constructed if there is an error so
+ // the destructor does not run.
+ match maybe_symbol_value {
+ Err(err) => Err(err),
+ Ok(symbol_value) => Ok(symbol_value as *mut T)
+ }
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+ use libc;
+ use std::mem;
+
+ #[test]
+ fn test_loading_cosine() {
+ if cfg!(windows) {
+ return
+ }
+
+ // The math library does not need to be loaded since it is already
+ // statically linked in
+ let libm = match DynamicLibrary::open(None) {
+ Err(error) => panic!("Could not load self as module: {}", error),
+ Ok(libm) => libm
+ };
+
+ let cosine: extern fn(libc::c_double) -> libc::c_double = unsafe {
+ match libm.symbol("cos") {
+ Err(error) => panic!("Could not load function cos: {}", error),
+ Ok(cosine) => mem::transmute::<*mut u8, _>(cosine)
+ }
+ };
+
+ let argument = 0.0;
+ let expected_result = 1.0;
+ let result = cosine(argument);
+ if result != expected_result {
+ panic!("cos({}) != {} but equaled {} instead", argument,
+ expected_result, result)
+ }
+ }
+
+ #[test]
+ fn test_errors_do_not_crash() {
+ use std::path::Path;
+
+ if !cfg!(unix) {
+ return
+ }
+
+ // Open /dev/null as a library to get an error, and make sure
+ // that only causes an error, and not a crash.
+ let path = Path::new("/dev/null");
+ match DynamicLibrary::open(Some(&path)) {
+ Err(_) => {}
+ Ok(_) => panic!("Successfully opened the empty library.")
+ }
+ }
+}
+
+#[cfg(unix)]
+mod dl {
+ use libc;
+ use std::ffi::{CStr, OsStr, CString};
+ use std::os::unix::prelude::*;
+ use std::ptr;
+ use std::str;
+
+ pub fn open(filename: Option<&OsStr>) -> Result<*mut u8, String> {
+ check_for_errors_in(|| {
+ unsafe {
+ match filename {
+ Some(filename) => open_external(filename),
+ None => open_internal(),
+ }
+ }
+ })
+ }
+
+ const LAZY: libc::c_int = 1;
+
+ unsafe fn open_external(filename: &OsStr) -> *mut u8 {
+ let s = CString::new(filename.as_bytes()).unwrap();
+ libc::dlopen(s.as_ptr(), LAZY) as *mut u8
+ }
+
+ unsafe fn open_internal() -> *mut u8 {
+ libc::dlopen(ptr::null(), LAZY) as *mut u8
+ }
+
+ pub fn check_for_errors_in<T, F>(f: F) -> Result<T, String> where
+ F: FnOnce() -> T,
+ {
+ use std::sync::StaticMutex;
+ static LOCK: StaticMutex = StaticMutex::new();
+ unsafe {
+ // dlerror isn't thread safe, so we need to lock around this entire
+ // sequence
+ let _guard = LOCK.lock();
+ let _old_error = libc::dlerror();
+
+ let result = f();
+
+ let last_error = libc::dlerror() as *const _;
+ let ret = if ptr::null() == last_error {
+ Ok(result)
+ } else {
+ let s = CStr::from_ptr(last_error).to_bytes();
+ Err(str::from_utf8(s).unwrap().to_owned())
+ };
+
+ ret
+ }
+ }
+
+ pub unsafe fn symbol(handle: *mut u8,
+ symbol: *const libc::c_char)
+ -> Result<*mut u8, String> {
+ check_for_errors_in(|| {
+ libc::dlsym(handle as *mut libc::c_void, symbol) as *mut u8
+ })
+ }
+ pub unsafe fn close(handle: *mut u8) {
+ libc::dlclose(handle as *mut libc::c_void); ()
+ }
+}
+
+#[cfg(windows)]
+mod dl {
+ use std::ffi::OsStr;
+ use std::io;
+ use std::os::windows::prelude::*;
+ use std::ptr;
+
+ use libc::{c_uint, c_void, c_char};
+
+ type DWORD = u32;
+ type HMODULE = *mut u8;
+ type BOOL = i32;
+ type LPCWSTR = *const u16;
+ type LPCSTR = *const i8;
+
+ extern "system" {
+ fn SetThreadErrorMode(dwNewMode: DWORD,
+ lpOldMode: *mut DWORD) -> c_uint;
+ fn LoadLibraryW(name: LPCWSTR) -> HMODULE;
+ fn GetModuleHandleExW(dwFlags: DWORD,
+ name: LPCWSTR,
+ handle: *mut HMODULE) -> BOOL;
+ fn GetProcAddress(handle: HMODULE,
+ name: LPCSTR) -> *mut c_void;
+ fn FreeLibrary(handle: HMODULE) -> BOOL;
+ }
+
+ pub fn open(filename: Option<&OsStr>) -> Result<*mut u8, String> {
+ // disable "dll load failed" error dialog.
+ let prev_error_mode = unsafe {
+ // SEM_FAILCRITICALERRORS 0x01
+ let new_error_mode = 1;
+ let mut prev_error_mode = 0;
+ let result = SetThreadErrorMode(new_error_mode,
+ &mut prev_error_mode);
+ if result == 0 {
+ return Err(io::Error::last_os_error().to_string())
+ }
+ prev_error_mode
+ };
+
+ let result = match filename {
+ Some(filename) => {
+ let filename_str: Vec<_> =
+ filename.encode_wide().chain(Some(0)).collect();
+ let result = unsafe {
+ LoadLibraryW(filename_str.as_ptr())
+ };
+ ptr_result(result)
+ }
+ None => {
+ let mut handle = ptr::null_mut();
+ let succeeded = unsafe {
+ GetModuleHandleExW(0 as DWORD, ptr::null(), &mut handle)
+ };
+ if succeeded == 0 {
+ Err(io::Error::last_os_error().to_string())
+ } else {
+ Ok(handle as *mut u8)
+ }
+ }
+ };
+
+ unsafe {
+ SetThreadErrorMode(prev_error_mode, ptr::null_mut());
+ }
+
+ result
+ }
+
+ pub unsafe fn symbol(handle: *mut u8,
+ symbol: *const c_char)
+ -> Result<*mut u8, String> {
+ let ptr = GetProcAddress(handle as HMODULE, symbol) as *mut u8;
+ ptr_result(ptr)
+ }
+
+ pub unsafe fn close(handle: *mut u8) {
+ FreeLibrary(handle as HMODULE);
+ }
+
+ fn ptr_result<T>(ptr: *mut T) -> Result<*mut T, String> {
+ if ptr.is_null() {
+ Err(io::Error::last_os_error().to_string())
+ } else {
+ Ok(ptr)
+ }
+ }
+}
#![cfg_attr(not(stage0), deny(warnings))]
#![feature(box_syntax)]
+#![feature(const_fn)]
#![feature(copy_from_slice)]
#![feature(libc)]
#![feature(rand)]
#![feature(rustc_private)]
#![feature(staged_api)]
#![feature(step_by)]
+#![cfg_attr(unix, feature(static_mutex))]
#![cfg_attr(test, feature(test, rand))]
extern crate syntax;
pub mod svh;
pub mod target;
pub mod slice;
+pub mod dynamic_lib;
[dependencies]
log = { path = "../liblog" }
rustc = { path = "../librustc" }
+rustc_back = { path = "../librustc_back" }
rustc_bitflags = { path = "../librustc_bitflags" }
rustc_front = { path = "../librustc_front" }
rustc_metadata = { path = "../librustc_metadata" }
html_root_url = "https://doc.rust-lang.org/nightly/")]
#![cfg_attr(not(stage0), deny(warnings))]
-#![feature(dynamic_lib)]
#![feature(staged_api)]
#![feature(rustc_diagnostic_macros)]
#![feature(rustc_private)]
#[macro_use] #[no_link] extern crate rustc_bitflags;
extern crate rustc;
+extern crate rustc_back;
extern crate rustc_front;
extern crate rustc_metadata;
extern crate rustc_mir;
}
// Dynamically link a registrar function into the compiler process.
- #[allow(deprecated)]
fn dylink_registrar(&mut self,
span: Span,
path: PathBuf,
symbol: String) -> PluginRegistrarFun {
- use std::dynamic_lib::DynamicLibrary;
+ use rustc_back::dynamic_lib::DynamicLibrary;
// Make sure the path contains a / or the linker will search for it.
let path = env::current_dir().unwrap().join(&path);
#![feature(box_patterns)]
#![feature(box_syntax)]
-#![feature(dynamic_lib)]
#![feature(libc)]
#![feature(recover)]
#![feature(rustc_private)]
use clean;
-use std::dynamic_lib as dl;
use serialize::json;
use std::mem;
use std::string::String;
use std::path::PathBuf;
+use rustc_back::dynamic_lib as dl;
+
pub type PluginJson = Option<(String, json::Json)>;
pub type PluginResult = (clean::Crate, PluginJson);
pub type PluginCallback = fn (clean::Crate) -> PluginResult;
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![allow(deprecated)]
-
use std::cell::{RefCell, Cell};
use std::collections::HashMap;
-use std::dynamic_lib::DynamicLibrary;
use std::env;
use std::ffi::OsString;
use std::io::prelude::*;
use rustc::session::config::{get_unstable_features_setting, OutputType};
use rustc::session::search_paths::{SearchPaths, PathKind};
use rustc_front::lowering::{lower_crate, LoweringContext};
+use rustc_back::dynamic_lib::DynamicLibrary;
use rustc_back::tempdir::TempDir;
use rustc_driver::{driver, Compilation};
use rustc_metadata::cstore::CStore;
}
}
- /// Deprecated, renamed to `with_hasher`
- #[inline]
- #[unstable(feature = "hashmap_hasher", reason = "hasher stuff is unclear",
- issue = "27713")]
- #[rustc_deprecated(since = "1.7.0", reason = "renamed to with_hasher")]
- pub fn with_hash_state(hash_state: S) -> HashMap<K, V, S> {
- HashMap::with_hasher(hash_state)
- }
-
/// Creates an empty HashMap with space for at least `capacity`
/// elements, using `hasher` to hash the keys.
///
}
}
- /// Deprecated, renamed to `with_capacity_and_hasher`
- #[inline]
- #[unstable(feature = "hashmap_hasher", reason = "hasher stuff is unclear",
- issue = "27713")]
- #[rustc_deprecated(since = "1.7.0",
- reason = "renamed to with_capacity_and_hasher")]
- pub fn with_capacity_and_hash_state(capacity: usize, hash_state: S)
- -> HashMap<K, V, S> {
- HashMap::with_capacity_and_hasher(capacity, hash_state)
- }
-
/// Returns a reference to the map's hasher.
#[unstable(feature = "hashmap_public_hasher", reason = "don't want to make insta-stable",
issue = "31262")]
mod table;
pub mod map;
pub mod set;
-pub mod state;
trait Recover<Q: ?Sized> {
type Key;
self.map.hasher()
}
- /// Deprecated, renamed to `with_hasher`
- #[inline]
- #[unstable(feature = "hashmap_hasher", reason = "hasher stuff is unclear",
- issue = "27713")]
- #[rustc_deprecated(since = "1.7.0", reason = "renamed to with_hasher")]
- pub fn with_hash_state(hash_state: S) -> HashSet<T, S> {
- HashSet::with_hasher(hash_state)
- }
-
- /// Deprecated, renamed to `with_capacity_and_hasher`
- #[inline]
- #[unstable(feature = "hashmap_hasher", reason = "hasher stuff is unclear",
- issue = "27713")]
- #[rustc_deprecated(since = "1.7.0",
- reason = "renamed to with_capacity_and_hasher")]
- pub fn with_capacity_and_hash_state(capacity: usize, hash_state: S)
- -> HashSet<T, S> {
- HashSet::with_capacity_and_hasher(capacity, hash_state)
- }
-
/// Returns the number of elements the set can hold without reallocating.
///
/// # Examples
+++ /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.
-
-#![unstable(feature = "hashmap_hasher", reason = "hasher stuff is unclear",
- issue = "27713")]
-#![rustc_deprecated(since = "1.7.0", reason = "support moved to std::hash")]
-#![allow(deprecated)]
-
-use clone::Clone;
-use default::Default;
-use hash;
-use marker;
-
-pub use hash::HashState;
-
-/// A structure which is a factory for instances of `Hasher` which implement the
-/// default trait.
-///
-/// This struct is 0-sized and does not need construction.
-pub struct DefaultState<H>(marker::PhantomData<H>);
-
-impl<H: Default + hash::Hasher> HashState for DefaultState<H> {
- type Hasher = H;
- fn hasher(&self) -> H { Default::default() }
-}
-
-impl<H> Clone for DefaultState<H> {
- fn clone(&self) -> DefaultState<H> { DefaultState(marker::PhantomData) }
-}
-
-impl<H> Default for DefaultState<H> {
- fn default() -> DefaultState<H> { DefaultState(marker::PhantomData) }
-}
#[stable(feature = "rust1", since = "1.0.0")]
pub use super::hash::set::*;
}
-
-/// Experimental support for providing custom hash algorithms to a HashMap and
-/// HashSet.
-#[unstable(feature = "hashmap_hasher", reason = "module was recently added",
- issue = "27713")]
-#[rustc_deprecated(since = "1.7.0", reason = "support moved to std::hash")]
-#[allow(deprecated)]
-pub mod hash_state {
- pub use super::hash::state::*;
-}
+++ /dev/null
-// Copyright 2013-2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Dynamic library facilities.
-//!
-//! A simple wrapper over the platform's dynamic library facilities
-
-#![unstable(feature = "dynamic_lib",
- reason = "API has not been scrutinized and is highly likely to \
- either disappear or change",
- issue = "27810")]
-#![allow(missing_docs)]
-#![allow(deprecated)]
-
-use prelude::v1::*;
-
-use env;
-use ffi::{CString, OsString};
-use path::{Path, PathBuf};
-
-#[unstable(feature = "dynamic_lib",
- reason = "API has not been scrutinized and is highly likely to \
- either disappear or change",
- issue = "27810")]
-#[rustc_deprecated(since = "1.5.0", reason = "replaced with 'dylib' on crates.io")]
-pub struct DynamicLibrary {
- handle: *mut u8
-}
-
-impl Drop for DynamicLibrary {
- fn drop(&mut self) {
- match dl::check_for_errors_in(|| {
- unsafe {
- dl::close(self.handle)
- }
- }) {
- Ok(()) => {},
- Err(str) => panic!("{}", str)
- }
- }
-}
-
-#[unstable(feature = "dynamic_lib",
- reason = "API has not been scrutinized and is highly likely to \
- either disappear or change",
- issue = "27810")]
-#[rustc_deprecated(since = "1.5.0", reason = "replaced with 'dylib' on crates.io")]
-impl DynamicLibrary {
- /// Lazily open a dynamic library. When passed None it gives a
- /// handle to the calling process
- pub fn open(filename: Option<&Path>) -> Result<DynamicLibrary, String> {
- let maybe_library = dl::open(filename.map(|path| path.as_os_str()));
-
- // The dynamic library must not be constructed if there is
- // an error opening the library so the destructor does not
- // run.
- match maybe_library {
- Err(err) => Err(err),
- Ok(handle) => Ok(DynamicLibrary { handle: handle })
- }
- }
-
- /// Prepends a path to this process's search path for dynamic libraries
- pub fn prepend_search_path(path: &Path) {
- let mut search_path = DynamicLibrary::search_path();
- search_path.insert(0, path.to_path_buf());
- env::set_var(DynamicLibrary::envvar(), &DynamicLibrary::create_path(&search_path));
- }
-
- /// From a slice of paths, create a new vector which is suitable to be an
- /// environment variable for this platforms dylib search path.
- pub fn create_path(path: &[PathBuf]) -> OsString {
- let mut newvar = OsString::new();
- for (i, path) in path.iter().enumerate() {
- if i > 0 { newvar.push(DynamicLibrary::separator()); }
- newvar.push(path);
- }
- return newvar;
- }
-
- /// Returns the environment variable for this process's dynamic library
- /// search path
- pub fn envvar() -> &'static str {
- if cfg!(windows) {
- "PATH"
- } else if cfg!(target_os = "macos") {
- "DYLD_LIBRARY_PATH"
- } else {
- "LD_LIBRARY_PATH"
- }
- }
-
- fn separator() -> &'static str {
- if cfg!(windows) { ";" } else { ":" }
- }
-
- /// Returns the current search path for dynamic libraries being used by this
- /// process
- pub fn search_path() -> Vec<PathBuf> {
- match env::var_os(DynamicLibrary::envvar()) {
- Some(var) => env::split_paths(&var).collect(),
- None => Vec::new(),
- }
- }
-
- /// Accesses the value at the symbol of the dynamic library.
- pub unsafe fn symbol<T>(&self, symbol: &str) -> Result<*mut T, String> {
- // This function should have a lifetime constraint of 'a on
- // T but that feature is still unimplemented
-
- let raw_string = CString::new(symbol).unwrap();
- let maybe_symbol_value = dl::check_for_errors_in(|| {
- dl::symbol(self.handle, raw_string.as_ptr())
- });
-
- // The value must not be constructed if there is an error so
- // the destructor does not run.
- match maybe_symbol_value {
- Err(err) => Err(err),
- Ok(symbol_value) => Ok(symbol_value as *mut T)
- }
- }
-}
-
-#[cfg(all(test, not(target_os = "ios"), not(target_os = "nacl")))]
-mod tests {
- use super::*;
- use prelude::v1::*;
- use libc;
- use mem;
-
- #[test]
- #[cfg_attr(any(windows,
- target_os = "android", // FIXME #10379
- target_env = "musl"), ignore)]
- #[allow(deprecated)]
- fn test_loading_cosine() {
- // The math library does not need to be loaded since it is already
- // statically linked in
- let libm = match DynamicLibrary::open(None) {
- Err(error) => panic!("Could not load self as module: {}", error),
- Ok(libm) => libm
- };
-
- let cosine: extern fn(libc::c_double) -> libc::c_double = unsafe {
- match libm.symbol("cos") {
- Err(error) => panic!("Could not load function cos: {}", error),
- Ok(cosine) => mem::transmute::<*mut u8, _>(cosine)
- }
- };
-
- let argument = 0.0;
- let expected_result = 1.0;
- let result = cosine(argument);
- if result != expected_result {
- panic!("cos({}) != {} but equaled {} instead", argument,
- expected_result, result)
- }
- }
-
- #[test]
- #[cfg(any(target_os = "linux",
- target_os = "macos",
- target_os = "freebsd",
- target_os = "dragonfly",
- target_os = "bitrig",
- target_os = "netbsd",
- target_os = "openbsd",
- target_os = "solaris"))]
- #[allow(deprecated)]
- fn test_errors_do_not_crash() {
- use path::Path;
-
- // Open /dev/null as a library to get an error, and make sure
- // that only causes an error, and not a crash.
- let path = Path::new("/dev/null");
- match DynamicLibrary::open(Some(&path)) {
- Err(_) => {}
- Ok(_) => panic!("Successfully opened the empty library.")
- }
- }
-}
-
-#[cfg(any(target_os = "linux",
- target_os = "android",
- target_os = "macos",
- target_os = "ios",
- target_os = "freebsd",
- target_os = "dragonfly",
- target_os = "bitrig",
- target_os = "netbsd",
- target_os = "openbsd",
- target_os = "solaris",
- target_os = "emscripten"))]
-mod dl {
- use prelude::v1::*;
-
- use ffi::{CStr, OsStr};
- use str;
- use libc;
- use ptr;
-
- pub fn open(filename: Option<&OsStr>) -> Result<*mut u8, String> {
- check_for_errors_in(|| {
- unsafe {
- match filename {
- Some(filename) => open_external(filename),
- None => open_internal(),
- }
- }
- })
- }
-
- const LAZY: libc::c_int = 1;
-
- unsafe fn open_external(filename: &OsStr) -> *mut u8 {
- let s = filename.to_cstring().unwrap();
- libc::dlopen(s.as_ptr(), LAZY) as *mut u8
- }
-
- unsafe fn open_internal() -> *mut u8 {
- libc::dlopen(ptr::null(), LAZY) as *mut u8
- }
-
- pub fn check_for_errors_in<T, F>(f: F) -> Result<T, String> where
- F: FnOnce() -> T,
- {
- use sync::StaticMutex;
- static LOCK: StaticMutex = StaticMutex::new();
- unsafe {
- // dlerror isn't thread safe, so we need to lock around this entire
- // sequence
- let _guard = LOCK.lock();
- let _old_error = libc::dlerror();
-
- let result = f();
-
- let last_error = libc::dlerror() as *const _;
- let ret = if ptr::null() == last_error {
- Ok(result)
- } else {
- let s = CStr::from_ptr(last_error).to_bytes();
- Err(str::from_utf8(s).unwrap().to_owned())
- };
-
- ret
- }
- }
-
- pub unsafe fn symbol(handle: *mut u8,
- symbol: *const libc::c_char) -> *mut u8 {
- libc::dlsym(handle as *mut libc::c_void, symbol) as *mut u8
- }
- pub unsafe fn close(handle: *mut u8) {
- libc::dlclose(handle as *mut libc::c_void); ()
- }
-}
-
-#[cfg(target_os = "windows")]
-mod dl {
- use prelude::v1::*;
-
- use ffi::OsStr;
- use libc;
- use os::windows::prelude::*;
- use ptr;
- use sys::c;
- use sys::os;
-
- pub fn open(filename: Option<&OsStr>) -> Result<*mut u8, String> {
- // disable "dll load failed" error dialog.
- let mut use_thread_mode = true;
- let prev_error_mode = unsafe {
- // SEM_FAILCRITICALERRORS 0x01
- let new_error_mode = 1;
- let mut prev_error_mode = 0;
- // Windows >= 7 supports thread error mode.
- let result = c::SetThreadErrorMode(new_error_mode,
- &mut prev_error_mode);
- if result == 0 {
- let err = os::errno();
- if err == c::ERROR_CALL_NOT_IMPLEMENTED as i32 {
- use_thread_mode = false;
- // SetThreadErrorMode not found. use fallback solution:
- // SetErrorMode() Note that SetErrorMode is process-wide so
- // this can cause race condition! However, since even
- // Windows APIs do not care of such problem (#20650), we
- // just assume SetErrorMode race is not a great deal.
- prev_error_mode = c::SetErrorMode(new_error_mode);
- }
- }
- prev_error_mode
- };
-
- unsafe {
- c::SetLastError(0);
- }
-
- let result = match filename {
- Some(filename) => {
- let filename_str: Vec<_> =
- filename.encode_wide().chain(Some(0)).collect();
- let result = unsafe {
- c::LoadLibraryW(filename_str.as_ptr())
- };
- // beware: Vec/String may change errno during drop!
- // so we get error here.
- if result == ptr::null_mut() {
- let errno = os::errno();
- Err(os::error_string(errno))
- } else {
- Ok(result as *mut u8)
- }
- }
- None => {
- let mut handle = ptr::null_mut();
- let succeeded = unsafe {
- c::GetModuleHandleExW(0 as c::DWORD, ptr::null(),
- &mut handle)
- };
- if succeeded == c::FALSE {
- let errno = os::errno();
- Err(os::error_string(errno))
- } else {
- Ok(handle as *mut u8)
- }
- }
- };
-
- unsafe {
- if use_thread_mode {
- c::SetThreadErrorMode(prev_error_mode, ptr::null_mut());
- } else {
- c::SetErrorMode(prev_error_mode);
- }
- }
-
- result
- }
-
- pub fn check_for_errors_in<T, F>(f: F) -> Result<T, String> where
- F: FnOnce() -> T,
- {
- unsafe {
- c::SetLastError(0);
-
- let result = f();
-
- let error = os::errno();
- if 0 == error {
- Ok(result)
- } else {
- Err(format!("Error code {}", error))
- }
- }
- }
-
- pub unsafe fn symbol(handle: *mut u8, symbol: *const libc::c_char) -> *mut u8 {
- c::GetProcAddress(handle as c::HMODULE, symbol) as *mut u8
- }
- pub unsafe fn close(handle: *mut u8) {
- c::FreeLibrary(handle as c::HMODULE);
- }
-}
-
-#[cfg(target_os = "nacl")]
-pub mod dl {
- use ffi::OsStr;
- use ptr;
- use result::Result;
- use result::Result::Err;
- use libc;
- use string::String;
- use ops::FnOnce;
- use option::Option;
-
- pub fn open(_filename: Option<&OsStr>) -> Result<*mut u8, String> {
- Err(format!("NaCl + Newlib doesn't impl loading shared objects"))
- }
-
- pub fn check_for_errors_in<T, F>(_f: F) -> Result<T, String>
- where F: FnOnce() -> T,
- {
- Err(format!("NaCl doesn't support shared objects"))
- }
-
- pub unsafe fn symbol(_handle: *mut u8, _symbol: *const libc::c_char) -> *mut u8 {
- ptr::null_mut()
- }
- pub unsafe fn close(_handle: *mut u8) { }
-}
// except according to those terms.
use borrow::{Borrow, Cow, ToOwned};
-use ffi::CString;
use fmt::{self, Debug};
use mem;
use string::String;
OsString { inner: Buf::from_string(String::new()) }
}
- /// Constructs an `OsString` from a byte sequence.
- ///
- /// # 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", issue = "27704")]
- #[rustc_deprecated(reason = "RFC was closed, hides subtle Windows semantics",
- since = "1.6.0")]
- pub fn from_bytes<B>(bytes: B) -> Option<OsString> where B: Into<Vec<u8>> {
- Self::_from_bytes(bytes.into())
- }
-
#[cfg(unix)]
fn _from_bytes(vec: Vec<u8>) -> Option<OsString> {
use os::unix::ffi::OsStringExt;
OsString { inner: self.inner.to_owned() }
}
- /// Yields 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", issue = "27704")]
- #[rustc_deprecated(reason = "RFC was closed, hides subtle Windows semantics",
- since = "1.6.0")]
- pub fn to_bytes(&self) -> Option<&[u8]> {
- if cfg!(windows) {
- self.to_str().map(|s| s.as_bytes())
- } else {
- Some(self.bytes())
- }
- }
-
- /// Creates 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", issue = "27704")]
- #[rustc_deprecated(reason = "RFC was closed, hides subtle Windows semantics",
- since = "1.6.0")]
- #[allow(deprecated)]
- pub fn to_cstring(&self) -> Option<CString> {
- self.to_bytes().and_then(|b| CString::new(b).ok())
- }
-
/// Checks whether the `OsStr` is empty.
#[unstable(feature = "osstring_simple_functions",
reason = "recently added", issue = "29453")]
#[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",
- issue = "27707")]
-#[rustc_deprecated(reason = "superceded by the walkdir crate",
- since = "1.6.0")]
-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
/// use std::fs::{self, DirEntry};
/// use std::path::Path;
///
-/// // one possible implementation of fs::walk_dir only visiting files
+/// // one possible implementation of walking a directory only visiting files
/// fn visit_dirs(dir: &Path, cb: &Fn(&DirEntry)) -> io::Result<()> {
/// if try!(fs::metadata(dir)).is_dir() {
/// for entry in try!(fs::read_dir(dir)) {
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",
- issue = "27707")]
-#[rustc_deprecated(reason = "superceded by the walkdir crate",
- since = "1.6.0")]
-#[allow(deprecated)]
-pub fn walk_dir<P: AsRef<Path>>(path: P) -> io::Result<WalkDir> {
- _walk_dir(path.as_ref())
-}
-
-#[allow(deprecated)]
-fn _walk_dir(path: &Path) -> io::Result<WalkDir> {
- let start = try!(read_dir(path));
- Ok(WalkDir { cur: Some(start), stack: Vec::new() })
-}
-
-#[unstable(feature = "fs_walk", issue = "27707")]
-#[rustc_deprecated(reason = "superceded by the walkdir crate",
- since = "1.6.0")]
-#[allow(deprecated)]
-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,
- }
- }
- }
-}
-
/// Changes the permissions found on a file or a directory.
///
/// # Platform-specific behavior
check!(fs::remove_dir(dir));
}
- #[test]
- #[allow(deprecated)]
- 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();
#[stable(feature = "rust1", since = "1.0.0")]
Other,
- #[allow(missing_docs)]
- #[unstable(feature = "read_exact_old", reason = "recently added",
- issue = "0")]
- #[rustc_deprecated(since = "1.6.0", reason = "renamed to UnexpectedEof")]
- UnexpectedEOF,
-
/// An error returned when an operation could not be completed because an
/// "end of file" was reached prematurely.
///
#[stable(feature = "rust1", since = "1.0.0")]
impl error::Error for Error {
- #[allow(deprecated)] // remove with UnexpectedEOF
fn description(&self) -> &str {
match self.repr {
Repr::Os(..) => match self.kind() {
ErrorKind::WriteZero => "write zero",
ErrorKind::Interrupted => "operation interrupted",
ErrorKind::Other => "other os error",
- ErrorKind::UnexpectedEOF => "unexpected end of file",
ErrorKind::UnexpectedEof => "unexpected end of file",
ErrorKind::__Nonexhaustive => unreachable!()
},
fn take(self, limit: u64) -> Take<Self> where Self: Sized {
Take { inner: self, limit: limit }
}
-
- /// Creates a reader adaptor which will write all read data into the given
- /// output stream.
- ///
- /// Whenever the returned `Read` instance is read it will write the read
- /// data to `out`. The current semantics of this implementation imply that
- /// a `write` error will not report how much data was initially read.
- ///
- /// # Examples
- ///
- /// [`File`][file]s implement `Read`:
- ///
- /// [file]: ../fs/struct.File.html
- ///
- /// ```
- /// #![feature(io)]
- /// use std::io;
- /// use std::io::prelude::*;
- /// use std::fs::File;
- ///
- /// # fn foo() -> io::Result<()> {
- /// let mut f = try!(File::open("foo.txt"));
- /// let mut buffer1 = Vec::with_capacity(10);
- /// let mut buffer2 = Vec::with_capacity(10);
- ///
- /// // write the output to buffer1 as we read
- /// let mut handle = f.tee(&mut buffer1);
- ///
- /// try!(handle.read(&mut buffer2));
- /// # Ok(())
- /// # }
- /// ```
- #[unstable(feature = "io", reason = "the semantics of a partial read/write \
- of where errors happen is currently \
- unclear and may change",
- issue = "27802")]
- #[rustc_deprecated(reason = "error handling semantics unclear and \
- don't seem to have an ergonomic resolution",
- since = "1.6.0")]
- #[allow(deprecated)]
- fn tee<W: Write>(self, out: W) -> Tee<Self, W> where Self: Sized {
- Tee { reader: self, writer: out }
- }
}
/// A trait for objects which are byte-oriented sinks.
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
fn by_ref(&mut self) -> &mut Self where Self: Sized { self }
-
- /// Creates a new writer which will write all data to both this writer and
- /// another writer.
- ///
- /// All data written to the returned writer will both be written to `self`
- /// as well as `other`. Note that the error semantics of the current
- /// implementation do not precisely track where errors happen. For example
- /// an error on the second call to `write` will not report that the first
- /// call to `write` succeeded.
- ///
- /// # Examples
- ///
- /// ```
- /// #![feature(io)]
- /// use std::io::prelude::*;
- /// use std::fs::File;
- ///
- /// # fn foo() -> std::io::Result<()> {
- /// let mut buffer1 = try!(File::create("foo.txt"));
- /// let mut buffer2 = Vec::new();
- ///
- /// // write the output to buffer1 as we read
- /// let mut handle = buffer1.broadcast(&mut buffer2);
- ///
- /// try!(handle.write(b"some bytes"));
- /// # Ok(())
- /// # }
- /// ```
- #[unstable(feature = "io", reason = "the semantics of a partial read/write \
- of where errors happen is currently \
- unclear and may change",
- issue = "27802")]
- #[rustc_deprecated(reason = "error handling semantics unclear and \
- don't seem to have an ergonomic resolution",
- since = "1.6.0")]
- #[allow(deprecated)]
- fn broadcast<W: Write>(self, other: W) -> Broadcast<Self, W>
- where Self: Sized
- {
- Broadcast { first: self, second: other }
- }
}
/// The `Seek` trait provides a cursor which can be moved within a stream of
}
}
-/// A `Write` adaptor which will write data to multiple locations.
-///
-/// This struct is generally created by calling [`broadcast()`][broadcast] on a
-/// writer. Please see the documentation of `broadcast()` for more details.
-///
-/// [broadcast]: trait.Write.html#method.broadcast
-#[unstable(feature = "io", reason = "awaiting stability of Write::broadcast",
- issue = "27802")]
-#[rustc_deprecated(reason = "error handling semantics unclear and \
- don't seem to have an ergonomic resolution",
- since = "1.6.0")]
-pub struct Broadcast<T, U> {
- first: T,
- second: U,
-}
-
-#[unstable(feature = "io", reason = "awaiting stability of Write::broadcast",
- issue = "27802")]
-#[rustc_deprecated(reason = "error handling semantics unclear and \
- don't seem to have an ergonomic resolution",
- since = "1.6.0")]
-#[allow(deprecated)]
-impl<T: Write, U: Write> Write for Broadcast<T, U> {
- fn write(&mut self, data: &[u8]) -> Result<usize> {
- let n = try!(self.first.write(data));
- // FIXME: what if the write fails? (we wrote something)
- try!(self.second.write_all(&data[..n]));
- Ok(n)
- }
-
- fn flush(&mut self) -> Result<()> {
- self.first.flush().and(self.second.flush())
- }
-}
-
/// Adaptor to chain together two readers.
///
/// This struct is generally created by calling [`chain()`][chain] on a reader.
}
}
-/// An adaptor which will emit all read data to a specified writer as well.
-///
-/// This struct is generally created by calling [`tee()`][tee] on a reader.
-/// Please see the documentation of `tee()` for more details.
-///
-/// [tee]: trait.Read.html#method.tee
-#[unstable(feature = "io", reason = "awaiting stability of Read::tee",
- issue = "27802")]
-#[rustc_deprecated(reason = "error handling semantics unclear and \
- don't seem to have an ergonomic resolution",
- since = "1.6.0")]
-pub struct Tee<R, W> {
- reader: R,
- writer: W,
-}
-
-#[unstable(feature = "io", reason = "awaiting stability of Read::tee",
- issue = "27802")]
-#[rustc_deprecated(reason = "error handling semantics unclear and \
- don't seem to have an ergonomic resolution",
- since = "1.6.0")]
-#[allow(deprecated)]
-impl<R: Read, W: Write> Read for Tee<R, W> {
- fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
- let n = try!(self.reader.read(buf));
- // FIXME: what if the write fails? (we read something)
- try!(self.writer.write_all(&buf[..n]));
- Ok(n)
- }
-}
-
/// An iterator over `u8` values of a reader.
///
/// This struct is generally created by calling [`bytes()`][bytes] on a reader.
assert_eq!(repeat(4).take(100).bytes().next().unwrap().unwrap(), 4);
assert_eq!(repeat(1).take(10).chain(repeat(2).take(10)).bytes().count(), 20);
}
-
- #[test]
- #[allow(deprecated)]
- fn tee() {
- let mut buf = [0; 10];
- {
- let mut ptr: &mut [u8] = &mut buf;
- assert_eq!(repeat(4).tee(&mut ptr).take(5).read(&mut [0; 10]).unwrap(), 5);
- }
- assert_eq!(buf, [4, 4, 4, 4, 4, 0, 0, 0, 0, 0]);
- }
-
- #[test]
- #[allow(deprecated)]
- fn broadcast() {
- let mut buf1 = [0; 10];
- let mut buf2 = [0; 10];
- {
- let mut ptr1: &mut [u8] = &mut buf1;
- let mut ptr2: &mut [u8] = &mut buf2;
-
- assert_eq!((&mut ptr1).broadcast(&mut ptr2)
- .write(&[1, 2, 3]).unwrap(), 3);
- }
- assert_eq!(buf1, buf2);
- assert_eq!(buf1, [1, 2, 3, 0, 0, 0, 0, 0, 0, 0]);
- }
}
pub mod thread;
pub mod collections;
-pub mod dynamic_lib;
pub mod env;
pub mod ffi;
pub mod fs;
pub fn lookup_host(host: &str) -> io::Result<LookupHost> {
net_imp::lookup_host(host).map(LookupHost)
}
-
-/// Resolve the given address to a hostname.
-///
-/// This function may perform a DNS query to resolve `addr` and may also inspect
-/// system configuration to resolve the specified address. If the address
-/// cannot be resolved, it is returned in string format.
-///
-/// # Examples
-///
-/// ```no_run
-/// #![feature(lookup_addr)]
-/// #![feature(ip_addr)]
-///
-/// use std::net::{self, Ipv4Addr, IpAddr};
-///
-/// let ip_addr = "8.8.8.8";
-/// let addr: Ipv4Addr = ip_addr.parse().unwrap();
-/// let hostname = net::lookup_addr(&IpAddr::V4(addr)).unwrap();
-///
-/// println!("{} --> {}", ip_addr, hostname);
-/// // Output: 8.8.8.8 --> google-public-dns-a.google.com
-/// ```
-#[unstable(feature = "lookup_addr", reason = "recent addition",
- issue = "27705")]
-#[rustc_deprecated(reason = "ipaddr type is being deprecated",
- since = "1.6.0")]
-#[allow(deprecated)]
-pub fn lookup_addr(addr: &IpAddr) -> io::Result<String> {
- net_imp::lookup_addr(addr)
-}
#[stable(feature = "rust1", since = "1.0.0")]
pub use core::num::{FpCategory, ParseIntError, ParseFloatError};
#[stable(feature = "rust1", since = "1.0.0")]
-pub use core::num::{wrapping, Wrapping};
+pub use core::num::Wrapping;
#[cfg(test)] use cmp::PartialEq;
#[cfg(test)] use fmt;
#![stable(feature = "rust1", since = "1.0.0")]
use ascii::*;
-#[allow(deprecated)]
-use borrow::{Borrow, IntoCow, ToOwned, Cow};
+use borrow::{Borrow, ToOwned, Cow};
use cmp;
use error::Error;
use fmt;
}
}
}
-
- /// Examine the next component without consuming it.
- #[unstable(feature = "path_components_peek", issue = "27727")]
- #[rustc_deprecated(reason = "use peekable() instead",
- since = "1.6.0")]
- pub fn peek(&self) -> Option<Component<'a>> {
- self.clone().next()
- }
}
#[stable(feature = "rust1", since = "1.0.0")]
}
}
-#[stable(feature = "rust1", since = "1.0.0")]
-#[allow(deprecated)]
-impl IntoCow<'static, Path> for PathBuf {
- fn into_cow(self) -> Cow<'static, Path> {
- Cow::Owned(self)
- }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-#[allow(deprecated)]
-impl<'a> IntoCow<'a, Path> for &'a Path {
- fn into_cow(self) -> Cow<'a, Path> {
- Cow::Borrowed(self)
- }
-}
-
#[stable(feature = "cow_from_path", since = "1.6.0")]
impl<'a> From<&'a Path> for Cow<'a, Path> {
#[inline]
!self.is_absolute()
}
- /// Returns the *prefix* of a path, if any.
- ///
- /// Prefixes are relevant only for Windows paths, and consist of volumes
- /// like `C:`, UNC prefixes like `\\server`, and others described in more
- /// detail in `std::os::windows::PathExt`.
- #[unstable(feature = "path_prefix",
- reason = "uncertain whether to expose this convenience",
- issue = "27722")]
- #[rustc_deprecated(since = "1.7.0",
- reason = "inspect components().next() instead")]
- pub fn prefix(&self) -> Option<Prefix> {
+ fn prefix(&self) -> Option<Prefix> {
self.components().prefix
}
})
}
- /// Returns a path that, when joined onto `base`, yields `self`.
- ///
- /// If `base` is not a prefix of `self` (i.e. `starts_with`
- /// returns false), then `relative_from` returns `None`.
- #[unstable(feature = "path_relative_from", reason = "see #23284",
- issue = "23284")]
- #[rustc_deprecated(since = "1.7.0", reason = "renamed to strip_prefix")]
- pub fn relative_from<'a, P: ?Sized + AsRef<Path>>(&'a self, base: &'a P) -> Option<&Path> {
- self._strip_prefix(base.as_ref()).ok()
- }
-
/// Returns a path that, when joined onto `base`, yields `self`.
///
/// # Errors
);
);
- #[test]
- #[allow(deprecated)]
- fn into_cow() {
- use borrow::{Cow, IntoCow};
-
- let static_path = Path::new("/home/foo");
- let static_cow_path: Cow<'static, Path> = static_path.into_cow();
- let pathbuf = PathBuf::from("/home/foo");
-
- {
- let path: &Path = &pathbuf;
- let borrowed_cow_path: Cow<Path> = path.into_cow();
-
- assert_eq!(static_cow_path, borrowed_cow_path);
- }
-
- let owned_cow_path: Cow<'static, Path> = pathbuf.into_cow();
-
- assert_eq!(static_cow_path, owned_cow_path);
- }
-
#[test]
fn into() {
use borrow::Cow;
/// returns, regardless of whether the timeout elapsed or not.
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_deprecated(since = "1.6.0", reason = "replaced by `std::sync::Condvar::wait_timeout`")]
- #[allow(deprecated)]
pub fn wait_timeout_ms<'a, T>(&self, guard: MutexGuard<'a, T>, ms: u32)
-> LockResult<(MutexGuard<'a, T>, bool)> {
- unsafe {
- let me: &'static Condvar = &*(self as *const _);
- me.inner.wait_timeout_ms(guard, ms)
- }
+ let res = self.wait_timeout(guard, Duration::from_millis(ms as u64));
+ poison::map_result(res, |(a, b)| {
+ (a, !b.timed_out())
+ })
}
/// Waits on this condition variable for a notification, timing out after a
}
}
- /// Waits on this condition variable for a notification, timing out after a
- /// specified duration.
- ///
- /// The semantics of this function are equivalent to `wait_timeout` except
- /// that the implementation will repeatedly wait while the duration has not
- /// passed and the provided function returns `false`.
- #[unstable(feature = "wait_timeout_with",
- reason = "unsure if this API is broadly needed or what form it should take",
- issue = "27748")]
- #[rustc_deprecated(since = "1.8.0",
- reason = "wonky signature and questionable \
- implementation didn't justify existence")]
- pub fn wait_timeout_with<'a, T, F>(&self,
- guard: MutexGuard<'a, T>,
- dur: Duration,
- f: F)
- -> LockResult<(MutexGuard<'a, T>, WaitTimeoutResult)>
- where F: FnMut(LockResult<&mut T>) -> bool {
- unsafe {
- let me: &'static Condvar = &*(self as *const _);
- me.inner.wait_timeout_with(guard, dur, f)
- }
- }
-
/// Wakes up one blocked thread on this condvar.
///
/// If there is a blocked thread on this condition variable, then it will
}
}
- /// Waits on this condition variable for a notification, timing out after a
- /// specified duration.
- ///
- /// See `Condvar::wait_timeout`.
- #[unstable(feature = "static_condvar",
- reason = "may be merged with Condvar in the future",
- issue = "27717")]
- #[rustc_deprecated(since = "1.6.0",
- reason = "replaced by `std::sync::StaticCondvar::wait_timeout`")]
- pub fn wait_timeout_ms<'a, T>(&'static self, guard: MutexGuard<'a, T>, ms: u32)
- -> LockResult<(MutexGuard<'a, T>, bool)> {
- match self.wait_timeout(guard, Duration::from_millis(ms as u64)) {
- Ok((guard, timed_out)) => Ok((guard, !timed_out.timed_out())),
- Err(poison) => {
- let (guard, timed_out) = poison.into_inner();
- Err(PoisonError::new((guard, !timed_out.timed_out())))
- }
- }
- }
-
/// Waits on this condition variable for a notification, timing out after a
/// specified duration.
///
pub use self::rwlock::{RwLockReadGuard, RwLockWriteGuard};
#[stable(feature = "rust1", since = "1.0.0")]
pub use self::rwlock::{RwLock, StaticRwLock, RW_LOCK_INIT};
-#[stable(feature = "rust1", since = "1.0.0")]
-#[allow(deprecated)]
-pub use self::semaphore::{Semaphore, SemaphoreGuard};
pub mod mpsc;
mod mutex;
mod once;
mod rwlock;
-mod semaphore;
+++ /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.
-
-#![unstable(feature = "semaphore",
- reason = "the interaction between semaphores and the acquisition/release \
- of resources is currently unclear",
- issue = "27798")]
-#![allow(deprecated)]
-
-use ops::Drop;
-use sync::{Mutex, Condvar};
-
-/// A counting, blocking, semaphore.
-///
-/// Semaphores are a form of atomic counter where access is only granted if the
-/// counter is a positive value. Each acquisition will block the calling thread
-/// until the counter is positive, and each release will increment the counter
-/// and unblock any threads if necessary.
-///
-/// # Examples
-///
-/// ```
-/// #![feature(semaphore)]
-///
-/// use std::sync::Semaphore;
-///
-/// // Create a semaphore that represents 5 resources
-/// let sem = Semaphore::new(5);
-///
-/// // Acquire one of the resources
-/// sem.acquire();
-///
-/// // Acquire one of the resources for a limited period of time
-/// {
-/// let _guard = sem.access();
-/// // ...
-/// } // resources is released here
-///
-/// // Release our initially acquired resource
-/// sem.release();
-/// ```
-#[rustc_deprecated(since = "1.7.0",
- reason = "easily confused with system semaphores and not \
- used enough to pull its weight")]
-#[unstable(feature = "semaphore",
- reason = "the interaction between semaphores and the acquisition/release \
- of resources is currently unclear",
- issue = "27798")]
-pub struct Semaphore {
- lock: Mutex<isize>,
- cvar: Condvar,
-}
-
-/// An RAII guard which will release a resource acquired from a semaphore when
-/// dropped.
-#[rustc_deprecated(since = "1.7.0",
- reason = "easily confused with system semaphores and not \
- used enough to pull its weight")]
-#[unstable(feature = "semaphore",
- reason = "the interaction between semaphores and the acquisition/release \
- of resources is currently unclear",
- issue = "27798")]
-pub struct SemaphoreGuard<'a> {
- sem: &'a Semaphore,
-}
-
-#[rustc_deprecated(since = "1.7.0",
- reason = "easily confused with system semaphores and not \
- used enough to pull its weight")]
-#[unstable(feature = "semaphore",
- reason = "the interaction between semaphores and the acquisition/release \
- of resources is currently unclear",
- issue = "27798")]
-impl Semaphore {
- /// Creates a new semaphore with the initial count specified.
- ///
- /// The count specified can be thought of as a number of resources, and a
- /// call to `acquire` or `access` will block until at least one resource is
- /// available. It is valid to initialize a semaphore with a negative count.
- pub fn new(count: isize) -> Semaphore {
- Semaphore {
- lock: Mutex::new(count),
- cvar: Condvar::new(),
- }
- }
-
- /// Acquires a resource of this semaphore, blocking the current thread until
- /// it can do so.
- ///
- /// This method will block until the internal count of the semaphore is at
- /// least 1.
- pub fn acquire(&self) {
- let mut count = self.lock.lock().unwrap();
- while *count <= 0 {
- count = self.cvar.wait(count).unwrap();
- }
- *count -= 1;
- }
-
- /// Release a resource from this semaphore.
- ///
- /// This will increment the number of resources in this semaphore by 1 and
- /// will notify any pending waiters in `acquire` or `access` if necessary.
- pub fn release(&self) {
- *self.lock.lock().unwrap() += 1;
- self.cvar.notify_one();
- }
-
- /// Acquires a resource of this semaphore, returning an RAII guard to
- /// release the semaphore when dropped.
- ///
- /// This function is semantically equivalent to an `acquire` followed by a
- /// `release` when the guard returned is dropped.
- pub fn access(&self) -> SemaphoreGuard {
- self.acquire();
- SemaphoreGuard { sem: self }
- }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a> Drop for SemaphoreGuard<'a> {
- fn drop(&mut self) {
- self.sem.release();
- }
-}
-
-#[cfg(test)]
-mod tests {
- use prelude::v1::*;
-
- use sync::Arc;
- use super::Semaphore;
- use sync::mpsc::channel;
- use thread;
-
- #[test]
- fn test_sem_acquire_release() {
- let s = Semaphore::new(1);
- s.acquire();
- s.release();
- s.acquire();
- }
-
- #[test]
- fn test_sem_basic() {
- let s = Semaphore::new(1);
- let _g = s.access();
- }
-
- #[test]
- fn test_sem_as_mutex() {
- let s = Arc::new(Semaphore::new(1));
- let s2 = s.clone();
- let _t = thread::spawn(move|| {
- let _g = s2.access();
- });
- let _g = s.access();
- }
-
- #[test]
- fn test_sem_as_cvar() {
- /* Child waits and parent signals */
- let (tx, rx) = channel();
- let s = Arc::new(Semaphore::new(0));
- let s2 = s.clone();
- let _t = thread::spawn(move|| {
- s2.acquire();
- tx.send(()).unwrap();
- });
- s.release();
- let _ = rx.recv();
-
- /* Parent waits and child signals */
- let (tx, rx) = channel();
- let s = Arc::new(Semaphore::new(0));
- let s2 = s.clone();
- let _t = thread::spawn(move|| {
- s2.release();
- let _ = rx.recv();
- });
- s.acquire();
- tx.send(()).unwrap();
- }
-
- #[test]
- fn test_sem_multi_resource() {
- // Parent and child both get in the critical section at the same
- // time, and shake hands.
- let s = Arc::new(Semaphore::new(2));
- let s2 = s.clone();
- let (tx1, rx1) = channel();
- let (tx2, rx2) = channel();
- let _t = thread::spawn(move|| {
- let _g = s2.access();
- let _ = rx2.recv();
- tx1.send(()).unwrap();
- });
- let _g = s.access();
- tx2.send(()).unwrap();
- rx1.recv().unwrap();
- }
-
- #[test]
- fn test_sem_runtime_friendly_blocking() {
- let s = Arc::new(Semaphore::new(1));
- let s2 = s.clone();
- let (tx, rx) = channel();
- {
- let _g = s.access();
- thread::spawn(move|| {
- tx.send(()).unwrap();
- drop(s2.access());
- tx.send(()).unwrap();
- });
- rx.recv().unwrap(); // wait for child to come alive
- }
- rx.recv().unwrap(); // wait for child to be done
- }
-}
use prelude::v1::*;
use cmp;
-use ffi::{CStr, CString};
+use ffi::CString;
use fmt;
use io::{self, Error, ErrorKind};
-use libc::{c_int, c_char, c_void};
+use libc::{c_int, c_void};
use mem;
-#[allow(deprecated)]
-use net::{SocketAddr, Shutdown, IpAddr, Ipv4Addr, Ipv6Addr};
+use net::{SocketAddr, Shutdown, Ipv4Addr, Ipv6Addr};
use ptr;
-use str::from_utf8;
use sys::net::{cvt, cvt_r, cvt_gai, Socket, init, wrlen_t};
use sys::net::netc as c;
use sys_common::{AsInner, FromInner, IntoInner};
}
}
-////////////////////////////////////////////////////////////////////////////////
-// lookup_addr
-////////////////////////////////////////////////////////////////////////////////
-
-#[allow(deprecated)]
-pub fn lookup_addr(addr: &IpAddr) -> io::Result<String> {
- init();
-
- let saddr = SocketAddr::new(*addr, 0);
- let (inner, len) = saddr.into_inner();
- let mut hostbuf = [0 as c_char; c::NI_MAXHOST as usize];
-
- let data = unsafe {
- try!(cvt_gai(c::getnameinfo(inner, len,
- hostbuf.as_mut_ptr(),
- c::NI_MAXHOST,
- ptr::null_mut(), 0, 0)));
-
- CStr::from_ptr(hostbuf.as_ptr())
- };
-
- match from_utf8(data.to_bytes()) {
- Ok(name) => Ok(name.to_owned()),
- Err(_) => Err(io::Error::new(io::ErrorKind::Other,
- "failed to lookup address information"))
- }
-}
-
////////////////////////////////////////////////////////////////////////////////
// TCP streams
////////////////////////////////////////////////////////////////////////////////
use fs::{self, Permissions, OpenOptions};
use io;
use libc;
-#[allow(deprecated)]
-use os::unix::raw;
use path::Path;
use sys;
use sys_common::{FromInner, AsInner, AsInnerMut};
use sys::platform::fs::MetadataExt as UnixMetadataExt;
-#[unstable(feature = "fs_mode", reason = "recently added API", issue = "27712")]
-#[rustc_deprecated(since = "1.7.0", reason = "moved to the libc crate instead")]
-#[allow(deprecated)]
-pub const USER_READ: raw::mode_t = 0o400;
-#[unstable(feature = "fs_mode", reason = "recently added API", issue = "27712")]
-#[rustc_deprecated(since = "1.7.0", reason = "moved to the libc crate instead")]
-#[allow(deprecated)]
-pub const USER_WRITE: raw::mode_t = 0o200;
-#[unstable(feature = "fs_mode", reason = "recently added API", issue = "27712")]
-#[rustc_deprecated(since = "1.7.0", reason = "moved to the libc crate instead")]
-#[allow(deprecated)]
-pub const USER_EXECUTE: raw::mode_t = 0o100;
-#[unstable(feature = "fs_mode", reason = "recently added API", issue = "27712")]
-#[rustc_deprecated(since = "1.7.0", reason = "moved to the libc crate instead")]
-#[allow(deprecated)]
-pub const USER_RWX: raw::mode_t = 0o700;
-#[unstable(feature = "fs_mode", reason = "recently added API", issue = "27712")]
-#[rustc_deprecated(since = "1.7.0", reason = "moved to the libc crate instead")]
-#[allow(deprecated)]
-pub const GROUP_READ: raw::mode_t = 0o040;
-#[unstable(feature = "fs_mode", reason = "recently added API", issue = "27712")]
-#[rustc_deprecated(since = "1.7.0", reason = "moved to the libc crate instead")]
-#[allow(deprecated)]
-pub const GROUP_WRITE: raw::mode_t = 0o020;
-#[unstable(feature = "fs_mode", reason = "recently added API", issue = "27712")]
-#[rustc_deprecated(since = "1.7.0", reason = "moved to the libc crate instead")]
-#[allow(deprecated)]
-pub const GROUP_EXECUTE: raw::mode_t = 0o010;
-#[unstable(feature = "fs_mode", reason = "recently added API", issue = "27712")]
-#[rustc_deprecated(since = "1.7.0", reason = "moved to the libc crate instead")]
-#[allow(deprecated)]
-pub const GROUP_RWX: raw::mode_t = 0o070;
-#[unstable(feature = "fs_mode", reason = "recently added API", issue = "27712")]
-#[rustc_deprecated(since = "1.7.0", reason = "moved to the libc crate instead")]
-#[allow(deprecated)]
-pub const OTHER_READ: raw::mode_t = 0o004;
-#[unstable(feature = "fs_mode", reason = "recently added API", issue = "27712")]
-#[rustc_deprecated(since = "1.7.0", reason = "moved to the libc crate instead")]
-#[allow(deprecated)]
-pub const OTHER_WRITE: raw::mode_t = 0o002;
-#[unstable(feature = "fs_mode", reason = "recently added API", issue = "27712")]
-#[rustc_deprecated(since = "1.7.0", reason = "moved to the libc crate instead")]
-#[allow(deprecated)]
-pub const OTHER_EXECUTE: raw::mode_t = 0o001;
-#[unstable(feature = "fs_mode", reason = "recently added API", issue = "27712")]
-#[rustc_deprecated(since = "1.7.0", reason = "moved to the libc crate instead")]
-#[allow(deprecated)]
-pub const OTHER_RWX: raw::mode_t = 0o007;
-#[unstable(feature = "fs_mode", reason = "recently added API", issue = "27712")]
-#[rustc_deprecated(since = "1.7.0", reason = "moved to the libc crate instead")]
-#[allow(deprecated)]
-pub const ALL_READ: raw::mode_t = 0o444;
-#[unstable(feature = "fs_mode", reason = "recently added API", issue = "27712")]
-#[rustc_deprecated(since = "1.7.0", reason = "moved to the libc crate instead")]
-#[allow(deprecated)]
-pub const ALL_WRITE: raw::mode_t = 0o222;
-#[unstable(feature = "fs_mode", reason = "recently added API", issue = "27712")]
-#[rustc_deprecated(since = "1.7.0", reason = "moved to the libc crate instead")]
-#[allow(deprecated)]
-pub const ALL_EXECUTE: raw::mode_t = 0o111;
-#[unstable(feature = "fs_mode", reason = "recently added API", issue = "27712")]
-#[rustc_deprecated(since = "1.7.0", reason = "moved to the libc crate instead")]
-#[allow(deprecated)]
-pub const ALL_RWX: raw::mode_t = 0o777;
-#[unstable(feature = "fs_mode", reason = "recently added API", issue = "27712")]
-#[rustc_deprecated(since = "1.7.0", reason = "moved to the libc crate instead")]
-#[allow(deprecated)]
-pub const SETUID: raw::mode_t = 0o4000;
-#[unstable(feature = "fs_mode", reason = "recently added API", issue = "27712")]
-#[rustc_deprecated(since = "1.7.0", reason = "moved to the libc crate instead")]
-#[allow(deprecated)]
-pub const SETGID: raw::mode_t = 0o2000;
-#[unstable(feature = "fs_mode", reason = "recently added API", issue = "27712")]
-#[rustc_deprecated(since = "1.7.0", reason = "moved to the libc crate instead")]
-#[allow(deprecated)]
-pub const STICKY_BIT: raw::mode_t = 0o1000;
-
/// Unix-specific extensions to `Permissions`
#[stable(feature = "fs_ext", since = "1.1.0")]
pub trait PermissionsExt {
use io::prelude::*;
-use dynamic_lib::DynamicLibrary;
use io;
use libc::c_void;
use mem;
-use path::Path;
use ptr;
use sync::StaticMutex;
use sys::c;
+use sys::dynamic_lib::DynamicLibrary;
-macro_rules! sym{ ($lib:expr, $e:expr, $t:ident) => (unsafe {
- let lib = $lib;
- match lib.symbol($e) {
- Ok(f) => $crate::mem::transmute::<*mut u8, $t>(f),
- Err(..) => return Ok(())
- }
-}) }
+macro_rules! sym {
+ ($lib:expr, $e:expr, $t:ident) => (
+ match $lib.symbol($e) {
+ Ok(f) => $crate::mem::transmute::<usize, $t>(f),
+ Err(..) => return Ok(())
+ }
+ )
+}
#[cfg(target_env = "msvc")]
#[path = "printing/msvc.rs"]
mod printing;
type SymInitializeFn =
- extern "system" fn(c::HANDLE, *mut c_void,
- c::BOOL) -> c::BOOL;
+ unsafe extern "system" fn(c::HANDLE, *mut c_void,
+ c::BOOL) -> c::BOOL;
type SymCleanupFn =
- extern "system" fn(c::HANDLE) -> c::BOOL;
+ unsafe extern "system" fn(c::HANDLE) -> c::BOOL;
type StackWalk64Fn =
- extern "system" fn(c::DWORD, c::HANDLE, c::HANDLE,
- *mut c::STACKFRAME64, *mut c::CONTEXT,
- *mut c_void, *mut c_void,
- *mut c_void, *mut c_void) -> c::BOOL;
+ unsafe extern "system" fn(c::DWORD, c::HANDLE, c::HANDLE,
+ *mut c::STACKFRAME64, *mut c::CONTEXT,
+ *mut c_void, *mut c_void,
+ *mut c_void, *mut c_void) -> c::BOOL;
#[cfg(target_arch = "x86")]
pub fn init_frame(frame: &mut c::STACKFRAME64,
}
impl Drop for Cleanup {
- fn drop(&mut self) { (self.SymCleanup)(self.handle); }
+ fn drop(&mut self) {
+ unsafe { (self.SymCleanup)(self.handle); }
+ }
}
pub fn write(w: &mut Write) -> io::Result<()> {
static LOCK: StaticMutex = StaticMutex::new();
let _g = LOCK.lock();
- // Open up dbghelp.dll, we don't link to it explicitly because it can't
- // always be found. Additionally, it's nice having fewer dependencies.
- let path = Path::new("dbghelp.dll");
- let dbghelp = match DynamicLibrary::open(Some(&path)) {
+ let dbghelp = match DynamicLibrary::open("dbghelp.dll") {
Ok(lib) => lib,
Err(..) => return Ok(()),
};
-
- // Fetch the symbols necessary from dbghelp.dll
- let SymInitialize = sym!(&dbghelp, "SymInitialize", SymInitializeFn);
- let SymCleanup = sym!(&dbghelp, "SymCleanup", SymCleanupFn);
- let StackWalk64 = sym!(&dbghelp, "StackWalk64", StackWalk64Fn);
-
- // Allocate necessary structures for doing the stack walk
- let process = unsafe { c::GetCurrentProcess() };
- let thread = unsafe { c::GetCurrentThread() };
- let mut context: c::CONTEXT = unsafe { mem::zeroed() };
- unsafe { c::RtlCaptureContext(&mut context); }
- let mut frame: c::STACKFRAME64 = unsafe { mem::zeroed() };
- let image = init_frame(&mut frame, &context);
-
- // Initialize this process's symbols
- let ret = SymInitialize(process, ptr::null_mut(), c::TRUE);
- if ret != c::TRUE { return Ok(()) }
- let _c = Cleanup { handle: process, SymCleanup: SymCleanup };
-
- // And now that we're done with all the setup, do the stack walking!
- // Start from -1 to avoid printing this stack frame, which will
- // always be exactly the same.
- let mut i = -1;
- try!(write!(w, "stack backtrace:\n"));
- while StackWalk64(image, process, thread, &mut frame, &mut context,
- ptr::null_mut(),
- ptr::null_mut(),
- ptr::null_mut(),
- ptr::null_mut()) == c::TRUE {
- let addr = frame.AddrPC.Offset;
- if addr == frame.AddrReturn.Offset || addr == 0 ||
- frame.AddrReturn.Offset == 0 { break }
-
- i += 1;
-
- if i >= 0 {
- try!(printing::print(w, i, addr-1, &dbghelp, process));
+ unsafe {
+ // Fetch the symbols necessary from dbghelp.dll
+ let SymInitialize = sym!(dbghelp, "SymInitialize", SymInitializeFn);
+ let SymCleanup = sym!(dbghelp, "SymCleanup", SymCleanupFn);
+ let StackWalk64 = sym!(dbghelp, "StackWalk64", StackWalk64Fn);
+
+ // Allocate necessary structures for doing the stack walk
+ let process = c::GetCurrentProcess();
+ let thread = c::GetCurrentThread();
+ let mut context: c::CONTEXT = mem::zeroed();
+ c::RtlCaptureContext(&mut context);
+ let mut frame: c::STACKFRAME64 = mem::zeroed();
+ let image = init_frame(&mut frame, &context);
+
+ // Initialize this process's symbols
+ let ret = SymInitialize(process, ptr::null_mut(), c::TRUE);
+ if ret != c::TRUE { return Ok(()) }
+ let _c = Cleanup { handle: process, SymCleanup: SymCleanup };
+
+ // And now that we're done with all the setup, do the stack walking!
+ // Start from -1 to avoid printing this stack frame, which will
+ // always be exactly the same.
+ let mut i = -1;
+ try!(write!(w, "stack backtrace:\n"));
+ while StackWalk64(image, process, thread, &mut frame, &mut context,
+ ptr::null_mut(),
+ ptr::null_mut(),
+ ptr::null_mut(),
+ ptr::null_mut()) == c::TRUE {
+ let addr = frame.AddrPC.Offset;
+ if addr == frame.AddrReturn.Offset || addr == 0 ||
+ frame.AddrReturn.Offset == 0 { break }
+
+ i += 1;
+
+ if i >= 0 {
+ try!(printing::print(w, i, addr - 1, process, &dbghelp));
+ }
}
- }
- Ok(())
+ Ok(())
+ }
}
pub const WSAETIMEDOUT: c_int = 10060;
pub const WSAECONNREFUSED: c_int = 10061;
-pub const NI_MAXHOST: DWORD = 1025;
-
pub const MAX_PROTOCOL_CHAIN: DWORD = 7;
pub const TOKEN_READ: DWORD = 0x20008;
hints: *const ADDRINFOA,
res: *mut *mut ADDRINFOA) -> c_int;
pub fn freeaddrinfo(res: *mut ADDRINFOA);
- pub fn getnameinfo(sa: *const SOCKADDR, salen: c_int,
- host: *mut c_char, hostlen: DWORD,
- serv: *mut c_char, servlen: DWORD,
- flags: c_int) -> c_int;
pub fn LoadLibraryW(name: LPCWSTR) -> HMODULE;
- pub fn GetModuleHandleExW(dwFlags: DWORD, name: LPCWSTR,
- handle: *mut HMODULE) -> BOOL;
+ pub fn FreeLibrary(handle: HMODULE) -> BOOL;
pub fn GetProcAddress(handle: HMODULE,
name: LPCSTR) -> *mut c_void;
- pub fn FreeLibrary(handle: HMODULE) -> BOOL;
- pub fn SetErrorMode(uMode: c_uint) -> c_uint;
pub fn GetModuleHandleW(lpModuleName: LPCWSTR) -> HMODULE;
pub fn CryptAcquireContextA(phProv: *mut HCRYPTPROV,
pszContainer: LPCSTR,
_dwFlags: DWORD) -> DWORD {
SetLastError(ERROR_CALL_NOT_IMPLEMENTED as DWORD); 0
}
- pub fn SetThreadErrorMode(_dwNewMode: DWORD,
- _lpOldMode: *mut DWORD) -> c_uint {
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED as DWORD); 0
- }
pub fn SetThreadStackGuarantee(_size: *mut c_ulong) -> BOOL {
SetLastError(ERROR_CALL_NOT_IMPLEMENTED as DWORD); 0
}
--- /dev/null
+// Copyright 2016 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 prelude::v1::*;
+use os::windows::prelude::*;
+
+use ffi::{CString, OsStr};
+use io;
+use sys::c;
+
+pub struct DynamicLibrary {
+ handle: c::HMODULE,
+}
+
+impl DynamicLibrary {
+ pub fn open(filename: &str) -> io::Result<DynamicLibrary> {
+ let filename = OsStr::new(filename)
+ .encode_wide()
+ .chain(Some(0))
+ .collect::<Vec<_>>();
+ let result = unsafe {
+ c::LoadLibraryW(filename.as_ptr())
+ };
+ if result.is_null() {
+ Err(io::Error::last_os_error())
+ } else {
+ Ok(DynamicLibrary { handle: result })
+ }
+ }
+
+ pub fn symbol(&self, symbol: &str) -> io::Result<usize> {
+ let symbol = try!(CString::new(symbol));
+ unsafe {
+ match c::GetProcAddress(self.handle, symbol.as_ptr()) as usize {
+ 0 => Err(io::Error::last_os_error()),
+ n => Ok(n),
+ }
+ }
+ }
+}
+
+impl Drop for DynamicLibrary {
+ fn drop(&mut self) {
+ unsafe {
+ c::FreeLibrary(self.handle);
+ }
+ }
+}
pub mod backtrace;
pub mod c;
pub mod condvar;
+pub mod dynamic_lib;
pub mod ext;
pub mod fs;
pub mod handle;
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![allow(deprecated)]
-
-use dynamic_lib::DynamicLibrary;
use io::prelude::*;
use io;
-use sys::c;
use libc::c_void;
-
+use sys::c;
+use sys::dynamic_lib::DynamicLibrary;
use sys_common::gnu::libbacktrace;
-pub fn print(w: &mut Write, i: isize, addr: u64, _: &DynamicLibrary, _: c::HANDLE)
- -> io::Result<()> {
+pub fn print(w: &mut Write,
+ i: isize,
+ addr: u64,
+ _process: c::HANDLE,
+ _dbghelp: &DynamicLibrary)
+ -> io::Result<()> {
let addr = addr as usize as *mut c_void;
libbacktrace::print(w, i, addr, addr)
}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![allow(deprecated)]
-
-use dynamic_lib::DynamicLibrary;
use ffi::CStr;
use io::prelude::*;
use io;
use libc::{c_ulong, c_int, c_char, c_void};
use mem;
use sys::c;
+use sys::dynamic_lib::DynamicLibrary;
use sys_common::backtrace::{output, output_fileline};
type SymFromAddrFn =
- extern "system" fn(c::HANDLE, u64, *mut u64,
- *mut c::SYMBOL_INFO) -> c::BOOL;
+ unsafe extern "system" fn(c::HANDLE, u64, *mut u64,
+ *mut c::SYMBOL_INFO) -> c::BOOL;
type SymGetLineFromAddr64Fn =
- extern "system" fn(c::HANDLE, u64, *mut u32,
- *mut c::IMAGEHLP_LINE64) -> c::BOOL;
+ unsafe extern "system" fn(c::HANDLE, u64, *mut u32,
+ *mut c::IMAGEHLP_LINE64) -> c::BOOL;
-pub fn print(w: &mut Write, i: isize, addr: u64, dbghelp: &DynamicLibrary,
- process: c::HANDLE) -> io::Result<()> {
- let SymFromAddr = sym!(dbghelp, "SymFromAddr", SymFromAddrFn);
- let SymGetLineFromAddr64 = sym!(dbghelp, "SymGetLineFromAddr64", SymGetLineFromAddr64Fn);
+pub fn print(w: &mut Write,
+ i: isize,
+ addr: u64,
+ process: c::HANDLE,
+ dbghelp: &DynamicLibrary)
+ -> io::Result<()> {
+ unsafe {
+ let SymFromAddr = sym!(dbghelp, "SymFromAddr", SymFromAddrFn);
+ let SymGetLineFromAddr64 = sym!(dbghelp,
+ "SymGetLineFromAddr64",
+ SymGetLineFromAddr64Fn);
- let mut info: c::SYMBOL_INFO = unsafe { mem::zeroed() };
- info.MaxNameLen = c::MAX_SYM_NAME as c_ulong;
- // the struct size in C. the value is different to
- // `size_of::<SYMBOL_INFO>() - MAX_SYM_NAME + 1` (== 81)
- // due to struct alignment.
- info.SizeOfStruct = 88;
+ let mut info: c::SYMBOL_INFO = mem::zeroed();
+ info.MaxNameLen = c::MAX_SYM_NAME as c_ulong;
+ // the struct size in C. the value is different to
+ // `size_of::<SYMBOL_INFO>() - MAX_SYM_NAME + 1` (== 81)
+ // due to struct alignment.
+ info.SizeOfStruct = 88;
- let mut displacement = 0u64;
- let ret = SymFromAddr(process, addr, &mut displacement, &mut info);
+ let mut displacement = 0u64;
+ let ret = SymFromAddr(process, addr, &mut displacement, &mut info);
- let name = if ret == c::TRUE {
- let ptr = info.Name.as_ptr() as *const c_char;
- Some(unsafe { CStr::from_ptr(ptr).to_bytes() })
- } else {
- None
- };
+ let name = if ret == c::TRUE {
+ let ptr = info.Name.as_ptr() as *const c_char;
+ Some(CStr::from_ptr(ptr).to_bytes())
+ } else {
+ None
+ };
- try!(output(w, i, addr as usize as *mut c_void, name));
+ try!(output(w, i, addr as usize as *mut c_void, name));
- // Now find out the filename and line number
- let mut line: c::IMAGEHLP_LINE64 = unsafe { mem::zeroed() };
- line.SizeOfStruct = ::mem::size_of::<c::IMAGEHLP_LINE64>() as u32;
+ // Now find out the filename and line number
+ let mut line: c::IMAGEHLP_LINE64 = mem::zeroed();
+ line.SizeOfStruct = ::mem::size_of::<c::IMAGEHLP_LINE64>() as u32;
- let mut displacement = 0u32;
- let ret = SymGetLineFromAddr64(process, addr, &mut displacement, &mut line);
- if ret == c::TRUE {
- output_fileline(w,
- unsafe { CStr::from_ptr(line.Filename).to_bytes() },
- line.LineNumber as c_int,
- false)
- } else {
- Ok(())
+ let mut displacement = 0u32;
+ let ret = SymGetLineFromAddr64(process, addr, &mut displacement, &mut line);
+ if ret == c::TRUE {
+ output_fileline(w,
+ CStr::from_ptr(line.Filename).to_bytes(),
+ line.LineNumber as c_int,
+ false)
+ } else {
+ Ok(())
+ }
}
}
unwind::panicking()
}
-/// Invokes a closure, capturing the cause of panic if one occurs.
-///
-/// This function will return `Ok` with the closure's result if the closure
-/// does not panic, and will return `Err(cause)` if the closure panics. The
-/// `cause` returned is the object with which panic was originally invoked.
-///
-/// It is currently undefined behavior to unwind from Rust code into foreign
-/// code, so this function is particularly useful when Rust is called from
-/// another language (normally C). This can run arbitrary Rust code, capturing a
-/// panic and allowing a graceful handling of the error.
-///
-/// It is **not** recommended to use this function for a general try/catch
-/// mechanism. The `Result` type is more appropriate to use for functions that
-/// can fail on a regular basis.
-///
-/// The closure provided is required to adhere to the `'static` bound to ensure
-/// that it cannot reference data in the parent stack frame, mitigating problems
-/// with exception safety. Furthermore, a `Send` bound is also required,
-/// providing the same safety guarantees as `thread::spawn` (ensuring the
-/// closure is properly isolated from the parent).
-#[unstable(feature = "catch_panic", reason = "recent API addition",
- issue = "27719")]
-#[rustc_deprecated(since = "1.6.0", reason = "renamed to std::panic::recover")]
-pub fn catch_panic<F, R>(f: F) -> Result<R>
- where F: FnOnce() -> R + Send + 'static
-{
- let mut result = None;
- unsafe {
- let result = &mut result;
- try!(unwind::try(move || *result = Some(f())))
- }
- Ok(result.unwrap())
-}
-
/// Puts the current thread to sleep for the specified amount of time.
///
/// The thread may sleep longer than the duration specified due to scheduling
// except according to those terms.
use ops::{Add, Sub, Mul, Div};
-use time::Instant;
const NANOS_PER_SEC: u32 = 1_000_000_000;
const NANOS_PER_MILLI: u32 = 1_000_000;
Duration { secs: secs, nanos: nanos }
}
- /// Runs a closure, returning the duration of time it took to run the
- /// closure.
- #[unstable(feature = "duration_span",
- reason = "unsure if this is the right API or whether it should \
- wait for a more general \"moment in time\" \
- abstraction",
- issue = "27799")]
- #[rustc_deprecated(reason = "use std::time::Instant instead",
- since = "1.6.0")]
- pub fn span<F>(f: F) -> Duration where F: FnOnce() {
- let start = Instant::now();
- f();
- start.elapsed()
- }
-
/// Creates a new `Duration` from the specified number of seconds.
#[stable(feature = "duration", since = "1.3.0")]
pub fn from_secs(secs: u64) -> Duration {
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(dynamic_lib)]
+#![feature(rustc_private)]
// We're testing linkage visibility; the compiler warns us, but we want to
// do the runtime check that these functions aren't exported.
#![allow(private_no_mangle_fns)]
-use std::dynamic_lib::DynamicLibrary;
+extern crate rustc_back;
+
+use rustc_back::dynamic_lib::DynamicLibrary;
#[no_mangle]
pub fn foo() { bar(); }
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-use std::borrow::IntoCow;
+use std::borrow::Cow;
+
+pub trait IntoCow<'a, B: ?Sized> where B: ToOwned {
+ fn into_cow(self) -> Cow<'a, B>;
+}
+
+impl<'a> IntoCow<'a, str> for String {
+ fn into_cow(self) -> Cow<'a, str> {
+ Cow::Owned(self)
+ }
+}
fn main() {
<String as IntoCow>::into_cow("foo".to_string());
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(dynamic_lib)]
+#![feature(rustc_private)]
-use std::dynamic_lib::DynamicLibrary;
+extern crate rustc_back;
+
+use rustc_back::dynamic_lib::DynamicLibrary;
use std::path::Path;
pub fn main() {
--- /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.
+
+// aux-build:linkage-visibility.rs
+// ignore-android: FIXME(#10356)
+// ignore-windows: std::dynamic_lib does not work on Windows well
+// ignore-musl
+
+extern crate linkage_visibility as foo;
+
+pub fn main() {
+ foo::test();
+ foo::foo2::<isize>();
+ foo::foo();
+}
+++ /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.
-
-#![feature(rustc_private)]
-
-extern crate arena;
-use arena::Arena;
-
-pub fn main() {
- let mut arena = Arena::new();
- let p = &mut arena;
- let x = p.alloc(|| 4_usize);
- println!("{}", *x);
- assert_eq!(*x, 4_usize);
-}
// ignore-emscripten
// no-prefer-dynamic
-#![feature(convert)]
#![feature(libc)]
extern crate libc;
use libc::c_char;
use libc::execve;
use std::env;
-use std::ffi::OsStr;
+use std::ffi::CString;
+use std::os::unix::prelude::*;
use std::ptr;
fn main() {
return;
}
- let current_exe = env::current_exe().unwrap().into_os_string().to_cstring().unwrap();
- let new_env_var = OsStr::new("FOOBAR").to_cstring().unwrap();
+ let current_exe = CString::new(env::current_exe()
+ .unwrap()
+ .as_os_str()
+ .as_bytes()).unwrap();
+ let new_env_var = CString::new("FOOBAR").unwrap();
let filename: *const c_char = current_exe.as_ptr();
let argv: &[*const c_char] = &[filename, filename, ptr::null()];
let envp: &[*const c_char] = &[new_env_var.as_ptr(), ptr::null()];
// pretty-expanded FIXME #23616
-#![feature(num_bits_bytes)]
-
-use std::u8;
+mod u8 {
+ pub const BITS: usize = 8;
+}
const NUM: usize = u8::BITS;
struct MyStruct { nums: [usize; 8] }
-
fn main() {
let _s = MyStruct { nums: [0; NUM] };
}
// pretty-expanded FIXME #23616
-#![feature(fs, net, fs_walk)]
+#![feature(fs, net)]
use std::{fs, net};
assert_both::<fs::Metadata>();
assert_both::<fs::ReadDir>();
assert_both::<fs::DirEntry>();
- assert_send::<fs::WalkDir>();
assert_both::<fs::OpenOptions>();
assert_both::<fs::Permissions>();
+++ /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.
-
-// aux-build:linkage-visibility.rs
-// ignore-android: FIXME(#10356)
-// ignore-windows: std::dynamic_lib does not work on Windows well
-// ignore-musl
-
-extern crate linkage_visibility as foo;
-
-pub fn main() {
- foo::test();
- foo::foo2::<isize>();
- foo::foo();
-}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(iter_min_max, cmp_partial, iter_cmp)]
-
use std::fmt::Debug;
use std::cmp::{self, PartialOrd, Ordering};
// `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!(data.iter().min_by_key(|a| a.n), Some(&a));
assert_eq!(cmp::min(a, b), a);
assert_eq!(cmp::min(b, a), 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!(data.iter().max_by_key(|a| a.n), Some(&f));
assert_eq!(cmp::max(e, f), f);
assert_eq!(cmp::max(f, e), e);
//
// Test std::num::Wrapping<T> for {uN, iN, usize, isize}
-#![feature(num_bits_bytes, test)]
+#![feature(test)]
extern crate test;
AddAssign, SubAssign, MulAssign, DivAssign, RemAssign, BitXorAssign, BitOrAssign, BitAndAssign,
Shl, Shr, ShlAssign, ShrAssign
};
-use std::{i8, i16, i32, i64, isize, u8, u16, u32, u64, usize};
use test::black_box;
+macro_rules! int_modules {
+ ($(($name:ident, $size:expr),)*) => ($(
+ mod $name {
+ pub const BITS: usize = $size;
+ pub use std::$name::*;
+ }
+ )*)
+}
+
+int_modules! {
+ (i8, 8),
+ (i16, 16),
+ (i32, 32),
+ (i64, 64),
+ (u8, 8),
+ (u16, 16),
+ (u32, 32),
+ (u64, 64),
+}
+
+#[cfg(target_pointer_width = "32")]
+int_modules! {
+ (isize, 32),
+ (usize, 32),
+}
+
+#[cfg(target_pointer_width = "64")]
+int_modules! {
+ (isize, 64),
+ (usize, 64),
+}
+
fn main() {
test_ops();
test_op_assigns();
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-
-#![feature(collections, into_cow)]
-
-extern crate collections;
-
use std::collections::HashMap;
-use std::borrow::{Cow, IntoCow};
+use std::borrow::Cow;
+
+use std::borrow::Cow::Borrowed as B;
+use std::borrow::Cow::Owned as O;
type SendStr = Cow<'static, str>;
-pub fn main() {
+fn main() {
let mut map: HashMap<SendStr, usize> = HashMap::new();
- assert!(map.insert("foo".into_cow(), 42).is_none());
- assert!(map.insert("foo".to_string().into_cow(), 42).is_some());
- assert!(map.insert("foo".into_cow(), 42).is_some());
- assert!(map.insert("foo".to_string().into_cow(), 42).is_some());
+ assert!(map.insert(B("foo"), 42).is_none());
+ assert!(map.insert(O("foo".to_string()), 42).is_some());
+ assert!(map.insert(B("foo"), 42).is_some());
+ assert!(map.insert(O("foo".to_string()), 42).is_some());
- assert!(map.insert("foo".into_cow(), 43).is_some());
- assert!(map.insert("foo".to_string().into_cow(), 44).is_some());
- assert!(map.insert("foo".into_cow(), 45).is_some());
- assert!(map.insert("foo".to_string().into_cow(), 46).is_some());
+ assert!(map.insert(B("foo"), 43).is_some());
+ assert!(map.insert(O("foo".to_string()), 44).is_some());
+ assert!(map.insert(B("foo"), 45).is_some());
+ assert!(map.insert(O("foo".to_string()), 46).is_some());
let v = 46;
- assert_eq!(map.get(&"foo".to_string().into_cow()), Some(&v));
- assert_eq!(map.get(&"foo".into_cow()), Some(&v));
+ assert_eq!(map.get(&O("foo".to_string())), Some(&v));
+ assert_eq!(map.get(&B("foo")), Some(&v));
let (a, b, c, d) = (50, 51, 52, 53);
- assert!(map.insert("abc".into_cow(), a).is_none());
- assert!(map.insert("bcd".to_string().into_cow(), b).is_none());
- assert!(map.insert("cde".into_cow(), c).is_none());
- assert!(map.insert("def".to_string().into_cow(), d).is_none());
+ assert!(map.insert(B("abc"), a).is_none());
+ assert!(map.insert(O("bcd".to_string()), b).is_none());
+ assert!(map.insert(B("cde"), c).is_none());
+ assert!(map.insert(O("def".to_string()), d).is_none());
- assert!(map.insert("abc".into_cow(), a).is_some());
- assert!(map.insert("bcd".to_string().into_cow(), b).is_some());
- assert!(map.insert("cde".into_cow(), c).is_some());
- assert!(map.insert("def".to_string().into_cow(), d).is_some());
+ assert!(map.insert(B("abc"), a).is_some());
+ assert!(map.insert(O("bcd".to_string()), b).is_some());
+ assert!(map.insert(B("cde"), c).is_some());
+ assert!(map.insert(O("def".to_string()), d).is_some());
- assert!(map.insert("abc".to_string().into_cow(), a).is_some());
- assert!(map.insert("bcd".into_cow(), b).is_some());
- assert!(map.insert("cde".to_string().into_cow(), c).is_some());
- assert!(map.insert("def".into_cow(), d).is_some());
+ assert!(map.insert(O("abc".to_string()), a).is_some());
+ assert!(map.insert(B("bcd"), b).is_some());
+ assert!(map.insert(O("cde".to_string()), c).is_some());
+ assert!(map.insert(B("def"), d).is_some());
assert_eq!(map.get("abc"), Some(&a));
assert_eq!(map.get("bcd"), Some(&b));
assert_eq!(map.get("cde"), Some(&c));
assert_eq!(map.get("def"), Some(&d));
- assert_eq!(map.get(&"abc".into_cow()), Some(&a));
- assert_eq!(map.get(&"bcd".into_cow()), Some(&b));
- assert_eq!(map.get(&"cde".into_cow()), Some(&c));
- assert_eq!(map.get(&"def".into_cow()), Some(&d));
+ assert_eq!(map.get(&B("abc")), Some(&a));
+ assert_eq!(map.get(&B("bcd")), Some(&b));
+ assert_eq!(map.get(&B("cde")), Some(&c));
+ assert_eq!(map.get(&B("def")), Some(&d));
}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
+use std::collections::BTreeMap;
+use std::borrow::Cow;
-#![feature(collections, into_cow)]
-
-extern crate collections;
-
-use self::collections::BTreeMap;
-use std::borrow::{Cow, IntoCow};
+use std::borrow::Cow::{Owned as O, Borrowed as B};
type SendStr = Cow<'static, str>;
-pub fn main() {
+fn main() {
let mut map: BTreeMap<SendStr, usize> = BTreeMap::new();
- assert!(map.insert("foo".into_cow(), 42).is_none());
- assert!(map.insert("foo".to_string().into_cow(), 42).is_some());
- assert!(map.insert("foo".into_cow(), 42).is_some());
- assert!(map.insert("foo".to_string().into_cow(), 42).is_some());
+ assert!(map.insert(B("foo"), 42).is_none());
+ assert!(map.insert(O("foo".to_string()), 42).is_some());
+ assert!(map.insert(B("foo"), 42).is_some());
+ assert!(map.insert(O("foo".to_string()), 42).is_some());
- assert!(map.insert("foo".into_cow(), 43).is_some());
- assert!(map.insert("foo".to_string().into_cow(), 44).is_some());
- assert!(map.insert("foo".into_cow(), 45).is_some());
- assert!(map.insert("foo".to_string().into_cow(), 46).is_some());
+ assert!(map.insert(B("foo"), 43).is_some());
+ assert!(map.insert(O("foo".to_string()), 44).is_some());
+ assert!(map.insert(B("foo"), 45).is_some());
+ assert!(map.insert(O("foo".to_string()), 46).is_some());
let v = 46;
- assert_eq!(map.get(&"foo".to_string().into_cow()), Some(&v));
- assert_eq!(map.get(&"foo".into_cow()), Some(&v));
+ assert_eq!(map.get(&O("foo".to_string())), Some(&v));
+ assert_eq!(map.get(&B("foo")), Some(&v));
let (a, b, c, d) = (50, 51, 52, 53);
- assert!(map.insert("abc".into_cow(), a).is_none());
- assert!(map.insert("bcd".to_string().into_cow(), b).is_none());
- assert!(map.insert("cde".into_cow(), c).is_none());
- assert!(map.insert("def".to_string().into_cow(), d).is_none());
+ assert!(map.insert(B("abc"), a).is_none());
+ assert!(map.insert(O("bcd".to_string()), b).is_none());
+ assert!(map.insert(B("cde"), c).is_none());
+ assert!(map.insert(O("def".to_string()), d).is_none());
- assert!(map.insert("abc".into_cow(), a).is_some());
- assert!(map.insert("bcd".to_string().into_cow(), b).is_some());
- assert!(map.insert("cde".into_cow(), c).is_some());
- assert!(map.insert("def".to_string().into_cow(), d).is_some());
+ assert!(map.insert(B("abc"), a).is_some());
+ assert!(map.insert(O("bcd".to_string()), b).is_some());
+ assert!(map.insert(B("cde"), c).is_some());
+ assert!(map.insert(O("def".to_string()), d).is_some());
- assert!(map.insert("abc".to_string().into_cow(), a).is_some());
- assert!(map.insert("bcd".into_cow(), b).is_some());
- assert!(map.insert("cde".to_string().into_cow(), c).is_some());
- assert!(map.insert("def".into_cow(), d).is_some());
+ assert!(map.insert(O("abc".to_string()), a).is_some());
+ assert!(map.insert(B("bcd"), b).is_some());
+ assert!(map.insert(O("cde".to_string()), c).is_some());
+ assert!(map.insert(B("def"), d).is_some());
- assert_eq!(map.get(&"abc".into_cow()), Some(&a));
- assert_eq!(map.get(&"bcd".into_cow()), Some(&b));
- assert_eq!(map.get(&"cde".into_cow()), Some(&c));
- assert_eq!(map.get(&"def".into_cow()), Some(&d));
+ assert_eq!(map.get(&B("abc")), Some(&a));
+ assert_eq!(map.get(&B("bcd")), Some(&b));
+ assert_eq!(map.get(&B("cde")), Some(&c));
+ assert_eq!(map.get(&B("def")), Some(&d));
- assert_eq!(map.get(&"abc".to_string().into_cow()), Some(&a));
- assert_eq!(map.get(&"bcd".to_string().into_cow()), Some(&b));
- assert_eq!(map.get(&"cde".to_string().into_cow()), Some(&c));
- assert_eq!(map.get(&"def".to_string().into_cow()), Some(&d));
+ assert_eq!(map.get(&O("abc".to_string())), Some(&a));
+ assert_eq!(map.get(&O("bcd".to_string())), Some(&b));
+ assert_eq!(map.get(&O("cde".to_string())), Some(&c));
+ assert_eq!(map.get(&O("def".to_string())), Some(&d));
- assert!(map.remove(&"foo".into_cow()).is_some());
+ assert!(map.remove(&B("foo")).is_some());
assert_eq!(map.into_iter().map(|(k, v)| format!("{}{}", k, v))
.collect::<Vec<String>>()
.concat(),
assert_both::<sync::Mutex<()>>();
assert_both::<sync::Condvar>();
assert_both::<sync::RwLock<()>>();
- assert_both::<sync::Semaphore>();
assert_both::<sync::Barrier>();
assert_both::<sync::Arc<()>>();
assert_both::<sync::Weak<()>>();
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(into_cow)]
-
-use std::borrow::{Cow, IntoCow};
+use std::borrow::{Cow, ToOwned};
use std::default::Default;
use std::iter::FromIterator;
use std::ops::Add;
}
impl Rand for i32 { }
+pub trait IntoCow<'a, B: ?Sized> where B: ToOwned {
+ fn into_cow(self) -> Cow<'a, B>;
+}
+
+impl<'a> IntoCow<'a, str> for String {
+ fn into_cow(self) -> Cow<'a, str> {
+ Cow::Owned(self)
+ }
+}
+
#[derive(PartialEq, Eq)]
struct Newt<T>(T);
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(vec_push_all)]
-
use std::vec;
pub fn main() {
let a: Vec<isize> = vec!(1, 2, 3, 4, 5);
let b: Vec<isize> = vec!(6, 7, 8, 9, 0);
let mut v: Vec<isize> = a;
- v.push_all(&b);
+ v.extend_from_slice(&b);
println!("{}", v[9]);
assert_eq!(v[0], 1);
assert_eq!(v[7], 8);
// ignore-emscripten no threads support
-#![feature(rand, num_bits_bytes)]
+#![feature(rand)]
#![feature(const_fn)]
use std::sync::atomic::{AtomicUsize, Ordering};
}
pub fn main() {
- assert!(MAX_LEN <= std::usize::BITS);
// len can't go above 64.
for len in 2..MAX_LEN {
for _ in 0..REPEATS {