Auto merge of #32804 - alexcrichton:stabilize-1.9, r=brson

std: Stabilize APIs for the 1.9 release

This commit applies all stabilizations, renamings, and deprecations that the
library team has decided on for the upcoming 1.9 release. All tracking issues
have gone through a cycle-long "final comment period" and the specific APIs
stabilized/deprecated are:

Stable

* `std::panic`
* `std::panic::catch_unwind` (renamed from `recover`)
* `std::panic::resume_unwind` (renamed from `propagate`)
* `std::panic::AssertUnwindSafe` (renamed from `AssertRecoverSafe`)
* `std::panic::UnwindSafe` (renamed from `RecoverSafe`)
* `str::is_char_boundary`
* `<*const T>::as_ref`
* `<*mut T>::as_ref`
* `<*mut T>::as_mut`
* `AsciiExt::make_ascii_uppercase`
* `AsciiExt::make_ascii_lowercase`
* `char::decode_utf16`
* `char::DecodeUtf16`
* `char::DecodeUtf16Error`
* `char::DecodeUtf16Error::unpaired_surrogate`
* `BTreeSet::take`
* `BTreeSet::replace`
* `BTreeSet::get`
* `HashSet::take`
* `HashSet::replace`
* `HashSet::get`
* `OsString::with_capacity`
* `OsString::clear`
* `OsString::capacity`
* `OsString::reserve`
* `OsString::reserve_exact`
* `OsStr::is_empty`
* `OsStr::len`
* `std::os::unix::thread`
* `RawPthread`
* `JoinHandleExt`
* `JoinHandleExt::as_pthread_t`
* `JoinHandleExt::into_pthread_t`
* `HashSet::hasher`
* `HashMap::hasher`
* `CommandExt::exec`
* `File::try_clone`
* `SocketAddr::set_ip`
* `SocketAddr::set_port`
* `SocketAddrV4::set_ip`
* `SocketAddrV4::set_port`
* `SocketAddrV6::set_ip`
* `SocketAddrV6::set_port`
* `SocketAddrV6::set_flowinfo`
* `SocketAddrV6::set_scope_id`
* `<[T]>::copy_from_slice`
* `ptr::read_volatile`
* `ptr::write_volatile`
* The `#[deprecated]` attribute
* `OpenOptions::create_new`

Deprecated

* `std::raw::Slice` - use raw parts of `slice` module instead
* `std::raw::Repr` - use raw parts of `slice` module instead
* `str::char_range_at` - use slicing plus `chars()` plus `len_utf8`
* `str::char_range_at_reverse` - use slicing plus `chars().rev()` plus `len_utf8`
* `str::char_at` - use slicing plus `chars()`
* `str::char_at_reverse` - use slicing plus `chars().rev()`
* `str::slice_shift_char` - use `chars()` plus `Chars::as_str`
* `CommandExt::session_leader` - use `before_exec` instead.

Closes #27719
cc #27751 (deprecating the `Slice` bits)
Closes #27754
Closes #27780
Closes #27809
Closes #27811
Closes #27830
Closes #28050
Closes #29453
Closes #29791
Closes #29935
Closes #30014
Closes #30752
Closes #31262
cc #31398 (still need to deal with `before_exec`)
Closes #31405
Closes #31572
Closes #31755
Closes #31756
This commit is contained in:
bors 2016-04-12 04:17:36 -07:00
commit bed32d83fc
58 changed files with 507 additions and 327 deletions

View File

