std: Clean out deprecated APIs

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.
This commit is contained in:
Alex Crichton 2016-03-07 15:42:29 -08:00
parent 083db64d90
commit b53764c73b
79 changed files with 442 additions and 2444 deletions

View File

@ -11,7 +11,6 @@
#![crate_type = "bin"]
#![feature(box_syntax)]
#![feature(dynamic_lib)]
#![feature(libc)]
#![feature(rustc_private)]
#![feature(str_char)]

View File

@ -8,9 +8,8 @@
// 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};
@ -18,15 +17,22 @@ 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);
}

View File

@ -32,7 +32,6 @@
#![feature(alloc)]
#![feature(core_intrinsics)]
#![feature(heap_api)]
#![feature(raw)]
#![feature(heap_api)]
#![feature(staged_api)]
#![feature(dropck_parametricity)]
@ -48,326 +47,10 @@ use std::intrinsics;
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.
@ -566,9 +249,8 @@ unsafe impl<T: Send> Send for TypedArena<T> {}
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)]
@ -642,12 +324,6 @@ mod tests {
})
}
#[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,
@ -673,22 +349,6 @@ mod tests {
}
}
#[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();
@ -700,66 +360,6 @@ mod tests {
}
}
#[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> {
@ -772,40 +372,6 @@ mod tests {
}
}
#[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);
@ -845,25 +411,6 @@ mod tests {
}
}
#[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));
@ -898,17 +445,4 @@ mod tests {
});
})
}
#[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],
}
})
})
}
}

View File

@ -244,24 +244,6 @@ impl<'a, B: ?Sized> Hash for Cow<'a, B> where B: Hash + ToOwned {
}
}
/// 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> {

View File

@ -81,13 +81,13 @@ pub trait CLike {
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
}

View File

@ -491,10 +491,6 @@ pub use core::fmt::{LowerExp, UpperExp};
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};

View File

@ -38,18 +38,15 @@
#![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)]

View File

@ -1232,7 +1232,7 @@ mod tests {
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))

View File

@ -104,9 +104,6 @@ pub use core::slice::{Iter, IterMut};
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};

View File

@ -66,8 +66,7 @@ use core::str::pattern::Pattern;
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;
@ -1838,26 +1837,6 @@ impl Into<Vec<u8>> for String {
}
}
#[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]

View File

@ -63,6 +63,7 @@ use alloc::boxed::Box;
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};
@ -74,9 +75,6 @@ use core::ops;
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.'
@ -967,17 +965,6 @@ impl<T: Clone> Vec<T> {
}
}
#[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
@ -1598,22 +1585,6 @@ impl<'a, T> FromIterator<T> for Cow<'a, [T]> where T: Clone {
}
}
#[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
////////////////////////////////////////////////////////////////////////////////

View File

@ -24,7 +24,6 @@
#![feature(pattern)]
#![feature(rand)]
#![feature(set_recovery)]
#![feature(slice_bytes)]
#![feature(step_by)]
#![feature(str_char)]
#![feature(str_escape)]

View File

@ -865,18 +865,6 @@ fn test_vec_default() {
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() {

View File

@ -124,7 +124,8 @@ impl<'a, 'b: 'a> DebugStruct<'a, 'b> {
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> {
@ -132,7 +133,8 @@ pub fn debug_tuple_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>, name: &str) -> D
DebugTuple {
fmt: fmt,
result: result,
has_fields: false,
fields: 0,
empty_name: name.is_empty(),
}
}
@ -141,7 +143,7 @@ impl<'a, 'b: 'a> DebugTuple<'a, 'b> {
#[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 {
("(", "")
@ -155,20 +157,22 @@ impl<'a, 'b: 'a> DebugTuple<'a, 'b> {
}
});
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
@ -177,14 +181,6 @@ impl<'a, 'b: 'a> DebugTuple<'a, 'b> {
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> {

View File

@ -36,18 +36,6 @@ pub enum Alignment {
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};
@ -1561,16 +1549,10 @@ macro_rules! tuple {
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()
}
}

View File

@ -140,81 +140,6 @@ radix! { LowerHex, 16, "0x", x @ 0 ... 9 => b'0' + x,
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")]
@ -243,14 +168,12 @@ macro_rules! integer {
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 }
}
}

View File

@ -238,30 +238,6 @@ impl<H> Default for BuildHasherDefault<H> {
}
}
// 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 {

View File

