]> git.lizzy.rs Git - rust.git/commitdiff
Auto merge of #31963 - barosl:rename-doc, r=alexcrichton
authorbors <bors@rust-lang.org>
Tue, 12 Apr 2016 17:12:55 +0000 (10:12 -0700)
committerbors <bors@rust-lang.org>
Tue, 12 Apr 2016 17:12:55 +0000 (10:12 -0700)
Describe more platform-specific behaviors of `std::fs::rename`

I did some tests myself regarding the situation when both `from` and `to` exist, and the results were:

On Linux:

`from` | `to` | Result
---- | ---- | ----
Directory | Directory | Ok
Directory | File | Error
File | Directory | Error
File | File | Ok

On Windows:

`from` | `to` | Result
---- | ---- | ----
Directory | Directory | Error
Directory | File | Ok
File | Directory | Error
File | File | Ok

This is a bit against the official MSDN documentation, which says "(`MOVEFILE_REPLACE_EXISTING`) cannot be used if `lpNewFileName` or `lpExistingFileName` names a directory." As evidenced above, `lpExistingFileName` *can* be a directory.

I also mentioned the atomicity of the operation.

Fixes #31301.

66 files changed:
src/compiletest/compiletest.rs
src/compiletest/errors.rs
src/compiletest/runtest.rs
src/libcollections/btree/set.rs
src/libcollections/lib.rs
src/libcollections/slice.rs
src/libcollections/str.rs
src/libcollections/string.rs
src/libcollectionstest/lib.rs
src/libcollectionstest/str.rs
src/libcore/ptr.rs
src/libcore/raw.rs
src/libcore/slice.rs
src/libcore/str/mod.rs
src/libcoretest/char.rs
src/libcoretest/lib.rs
src/libgetopts/lib.rs
src/librbml/lib.rs
src/librustc/hir/print.rs
src/librustc/lib.rs
src/librustc/session/mod.rs
src/librustc_back/lib.rs
src/librustc_driver/driver.rs
src/librustc_lint/bad_style.rs
src/librustc_lint/lib.rs
src/librustc_typeck/diagnostics.rs
src/librustc_unicode/char.rs
src/librustdoc/lib.rs
src/librustdoc/test.rs
src/libserialize/hex.rs
src/libserialize/lib.rs
src/libstd/ascii.rs
src/libstd/collections/hash/map.rs
src/libstd/collections/hash/set.rs
src/libstd/error.rs
src/libstd/ffi/os_str.rs
src/libstd/fs.rs
src/libstd/io/mod.rs
src/libstd/lib.rs
src/libstd/net/addr.rs
src/libstd/panic.rs
src/libstd/rt.rs
src/libstd/sync/once.rs
src/libstd/sys/common/backtrace.rs
src/libstd/sys/common/wtf8.rs
src/libstd/sys/unix/ext/mod.rs
src/libstd/sys/unix/ext/process.rs
src/libstd/sys/unix/ext/thread.rs
src/libstd/sys/windows/ext/thread.rs
src/libsyntax/feature_gate.rs
src/libsyntax/lib.rs
src/libsyntax/parse/parser.rs
src/libsyntax/print/pprust.rs
src/libsyntax_ext/asm.rs
src/libsyntax_ext/lib.rs
src/test/compile-fail/deprecation-in-staged-api.rs
src/test/compile-fail/deprecation-lint.rs
src/test/compile-fail/deprecation-sanity.rs
src/test/compile-fail/not-panic-safe.rs
src/test/compile-fail/placement-expr-unstable.rs
src/test/compile-fail/symbol-names/issue-32709.rs [new file with mode: 0644]
src/test/run-pass/coerce-expect-unsized.rs
src/test/run-pass/deriving-via-extension-hash-enum.rs
src/test/run-pass/foreign-dupe.rs
src/test/run-pass/panic-safe.rs
src/test/rustdoc/no-run-still-checks-lints.rs [new file with mode: 0644]