@ -13,7 +13,6 @@
#![feature(box_syntax)]
#![feature(libc)]
#![feature(rustc_private)]
#![feature(str_char)]
#![feature(test)]
#![feature(question_mark)]
@ -412,16 +411,26 @@ fn extract_gdb_version(full_version_line: Option<String>) -> Option<String> {
// used to be a regex "(^|[^0-9])([0-9]\.[0-9]+)"
for (pos, c) in full_version_line.char_indices() {
if !c.is_digit(10) { continue }
if pos + 2 >= full_version_line.len() { continue }
if full_version_line.char_at(pos + 1) != '.' { continue }
if !full_version_line.char_at(pos + 2).is_digit(10) { continue }
if pos > 0 && full_version_line.char_at_reverse(pos).is_digit(10) {
if !c.is_digit(10) {
continue
}
if pos + 2 >= full_version_line.len() {
continue
}
if full_version_line[pos + 1..].chars().next().unwrap() != '.' {
continue
}
if !full_version_line[pos + 2..].chars().next().unwrap().is_digit(10) {
continue
}
if pos > 0 && full_version_line[..pos].chars().next_back()
.unwrap().is_digit(10) {
continue
}
let mut end = pos + 3;
while end < full_version_line.len() &&
full_version_line.char_at(end).is_digit(10) {
full_version_line[end..].chars().next()
.unwrap().is_digit(10) {
end += 1;
}
return Some(full_version_line[pos..end].to_owned());
@ -453,13 +462,13 @@ fn extract_lldb_version(full_version_line: Option<String>) -> Option<String> {
for (pos, l) in full_version_line.char_indices() {
if l != 'l' && l != 'L' { continue }
if pos + 5 >= full_version_line.len() { continue }
let l = full_version_line.char_at(pos + 1);
let l = full_version_line[pos + 1..].chars().next().unwrap();
if l != 'l' && l != 'L' { continue }
let d = full_version_line.char_at(pos + 2);
let d = full_version_line[pos + 2..].chars().next().unwrap();
if d != 'd' && d != 'D' { continue }
let b = full_version_line.char_at(pos + 3);
let b = full_version_line[pos + 3..].chars().next().unwrap();
if b != 'b' && b != 'B' { continue }
let dash = full_version_line.char_at(pos + 4);
let dash = full_version_line[pos + 4..].chars().next().unwrap();
if dash != '-' { continue }
let vers = full_version_line[pos + 5..].chars().take_while(|c| {

View File

@ -115,7 +115,7 @@ fn parse_expected(last_nonfollow_error: Option<usize>,
tag: &str)
-> Option<(WhichLine, ExpectedError)> {
let start = match line.find(tag) { Some(i) => i, None => return None };
let (follow, adjusts) = if line.char_at(start + tag.len()) == '|' {
let (follow, adjusts) = if line[start + tag.len()..].chars().next().unwrap() == '|' {
(true, 0)
} else {
(false, line[start + tag.len()..].chars().take_while(|c| *c == '^').count())

View File

@ -1177,7 +1177,7 @@ fn scan_char(haystack: &str, needle: char, idx: &mut usize) -> bool {
if *idx >= haystack.len() {
return false;
}
let ch = haystack.char_at(*idx);
let ch = haystack[*idx..].chars().next().unwrap();
if ch != needle {
return false;
}
@ -1188,7 +1188,7 @@ fn scan_char(haystack: &str, needle: char, idx: &mut usize) -> bool {
fn scan_integer(haystack: &str, idx: &mut usize) -> bool {
let mut i = *idx;
while i < haystack.len() {
let ch = haystack.char_at(i);
let ch = haystack[i..].chars().next().unwrap();
if ch < '0' || '9' < ch {
break;
}
@ -1208,7 +1208,7 @@ fn scan_string(haystack: &str, needle: &str, idx: &mut usize) -> bool {
if haystack_i >= haystack.len() {
return false;
}
let ch = haystack.char_at(haystack_i);
let ch = haystack[haystack_i..].chars().next().unwrap();
haystack_i += ch.len_utf8();
if !scan_char(needle, ch, &mut needle_i) {
return false;

View File

@ -379,7 +379,7 @@ impl<T: Ord> BTreeSet<T> {
/// The value may be any borrowed form of the set's value type,
/// but the ordering on the borrowed form *must* match the
/// ordering on the value type.
#[unstable(feature = "set_recovery", issue = "28050")]
#[stable(feature = "set_recovery", since = "1.9.0")]
pub fn get<Q: ?Sized>(&self, value: &Q) -> Option<&T>
where T: Borrow<Q>,
Q: Ord
@ -502,7 +502,7 @@ impl<T: Ord> BTreeSet<T> {
/// Adds a value to the set, replacing the existing value, if any, that is equal to the given
/// one. Returns the replaced value.
#[unstable(feature = "set_recovery", issue = "28050")]
#[stable(feature = "set_recovery", since = "1.9.0")]
pub fn replace(&mut self, value: T) -> Option<T> {
Recover::replace(&mut self.map, value)
}
@ -538,7 +538,7 @@ impl<T: Ord> BTreeSet<T> {
/// The value may be any borrowed form of the set's value type,
/// but the ordering on the borrowed form *must* match the
/// ordering on the value type.
#[unstable(feature = "set_recovery", issue = "28050")]
#[stable(feature = "set_recovery", since = "1.9.0")]
pub fn take<Q: ?Sized>(&mut self, value: &Q) -> Option<T>
where T: Borrow<Q>,
Q: Ord

View File

@ -27,7 +27,6 @@
test(no_crate_inject, attr(allow(unused_variables), deny(warnings))))]
#![cfg_attr(test, allow(deprecated))] // rand
#![cfg_attr(not(test), feature(copy_from_slice))] // impl [T]
#![cfg_attr(not(stage0), deny(warnings))]
#![feature(alloc)]
@ -35,7 +34,6 @@
#![feature(box_patterns)]
#![feature(box_syntax)]
#![feature(core_intrinsics)]
#![feature(decode_utf16)]
#![feature(dropck_parametricity)]
#![feature(fmt_internals)]
#![feature(heap_api)]

View File

@ -845,14 +845,13 @@ impl<T> [T] {
/// # Example
///
/// ```rust
/// #![feature(copy_from_slice)]
/// let mut dst = [0, 0, 0];
/// let src = [1, 2, 3];
///
/// dst.copy_from_slice(&src);
/// assert_eq!(src, dst);
/// ```
#[unstable(feature = "copy_from_slice", issue = "31755")]
#[stable(feature = "copy_from_slice", since = "1.9.0")]
pub fn copy_from_slice(&mut self, src: &[T]) where T: Copy {
core_slice::SliceExt::copy_from_slice(self, src)
}

View File

@ -228,8 +228,6 @@ impl str {
/// # Examples
///
/// ```
/// #![feature(str_char)]
///
/// let s = "Löwe 老虎 Léopard";
/// assert!(s.is_char_boundary(0));
/// // start of `老`
@ -242,12 +240,7 @@ impl str {
/// // third byte of `老`
/// assert!(!s.is_char_boundary(8));
/// ```
#[unstable(feature = "str_char",
reason = "it is unclear whether this method pulls its weight \
with the existence of the char_indices iterator or \
this method may want to be replaced with checked \
slicing",
issue = "27754")]
#[stable(feature = "is_char_boundary", since = "1.9.0")]
#[inline]
pub fn is_char_boundary(&self, index: usize) -> bool {
core_str::StrExt::is_char_boundary(self, index)
@ -374,6 +367,7 @@ impl str {
///
/// ```
/// #![feature(str_char)]
/// #![allow(deprecated)]
///
/// use std::str::CharRange;
///
@ -408,6 +402,9 @@ impl str {
removed altogether",
issue = "27754")]
#[inline]
#[rustc_deprecated(reason = "use slicing plus chars() plus len_utf8",
since = "1.9.0")]
#[allow(deprecated)]
pub fn char_range_at(&self, start: usize) -> CharRange {
core_str::StrExt::char_range_at(self, start)
}
@ -432,6 +429,7 @@ impl str {
///
/// ```
/// #![feature(str_char)]
/// #![allow(deprecated)]
///
/// use std::str::CharRange;
///
@ -466,6 +464,9 @@ impl str {
eventually removed altogether",
issue = "27754")]
#[inline]
#[rustc_deprecated(reason = "use slicing plus chars().rev() plus len_utf8",
since = "1.9.0")]
#[allow(deprecated)]
pub fn char_range_at_reverse(&self, start: usize) -> CharRange {
core_str::StrExt::char_range_at_reverse(self, start)
}
@ -481,6 +482,7 @@ impl str {
///
/// ```
/// #![feature(str_char)]
/// #![allow(deprecated)]
///
/// let s = "abπc";
/// assert_eq!(s.char_at(1), 'b');
@ -495,6 +497,9 @@ impl str {
subslice",
issue = "27754")]
#[inline]
#[allow(deprecated)]
#[rustc_deprecated(reason = "use slicing plus chars()",
since = "1.9.0")]
pub fn char_at(&self, i: usize) -> char {
core_str::StrExt::char_at(self, i)
}
@ -511,6 +516,7 @@ impl str {
///
/// ```
/// #![feature(str_char)]
/// #![allow(deprecated)]
///
/// let s = "abπc";
/// assert_eq!(s.char_at_reverse(1), 'a');
@ -523,6 +529,9 @@ impl str {
cases generate panics",
issue = "27754")]
#[inline]
#[rustc_deprecated(reason = "use slicing plus chars().rev()",
since = "1.9.0")]
#[allow(deprecated)]
pub fn char_at_reverse(&self, i: usize) -> char {
core_str::StrExt::char_at_reverse(self, i)
}
@ -541,6 +550,7 @@ impl str {
///
/// ```
/// #![feature(str_char)]
/// #![allow(deprecated)]
///
/// let s = "Łódź"; // \u{141}o\u{301}dz\u{301}
/// let (c, s1) = s.slice_shift_char().unwrap();
@ -559,6 +569,9 @@ impl str {
and/or char_indices iterators",
issue = "27754")]
#[inline]
#[rustc_deprecated(reason = "use chars() plus Chars::as_str",
since = "1.9.0")]
#[allow(deprecated)]
pub fn slice_shift_char(&self) -> Option<(char, &str)> {
core_str::StrExt::slice_shift_char(self)
}

View File

@ -1037,14 +1037,13 @@ impl String {
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn pop(&mut self) -> Option<char> {
let len = self.len();
if len == 0 {
return None;
}
let ch = self.char_at_reverse(len);
let ch = match self.chars().rev().next() {
Some(ch) => ch,
None => return None,
};
let newlen = self.len() - ch.len_utf8();
unsafe {
self.vec.set_len(len - ch.len_utf8());
self.vec.set_len(newlen);
}
Some(ch)
}
@ -1075,11 +1074,13 @@ impl String {
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn remove(&mut self, idx: usize) -> char {
let len = self.len();
assert!(idx < len);
let ch = match self[idx..].chars().next() {
Some(ch) => ch,
None => panic!("cannot remove a char from the end of a string"),
};
let ch = self.char_at(idx);
let next = idx + ch.len_utf8();
let len = self.len();
unsafe {
ptr::copy(self.vec.as_ptr().offset(next as isize),
self.vec.as_mut_ptr().offset(idx as isize),

View File

@ -10,13 +10,11 @@
#![deny(warnings)]
#![feature(ascii)]
#![feature(binary_heap_extras)]
#![feature(box_syntax)]
#![feature(btree_range)]
#![feature(collections)]
#![feature(collections_bound)]
#![feature(copy_from_slice)]
#![feature(const_fn)]
#![feature(fn_traits)]
#![feature(enumset)]
@ -25,7 +23,6 @@
#![feature(map_values_mut)]
#![feature(pattern)]
#![feature(rand)]
#![feature(set_recovery)]
#![feature(step_by)]
#![feature(str_char)]
#![feature(str_escape)]

View File

@ -464,12 +464,14 @@ fn test_is_whitespace() {
}
#[test]
#[allow(deprecated)]
fn test_slice_shift_char() {
let data = "ประเทศไทย中";
assert_eq!(data.slice_shift_char(), Some(('ป', "ระเทศไทย中")));
}
#[test]
#[allow(deprecated)]
fn test_slice_shift_char_2() {
let empty = "";
assert_eq!(empty.slice_shift_char(), None);
@ -657,6 +659,7 @@ fn test_contains_char() {
}
#[test]
#[allow(deprecated)]
fn test_char_at() {
let s = "ศไทย中华Việt Nam";
let v = vec!['ศ','ไ','ท','ย','中','华','V','i','ệ','t',' ','N','a','m'];
@ -668,6 +671,7 @@ fn test_char_at() {
}
#[test]
#[allow(deprecated)]
fn test_char_at_reverse() {
let s = "ศไทย中华Việt Nam";
let v = vec!['ศ','ไ','ท','ย','中','华','V','i','ệ','t',' ','N','a','m'];
@ -745,6 +749,7 @@ fn test_total_ord() {
}
#[test]
#[allow(deprecated)]
fn test_char_range_at() {
let data = "b¢€𤭢𤭢€¢b";
assert_eq!('b', data.char_range_at(0).ch);
@ -758,6 +763,7 @@ fn test_char_range_at() {
}
#[test]
#[allow(deprecated)]
fn test_char_range_at_reverse_underflow() {
assert_eq!("abc".char_range_at_reverse(0).next, 0);
}

View File

@ -166,9 +166,16 @@ pub unsafe fn write<T>(dst: *mut T, src: T) {
///
/// Volatile operations are intended to act on I/O memory, and are guaranteed
/// to not be elided or reordered by the compiler across other volatile
/// operations. See the LLVM documentation on [[volatile]].
/// operations.
///
/// [volatile]: http://llvm.org/docs/LangRef.html#volatile-memory-accesses
/// # Notes
///
/// Rust does not currently have a rigorously and formally defined memory model,
/// so the precise semantics of what "volatile" means here is subject to change
/// over time. That being said, the semantics will almost always end up pretty
/// similar to [C11's definition of volatile][c11].
///
/// [c11]: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf
///
/// # Safety
///
@ -179,7 +186,7 @@ pub unsafe fn write<T>(dst: *mut T, src: T) {
/// `zero_memory`, or `copy_memory`). Note that `*src = foo` counts as a use
/// because it will attempt to drop the value previously at `*src`.
#[inline]
#[unstable(feature = "volatile", reason = "recently added", issue = "31756")]
#[stable(feature = "volatile", since = "1.9.0")]
pub unsafe fn read_volatile<T>(src: *const T) -> T {
intrinsics::volatile_load(src)
}
@ -189,9 +196,16 @@ pub unsafe fn read_volatile<T>(src: *const T) -> T {
///
/// Volatile operations are intended to act on I/O memory, and are guaranteed
/// to not be elided or reordered by the compiler across other volatile
/// operations. See the LLVM documentation on [[volatile]].
/// operations.
///
/// [volatile]: http://llvm.org/docs/LangRef.html#volatile-memory-accesses
/// # Notes
///
/// Rust does not currently have a rigorously and formally defined memory model,
/// so the precise semantics of what "volatile" means here is subject to change
/// over time. That being said, the semantics will almost always end up pretty
/// similar to [C11's definition of volatile][c11].
///
/// [c11]: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf
///
/// # Safety
///
@ -204,7 +218,7 @@ pub unsafe fn read_volatile<T>(src: *const T) -> T {
/// This is appropriate for initializing uninitialized memory, or overwriting
/// memory that has previously been `read` from.
#[inline]
#[unstable(feature = "volatile", reason = "recently added", issue = "31756")]
#[stable(feature = "volatile", since = "1.9.0")]
pub unsafe fn write_volatile<T>(dst: *mut T, src: T) {
intrinsics::volatile_store(dst, src);
}
@ -238,6 +252,9 @@ impl<T: ?Sized> *const T {
/// operation because the returned value could be pointing to invalid
/// memory.
///
/// Additionally, the lifetime `'a` returned is arbitrarily chosen and does
/// not necessarily reflect the actual lifetime of the data.
///
/// # Examples
///
/// Basic usage:
@ -251,17 +268,13 @@ impl<T: ?Sized> *const T {
/// }
/// }
/// ```
#[unstable(feature = "ptr_as_ref",
reason = "Option is not clearly the right return type, and we \
may want to tie the return lifetime to a borrow of \
the raw pointer",
issue = "27780")]
#[stable(feature = "ptr_as_ref", since = "1.9.0")]
#[inline]
pub unsafe fn as_ref<'a>(&self) -> Option<&'a T> where T: Sized {
pub unsafe fn as_ref<'a>(self) -> Option<&'a T> where T: Sized {
if self.is_null() {
None
} else {
Some(&**self)
Some(&*self)
}
}
@ -324,6 +337,9 @@ impl<T: ?Sized> *mut T {
/// operation because the returned value could be pointing to invalid
/// memory.
///
/// Additionally, the lifetime `'a` returned is arbitrarily chosen and does
/// not necessarily reflect the actual lifetime of the data.
///
/// # Examples
///
/// Basic usage:
@ -337,17 +353,13 @@ impl<T: ?Sized> *mut T {
/// }
/// }
/// ```
#[unstable(feature = "ptr_as_ref",
reason = "Option is not clearly the right return type, and we \
may want to tie the return lifetime to a borrow of \
the raw pointer",
issue = "27780")]
#[stable(feature = "ptr_as_ref", since = "1.9.0")]
#[inline]
pub unsafe fn as_ref<'a>(&self) -> Option<&'a T> where T: Sized {
pub unsafe fn as_ref<'a>(self) -> Option<&'a T> where T: Sized {
if self.is_null() {
None
} else {
Some(&**self)
Some(&*self)
}
}
@ -385,7 +397,8 @@ impl<T: ?Sized> *mut T {
/// # Safety
///
/// As with `as_ref`, this is unsafe because it cannot verify the validity
/// of the returned pointer.
/// of the returned pointer, nor can it ensure that the lifetime `'a`
/// returned is indeed a valid lifetime for the contained data.
///
/// # Examples
///
@ -395,16 +408,13 @@ impl<T: ?Sized> *mut T {
/// let mut s = [1, 2, 3];
/// let ptr: *mut u32 = s.as_mut_ptr();
/// ```
#[unstable(feature = "ptr_as_ref",
reason = "return value does not necessarily convey all possible \
information",
issue = "27780")]
#[stable(feature = "ptr_as_ref", since = "1.9.0")]
#[inline]
pub unsafe fn as_mut<'a>(&self) -> Option<&'a mut T> where T: Sized {
pub unsafe fn as_mut<'a>(self) -> Option<&'a mut T> where T: Sized {
if self.is_null() {
None
} else {
Some(&mut **self)
Some(&mut *self)
}
}
}

View File

@ -60,12 +60,17 @@ use mem;
/// ```
#[repr(C)]
#[allow(missing_debug_implementations)]
#[rustc_deprecated(reason = "use raw accessors/constructors in `slice` module",
since = "1.9.0")]
#[unstable(feature = "raw", issue = "27751")]
pub struct Slice<T> {
pub data: *const T,
pub len: usize,
}
#[allow(deprecated)]
impl<T> Copy for Slice<T> {}
#[allow(deprecated)]
impl<T> Clone for Slice<T> {
fn clone(&self) -> Slice<T> { *self }
}
@ -152,6 +157,9 @@ pub struct TraitObject {
/// This trait is meant to map equivalences between raw structs and their
/// corresponding rust values.
#[rustc_deprecated(reason = "use raw accessors/constructors in `slice` module",
since = "1.9.0")]
#[unstable(feature = "raw", issue = "27751")]
pub unsafe trait Repr<T> {
/// This function "unwraps" a rust value (without consuming it) into its raw
/// struct representation. This can be used to read/write different values
@ -161,5 +169,7 @@ pub unsafe trait Repr<T> {
fn repr(&self) -> T { unsafe { mem::transmute_copy(&self) } }
}
#[allow(deprecated)]
unsafe impl<T> Repr<Slice<T>> for [T] {}
#[allow(deprecated)]
unsafe impl Repr<Slice<u8>> for str {}

View File

@ -50,10 +50,12 @@ use result::Result::{Ok, Err};
use ptr;
use mem;
use marker::{Copy, Send, Sync, self};
use raw::Repr;
// Avoid conflicts with *both* the Slice trait (buggy) and the `slice::raw` module.
use raw::Slice as RawSlice;
#[repr(C)]
struct Repr<T> {
pub data: *const T,
pub len: usize,
}
//
// Extension traits
@ -152,8 +154,8 @@ pub trait SliceExt {
fn ends_with(&self, needle: &[Self::Item]) -> bool where Self::Item: PartialEq;
#[stable(feature = "clone_from_slice", since = "1.7.0")]
fn clone_from_slice(&mut self, &[Self::Item]) where Self::Item: Clone;
#[unstable(feature = "copy_from_slice", issue = "31755")]
fn clone_from_slice(&mut self, src: &[Self::Item]) where Self::Item: Clone;
#[stable(feature = "copy_from_slice", since = "1.9.0")]
fn copy_from_slice(&mut self, src: &[Self::Item]) where Self::Item: Copy;
}
@ -317,7 +319,11 @@ impl<T> SliceExt for [T] {
}
#[inline]
fn len(&self) -> usize { self.repr().len }
fn len(&self) -> usize {
unsafe {
mem::transmute::<&[T], Repr<T>>(self).len
}
}
#[inline]
fn get_mut(&mut self, index: usize) -> Option<&mut T> {
@ -1695,7 +1701,7 @@ impl<'a, T> ExactSizeIterator for ChunksMut<'a, T> {}
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub unsafe fn from_raw_parts<'a, T>(p: *const T, len: usize) -> &'a [T] {
mem::transmute(RawSlice { data: p, len: len })
mem::transmute(Repr { data: p, len: len })
}
/// Performs the same functionality as `from_raw_parts`, except that a mutable
@ -1707,7 +1713,7 @@ pub unsafe fn from_raw_parts<'a, T>(p: *const T, len: usize) -> &'a [T] {
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub unsafe fn from_raw_parts_mut<'a, T>(p: *mut T, len: usize) -> &'a mut [T] {
mem::transmute(RawSlice { data: p, len: len })
mem::transmute(Repr { data: p, len: len })
}
//

View File

@ -29,7 +29,6 @@ use marker::Sized;
use mem;
use ops::{Fn, FnMut, FnOnce};
use option::Option::{self, None, Some};
use raw::{Repr, Slice};
use result::Result::{self, Ok, Err};
use slice::{self, SliceExt};
@ -1664,24 +1663,23 @@ pub trait StrExt {
#[stable(feature = "core", since = "1.6.0")]
fn trim_right_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str
where P::Searcher: ReverseSearcher<'a>;
#[unstable(feature = "str_char",
reason = "it is unclear whether this method pulls its weight \
with the existence of the char_indices iterator or \
this method may want to be replaced with checked \
slicing",
issue = "27754")]
#[stable(feature = "is_char_boundary", since = "1.9.0")]
fn is_char_boundary(&self, index: usize) -> bool;
#[unstable(feature = "str_char",
reason = "often replaced by char_indices, this method may \
be removed in favor of just char_at() or eventually \
removed altogether",
issue = "27754")]
#[rustc_deprecated(reason = "use slicing plus chars() plus len_utf8",
since = "1.9.0")]
fn char_range_at(&self, start: usize) -> CharRange;
#[unstable(feature = "str_char",
reason = "often replaced by char_indices, this method may \
be removed in favor of just char_at_reverse() or \
eventually removed altogether",
issue = "27754")]
#[rustc_deprecated(reason = "use slicing plus chars().rev() plus len_utf8",
since = "1.9.0")]
fn char_range_at_reverse(&self, start: usize) -> CharRange;
#[unstable(feature = "str_char",
reason = "frequently replaced by the chars() iterator, this \
@ -1690,12 +1688,16 @@ pub trait StrExt {
iterators or by getting the first char from a \
subslice",
issue = "27754")]
#[rustc_deprecated(reason = "use slicing plus chars()",
since = "1.9.0")]
fn char_at(&self, i: usize) -> char;
#[unstable(feature = "str_char",
reason = "see char_at for more details, but reverse semantics \
are also somewhat unclear, especially with which \
cases generate panics",
issue = "27754")]
#[rustc_deprecated(reason = "use slicing plus chars().rev()",
since = "1.9.0")]
fn char_at_reverse(&self, i: usize) -> char;
#[stable(feature = "core", since = "1.6.0")]
fn as_bytes(&self) -> &[u8];
@ -1714,6 +1716,8 @@ pub trait StrExt {
may not be warranted with the existence of the chars \
and/or char_indices iterators",
issue = "27754")]
#[rustc_deprecated(reason = "use chars() plus Chars::as_str",
since = "1.9.0")]
fn slice_shift_char(&self) -> Option<(char, &str)>;
#[stable(feature = "core", since = "1.6.0")]
fn as_ptr(&self) -> *const u8;
@ -1857,18 +1861,16 @@ impl StrExt for str {
#[inline]
unsafe fn slice_unchecked(&self, begin: usize, end: usize) -> &str {
mem::transmute(Slice {
data: self.as_ptr().offset(begin as isize),
len: end - begin,
})
let ptr = self.as_ptr().offset(begin as isize);
let len = end - begin;
from_utf8_unchecked(slice::from_raw_parts(ptr, len))
}
#[inline]
unsafe fn slice_mut_unchecked(&mut self, begin: usize, end: usize) -> &mut str {
mem::transmute(Slice {
data: self.as_ptr().offset(begin as isize),
len: end - begin,
})
let ptr = self.as_ptr().offset(begin as isize);
let len = end - begin;
mem::transmute(slice::from_raw_parts_mut(ptr as *mut u8, len))
}
#[inline]
@ -1983,11 +1985,13 @@ impl StrExt for str {
}
#[inline]
#[allow(deprecated)]
fn char_at(&self, i: usize) -> char {
self.char_range_at(i).ch
}
#[inline]
#[allow(deprecated)]
fn char_at_reverse(&self, i: usize) -> char {
self.char_range_at_reverse(i).ch
}
@ -2039,6 +2043,7 @@ impl StrExt for str {
}
#[inline]
#[allow(deprecated)]
fn slice_shift_char(&self) -> Option<(char, &str)> {
if self.is_empty() {
None
@ -2055,7 +2060,9 @@ impl StrExt for str {
}
#[inline]
fn len(&self) -> usize { self.repr().len }
fn len(&self) -> usize {
self.as_bytes().len()
}
#[inline]
fn is_empty(&self) -> bool { self.len() == 0 }

View File

@ -8,6 +8,8 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use std::char;
#[test]
fn test_is_lowercase() {
assert!('a'.is_lowercase());
@ -213,7 +215,10 @@ fn test_len_utf16() {
#[test]
fn test_decode_utf16() {
fn check(s: &[u16], expected: &[Result<char, u16>]) {
assert_eq!(::std::char::decode_utf16(s.iter().cloned()).collect::<Vec<_>>(), expected);
let v = char::decode_utf16(s.iter().cloned())
.map(|r| r.map_err(|e| e.unpaired_surrogate()))
.collect::<Vec<_>>();
assert_eq!(v, expected);
}
check(&[0xD800, 0x41, 0x42], &[Err(0xD800), Ok('A'), Ok('B')]);
check(&[0xD800, 0], &[Err(0xD800), Ok('\0')]);

View File

@ -15,12 +15,10 @@
#![feature(box_syntax)]
#![feature(cell_extras)]
#![feature(const_fn)]
#![feature(copy_from_slice)]
#![feature(core_float)]
#![feature(core_private_bignum)]
#![feature(core_private_diy_float)]
#![feature(dec2flt)]
#![feature(decode_utf16)]
#![feature(fixed_size_array)]
#![feature(float_extras)]
#![feature(flt2dec)]
@ -28,7 +26,6 @@
#![feature(libc)]
#![feature(nonzero)]
#![feature(peekable_is_empty)]
#![feature(ptr_as_ref)]
#![feature(rand)]
#![feature(raw)]
#![feature(slice_patterns)]

View File

@ -91,7 +91,6 @@
#![deny(missing_docs)]
#![feature(staged_api)]
#![feature(str_char)]
use self::Name::*;
use self::HasArg::*;
@ -223,7 +222,7 @@ pub type Result = result::Result<Matches, Fail>;
impl Name {
fn from_str(nm: &str) -> Name {
if nm.len() == 1 {
Short(nm.char_at(0))
Short(nm.chars().next().unwrap())
} else {
Long(nm.to_owned())
}
@ -261,7 +260,7 @@ impl OptGroup {
}
(1, 0) => {
Opt {
name: Short(short_name.char_at(0)),
name: Short(short_name.chars().next().unwrap()),
hasarg: hasarg,
occur: occur,
aliases: Vec::new(),
@ -273,7 +272,7 @@ impl OptGroup {
hasarg: hasarg,
occur: occur,
aliases: vec![Opt {
name: Short(short_name.char_at(0)),
name: Short(short_name.chars().next().unwrap()),
hasarg: hasarg,
occur: occur,
aliases: Vec::new(),
@ -599,7 +598,7 @@ pub fn getopts(args: &[String], optgrps: &[OptGroup]) -> Result {
let mut j = 1;
names = Vec::new();
while j < curlen {
let ch = cur.char_at(j);
let ch = cur[j..].chars().next().unwrap();
let opt = Short(ch);
// In a series of potential options (eg. -aheJ), if we

View File

@ -122,7 +122,6 @@
test(attr(deny(warnings))))]
#![cfg_attr(not(stage0), deny(warnings))]
#![feature(copy_from_slice)]
#![feature(rustc_private)]
#![feature(staged_api)]
#![feature(question_mark)]

View File

@ -1494,11 +1494,14 @@ impl<'a> State<'a> {
let mut out_idx = 0;
self.commasep(Inconsistent, &a.outputs, |s, out| {
match out.constraint.slice_shift_char() {
Some(('=', operand)) if out.is_rw => {
s.print_string(&format!("+{}", operand), ast::StrStyle::Cooked)?
let mut ch = out.constraint.chars();
match ch.next() {
Some('=') if out.is_rw => {
s.print_string(&format!("+{}", ch.as_str()),
ast::StrStyle::Cooked)?
}
_ => s.print_string(&out.constraint, ast::StrStyle::Cooked)?,
_ => s.print_string(&out.constraint,
ast::StrStyle::Cooked)?,
}
s.popen()?;
s.print_expr(&outputs[out_idx])?;

View File

@ -28,7 +28,6 @@
#![feature(box_syntax)]
#![feature(collections)]
#![feature(const_fn)]
#![feature(copy_from_slice)]
#![feature(enumset)]
#![feature(iter_arith)]
#![feature(libc)]
@ -39,7 +38,6 @@
#![feature(slice_patterns)]
#![feature(staged_api)]
#![feature(step_by)]
#![feature(str_char)]
#![feature(question_mark)]
#![cfg_attr(test, feature(test))]

View File

@ -351,11 +351,11 @@ fn split_msg_into_multilines(msg: &str) -> Option<String> {
return None
}
let first = msg.match_indices("expected").filter(|s| {
s.0 > 0 && (msg.char_at_reverse(s.0) == ' ' ||
msg.char_at_reverse(s.0) == '(')
let last = msg[..s.0].chars().rev().next();
last == Some(' ') || last == Some('(')
}).map(|(a, b)| (a - 1, a + b.len()));
let second = msg.match_indices("found").filter(|s| {
msg.char_at_reverse(s.0) == ' '
msg[..s.0].chars().rev().next() == Some(' ')
}).map(|(a, b)| (a - 1, a + b.len()));
let mut new_msg = String::new();

View File

@ -32,7 +32,6 @@
#![feature(box_syntax)]
#![feature(const_fn)]
#![feature(copy_from_slice)]
#![feature(libc)]
#![feature(rand)]
#![feature(rustc_private)]

View File

@ -63,7 +63,9 @@ impl NonCamelCaseTypes {
// start with a non-lowercase letter rather than non-uppercase
// ones (some scripts don't have a concept of upper/lowercase)
!name.is_empty() && !name.char_at(0).is_lowercase() && !name.contains('_')
!name.is_empty() &&
!name.chars().next().unwrap().is_lowercase() &&
!name.contains('_')
}
fn to_camel_case(s: &str) -> String {

View File

@ -36,7 +36,6 @@
#![feature(rustc_private)]
#![feature(slice_patterns)]
#![feature(staged_api)]
#![feature(str_char)]
#[macro_use]
extern crate syntax;

View File

@ -29,8 +29,7 @@
#![stable(feature = "rust1", since = "1.0.0")]
use core::char::CharExt as C;
use core::option::Option::{self, Some, None};
use core::iter::Iterator;
use core::fmt;
use tables::{derived_property, property, general_category, conversions};
// stable reexports
@ -739,7 +738,7 @@ impl char {
}
/// An iterator that decodes UTF-16 encoded code points from an iterator of `u16`s.
#[unstable(feature = "decode_utf16", reason = "recently exposed", issue = "27830")]
#[stable(feature = "decode_utf16", since = "1.9.0")]
#[derive(Clone)]
pub struct DecodeUtf16<I>
where I: Iterator<Item = u16>
@ -748,6 +747,13 @@ pub struct DecodeUtf16<I>
buf: Option<u16>,
}
/// An iterator that decodes UTF-16 encoded code points from an iterator of `u16`s.
#[stable(feature = "decode_utf16", since = "1.9.0")]
#[derive(Debug, Clone, Eq, PartialEq)]
pub struct DecodeUtf16Error {
code: u16,
}
/// Create an iterator over the UTF-16 encoded code points in `iter`,
/// returning unpaired surrogates as `Err`s.
///
@ -756,8 +762,6 @@ pub struct DecodeUtf16<I>
/// Basic usage:
///
/// ```
/// #![feature(decode_utf16)]
///
/// use std::char::decode_utf16;
///
/// fn main() {
@ -766,7 +770,9 @@ pub struct DecodeUtf16<I>
/// 0x0073, 0xDD1E, 0x0069, 0x0063,
/// 0xD834];
///
/// assert_eq!(decode_utf16(v.iter().cloned()).collect::<Vec<_>>(),
/// assert_eq!(decode_utf16(v.iter().cloned())
/// .map(|r| r.map_err(|e| e.unpaired_surrogate()))
/// .collect::<Vec<_>>(),
/// vec![Ok('𝄞'),
/// Ok('m'), Ok('u'), Ok('s'),
/// Err(0xDD1E),
@ -778,8 +784,6 @@ pub struct DecodeUtf16<I>
/// A lossy decoder can be obtained by replacing `Err` results with the replacement character:
///
/// ```
/// #![feature(decode_utf16)]
///
/// use std::char::{decode_utf16, REPLACEMENT_CHARACTER};
///
/// fn main() {
@ -794,7 +798,7 @@ pub struct DecodeUtf16<I>
/// "𝄞mus<75>ic<69>");
/// }
/// ```
#[unstable(feature = "decode_utf16", reason = "recently exposed", issue = "27830")]
#[stable(feature = "decode_utf16", since = "1.9.0")]
#[inline]
pub fn decode_utf16<I: IntoIterator<Item = u16>>(iter: I) -> DecodeUtf16<I::IntoIter> {
DecodeUtf16 {
@ -803,11 +807,11 @@ pub fn decode_utf16<I: IntoIterator<Item = u16>>(iter: I) -> DecodeUtf16<I::Into
}
}
#[unstable(feature = "decode_utf16", reason = "recently exposed", issue = "27830")]
#[stable(feature = "decode_utf16", since = "1.9.0")]
impl<I: Iterator<Item=u16>> Iterator for DecodeUtf16<I> {
type Item = Result<char, u16>;
type Item = Result<char, DecodeUtf16Error>;
fn next(&mut self) -> Option<Result<char, u16>> {
fn next(&mut self) -> Option<Result<char, DecodeUtf16Error>> {
let u = match self.buf.take() {
Some(buf) => buf,
None => match self.iter.next() {
@ -821,18 +825,18 @@ impl<I: Iterator<Item=u16>> Iterator for DecodeUtf16<I> {
Some(Ok(unsafe { from_u32_unchecked(u as u32) }))
} else if u >= 0xDC00 {
// a trailing surrogate
Some(Err(u))
Some(Err(DecodeUtf16Error { code: u }))
} else {
let u2 = match self.iter.next() {
Some(u2) => u2,
// eof
None => return Some(Err(u)),
None => return Some(Err(DecodeUtf16Error { code: u })),
};
if u2 < 0xDC00 || u2 > 0xDFFF {
// not a trailing surrogate so we're not a valid
// surrogate pair, so rewind to redecode u2 next time.
self.buf = Some(u2);
return Some(Err(u));
return Some(Err(DecodeUtf16Error { code: u }));
}
// all ok, so lets decode it.
@ -850,8 +854,25 @@ impl<I: Iterator<Item=u16>> Iterator for DecodeUtf16<I> {
}
}
/// `U+FFFD REPLACEMENT CHARACTER` (<28>) is used in Unicode to represent a decoding error.
impl DecodeUtf16Error {
/// Returns the unpaired surrogate which caused this error.
#[stable(feature = "decode_utf16", since = "1.9.0")]
pub fn unpaired_surrogate(&self) -> u16 {
self.code
}
}
#[stable(feature = "decode_utf16", since = "1.9.0")]
impl fmt::Display for DecodeUtf16Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "unpaired surrogate found: {:x}", self.code)
}
}
/// `U+FFFD REPLACEMENT CHARACTER` (<28>) is used in Unicode to represent a
/// decoding error.
///
/// It can occur, for example, when giving ill-formed UTF-8 bytes to
/// [`String::from_utf8_lossy`](../../std/string/struct.String.html#method.from_utf8_lossy).
#[unstable(feature = "decode_utf16", reason = "recently added", issue = "27830")]
#[stable(feature = "decode_utf16", since = "1.9.0")]
pub const REPLACEMENT_CHARACTER: char = '\u{FFFD}';

View File

@ -21,12 +21,10 @@
#![feature(box_patterns)]
#![feature(box_syntax)]
#![feature(libc)]
#![feature(recover)]
#![feature(rustc_private)]
#![feature(set_stdio)]
#![feature(slice_patterns)]
#![feature(staged_api)]
#![feature(std_panic)]
#![feature(test)]
#![feature(unicode)]
#![feature(question_mark)]

View File

@ -15,7 +15,7 @@ use std::ffi::OsString;
use std::io::prelude::*;
use std::io;
use std::path::PathBuf;
use std::panic::{self, AssertRecoverSafe};
use std::panic::{self, AssertUnwindSafe};
use std::process::Command;
use std::rc::Rc;
use std::str;
@ -256,18 +256,13 @@ fn runtest(test: &str, cratename: &str, cfgs: Vec<String>, libs: SearchPaths,
control.after_analysis.stop = Compilation::Stop;
}
match {
let b_sess = AssertRecoverSafe(&sess);
let b_cstore = AssertRecoverSafe(&cstore);
let b_cfg = AssertRecoverSafe(cfg.clone());
let b_control = AssertRecoverSafe(&control);
let res = panic::catch_unwind(AssertUnwindSafe(|| {
driver::compile_input(&sess, &cstore, cfg.clone(),
&input, &out,
&None, None, &control)
}));
panic::recover(|| {
driver::compile_input(&b_sess, &b_cstore, (*b_cfg).clone(),
&input, &out,
&None, None, &b_control)
})
} {
match res {
Ok(r) => {
match r {
Err(count) if count > 0 && compile_fail == false => {

View File

@ -132,7 +132,10 @@ impl FromHex for str {
buf >>= 4;
continue
}
_ => return Err(InvalidHexCharacter(self.char_at(idx), idx)),
_ => {
let ch = self[idx..].chars().next().unwrap();
return Err(InvalidHexCharacter(ch, idx))
}
}
modulus += 1;

View File

@ -32,7 +32,6 @@ Core encoding and decoding interfaces.
#![feature(enumset)]
#![feature(rustc_private)]
#![feature(staged_api)]
#![feature(str_char)]
#![feature(unicode)]
#![feature(question_mark)]
#![cfg_attr(test, feature(test))]

View File

@ -128,8 +128,6 @@ pub trait AsciiExt {
/// # Examples
///
/// ```
/// #![feature(ascii)]
///
/// use std::ascii::AsciiExt;
///
/// let mut ascii = 'a';
@ -138,7 +136,7 @@ pub trait AsciiExt {
///
/// assert_eq!('A', ascii);
/// ```
#[unstable(feature = "ascii", issue = "27809")]
#[stable(feature = "ascii", since = "1.9.0")]
fn make_ascii_uppercase(&mut self);
/// Converts this type to its ASCII lower case equivalent in-place.
@ -148,8 +146,6 @@ pub trait AsciiExt {
/// # Examples
///
/// ```
/// #![feature(ascii)]
///
/// use std::ascii::AsciiExt;
///
/// let mut ascii = 'A';
@ -158,7 +154,7 @@ pub trait AsciiExt {
///
/// assert_eq!('a', ascii);
/// ```
#[unstable(feature = "ascii", issue = "27809")]
#[stable(feature = "ascii", since = "1.9.0")]
fn make_ascii_lowercase(&mut self);
}

View File

@ -620,8 +620,7 @@ impl<K, V, S> HashMap<K, V, S>
}
/// Returns a reference to the map's hasher.
#[unstable(feature = "hashmap_public_hasher", reason = "don't want to make insta-stable",
issue = "31262")]
#[stable(feature = "hashmap_public_hasher", since = "1.9.0")]
pub fn hasher(&self) -> &S {
&self.hash_builder
}

View File

@ -194,8 +194,7 @@ impl<T, S> HashSet<T, S>
}
/// Returns a reference to the set's hasher.
#[unstable(feature = "hashmap_public_hasher", reason = "don't want to make insta-stable",
issue = "31262")]
#[stable(feature = "hashmap_public_hasher", since = "1.9.0")]
pub fn hasher(&self) -> &S {
self.map.hasher()
}
@ -459,7 +458,7 @@ impl<T, S> HashSet<T, S>
/// The value may be any borrowed form of the set's value type, but
/// `Hash` and `Eq` on the borrowed form *must* match those for
/// the value type.
#[unstable(feature = "set_recovery", issue = "28050")]
#[stable(feature = "set_recovery", since = "1.9.0")]
pub fn get<Q: ?Sized>(&self, value: &Q) -> Option<&T>
where T: Borrow<Q>, Q: Hash + Eq
{
@ -556,7 +555,7 @@ impl<T, S> HashSet<T, S>
/// Adds a value to the set, replacing the existing value, if any, that is equal to the given
/// one. Returns the replaced value.
#[unstable(feature = "set_recovery", issue = "28050")]
#[stable(feature = "set_recovery", since = "1.9.0")]
pub fn replace(&mut self, value: T) -> Option<T> {
Recover::replace(&mut self.map, value)
}
@ -591,7 +590,7 @@ impl<T, S> HashSet<T, S>
/// The value may be any borrowed form of the set's value type, but
/// `Hash` and `Eq` on the borrowed form *must* match those for
/// the value type.
#[unstable(feature = "set_recovery", issue = "28050")]
#[stable(feature = "set_recovery", since = "1.9.0")]
pub fn take<Q: ?Sized>(&mut self, value: &Q) -> Option<T>
where T: Borrow<Q>, Q: Hash + Eq
{

View File

@ -49,13 +49,11 @@
use any::TypeId;
use boxed::Box;
use convert::From;
use char;
use fmt::{self, Debug, Display};
use marker::{Send, Sync, Reflect};
use mem::transmute;
use num;
use option::Option::{self, Some, None};
use result::Result::{self, Ok, Err};
use raw::TraitObject;
use str;
use string::{self, String};
@ -189,6 +187,13 @@ impl Error for string::ParseError {
}
}
#[stable(feature = "decode_utf16", since = "1.9.0")]
impl Error for char::DecodeUtf16Error {
fn description(&self) -> &str {
"unpaired surrogate found"
}
}
#[stable(feature = "box_error", since = "1.7.0")]
impl<T: Error> Error for Box<T> {
fn description(&self) -> &str {

View File

@ -86,13 +86,14 @@ impl OsString {
self.inner.push_slice(&s.as_ref().inner)
}
/// Creates a new `OsString` with the given capacity. The string will be
/// able to hold exactly `capacity` bytes without reallocating. If
/// `capacity` is 0, the string will not allocate.
/// Creates a new `OsString` with the given capacity.
///
/// The string will be able to hold exactly `capacity` lenth units of other
/// OS strings without reallocating. If `capacity` is 0, the string will not
/// allocate.
///
/// See main `OsString` documentation information about encoding.
#[unstable(feature = "osstring_simple_functions",
reason = "recently added", issue = "29453")]
#[stable(feature = "osstring_simple_functions", since = "1.9.0")]
pub fn with_capacity(capacity: usize) -> OsString {
OsString {
inner: Buf::with_capacity(capacity)
@ -100,40 +101,36 @@ impl OsString {
}
/// Truncates the `OsString` to zero length.
#[unstable(feature = "osstring_simple_functions",
reason = "recently added", issue = "29453")]
#[stable(feature = "osstring_simple_functions", since = "1.9.0")]
pub fn clear(&mut self) {
self.inner.clear()
}
/// Returns the number of bytes this `OsString` can hold without
/// reallocating.
/// Returns the capacity this `OsString` can hold without reallocating.
///
/// See `OsString` introduction for information about encoding.
#[unstable(feature = "osstring_simple_functions",
reason = "recently added", issue = "29453")]
#[stable(feature = "osstring_simple_functions", since = "1.9.0")]
pub fn capacity(&self) -> usize {
self.inner.capacity()
}
/// Reserves capacity for at least `additional` more bytes to be inserted
/// in the given `OsString`. The collection may reserve more space to avoid
/// frequent reallocations.
#[unstable(feature = "osstring_simple_functions",
reason = "recently added", issue = "29453")]
/// Reserves capacity for at least `additional` more capacity to be inserted
/// in the given `OsString`.
///
/// The collection may reserve more space to avoid frequent reallocations.
#[stable(feature = "osstring_simple_functions", since = "1.9.0")]
pub fn reserve(&mut self, additional: usize) {
self.inner.reserve(additional)
}
/// Reserves the minimum capacity for exactly `additional` more bytes to be
/// inserted in the given `OsString`. Does nothing if the capacity is
/// Reserves the minimum capacity for exactly `additional` more capacity to
/// be inserted in the given `OsString`. Does nothing if the capacity is
/// already sufficient.
///
/// Note that the allocator may give the collection more space than it
/// requests. Therefore capacity can not be relied upon to be precisely
/// minimal. Prefer reserve if future insertions are expected.
#[unstable(feature = "osstring_simple_functions",
reason = "recently added", issue = "29453")]
#[stable(feature = "osstring_simple_functions", since = "1.9.0")]
pub fn reserve_exact(&mut self, additional: usize) {
self.inner.reserve_exact(additional)
}
@ -286,17 +283,20 @@ impl OsStr {
}
/// Checks whether the `OsStr` is empty.
#[unstable(feature = "osstring_simple_functions",
reason = "recently added", issue = "29453")]
#[stable(feature = "osstring_simple_functions", since = "1.9.0")]
pub fn is_empty(&self) -> bool {
self.inner.inner.is_empty()
}
/// Returns the number of bytes in this `OsStr`.
/// Returns the length of this `OsStr`.
///
/// See `OsStr` introduction for information about encoding.
#[unstable(feature = "osstring_simple_functions",
reason = "recently added", issue = "29453")]
/// Note that this does **not** return the number of bytes in this string
/// as, for example, OS strings on Windows are encoded as a list of `u16`
/// rather than a list of bytes. This number is simply useful for passing to
/// other methods like `OsString::with_capacity` to avoid reallocations.
///
/// See `OsStr` introduction for more information about encoding.
#[stable(feature = "osstring_simple_functions", since = "1.9.0")]
pub fn len(&self) -> usize {
self.inner.inner.len()
}

View File

@ -302,7 +302,7 @@ impl File {
/// The returned `File` is a reference to the same state that this object
/// references. Both handles will read and write with the same cursor
/// position.
#[unstable(feature = "file_try_clone", reason = "newly added", issue = "31405")]
#[stable(feature = "file_try_clone", since = "1.9.0")]
pub fn try_clone(&self) -> io::Result<File> {
Ok(File {
inner: self.inner.duplicate()?
@ -523,16 +523,13 @@ impl OpenOptions {
/// # Examples
///
/// ```no_run
/// #![feature(expand_open_options)]
/// use std::fs::OpenOptions;
///
/// let file = OpenOptions::new().write(true)
/// .create_new(true)
/// .open("foo.txt");
/// ```
#[unstable(feature = "expand_open_options",
reason = "recently added",
issue = "30014")]
#[stable(feature = "expand_open_options2", since = "1.9.0")]
pub fn create_new(&mut self, create_new: bool) -> &mut OpenOptions {
self.0.create_new(create_new); self
}

View File

@ -1596,7 +1596,7 @@ impl<R: Read> Iterator for Chars<R> {
}
}
Some(match str::from_utf8(&buf[..width]).ok() {
Some(s) => Ok(s.char_at(0)),
Some(s) => Ok(s.chars().next().unwrap()),
None => Err(CharsError::NotUtf8),
})
}

View File

@ -222,10 +222,8 @@
#![feature(collections)]
#![feature(collections_bound)]
#![feature(const_fn)]
#![feature(copy_from_slice)]
#![feature(core_float)]
#![feature(core_intrinsics)]
#![feature(decode_utf16)]
#![feature(dropck_parametricity)]
#![feature(float_extras)]
#![feature(float_from_str_radix)]

View File

@ -68,7 +68,7 @@ impl SocketAddr {
}
/// Change the IP address associated with this socket address.
#[unstable(feature = "sockaddr_setters", reason = "recent addition", issue = "31572")]
#[stable(feature = "sockaddr_setters", since = "1.9.0")]
pub fn set_ip(&mut self, new_ip: IpAddr) {
// `match (*self, new_ip)` would have us mutate a copy of self only to throw it away.
match (self, new_ip) {
@ -88,7 +88,7 @@ impl SocketAddr {
}
/// Change the port number associated with this socket address.
#[unstable(feature = "sockaddr_setters", reason = "recent addition", issue = "31572")]
#[stable(feature = "sockaddr_setters", since = "1.9.0")]
pub fn set_port(&mut self, new_port: u16) {
match *self {
SocketAddr::V4(ref mut a) => a.set_port(new_port),
@ -120,16 +120,22 @@ impl SocketAddrV4 {
}
/// Change the IP address associated with this socket address.
#[unstable(feature = "sockaddr_setters", reason = "recent addition", issue = "31572")]
pub fn set_ip(&mut self, new_ip: Ipv4Addr) { self.inner.sin_addr = *new_ip.as_inner() }
#[stable(feature = "sockaddr_setters", since = "1.9.0")]
pub fn set_ip(&mut self, new_ip: Ipv4Addr) {
self.inner.sin_addr = *new_ip.as_inner()
}
/// Returns the port number associated with this socket address.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn port(&self) -> u16 { ntoh(self.inner.sin_port) }
pub fn port(&self) -> u16 {
ntoh(self.inner.sin_port)
}
/// Change the port number associated with this socket address.
#[unstable(feature = "sockaddr_setters", reason = "recent addition", issue = "31572")]
pub fn set_port(&mut self, new_port: u16) { self.inner.sin_port = hton(new_port) }
#[stable(feature = "sockaddr_setters", since = "1.9.0")]
pub fn set_port(&mut self, new_port: u16) {
self.inner.sin_port = hton(new_port);
}
}
impl SocketAddrV6 {
@ -159,24 +165,32 @@ impl SocketAddrV6 {
}
/// Change the IP address associated with this socket address.
#[unstable(feature = "sockaddr_setters", reason = "recent addition", issue = "31572")]
pub fn set_ip(&mut self, new_ip: Ipv6Addr) { self.inner.sin6_addr = *new_ip.as_inner() }
#[stable(feature = "sockaddr_setters", since = "1.9.0")]
pub fn set_ip(&mut self, new_ip: Ipv6Addr) {
self.inner.sin6_addr = *new_ip.as_inner()
}
/// Returns the port number associated with this socket address.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn port(&self) -> u16 { ntoh(self.inner.sin6_port) }
pub fn port(&self) -> u16 {
ntoh(self.inner.sin6_port)
}
/// Change the port number associated with this socket address.
#[unstable(feature = "sockaddr_setters", reason = "recent addition", issue = "31572")]
pub fn set_port(&mut self, new_port: u16) { self.inner.sin6_port = hton(new_port) }
#[stable(feature = "sockaddr_setters", since = "1.9.0")]
pub fn set_port(&mut self, new_port: u16) {
self.inner.sin6_port = hton(new_port);
}
/// Returns the flow information associated with this address,
/// corresponding to the `sin6_flowinfo` field in C.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn flowinfo(&self) -> u32 { self.inner.sin6_flowinfo }
pub fn flowinfo(&self) -> u32 {
self.inner.sin6_flowinfo
}
/// Change the flow information associated with this socket address.
#[unstable(feature = "sockaddr_setters", reason = "recent addition", issue = "31572")]
#[stable(feature = "sockaddr_setters", since = "1.9.0")]
pub fn set_flowinfo(&mut self, new_flowinfo: u32) {
self.inner.sin6_flowinfo = new_flowinfo;
}
@ -184,10 +198,12 @@ impl SocketAddrV6 {
/// Returns the scope ID associated with this address,
/// corresponding to the `sin6_scope_id` field in C.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn scope_id(&self) -> u32 { self.inner.sin6_scope_id }
pub fn scope_id(&self) -> u32 {
self.inner.sin6_scope_id
}
/// Change the scope ID associated with this socket address.
#[unstable(feature = "sockaddr_setters", reason = "recent addition", issue = "31572")]
#[stable(feature = "sockaddr_setters", since = "1.9.0")]
pub fn set_scope_id(&mut self, new_scope_id: u32) {
self.inner.sin6_scope_id = new_scope_id;
}

View File

@ -10,8 +10,7 @@
//! Panic support in the standard library
#![unstable(feature = "std_panic", reason = "awaiting feedback",
issue = "27719")]
#![stable(feature = "std_panic", since = "1.9.0")]
use any::Any;
use boxed::Box;
@ -23,6 +22,7 @@ use sync::{Arc, Mutex, RwLock};
use sys_common::unwind;
use thread::Result;
#[unstable(feature = "panic_handler", issue = "30449")]
pub use panicking::{take_hook, set_hook, PanicInfo, Location};
///
@ -92,7 +92,7 @@ pub fn take_handler() -> Box<Fn(&PanicInfo) + 'static + Sync + Send> {
/// "speed bump" to alert users of `recover` that broken invariants may be
/// witnessed and may need to be accounted for.
///
/// ## Who implements `RecoverSafe`?
/// ## Who implements `UnwindSafe`?
///
/// Types such as `&mut T` and `&RefCell<T>` are examples which are **not**
/// recover safe. The general idea is that any mutable state which can be shared
@ -104,7 +104,7 @@ pub fn take_handler() -> Box<Fn(&PanicInfo) + 'static + Sync + Send> {
/// poisoning by default. They still allow witnessing a broken invariant, but
/// they already provide their own "speed bumps" to do so.
///
/// ## When should `RecoverSafe` be used?
/// ## When should `UnwindSafe` be used?
///
/// Is not intended that most types or functions need to worry about this trait.
/// It is only used as a bound on the `recover` function and as mentioned above,
@ -112,10 +112,18 @@ pub fn take_handler() -> Box<Fn(&PanicInfo) + 'static + Sync + Send> {
/// wrapper struct in this module can be used to force this trait to be
/// implemented for any closed over variables passed to the `recover` function
/// (more on this below).
#[unstable(feature = "recover", reason = "awaiting feedback", issue = "27719")]
#[stable(feature = "catch_unwind", since = "1.9.0")]
#[rustc_on_unimplemented = "the type {Self} may not be safely transferred \
across a recover boundary"]
pub trait UnwindSafe {}
/// Deprecated, renamed to UnwindSafe
#[unstable(feature = "recover", reason = "awaiting feedback", issue = "27719")]
#[rustc_deprecated(reason = "renamed to `UnwindSafe`", since = "1.9.0")]
pub trait RecoverSafe {}
#[unstable(feature = "recover", reason = "awaiting feedback", issue = "27719")]
#[allow(deprecated)]
impl<T: UnwindSafe> RecoverSafe for T {}
/// A marker trait representing types where a shared reference is considered
/// recover safe.
@ -124,12 +132,12 @@ pub trait RecoverSafe {}
/// interior mutability.
///
/// This is a "helper marker trait" used to provide impl blocks for the
/// `RecoverSafe` trait, for more information see that documentation.
#[unstable(feature = "recover", reason = "awaiting feedback", issue = "27719")]
/// `UnwindSafe` trait, for more information see that documentation.
#[stable(feature = "catch_unwind", since = "1.9.0")]
#[rustc_on_unimplemented = "the type {Self} contains interior mutability \
and a reference may not be safely transferrable \
across a recover boundary"]
pub trait RefRecoverSafe {}
pub trait RefUnwindSafe {}
/// A simple wrapper around a type to assert that it is panic safe.
///
@ -143,90 +151,141 @@ pub trait RefRecoverSafe {}
///
/// # Examples
///
/// One way to use `AssertRecoverSafe` is to assert that the entire closure
/// One way to use `AssertUnwindSafe` is to assert that the entire closure
/// itself is recover safe, bypassing all checks for all variables:
///
/// ```
/// #![feature(recover, std_panic)]
///
/// use std::panic::{self, AssertRecoverSafe};
/// use std::panic::{self, AssertUnwindSafe};
///
/// let mut variable = 4;
///
/// // This code will not compile because the closure captures `&mut variable`
/// // which is not considered panic safe by default.
///
/// // panic::recover(|| {
/// // panic::catch_unwind(|| {
/// // variable += 3;
/// // });
///
/// // This, however, will compile due to the `AssertRecoverSafe` wrapper
/// let result = panic::recover(AssertRecoverSafe(|| {
/// // This, however, will compile due to the `AssertUnwindSafe` wrapper
/// let result = panic::catch_unwind(AssertUnwindSafe(|| {
/// variable += 3;
/// }));
/// // ...
/// ```
///
/// Wrapping the entire closure amounts to a blanket assertion that all captured
/// variables are recover safe. This has the downside that if new captures are
/// added in the future, they will also be considered recover safe. Therefore,
/// variables are unwind safe. This has the downside that if new captures are
/// added in the future, they will also be considered unwind safe. Therefore,
/// you may prefer to just wrap individual captures, as shown below. This is
/// more annotation, but it ensures that if a new capture is added which is not
/// recover safe, you will get a compilation error at that time, which will
/// unwind safe, you will get a compilation error at that time, which will
/// allow you to consider whether that new capture in fact represent a bug or
/// not.
///
/// ```
/// #![feature(recover, std_panic)]
///
/// use std::panic::{self, AssertRecoverSafe};
/// use std::panic::{self, AssertUnwindSafe};
///
/// let mut variable = 4;
/// let other_capture = 3;
///
/// let result = {
/// let mut wrapper = AssertRecoverSafe(&mut variable);
/// panic::recover(move || {
/// let mut wrapper = AssertUnwindSafe(&mut variable);
/// panic::catch_unwind(move || {
/// **wrapper += other_capture;
/// })
/// };
/// // ...
/// ```
#[unstable(feature = "recover", reason = "awaiting feedback", issue = "27719")]
#[stable(feature = "catch_unwind", since = "1.9.0")]
pub struct AssertUnwindSafe<T>(
#[stable(feature = "catch_unwind", since = "1.9.0")]
pub T
);
/// Deprecated, renamed to `AssertUnwindSafe`
#[unstable(feature = "recover", issue = "27719")]
#[rustc_deprecated(reason = "renamed to `AssertUnwindSafe`", since = "1.9.0")]
pub struct AssertRecoverSafe<T>(pub T);
// Implementations of the `RecoverSafe` trait:
// Implementations of the `UnwindSafe` trait:
//
// * By default everything is recover safe
// * pointers T contains mutability of some form are not recover safe
// * By default everything is unwind safe
// * pointers T contains mutability of some form are not unwind safe
// * Unique, an owning pointer, lifts an implementation
// * Types like Mutex/RwLock which are explicilty poisoned are recover safe
// * Our custom AssertRecoverSafe wrapper is indeed recover safe
impl RecoverSafe for .. {}
impl<'a, T: ?Sized> !RecoverSafe for &'a mut T {}
impl<'a, T: RefRecoverSafe + ?Sized> RecoverSafe for &'a T {}
impl<T: RefRecoverSafe + ?Sized> RecoverSafe for *const T {}
impl<T: RefRecoverSafe + ?Sized> RecoverSafe for *mut T {}
impl<T: RecoverSafe> RecoverSafe for Unique<T> {}
impl<T: RefRecoverSafe + ?Sized> RecoverSafe for Shared<T> {}
impl<T: ?Sized> RecoverSafe for Mutex<T> {}
impl<T: ?Sized> RecoverSafe for RwLock<T> {}
impl<T> RecoverSafe for AssertRecoverSafe<T> {}
// * Types like Mutex/RwLock which are explicilty poisoned are unwind safe
// * Our custom AssertUnwindSafe wrapper is indeed unwind safe
#[stable(feature = "catch_unwind", since = "1.9.0")]
impl UnwindSafe for .. {}
#[stable(feature = "catch_unwind", since = "1.9.0")]
impl<'a, T: ?Sized> !UnwindSafe for &'a mut T {}
#[stable(feature = "catch_unwind", since = "1.9.0")]
impl<'a, T: RefUnwindSafe + ?Sized> UnwindSafe for &'a T {}
#[stable(feature = "catch_unwind", since = "1.9.0")]
impl<T: RefUnwindSafe + ?Sized> UnwindSafe for *const T {}
#[stable(feature = "catch_unwind", since = "1.9.0")]
impl<T: RefUnwindSafe + ?Sized> UnwindSafe for *mut T {}
#[stable(feature = "catch_unwind", since = "1.9.0")]
impl<T: UnwindSafe> UnwindSafe for Unique<T> {}
#[stable(feature = "catch_unwind", since = "1.9.0")]
impl<T: RefUnwindSafe + ?Sized> UnwindSafe for Shared<T> {}
#[stable(feature = "catch_unwind", since = "1.9.0")]
impl<T: ?Sized> UnwindSafe for Mutex<T> {}
#[stable(feature = "catch_unwind", since = "1.9.0")]
impl<T: ?Sized> UnwindSafe for RwLock<T> {}
#[stable(feature = "catch_unwind", since = "1.9.0")]
impl<T> UnwindSafe for AssertUnwindSafe<T> {}
#[unstable(feature = "recover", issue = "27719")]
#[allow(deprecated)]
impl<T> UnwindSafe for AssertRecoverSafe<T> {}
// not covered via the Shared impl above b/c the inner contents use
// Cell/AtomicUsize, but the usage here is recover safe so we can lift the
// impl up one level to Arc/Rc itself
impl<T: RefRecoverSafe + ?Sized> RecoverSafe for Rc<T> {}
impl<T: RefRecoverSafe + ?Sized> RecoverSafe for Arc<T> {}
#[stable(feature = "catch_unwind", since = "1.9.0")]
impl<T: RefUnwindSafe + ?Sized> UnwindSafe for Rc<T> {}
#[stable(feature = "catch_unwind", since = "1.9.0")]
impl<T: RefUnwindSafe + ?Sized> UnwindSafe for Arc<T> {}
// Pretty simple implementations for the `RefRecoverSafe` marker trait,
// basically just saying that this is a marker trait and `UnsafeCell` is the
// only thing which doesn't implement it (which then transitively applies to
// everything else).
impl RefRecoverSafe for .. {}
impl<T: ?Sized> !RefRecoverSafe for UnsafeCell<T> {}
impl<T> RefRecoverSafe for AssertRecoverSafe<T> {}
#[stable(feature = "catch_unwind", since = "1.9.0")]
impl RefUnwindSafe for .. {}
#[stable(feature = "catch_unwind", since = "1.9.0")]
impl<T: ?Sized> !RefUnwindSafe for UnsafeCell<T> {}
#[stable(feature = "catch_unwind", since = "1.9.0")]
impl<T> RefUnwindSafe for AssertUnwindSafe<T> {}
#[unstable(feature = "recover", issue = "27719")]
#[allow(deprecated)]
impl<T> RefUnwindSafe for AssertRecoverSafe<T> {}
#[stable(feature = "catch_unwind", since = "1.9.0")]
impl<T> Deref for AssertUnwindSafe<T> {
type Target = T;
fn deref(&self) -> &T {
&self.0
}
}
#[stable(feature = "catch_unwind", since = "1.9.0")]
impl<T> DerefMut for AssertUnwindSafe<T> {
fn deref_mut(&mut self) -> &mut T {
&mut self.0
}
}
#[stable(feature = "catch_unwind", since = "1.9.0")]
impl<R, F: FnOnce() -> R> FnOnce<()> for AssertUnwindSafe<F> {
type Output = R;
extern "rust-call" fn call_once(self, _args: ()) -> R {
(self.0)()
}
}
#[allow(deprecated)]
impl<T> AssertRecoverSafe<T> {
/// Creates a new `AssertRecoverSafe` wrapper around the provided type.
#[unstable(feature = "recover", reason = "awaiting feedback", issue = "27719")]
@ -245,6 +304,8 @@ impl<T> AssertRecoverSafe<T> {
}
}
#[unstable(feature = "recover", issue = "27719")]
#[allow(deprecated)]
impl<T> Deref for AssertRecoverSafe<T> {
type Target = T;
@ -253,12 +314,16 @@ impl<T> Deref for AssertRecoverSafe<T> {
}
}
#[unstable(feature = "recover", issue = "27719")]
#[allow(deprecated)]
impl<T> DerefMut for AssertRecoverSafe<T> {
fn deref_mut(&mut self) -> &mut T {
&mut self.0
}
}
#[unstable(feature = "recover", issue = "27719")]
#[allow(deprecated)]
impl<R, F: FnOnce() -> R> FnOnce<()> for AssertRecoverSafe<F> {
type Output = R;
@ -267,7 +332,7 @@ impl<R, F: FnOnce() -> R> FnOnce<()> for AssertRecoverSafe<F> {
}
}
/// Invokes a closure, capturing the cause of panic if one occurs.
/// Invokes a closure, capturing the cause of an unwinding 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
@ -280,38 +345,44 @@ impl<R, F: FnOnce() -> R> FnOnce<()> for AssertRecoverSafe<F> {
///
/// 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.
/// can fail on a regular basis. Additionally, this function is not guaranteed
/// to catch all panics, see the "Notes" sectino below.
///
/// The closure provided is required to adhere to the `RecoverSafe` to ensure
/// that all captured variables are safe to cross this recover boundary. The
/// purpose of this bound is to encode the concept of [exception safety][rfc] in
/// the type system. Most usage of this function should not need to worry about
/// this bound as programs are naturally panic safe without `unsafe` code. If it
/// becomes a problem the associated `AssertRecoverSafe` wrapper type in this
/// The closure provided is required to adhere to the `UnwindSafe` to ensure
/// that all captured variables are safe to cross this boundary. The purpose of
/// this bound is to encode the concept of [exception safety][rfc] in the type
/// system. Most usage of this function should not need to worry about this
/// bound as programs are naturally panic safe without `unsafe` code. If it
/// becomes a problem the associated `AssertUnwindSafe` wrapper type in this
/// module can be used to quickly assert that the usage here is indeed exception
/// safe.
///
/// [rfc]: https://github.com/rust-lang/rfcs/blob/master/text/1236-stabilize-catch-panic.md
///
/// # Notes
///
/// Note that this function **may not catch all panics** in Rust. A panic in
/// Rust is not always implemented via unwinding, but can be implemented by
/// aborting the process as well. This function *only* catches unwinding panics,
/// not those that abort the process.
///
/// # Examples
///
/// ```
/// #![feature(recover, std_panic)]
///
/// use std::panic;
///
/// let result = panic::recover(|| {
/// let result = panic::catch_unwind(|| {
/// println!("hello!");
/// });
/// assert!(result.is_ok());
///
/// let result = panic::recover(|| {
/// let result = panic::catch_unwind(|| {
/// panic!("oh no!");
/// });
/// assert!(result.is_err());
/// ```
#[unstable(feature = "recover", reason = "awaiting feedback", issue = "27719")]
pub fn recover<F: FnOnce() -> R + RecoverSafe, R>(f: F) -> Result<R> {
#[stable(feature = "catch_unwind", since = "1.9.0")]
pub fn catch_unwind<F: FnOnce() -> R + UnwindSafe, R>(f: F) -> Result<R> {
let mut result = None;
unsafe {
let result = &mut result;
@ -320,27 +391,46 @@ pub fn recover<F: FnOnce() -> R + RecoverSafe, R>(f: F) -> Result<R> {
Ok(result.unwrap())
}
/// Deprecated, renamed to `catch_unwind`
#[unstable(feature = "recover", reason = "awaiting feedback", issue = "27719")]
#[rustc_deprecated(reason = "renamed to `catch_unwind`", since = "1.9.0")]
pub fn recover<F: FnOnce() -> R + UnwindSafe, R>(f: F) -> Result<R> {
catch_unwind(f)
}
/// Triggers a panic without invoking the panic handler.
///
/// This is designed to be used in conjunction with `recover` to, for example,
/// carry a panic across a layer of C code.
/// This is designed to be used in conjunction with `catch_unwind` to, for
/// example, carry a panic across a layer of C code.
///
/// # Notes
///
/// Note that panics in Rust are not always implemented via unwinding, but they
/// may be implemented by aborting the process. If this function is called when
/// panics are implemented this way then this function will abort the process,
/// not trigger an unwind.
///
/// # Examples
///
/// ```should_panic
/// #![feature(std_panic, recover, panic_propagate)]
///
/// use std::panic;
///
/// let result = panic::recover(|| {
/// let result = panic::catch_unwind(|| {
/// panic!("oh no!");
/// });
///
/// if let Err(err) = result {
/// panic::propagate(err);
/// panic::resume_unwind(err);
/// }
/// ```
#[unstable(feature = "panic_propagate", reason = "awaiting feedback", issue = "30752")]
pub fn propagate(payload: Box<Any + Send>) -> ! {
#[stable(feature = "resume_unwind", since = "1.9.0")]
pub fn resume_unwind(payload: Box<Any + Send>) -> ! {
unwind::rust_panic(payload)
}
/// Deprecated, use resume_unwind instead
#[unstable(feature = "panic_propagate", reason = "awaiting feedback", issue = "30752")]
#[rustc_deprecated(reason = "renamed to `resume_unwind`", since = "1.9.0")]
pub fn propagate(payload: Box<Any + Send>) -> ! {
resume_unwind(payload)
}

View File

@ -60,7 +60,7 @@ fn lang_start(main: *const u8, argc: isize, argv: *const *const u8) -> isize {
sys_common::args::init(argc, argv);
// Let's run some code!
let res = panic::recover(mem::transmute::<_, fn()>(main));
let res = panic::catch_unwind(mem::transmute::<_, fn()>(main));
sys_common::cleanup();
res.is_err()
};

View File

@ -425,13 +425,13 @@ mod tests {
static O: Once = Once::new();
// poison the once
let t = panic::recover(|| {
let t = panic::catch_unwind(|| {
O.call_once(|| panic!());
});
assert!(t.is_err());
// poisoning propagates
let t = panic::recover(|| {
let t = panic::catch_unwind(|| {
O.call_once(|| {});
});
assert!(t.is_err());
@ -453,7 +453,7 @@ mod tests {
static O: Once = Once::new();
// poison the once
let t = panic::recover(|| {
let t = panic::catch_unwind(|| {
O.call_once(|| panic!());
});
assert!(t.is_err());

View File

@ -131,7 +131,7 @@ pub fn demangle(writer: &mut Write, s: &str) -> io::Result<()> {
first = false;
}
let mut rest = inner;
while rest.char_at(0).is_numeric() {
while rest.chars().next().unwrap().is_numeric() {
rest = &rest[1..];
}
let i: usize = inner[.. (inner.len() - rest.len())].parse().unwrap();

View File

@ -191,8 +191,11 @@ impl Wtf8Buf {
match item {
Ok(ch) => string.push_char(ch),
Err(surrogate) => {
let surrogate = surrogate.unpaired_surrogate();
// Surrogates are known to be in the code point range.
let code_point = unsafe { CodePoint::from_u32_unchecked(surrogate as u32) };
let code_point = unsafe {
CodePoint::from_u32_unchecked(surrogate as u32)
};
// Skip the WTF-8 concatenation check,
// surrogate pairs are already decoded by decode_utf16
string.push_code_point_unchecked(code_point)

View File

@ -49,7 +49,9 @@ pub mod prelude {
#[doc(no_inline)] #[stable(feature = "rust1", since = "1.0.0")]
pub use super::fs::{PermissionsExt, OpenOptionsExt, MetadataExt, FileTypeExt};
#[doc(no_inline)] #[stable(feature = "rust1", since = "1.0.0")]
pub use super::fs::{DirEntryExt};
pub use super::fs::DirEntryExt;
#[doc(no_inline)] #[stable(feature = "rust1", since = "1.0.0")]
pub use super::thread::JoinHandleExt;
#[doc(no_inline)] #[stable(feature = "rust1", since = "1.0.0")]
pub use super::process::{CommandExt, ExitStatusExt};
}

View File

@ -45,6 +45,8 @@ pub trait CommandExt {
/// (the daemon) in the same session.
#[unstable(feature = "process_session_leader", reason = "recently added",
issue = "27811")]
#[rustc_deprecated(reason = "use `before_exec` instead",
since = "1.9.0")]
fn session_leader(&mut self, on: bool) -> &mut process::Command;
/// Schedules a closure to be run just before the `exec` function is
@ -94,7 +96,7 @@ pub trait CommandExt {
/// file descriptors may have changed. If a "transactional spawn" is
/// required to gracefully handle errors it is recommended to use the
/// cross-platform `spawn` instead.
#[unstable(feature = "process_exec", issue = "31398")]
#[stable(feature = "process_exec2", since = "1.9.0")]
fn exec(&mut self) -> io::Error;
}

View File

@ -8,37 +8,41 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//! Unix-specific extensions to primitives in the `std::process` module.
//! Unix-specific extensions to primitives in the `std::thread` module.
#![unstable(feature = "thread_extensions", issue = "29791")]
#![stable(feature = "thread_extensions", since = "1.9.0")]
#[allow(deprecated)]
use os::unix::raw::pthread_t;
use sys_common::{AsInner, IntoInner};
use thread::JoinHandle;
#[unstable(feature = "thread_extensions", issue = "29791")]
#[stable(feature = "thread_extensions", since = "1.9.0")]
#[allow(deprecated)]
pub type RawPthread = pthread_t;
/// Unix-specific extensions to `std::thread::JoinHandle`
#[unstable(feature = "thread_extensions", issue = "29791")]
#[stable(feature = "thread_extensions", since = "1.9.0")]
pub trait JoinHandleExt {
/// Extracts the raw pthread_t without taking ownership
#[stable(feature = "thread_extensions", since = "1.9.0")]
fn as_pthread_t(&self) -> RawPthread;
/// Consumes the thread, returning the raw pthread_t
///
/// This function **transfers ownership** of the underlying pthread_t to
/// the caller. Callers are then the unique owners of the pthread_t and
/// must either detach or join the pthread_t once it's no longer needed.
#[stable(feature = "thread_extensions", since = "1.9.0")]
fn into_pthread_t(self) -> RawPthread;
}
#[unstable(feature = "thread_extensions", issue = "29791")]
#[stable(feature = "thread_extensions", since = "1.9.0")]
impl<T> JoinHandleExt for JoinHandle<T> {
fn as_pthread_t(&self) -> RawPthread {
self.as_inner().id() as RawPthread
}
fn into_pthread_t(self) -> RawPthread {
self.into_inner().into_id() as RawPthread
}

View File

@ -10,18 +10,20 @@
//! Extensions to `std::thread` for Windows.
#![unstable(feature = "thread_extensions", issue = "29791")]
#![stable(feature = "thread_extensions", since = "1.9.0")]
use os::windows::io::{RawHandle, AsRawHandle, IntoRawHandle};
use thread;
use sys_common::{AsInner, IntoInner};
#[stable(feature = "thread_extensions", since = "1.9.0")]
impl<T> AsRawHandle for thread::JoinHandle<T> {
fn as_raw_handle(&self) -> RawHandle {
self.as_inner().handle().raw() as *mut _
}
}
#[stable(feature = "thread_extensions", since = "1.9.0")]
impl<T> IntoRawHandle for thread::JoinHandle<T> {
fn into_raw_handle(self) -> RawHandle {
self.into_inner().into_handle().into_raw() as *mut _

View File

@ -237,7 +237,7 @@ const KNOWN_FEATURES: &'static [(&'static str, &'static str, Option<u32>, Status
("stmt_expr_attributes", "1.6.0", Some(15701), Active),
// Allows `#[deprecated]` attribute
("deprecated", "1.6.0", Some(29935), Active),
("deprecated", "1.9.0", Some(29935), Accepted),
// allow using type ascription in expressions
("type_ascription", "1.6.0", Some(23416), Active),
@ -435,7 +435,7 @@ pub const KNOWN_ATTRIBUTES: &'static [(&'static str, AttributeType, AttributeGat
("must_use", Whitelisted, Ungated),
("stable", Whitelisted, Ungated),
("unstable", Whitelisted, Ungated),
("deprecated", Normal, Gated("deprecated", "`#[deprecated]` attribute is unstable")),
("deprecated", Normal, Ungated),
("rustc_paren_sugar", Normal, Gated("unboxed_closures",
"unboxed_closures are still evolving")),

View File

@ -29,7 +29,6 @@
#![feature(libc)]
#![feature(rustc_private)]
#![feature(staged_api)]
#![feature(str_char)]
#![feature(str_escape)]
#![feature(unicode)]
#![feature(question_mark)]

View File

@ -2209,12 +2209,14 @@ impl<'a> State<'a> {
self.commasep(Inconsistent, &a.outputs,
|s, out| {
match out.constraint.slice_shift_char() {
Some(('=', operand)) if out.is_rw => {
s.print_string(&format!("+{}", operand),
let mut ch = out.constraint.chars();
match ch.next() {
Some('=') if out.is_rw => {
s.print_string(&format!("+{}", ch.as_str()),
ast::StrStyle::Cooked)?
}
_ => s.print_string(&out.constraint, ast::StrStyle::Cooked)?
_ => s.print_string(&out.constraint,
ast::StrStyle::Cooked)?
}
s.popen()?;
s.print_expr(&out.expr)?;

View File

@ -131,11 +131,12 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
// It's the opposite of '=&' which means that the memory
// cannot be shared with any other operand (usually when
// a register is clobbered early.)
let output = match constraint.slice_shift_char() {
Some(('=', _)) => None,
Some(('+', operand)) => {
let mut ch = constraint.chars();
let output = match ch.next() {
Some('=') => None,
Some('+') => {
Some(token::intern_and_get_ident(&format!(
"={}", operand)))
"={}", ch.as_str())))
}
_ => {
cx.span_err(span, "output operand constraint lacks '=' or '+'");
@ -146,7 +147,7 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
let is_rw = output.is_some();
let is_indirect = constraint.contains("*");
outputs.push(ast::InlineAsmOutput {
constraint: output.unwrap_or(constraint),
constraint: output.unwrap_or(constraint.clone()),
expr: out,
is_rw: is_rw,
is_indirect: is_indirect,

View File

@ -21,7 +21,6 @@
#![feature(rustc_private)]
#![feature(staged_api)]
#![feature(str_char)]
extern crate fmt_macros;
#[macro_use] extern crate log;

View File

@ -10,7 +10,7 @@
// #[deprecated] can't be used in staged api
#![feature(deprecated, staged_api)]
#![feature(staged_api)]
#![stable(feature = "test_feature", since = "1.0.0")]

View File

@ -10,8 +10,6 @@
// aux-build:deprecation-lint.rs
#![feature(deprecated)]
#![deny(deprecated)]
#![allow(warnings)]

View File

@ -10,8 +10,6 @@
// Various checks that deprecation attributes are used correctly
#![feature(deprecated)]
mod bogus_attribute_types_1 {
#[deprecated(since = "a", note = "a", reason)] //~ ERROR unknown meta item 'reason'
fn f1() { }

View File

@ -11,10 +11,10 @@
#![allow(dead_code)]
#![feature(recover)]
use std::panic::RecoverSafe;
use std::panic::UnwindSafe;
fn assert<T: RecoverSafe + ?Sized>() {}
fn assert<T: UnwindSafe + ?Sized>() {}
fn main() {
assert::<&mut i32>(); //~ ERROR: RecoverSafe` is not satisfied
assert::<&mut i32>(); //~ ERROR: UnwindSafe` is not satisfied
}

View File

@ -18,9 +18,6 @@ fn main() {
use std::boxed::HEAP; //~ ERROR use of unstable library feature
let _ = HEAP <- { //~ ERROR use of unstable library feature
::core::raw::Slice { //~ ERROR use of unstable library feature
data: &42, //~ ERROR use of unstable library feature
len: 1 //~ ERROR use of unstable library feature
}
HEAP //~ ERROR use of unstable library feature
};
}

View File

@ -11,14 +11,14 @@
#![allow(dead_code)]
#![feature(recover)]
use std::panic::{RecoverSafe, AssertRecoverSafe};
use std::panic::{UnwindSafe, AssertUnwindSafe};
use std::cell::RefCell;
use std::sync::{Mutex, RwLock, Arc};
use std::rc::Rc;
struct Foo { a: i32 }
fn assert<T: RecoverSafe + ?Sized>() {}
fn assert<T: UnwindSafe + ?Sized>() {}
fn main() {
assert::<i32>();
@ -43,13 +43,13 @@ fn main() {
assert::<Mutex<T>>();
assert::<RwLock<T>>();
}
fn baz<T: RecoverSafe>() {
fn baz<T: UnwindSafe>() {
assert::<Box<T>>();
assert::<Vec<T>>();
assert::<RefCell<T>>();
assert::<AssertRecoverSafe<T>>();
assert::<&AssertRecoverSafe<T>>();
assert::<Rc<AssertRecoverSafe<T>>>();
assert::<Arc<AssertRecoverSafe<T>>>();
assert::<AssertUnwindSafe<T>>();
assert::<&AssertUnwindSafe<T>>();
assert::<Rc<AssertUnwindSafe<T>>>();
assert::<Arc<AssertUnwindSafe<T>>>();
}
}