@ -1922,19 +1922,6 @@ pub trait Iterator {
.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.
///
@ -1960,19 +1947,6 @@ pub trait Iterator {
.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.
///

View File

@ -12,25 +12,6 @@
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")]

View File

@ -41,7 +41,7 @@ use slice::SliceExt;
#[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;

View File

@ -12,21 +12,6 @@
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;

View File

@ -8,34 +8,10 @@
// 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")]
@ -331,120 +307,3 @@ mod shift_max {
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 }

View File

@ -1552,52 +1552,6 @@ pub unsafe fn from_raw_parts_mut<'a, T>(p: *mut T, len: usize) -> &'a mut [T] {
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
//

View File

@ -150,107 +150,3 @@ fn test_format_int_twos_complement() {
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)) })
}
}

View File

@ -24,8 +24,6 @@
#![feature(fixed_size_array)]
#![feature(float_extras)]
#![feature(flt2dec)]
#![feature(fmt_radix)]
#![feature(iter_arith)]
#![feature(iter_arith)]
#![feature(libc)]
#![feature(nonzero)]

View File

@ -27,7 +27,7 @@
#![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]
@ -173,7 +173,7 @@ mod tests {
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());

View File

@ -30,7 +30,6 @@
issue = "27703")]
#![feature(core_float)]
#![feature(core_intrinsics)]
#![feature(num_bits_bytes)]
#![feature(staged_api)]
#![feature(step_by)]
#![feature(custom_attribute)]

View File

@ -11,15 +11,14 @@
//! 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
@ -58,7 +57,7 @@ impl Rand for i64 {
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

View File

@ -12,46 +12,22 @@
//!
//! 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 std::env;
use std::ffi::{CString, OsString};
use std::path::{Path, PathBuf};
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)
unsafe {
dl::close(self.handle)
}
}
}
#[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
@ -116,9 +92,7 @@ impl DynamicLibrary {
// 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())
});
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.
@ -129,19 +103,18 @@ impl DynamicLibrary {
}
}
#[cfg(all(test, not(target_os = "ios"), not(target_os = "nacl")))]
#[cfg(test)]
mod tests {
use super::*;
use prelude::v1::*;
use libc;
use mem;
use std::mem;
#[test]
#[cfg_attr(any(windows,
target_os = "android", // FIXME #10379
target_env = "musl"), ignore)]
#[allow(deprecated)]
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) {
@ -166,17 +139,12 @@ mod tests {
}
#[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;
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.
@ -188,24 +156,13 @@ mod tests {
}
}
#[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"))]
#[cfg(unix)]
mod dl {
use prelude::v1::*;
use ffi::{CStr, OsStr};
use str;
use libc;
use ptr;
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(|| {
@ -221,7 +178,7 @@ mod dl {
const LAZY: libc::c_int = 1;
unsafe fn open_external(filename: &OsStr) -> *mut u8 {
let s = filename.to_cstring().unwrap();
let s = CString::new(filename.as_bytes()).unwrap();
libc::dlopen(s.as_ptr(), LAZY) as *mut u8
}
@ -232,7 +189,7 @@ mod dl {
pub fn check_for_errors_in<T, F>(f: F) -> Result<T, String> where
F: FnOnce() -> T,
{
use sync::StaticMutex;
use std::sync::StaticMutex;
static LOCK: StaticMutex = StaticMutex::new();
unsafe {
// dlerror isn't thread safe, so we need to lock around this entire
@ -255,79 +212,74 @@ mod dl {
}
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
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(target_os = "windows")]
#[cfg(windows)]
mod dl {
use prelude::v1::*;
use std::ffi::OsStr;
use std::io;
use std::os::windows::prelude::*;
use std::ptr;
use ffi::OsStr;
use libc;
use os::windows::prelude::*;
use ptr;
use sys::c;
use sys::os;
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 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);
let result = 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);
}
return Err(io::Error::last_os_error().to_string())
}
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())
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)
}
ptr_result(result)
}
None => {
let mut handle = ptr::null_mut();
let succeeded = unsafe {
c::GetModuleHandleExW(0 as c::DWORD, ptr::null(),
&mut handle)
GetModuleHandleExW(0 as DWORD, ptr::null(), &mut handle)
};
if succeeded == c::FALSE {
let errno = os::errno();
Err(os::error_string(errno))
if succeeded == 0 {
Err(io::Error::last_os_error().to_string())
} else {
Ok(handle as *mut u8)
}
@ -335,64 +287,28 @@ mod dl {
};
unsafe {
if use_thread_mode {
c::SetThreadErrorMode(prev_error_mode, ptr::null_mut());
} else {
c::SetErrorMode(prev_error_mode);
}
SetThreadErrorMode(prev_error_mode, ptr::null_mut());
}
result
}
pub fn check_for_errors_in<T, F>(f: F) -> Result<T, String> where
F: FnOnce() -> T,
{
unsafe {
c::SetLastError(0);
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)
}
let result = f();
pub unsafe fn close(handle: *mut u8) {
FreeLibrary(handle as HMODULE);
}
let error = os::errno();
if 0 == error {
Ok(result)
} else {
Err(format!("Error code {}", error))
}
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)
}
}
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) { }
}