index 1c06b2a23d54dde779f98c7cda5b7708d3f37979..8d2558e4344e631fd1fde74c4eaea9660f50ed66 100644 (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| {
index 7ad0cd2a95d4bedd8b7966b4f0af52c5cd5bcff8..418a0bc7121cbd624be4797e47fd78b5226b59be 100644 (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())
index 994f45da14626eb5a37c7e5945ba2a6620ab76e6..6773c34c7d76da8cadaafb314c9e2f3bbfdc3364 100644 (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;
index 23e0af8113bf11f95d5dd8445e04b39b9562283d..e679381f223f8a97624c21efefbc1f49b9d28c90 100644 (file)
@@ -379,7 +379,7 @@ pub fn contains<Q: ?Sized>(&self, value: &Q) -> bool
     /// 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 @@ pub fn insert(&mut self, value: T) -> bool {
 
     /// 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 @@ pub fn remove<Q: ?Sized>(&mut self, value: &Q) -> bool
     /// 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
index 8e62b389a6e3f290f701eed42683531bb6628b1c..7540c51e236d226b18343352e9bce5649d6d6d1b 100644 (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)]
index 8fa594c967cf7c0c54715706c0fdc09a57270cb2..db91d911c7355d0a68b07bb2b70ac073a406953c 100644 (file)
@@ -845,14 +845,13 @@ pub fn clone_from_slice(&mut self, src: &[T]) where T: Clone {
     /// # 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)
     }
index 9798e323a6140c782c6cb8606e3686fe339d1dff..b2b1e019a1b899f1887c2e436ac87993b177154d 100644 (file)
@@ -228,8 +228,6 @@ pub fn is_empty(&self) -> bool {
     /// # Examples
     ///
     /// ```
-    /// #![feature(str_char)]
-    ///
     /// let s = "Löwe 老虎 Léopard";
     /// assert!(s.is_char_boundary(0));
     /// // start of `老`
@@ -242,12 +240,7 @@ pub fn is_empty(&self) -> bool {
     /// // 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 @@ pub unsafe fn slice_mut_unchecked(&mut self, begin: usize, end: usize) -> &mut s
     ///
     /// ```
     /// #![feature(str_char)]
+    /// #![allow(deprecated)]
     ///
     /// use std::str::CharRange;
     ///
@@ -408,6 +402,9 @@ pub unsafe fn slice_mut_unchecked(&mut self, begin: usize, end: usize) -> &mut s
                          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 @@ pub fn char_range_at(&self, start: usize) -> CharRange {
     ///
     /// ```
     /// #![feature(str_char)]
+    /// #![allow(deprecated)]
     ///
     /// use std::str::CharRange;
     ///
@@ -466,6 +464,9 @@ pub fn char_range_at(&self, start: usize) -> CharRange {
                          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 @@ pub fn char_range_at_reverse(&self, start: usize) -> CharRange {
     ///
     /// ```
     /// #![feature(str_char)]
+    /// #![allow(deprecated)]
     ///
     /// let s = "abπc";
     /// assert_eq!(s.char_at(1), 'b');
@@ -495,6 +497,9 @@ pub fn char_range_at_reverse(&self, start: usize) -> CharRange {
                          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 @@ pub fn char_at(&self, i: usize) -> char {
     ///
     /// ```
     /// #![feature(str_char)]
+    /// #![allow(deprecated)]
     ///
     /// let s = "abπc";
     /// assert_eq!(s.char_at_reverse(1), 'a');
@@ -523,6 +529,9 @@ pub fn char_at(&self, i: usize) -> char {
                          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 @@ pub fn char_at_reverse(&self, i: usize) -> char {
     ///
     /// ```
     /// #![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 @@ pub fn char_at_reverse(&self, i: usize) -> char {
                          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)
     }
index c84d84959dbc22edb06bd17ae6371c689a066b47..2226116585fcb072550d4fa6ce90faf43d8a5180 100644 (file)
@@ -1037,14 +1037,13 @@ pub fn truncate(&mut self, new_len: usize) {
     #[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 @@ pub fn pop(&mut self) -> Option<char> {
     #[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),
index 045ac1ce977fcc9399e5f05b0ffec1b3d5afae3f..211942f2294ecd165246ecb95e43dd7782cdbaca 100644 (file)
 
 #![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)]
index 1150035eb425545775063fb2b49ad7a24b1fa0e2..929ac7a52ab2786a3a0945a7237c37db9c7767d5 100644 (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);
 }
index 42aef3ab3dd7503e22689c45ac4fb7638d873e14..a6b5355d947860be655fd50118510c222b1b4ed8 100644 (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.
+///
+/// # Notes
 ///
-/// [volatile]: http://llvm.org/docs/LangRef.html#volatile-memory-accesses
+/// 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 @@ pub fn is_null(self) -> bool where T: Sized {
     /// 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 @@ pub fn is_null(self) -> bool where T: Sized {
     ///     }
     /// }
     /// ```
-    #[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 @@ pub fn is_null(self) -> bool where T: Sized {
     /// 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 @@ pub fn is_null(self) -> bool where T: Sized {
     ///     }
     /// }
     /// ```
-    #[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 @@ pub unsafe fn offset(self, count: isize) -> *mut T where T: Sized {
     /// # 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 @@ pub unsafe fn offset(self, count: isize) -> *mut T where T: Sized {
     /// 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)
         }
     }
 }
index 20c85b5efc116cdc03cc7b62c0de5e9e3670745b..19226d81f16882000966fcd514a046d1f16abe86 100644 (file)
 /// ```
 #[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 {}
index f21af7d917e20ef15a2eac06972c00a9bc069d2e..2e91238bff3cc1966b54b88728511a9b13885725 100644 (file)
 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 @@ fn rsplitn_mut<P>(&mut self,  n: usize, pred: P) -> RSplitNMut<Self::Item, P>
     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 @@ fn binary_search_by<F>(&self, mut f: F) -> Result<usize, usize> where
     }
 
     #[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 })
 }
 
 //
index f1be10da872411e80e6ffead263c559e91e89696..f3c31d59fc4671717be8f1628c52b2d74bbbf08c 100644 (file)
@@ -29,7 +29,6 @@
 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 @@ fn trim_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str
     #[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 @@ fn trim_right_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str
                          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 @@ fn rfind<'a, P: Pattern<'a>>(&'a self, pat: P) -> Option<usize>
                          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 @@ fn lines_any(&self) -> LinesAny {
 
     #[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 @@ fn multibyte_char_range_at_reverse(s: &str, mut i: usize) -> CharRange {
     }
 
     #[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 @@ fn split_at_mut(&mut self, mid: usize) -> (&mut str, &mut str) {
     }
 
     #[inline]
+    #[allow(deprecated)]
     fn slice_shift_char(&self) -> Option<(char, &str)> {
         if self.is_empty() {
             None
@@ -2055,7 +2060,9 @@ fn as_ptr(&self) -> *const u8 {
     }
 
     #[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 }
index ba8918fc6cb4528742e96e4534c4f2fb27d35c96..41fd742c9e011f48094edd8b250b1857ebc3ed33 100644 (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')]);
index 506f9e9b7a5764ddac10ec74bce14c94d220aa93..aa7ab4b4e3f85c82eee639a02bae62b213baf687 100644 (file)
 #![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)]
index 884f4490d9f4b379d6e9bf10c9542f8e9d834ea1..eda20699755a18e89d9749627074c66a50547def 100644 (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 enum FailType {
 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 @@ pub fn long_to_short(&self) -> Opt {
             }
             (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 @@ pub fn long_to_short(&self) -> Opt {
                     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 @@ fn f(_x: usize) -> Vec<Optval> {
                 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
index ef89b5d25b8875b04b443af9e220b01371524f76..4edbeab5dfb11049cbedf1255d30608c16abcc6f 100644 (file)
        test(attr(deny(warnings))))]
 #![cfg_attr(not(stage0), deny(warnings))]
 
-#![feature(copy_from_slice)]
 #![feature(rustc_private)]
 #![feature(staged_api)]
 #![feature(question_mark)]
index 7affb129313c886015b53931c07bbd570bd21acc..e9ed0ed574eaffb9c2f7aa69e099af529644e9ad 100644 (file)
@@ -1494,11 +1494,14 @@ pub fn print_expr(&mut self, expr: &hir::Expr) -> io::Result<()> {
 
                 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])?;
index deb206277722071cfbd8f903aca237d5f9b67a56..d1bbbf08ac230f5a261a619c7a74aaf433bb563f 100644 (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))]
 
index d3005ff2ded251e4c68ea560d36febb8f16f953a..815e60a8e0342a1a25960cfdf426a1e50b808504 100644 (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();
index 25edaf4b8e4e9774740a34513f18934797b2b3f4..67b11a930d6f7fbbef6da55e3ef4bf84752d6b0f 100644 (file)
@@ -32,7 +32,6 @@
 
 #![feature(box_syntax)]
 #![feature(const_fn)]
-#![feature(copy_from_slice)]
 #![feature(libc)]
 #![feature(rand)]
 #![feature(rustc_private)]
index 67c52bb6c36d780eb73719cf3b3a1693edb3bf11..de1a740e0bba486e752c5d12f9137ed5b7007ee6 100644 (file)
@@ -194,7 +194,7 @@ macro_rules! controller_entry_point {
                 (control.after_analysis.callback)(state);
 
                 if control.after_analysis.stop == Compilation::Stop {
-                    return Err(0usize);
+                    return result.and_then(|_| Err(0usize));
                 }
             }
 
index d10691d12ed970c1d71c61e63e6692a04c0fab84..f4fb226d3525f7aaf598530dcf940cdd3a04018e 100644 (file)
@@ -63,7 +63,9 @@ fn is_camel_case(name: ast::Name) -> bool {
 
             // 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 {
index 2075bd5edcaeb913c3dfc002b651c4c23d789a47..e7c9097a56a58ea27bf26a1548c9a3db6edb0705 100644 (file)
@@ -36,7 +36,6 @@
 #![feature(rustc_private)]
 #![feature(slice_patterns)]
 #![feature(staged_api)]
-#![feature(str_char)]
 
 #[macro_use]
 extern crate syntax;
index 8f76bf92ef4f52665a2b2a84b1fcc61cc8352305..1cfbfb37d34bd3fb2131429eb165717d26159fc9 100644 (file)
@@ -632,7 +632,7 @@ fn bar(&mut self) { }
 
 For a somewhat artificial example:
 
-```compile_fail
+```compile_fail,ignore
 #![recursion_limit="2"]
 
 struct Foo;
index 4d8021138a0d5f62e8ff7b8299cca69a9480cc78..863cada5b88090f09a9eb434c37b93add48ca19d 100644 (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 @@ pub fn to_uppercase(self) -> ToUppercase {
 }
 
 /// 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�ic�");
 /// }
 /// ```
-#[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 @@ fn next(&mut self) -> Option<Result<char, u16>> {
             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 @@ fn size_hint(&self) -> (usize, Option<usize>) {
     }
 }
 
-/// `U+FFFD REPLACEMENT CHARACTER` (�) 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` (�) 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}';
index 34c0edd8ee1e4f235832c4c3656f46caadc21f23..bc7c7c5e0caf06d80ce8e6d6bd8e175b5cb6bdb0 100644 (file)
 #![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)]
index 1fe9a8240fa80d97e002b218c0ecb8a70c68e401..982f477fc4ae1c0c5429551048c989711e9da4ec 100644 (file)
@@ -15,7 +15,7 @@
 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 drop(&mut self) {
         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);
-
-        panic::recover(|| {
-            driver::compile_input(&b_sess, &b_cstore, (*b_cfg).clone(),
-                                  &input, &out,
-                                  &None, None, &b_control)
-        })
-    } {
+    let res = panic::catch_unwind(AssertUnwindSafe(|| {
+        driver::compile_input(&sess, &cstore, cfg.clone(),
+                              &input, &out,
+                              &None, None, &control)
+    }));
+
+    match res {
         Ok(r) => {
             match r {
                 Err(count) if count > 0 && compile_fail == false => {
index 609ebe8546164d1872790a48c32a6bb0a8e0107c..31b71dbc80b62c2bd3ce75f5e78778d6b0567590 100644 (file)
@@ -132,7 +132,10 @@ fn from_hex(&self) -> Result<Vec<u8>, FromHexError> {
                     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;
index 173ecca648c4141376a058f8c368f780a095ed57..80cd47c85ccdfd64e5b5764a12b9d4aaa11f3e04 100644 (file)
@@ -32,7 +32,6 @@
 #![feature(enumset)]
 #![feature(rustc_private)]
 #![feature(staged_api)]
-#![feature(str_char)]
 #![feature(unicode)]
 #![feature(question_mark)]
 #![cfg_attr(test, feature(test))]
index 3ae3cf8504ea4b3f57c0ac58fcdb331dbe8608e4..0db91034eb5ac8eed231b5d28b9c3f4f9bc06347 100644 (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);
 }
 
index 234042ab011bc6a5cb30b8005a2b0d28ba8821c2..c20270e830665d4ee0eb36d3bef5b9352f62166d 100644 (file)
@@ -620,8 +620,7 @@ pub fn with_capacity_and_hasher(capacity: usize, hash_builder: 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
     }
index 954adf313be0db086de984ac1f8797ff1e2ff90f..b353a4c1ba120ca6521e0bf8cf6133336c911af1 100644 (file)
@@ -194,8 +194,7 @@ pub fn with_capacity_and_hasher(capacity: usize, hasher: 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 @@ pub fn contains<Q: ?Sized>(&self, value: &Q) -> bool
     /// 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 @@ pub fn insert(&mut self, value: T) -> bool { self.map.insert(value, ()).is_none(
 
     /// 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 @@ pub fn remove<Q: ?Sized>(&mut self, value: &Q) -> bool
     /// 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
     {
index 660948b0accac4c38808906cacf071d4ca6c1b7d..35cd4a5ec5292076fef8fc29d4d8dd2f5883199f 100644 (file)
 
 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 @@ fn description(&self) -> &str {
     }
 }
 
+#[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 {
index de840457a01f471c31e30d665818d204b5bd1204..0d29e62485abb8035fa3c7a404174790cc6d61c9 100644 (file)
@@ -86,13 +86,14 @@ pub fn push<T: AsRef<OsStr>>(&mut self, s: T) {
         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 @@ pub fn with_capacity(capacity: usize) -> 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 @@ pub fn to_os_string(&self) -> OsString {
     }
 
     /// 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`.
+    ///
+    /// 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 information about encoding.
-    #[unstable(feature = "osstring_simple_functions",
-               reason = "recently added", issue = "29453")]
+    /// 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()
     }
index 6777dfdabb7c50e702d1201fb11ab61b51dfe401..03ebaa59ca56287ca76a35ffe2fa7c5161d5a572 100644 (file)
@@ -302,7 +302,7 @@ pub fn metadata(&self) -> io::Result<Metadata> {
     /// 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 @@ pub fn create(&mut self, create: bool) -> &mut 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
     }
index bcce8ee6abf4426a5e3196e5ff08f4305fdc250d..6dd7273c17fe7b614cebcc67cc4cac7c68e0468f 100644 (file)
@@ -1596,7 +1596,7 @@ fn next(&mut self) -> Option<result::Result<char, CharsError>> {
             }
         }
         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),
         })
     }
index 8dcac51417224795178f43ed77147bf182fdb4c8..e14a31453d381601f4ccf4e860f8fc4c95bcadef 100644 (file)
 #![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)]
index a915872d8ac94166df960dfd05ab5ef51cb3d934..d510339f1c5b492d29941a9cbfe10bc7e4e926d5 100644 (file)
@@ -68,7 +68,7 @@ pub fn ip(&self) -> IpAddr {
     }
 
     /// 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 @@ pub fn port(&self) -> u16 {
     }
 
     /// 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 @@ pub fn ip(&self) -> &Ipv4Addr {
     }
 
     /// 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 @@ pub fn ip(&self) -> &Ipv6Addr {
     }
 
     /// 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 @@ pub fn set_flowinfo(&mut self, new_flowinfo: u32) {
     /// 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;
     }
index 4462ce24dce048d268c2c966b9e153d6e20bde54..16401c4527f160b15dab692c8872aeff10018ccf 100644 (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 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 @@ pub fn into_inner(self) -> T {
     }
 }
 
+#[unstable(feature = "recover", issue = "27719")]
+#[allow(deprecated)]
 impl<T> Deref for AssertRecoverSafe<T> {
     type Target = T;
 
@@ -253,12 +314,16 @@ fn deref(&self) -> &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 @@ extern "rust-call" fn call_once(self, _args: ()) -> R {
     }
 }
 
-/// 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 @@ extern "rust-call" fn call_once(self, _args: ()) -> R {
 ///
 /// 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 `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
+/// 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 `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);
 /// }
 /// ```
+#[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>) -> ! {
-    unwind::rust_panic(payload)
+    resume_unwind(payload)
 }
index fcd827e2a8b722e9b4e18d17299d90cf12192ee0..83091c72c0d6bea2a2c4a0a990679effac0fd93e 100644 (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()
     };
index e673879d20db28c887149b8c48e5d1b222244359..e228d236a3ca716317dd709ecd79471c508dc971 100644 (file)
@@ -425,13 +425,13 @@ fn poison_bad() {
         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 @@ fn wait_for_force_to_finish() {
         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());
index 24e1a82a593bad2d248a3da706e55a5fb07d50c8..6f185437e50af47b3d4b7966210fbaa636284e78 100644 (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();
index f64f835e198541e720f3b899cc8673cede7a3551..55e485e5811acc687dce80d57e2f43571489f3d3 100644 (file)
@@ -191,8 +191,11 @@ pub fn from_wide(v: &[u16]) -> 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)
index 4d8f12c2d7c42f2bf0f3d2c38f2cb444d0a21bd3..1be3d75d866dd7123c663604a142fb9f8ffcfeed 100644 (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};
 }
index 8cc291d00ee027cf4cca947a1db1b0a6829ed556..7f31cf9f3bf80690b7f01506e9bdf317b3b07b78 100644 (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 @@ fn before_exec<F>(&mut self, f: F) -> &mut process::Command
     /// 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;
 }
 
index c98e42faba7c2591d22ab452dae488d383661ab3..fe2a48764dc3a99799373cf3f0878a8b61d6dca7 100644 (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
     }
index 3a07204b2bcf80f43cd514ec6b35f3b50ffabe11..36b3a3d4bdec8570f839bf1a580276f1c16973b7 100644 (file)
 
 //! 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 _
index fbe38aee295aff410ce251e5e3391c844d34e082..fc18ef407ab2f9e138f5bb435a793959bf959c47 100644 (file)
     ("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 @@ enum Status {
     ("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")),
index ab14e21e251cb00cfb30172e4e7cdaffb7ed32ea..ca7e5729c0b7a176dd83ac415e85e2acf08dd07a 100644 (file)
@@ -29,7 +29,6 @@
 #![feature(libc)]
 #![feature(rustc_private)]
 #![feature(staged_api)]
-#![feature(str_char)]
 #![feature(str_escape)]
 #![feature(unicode)]
 #![feature(question_mark)]
index b8c926f8de9cb7b693025153067bc6d8a94ffc49..c4997348537f4222ffc188b83582742b2ad72f87 100644 (file)
@@ -2578,7 +2578,7 @@ fn parse_dot_or_call_expr_with_(&mut self, e0: P<Expr>, lo: BytePos) -> PResult<
         loop {
             // expr?
             while self.eat(&token::Question) {
-                let hi = self.span.hi;
+                let hi = self.last_span.hi;
                 e = self.mk_expr(lo, hi, ExprKind::Try(e), None);
             }
 
index e2b1d2f5e7abeb85f9b3c7536e746a3ef1ad11e3..fcd83b4104130294b1f0a471e487287572031e25 100644 (file)
@@ -2209,12 +2209,14 @@ fn print_expr_outer_attr_style(&mut self,
 
                 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)?;
index b9ba1f107ad7aefa8867eb59e13d0d8a1111831f..50d2b9d31fe010b396ad1dff085d8307387bf455 100644 (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,
index f214ecdc3368dd4278ee4565b070b46c0bafb30c..8f5362b4d2895c270ca10440b0459d76b9793089 100644 (file)
@@ -21,7 +21,6 @@
 
 #![feature(rustc_private)]
 #![feature(staged_api)]
-#![feature(str_char)]
 
 extern crate fmt_macros;
 #[macro_use] extern crate log;
index 4f4aed21f994d8383c109e69ebd305862528457f..8170c9fd8f161db0ebf4bceafd079d94576c804c 100644 (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")]
 
index 58fa00fb41086d2f09a621bbfb42047dcac29491..5fc8f684a66fe01f678fdc4cb3bde67a7f15a6f3 100644 (file)
@@ -10,8 +10,6 @@
 
 // aux-build:deprecation-lint.rs
 
-#![feature(deprecated)]
-
 #![deny(deprecated)]
 #![allow(warnings)]
 
index 6ee5cd2c7e3cf171887d12ce69db6bbc325c4266..af2ac79ea80721808bcc49e694f9ba8e6c9f52a0 100644 (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() { }
index fd0f830a17d877ec79beb9383dd85de6a50e9de2..ece8fa7dc47bb12da8a4ffdbdad81c48a9a513e7 100644 (file)
 #![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
 }
index b3aa4e9187d34dc7fdb4cdb8ec18fac2c8514e7c..cc73cbe15fe5f9f16dfe8aa62b98fc895ac3b2e8 100644 (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
     };
 }
diff --git a/src/test/compile-fail/symbol-names/issue-32709.rs b/src/test/compile-fail/symbol-names/issue-32709.rs
new file mode 100644 (file)
index 0000000..f9d11f3
--- /dev/null
@@ -0,0 +1,20 @@
+// 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.
+
+#![feature(question_mark)]
+
+// Make sure that the span of try shorthand does not include the trailing
+// semicolon;
+fn a() -> Result<i32, ()> {
+    Err(5)?; //~ ERROR 16:5: 16:12
+    Ok(1)
+}
+
+fn main() {}
index f846ee8f3d0b924035886db8f93ecda1c4464404..e4792e7936bc4e067feffd0e0319958073d19677 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// pretty-expanded FIXME #23616
-
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
index 249661f003f0644b62182dfb3edc2584a28a0c92..cbe23ea0522bab27c8a37e7105f2d997833444f7 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// pretty-expanded FIXME #23616
-
 #[derive(Hash)]
 enum Foo {
     Bar(isize, char),
index 6c393ce99e34df204e3d2c2eb8b2fcc7c0cae7db..4e06c434ccc1203b597f4cb066e516df95138965 100644 (file)
@@ -10,8 +10,6 @@
 
 // calling pin_thread and that's having weird side-effects.
 
-// pretty-expanded FIXME #23616
-
 #![feature(libc)]
 
 mod rustrt1 {
index 9949b79278c11a2ecb871557a17ce481302d57d1..b918f79f2d5d6fc71f147d68a8459dc14a393f1b 100644 (file)
 #![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 bar<T>() {
         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>>>();
     }
 }
diff --git a/src/test/rustdoc/no-run-still-checks-lints.rs b/src/test/rustdoc/no-run-still-checks-lints.rs
new file mode 100644 (file)
index 0000000..a9df3c3
--- /dev/null
@@ -0,0 +1,19 @@
+// 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.
+
+// compile-flags:--test
+// should-fail
+
+#![doc(test(attr(deny(warnings))))]
+
+/// ```no_run
+/// let a = 3;
+/// ```
+pub fn foo() {}