View File

@ -31,12 +31,14 @@
#![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;
@ -53,3 +55,4 @@ pub mod sha2;
pub mod svh;
pub mod target;
pub mod slice;
pub mod dynamic_lib;

View File

@ -11,6 +11,7 @@ crate-type = ["dylib"]
[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" }

View File

@ -59,7 +59,6 @@
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)]
@ -69,6 +68,7 @@
#[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;

View File

@ -103,12 +103,11 @@ impl<'a> PluginLoader<'a> {
}
// 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);

View File

@ -20,7 +20,6 @@
#![feature(box_patterns)]
#![feature(box_syntax)]
#![feature(dynamic_lib)]
#![feature(libc)]
#![feature(recover)]
#![feature(rustc_private)]

View File

@ -12,12 +12,13 @@
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;

View File

@ -8,11 +8,8 @@
// 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::*;
@ -32,6 +29,7 @@ use rustc::session::{self, config};
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;

View File

@ -592,15 +592,6 @@ impl<K, V, S> HashMap<K, V, S>
}
}
/// 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.
///
@ -634,17 +625,6 @@ impl<K, V, S> HashMap<K, V, S>
}
}
/// 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")]

View File

@ -14,7 +14,6 @@ mod bench;
mod table;
pub mod map;
pub mod set;
pub mod state;
trait Recover<Q: ?Sized> {
type Key;

View File

@ -200,26 +200,6 @@ impl<T, S> HashSet<T, S>
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

View File

@ -1,40 +0,0 @@
// 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) }
}

View File

@ -442,13 +442,3 @@ pub mod hash_set {
#[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::*;
}

View File

@ -9,7 +9,6 @@
// except according to those terms.
use borrow::{Borrow, Cow, ToOwned};
use ffi::CString;
use fmt::{self, Debug};
use mem;
use string::String;
@ -56,22 +55,6 @@ impl OsString {
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;
@ -294,41 +277,6 @@ impl OsStr {
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")]

View File

@ -85,19 +85,6 @@ pub struct ReadDir(fs_imp::ReadDir);
#[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
@ -1345,7 +1332,7 @@ pub fn remove_dir_all<P: AsRef<Path>>(path: P) -> io::Result<()> {
/// 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)) {
@ -1365,64 +1352,6 @@ pub fn read_dir<P: AsRef<Path>>(path: P) -> io::Result<ReadDir> {
fs_imp::readdir(path.as_ref()).map(ReadDir)
}
/// Returns an iterator that will recursively walk the directory structure
/// rooted at `path`.
///
/// The path given will not be iterated over, and this will perform iteration in
/// some top-down order. The contents of unreadable subdirectories are ignored.
///
/// The iterator will yield instances of `io::Result<DirEntry>`. New errors may
/// be encountered after an iterator is initially constructed.
#[unstable(feature = "fs_walk",
reason = "the precise semantics and defaults for a recursive walk \
may change and this may end up accounting for files such \
as symlinks differently",
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
@ -1865,35 +1794,6 @@ mod tests {
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();

View File

@ -150,12 +150,6 @@ pub enum ErrorKind {
#[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.
///
@ -311,7 +305,6 @@ impl fmt::Display for Error {
#[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() {
@ -332,7 +325,6 @@ impl error::Error for Error {
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!()
},

View File

@ -811,49 +811,6 @@ pub trait Read {
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.
@ -1089,47 +1046,6 @@ pub trait Write {
/// ```
#[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
@ -1500,41 +1416,6 @@ pub trait BufRead: Read {
}
}
/// 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.
@ -1616,37 +1497,6 @@ impl<T: BufRead> BufRead for Take<T> {
}
}
/// 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.

View File

@ -197,31 +197,4 @@ mod tests {
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]);
}
}

View File

@ -418,7 +418,6 @@ pub mod num;
pub mod thread;
pub mod collections;
pub mod dynamic_lib;
pub mod env;
pub mod ffi;
pub mod fs;

View File

@ -128,33 +128,3 @@ impl Iterator for LookupHost {
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)
}

View File

@ -21,7 +21,7 @@ pub use core::num::{Zero, One};
#[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;

View File

@ -100,8 +100,7 @@
#![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;
@ -781,14 +780,6 @@ impl<'a> Components<'a> {
}
}
}
/// 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")]
@ -1218,22 +1209,6 @@ impl Borrow<Path> for PathBuf {
}
}
#[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]
@ -1474,17 +1449,7 @@ impl Path {
!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
}
@ -1566,17 +1531,6 @@ impl Path {
})
}
/// 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
@ -2236,27 +2190,6 @@ mod tests {
);
);
#[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;

View File

@ -167,13 +167,12 @@ impl Condvar {
/// 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
@ -200,30 +199,6 @@ impl Condvar {
}
}
/// 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
@ -286,26 +261,6 @@ impl StaticCondvar {
}
}
/// 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.
///

View File

@ -38,9 +38,6 @@ pub use sys_common::poison::{PoisonError, TryLockError, TryLockResult, LockResul
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;
@ -49,4 +46,3 @@ mod condvar;
mod mutex;
mod once;
mod rwlock;
mod semaphore;

View File

@ -1,226 +0,0 @@
// 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
}
}

View File

@ -11,15 +11,13 @@
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};
@ -154,34 +152,6 @@ pub fn lookup_host(host: &str) -> io::Result<LookupHost> {
}
}
////////////////////////////////////////////////////////////////////////////////
// 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
////////////////////////////////////////////////////////////////////////////////

View File

@ -15,90 +15,11 @@
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 {

View File

@ -26,22 +26,22 @@
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"]
@ -52,16 +52,16 @@ mod printing;
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,
@ -93,7 +93,9 @@ struct Cleanup {
}
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<()> {
@ -102,52 +104,50 @@ 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(()),
};
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);
// 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);
// 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 };
// 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 }
// 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;
i += 1;
if i >= 0 {
try!(printing::print(w, i, addr-1, &dbghelp, process));
if i >= 0 {
try!(printing::print(w, i, addr - 1, process, &dbghelp));
}
}
}
Ok(())
Ok(())
}
}

View File

@ -154,8 +154,6 @@ pub const WSAESHUTDOWN: c_int = 10058;
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;
@ -1099,18 +1097,11 @@ extern "system" {
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,
@ -1177,10 +1168,6 @@ compat_fn! {
_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
}

View File

@ -0,0 +1,55 @@
// 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);
}
}
}

View File

@ -24,6 +24,7 @@ use time::Duration;
pub mod backtrace;
pub mod c;
pub mod condvar;
pub mod dynamic_lib;
pub mod ext;
pub mod fs;
pub mod handle;

View File

@ -8,18 +8,19 @@
// 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)
}

View File

@ -8,60 +8,66 @@
// 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(())
}
}
}

View File

@ -339,40 +339,6 @@ pub fn panicking() -> bool {
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

View File

@ -9,7 +9,6 @@
// 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;
@ -59,21 +58,6 @@ impl Duration {
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 {

View File

@ -8,13 +8,15 @@
// 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(); }

View File

@ -8,7 +8,17 @@
// 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());

View File

@ -8,9 +8,11 @@
// 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() {

View File

@ -1,22 +0,0 @@
// 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);
}

View File

@ -15,7 +15,6 @@
// ignore-emscripten
// no-prefer-dynamic
#![feature(convert)]
#![feature(libc)]
extern crate libc;
@ -23,7 +22,8 @@ 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() {
@ -34,8 +34,11 @@ 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()];

View File

@ -10,15 +10,14 @@
// 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] };
}

View File

@ -10,7 +10,7 @@
// pretty-expanded FIXME #23616
#![feature(fs, net, fs_walk)]
#![feature(fs, net)]
use std::{fs, net};
@ -22,7 +22,6 @@ fn main() {
assert_both::<fs::Metadata>();
assert_both::<fs::ReadDir>();
assert_both::<fs::DirEntry>();
assert_send::<fs::WalkDir>();
assert_both::<fs::OpenOptions>();
assert_both::<fs::Permissions>();

View File

@ -8,8 +8,6 @@
// 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};
@ -43,13 +41,13 @@ fn main() {
// `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);

View File

@ -12,7 +12,7 @@
//
// Test std::num::Wrapping<T> for {uN, iN, usize, isize}
#![feature(num_bits_bytes, test)]
#![feature(test)]
extern crate test;
@ -22,9 +22,40 @@ use std::ops::{
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();

View File

@ -8,57 +8,55 @@
// 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));
}

View File

@ -8,61 +8,58 @@
// 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(),

View File

@ -24,7 +24,6 @@ fn main() {
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<()>>();

View File

@ -8,9 +8,7 @@
// 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;
@ -25,6 +23,16 @@ pub trait Rand: Default + Sized {
}
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);

View File

@ -8,15 +8,13 @@
// 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);

View File

@ -10,7 +10,7 @@
// ignore-emscripten no threads support
#![feature(rand, num_bits_bytes)]
#![feature(rand)]
#![feature(const_fn)]
use std::sync::atomic::{AtomicUsize, Ordering};
@ -47,7 +47,6 @@ impl Drop for DropCounter {
}
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 {