about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2017-04-06 01:00:15 +0000
committerbors <bors@rust-lang.org>2017-04-06 01:00:15 +0000
commit6cd15a0e8fecce04fd99b77b25099bf374bb0f56 (patch)
tree47828ad744694e7cfeed50af05ee9d6c8f1b3779
parent91ae22a012fae7fa7589b1bba77bf4579708ee33 (diff)
parentd8b61091f619be7c4605e56561eba58a3618447b (diff)
downloadrust-6cd15a0e8fecce04fd99b77b25099bf374bb0f56.tar.gz
rust-6cd15a0e8fecce04fd99b77b25099bf374bb0f56.zip
Auto merge of #41098 - arielb1:rollup, r=arielb1
Rollup of 12 pull requests

- Successful merges: #40479, #40561, #40709, #40815, #40909, #40927, #40943, #41015, #41028, #41052, #41054, #41065
- Failed merges:
-rw-r--r--src/bootstrap/install.rs9
-rw-r--r--src/doc/unstable-book/src/SUMMARY.md2
-rw-r--r--src/doc/unstable-book/src/offset-to.md7
-rw-r--r--src/doc/unstable-book/src/slice-rsplit.md10
-rw-r--r--src/etc/char_private.py132
-rw-r--r--src/libcollections/lib.rs2
-rw-r--r--src/libcollections/slice.rs68
-rw-r--r--src/libcollections/vec.rs58
-rw-r--r--src/libcore/char_private.rs1238
-rw-r--r--src/libcore/iter/mod.rs12
-rw-r--r--src/libcore/iter/traits.rs2
-rw-r--r--src/libcore/ptr.rs76
-rw-r--r--src/libcore/slice/mod.rs172
-rw-r--r--src/libcore/sync/atomic.rs39
-rw-r--r--src/librustc_mir/build/cfg.rs3
-rw-r--r--src/librustc_typeck/coherence/inherent_impls_overlap.rs17
-rw-r--r--src/libstd/collections/hash/map.rs32
-rw-r--r--src/libstd/collections/hash/table.rs324
-rw-r--r--src/libstd/sys/unix/mod.rs2
-rw-r--r--src/libsyntax/parse/parser.rs57
-rw-r--r--src/libsyntax_pos/lib.rs24
-rw-r--r--src/test/ui/codemap_tests/coherence-overlapping-inherent-impl-trait.rs (renamed from src/test/compile-fail/coherence-overlapping-inherent-impl-trait.rs)2
-rw-r--r--src/test/ui/codemap_tests/coherence-overlapping-inherent-impl-trait.stderr10
-rw-r--r--src/test/ui/codemap_tests/overlapping_inherent_impls.rs (renamed from src/test/compile-fail/inherent-overlap.rs)6
-rw-r--r--src/test/ui/codemap_tests/overlapping_inherent_impls.stderr29
-rw-r--r--src/test/ui/did_you_mean/issue-40006.rs21
-rw-r--r--src/test/ui/did_you_mean/issue-40006.stderr8
27 files changed, 1275 insertions, 1087 deletions
diff --git a/src/bootstrap/install.rs b/src/bootstrap/install.rs
index 249f241a151..25082e3a9d0 100644
--- a/src/bootstrap/install.rs
+++ b/src/bootstrap/install.rs
@@ -49,12 +49,17 @@ pub fn install(build: &Build, stage: u32, host: &str) {
         install_sh(&build, "docs", "rust-docs", stage, host, &prefix,
                    &docdir, &libdir, &mandir, &empty_dir);
     }
+
+    for target in build.config.target.iter() {
+        install_sh(&build, "std", "rust-std", stage, target, &prefix,
+                   &docdir, &libdir, &mandir, &empty_dir);
+    }
+
     if build.config.rust_save_analysis {
         install_sh(&build, "analysis", "rust-analysis", stage, host, &prefix,
                    &docdir, &libdir, &mandir, &empty_dir);
     }
-    install_sh(&build, "std", "rust-std", stage, host, &prefix,
-               &docdir, &libdir, &mandir, &empty_dir);
+
     install_sh(&build, "rustc", "rustc", stage, host, &prefix,
                &docdir, &libdir, &mandir, &empty_dir);
     t!(fs::remove_dir_all(&empty_dir));
diff --git a/src/doc/unstable-book/src/SUMMARY.md b/src/doc/unstable-book/src/SUMMARY.md
index 72c2461c8bb..9ce097e78a4 100644
--- a/src/doc/unstable-book/src/SUMMARY.md
+++ b/src/doc/unstable-book/src/SUMMARY.md
@@ -123,6 +123,7 @@
 - [no_debug](no-debug.md)
 - [non_ascii_idents](non-ascii-idents.md)
 - [nonzero](nonzero.md)
+- [offset_to](offset-to.md)
 - [omit_gdb_pretty_printer_section](omit-gdb-pretty-printer-section.md)
 - [on_unimplemented](on-unimplemented.md)
 - [once_poison](once-poison.md)
@@ -171,6 +172,7 @@
 - [slice_concat_ext](slice-concat-ext.md)
 - [slice_get_slice](slice-get-slice.md)
 - [slice_patterns](slice-patterns.md)
+- [slice_rsplit](slice-rsplit.md)
 - [sort_internals](sort-internals.md)
 - [sort_unstable](sort-unstable.md)
 - [specialization](specialization.md)
diff --git a/src/doc/unstable-book/src/offset-to.md b/src/doc/unstable-book/src/offset-to.md
new file mode 100644
index 00000000000..03d990eb4ae
--- /dev/null
+++ b/src/doc/unstable-book/src/offset-to.md
@@ -0,0 +1,7 @@
+# `offset_to`
+
+The tracking issue for this feature is: [#41079]
+
+[#41079]: https://github.com/rust-lang/rust/issues/41079
+
+------------------------
diff --git a/src/doc/unstable-book/src/slice-rsplit.md b/src/doc/unstable-book/src/slice-rsplit.md
new file mode 100644
index 00000000000..8c2954f7294
--- /dev/null
+++ b/src/doc/unstable-book/src/slice-rsplit.md
@@ -0,0 +1,10 @@
+# `slice_rsplit`
+
+The tracking issue for this feature is: [#41020]
+
+[#41020]: https://github.com/rust-lang/rust/issues/41020
+
+------------------------
+
+The `slice_rsplit` feature enables two methods on slices:
+`slice.rsplit(predicate)` and `slice.rsplit_mut(predicate)`.
diff --git a/src/etc/char_private.py b/src/etc/char_private.py
index 9d15f98e067..75ab3f1a17b 100644
--- a/src/etc/char_private.py
+++ b/src/etc/char_private.py
@@ -76,6 +76,66 @@ def get_codepoints(f):
     for c in range(prev_codepoint + 1, NUM_CODEPOINTS):
         yield Codepoint(c, None)
 
+def compress_singletons(singletons):
+    uppers = [] # (upper, # items in lowers)
+    lowers = []
+
+    for i in singletons:
+        upper = i >> 8
+        lower = i & 0xff
+        if len(uppers) == 0 or uppers[-1][0] != upper:
+            uppers.append((upper, 1))
+        else:
+            upper, count = uppers[-1]
+            uppers[-1] = upper, count + 1
+        lowers.append(lower)
+
+    return uppers, lowers
+
+def compress_normal(normal):
+    # lengths 0x00..0x7f are encoded as 00, 01, ..., 7e, 7f
+    # lengths 0x80..0x7fff are encoded as 80 80, 80 81, ..., ff fe, ff ff
+    compressed = [] # [truelen, (truelenaux), falselen, (falselenaux)]
+
+    prev_start = 0
+    for start, count in normal:
+        truelen = start - prev_start
+        falselen = count
+        prev_start = start + count
+
+        assert truelen < 0x8000 and falselen < 0x8000
+        entry = []
+        if truelen > 0x7f:
+            entry.append(0x80 | (truelen >> 8))
+            entry.append(truelen & 0xff)
+        else:
+            entry.append(truelen & 0x7f)
+        if falselen > 0x7f:
+            entry.append(0x80 | (falselen >> 8))
+            entry.append(falselen & 0xff)
+        else:
+            entry.append(falselen & 0x7f)
+
+        compressed.append(entry)
+
+    return compressed
+
+def print_singletons(uppers, lowers, uppersname, lowersname):
+    print("const {}: &'static [(u8, u8)] = &[".format(uppersname))
+    for u, c in uppers:
+        print("    ({:#04x}, {}),".format(u, c))
+    print("];")
+    print("const {}: &'static [u8] = &[".format(lowersname))
+    for i in range(0, len(lowers), 8):
+        print("    {}".format(" ".join("{:#04x},".format(l) for l in lowers[i:i+8])))
+    print("];")
+
+def print_normal(normal, normalname):
+    print("const {}: &'static [u8] = &[".format(normalname))
+    for v in normal:
+        print("    {}".format(" ".join("{:#04x},".format(i) for i in v)))
+    print("];")
+
 def main():
     file = get_file("http://www.unicode.org/Public/UNIDATA/UnicodeData.txt")
 
@@ -111,6 +171,11 @@ def main():
             else:
                 normal0.append((a, b - a))
 
+    singletons0u, singletons0l = compress_singletons(singletons0)
+    singletons1u, singletons1l = compress_singletons(singletons1)
+    normal0 = compress_normal(normal0)
+    normal1 = compress_normal(normal1)
+
     print("""\
 // Copyright 2012-2016 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
@@ -125,38 +190,49 @@ def main():
 // NOTE: The following code was generated by "src/etc/char_private.py",
 //       do not edit directly!
 
-use slice::SliceExt;
-
-fn check(x: u16, singletons: &[u16], normal: &[u16]) -> bool {
-    for &s in singletons {
-        if x == s {
-            return false;
-        } else if x < s {
+fn check(x: u16, singletonuppers: &[(u8, u8)], singletonlowers: &[u8],
+         normal: &[u8]) -> bool {
+    let xupper = (x >> 8) as u8;
+    let mut lowerstart = 0;
+    for &(upper, lowercount) in singletonuppers {
+        let lowerend = lowerstart + lowercount as usize;
+        if xupper == upper {
+            for &lower in &singletonlowers[lowerstart..lowerend] {
+                if lower == x as u8 {
+                    return false;
+                }
+            }
+        } else if xupper < upper {
             break;
         }
+        lowerstart = lowerend;
     }
-    for w in normal.chunks(2) {
-        let start = w[0];
-        let len = w[1];
-        let difference = (x as i32) - (start as i32);
-        if 0 <= difference {
-            if difference < len as i32 {
-                return false;
-            }
+
+    let mut x = x as i32;
+    let mut normal = normal.iter().cloned();
+    let mut current = true;
+    while let Some(v) = normal.next() {
+        let len = if v & 0x80 != 0 {
+            ((v & 0x7f) as i32) << 8 | normal.next().unwrap() as i32
         } else {
+            v as i32
+        };
+        x -= len;
+        if x < 0 {
             break;
         }
+        current = !current;
     }
-    true
+    current
 }
 
 pub fn is_printable(x: char) -> bool {
     let x = x as u32;
     let lower = x as u16;
     if x < 0x10000 {
-        check(lower, SINGLETONS0, NORMAL0)
+        check(lower, SINGLETONS0U, SINGLETONS0L, NORMAL0)
     } else if x < 0x20000 {
-        check(lower, SINGLETONS1, NORMAL1)
+        check(lower, SINGLETONS1U, SINGLETONS1L, NORMAL1)
     } else {\
 """)
     for a, b in extra:
@@ -169,22 +245,10 @@ pub fn is_printable(x: char) -> bool {
 }\
 """)
     print()
-    print("const SINGLETONS0: &'static [u16] = &[")
-    for s in singletons0:
-        print("    0x{:x},".format(s))
-    print("];")
-    print("const SINGLETONS1: &'static [u16] = &[")
-    for s in singletons1:
-        print("    0x{:x},".format(s))
-    print("];")
-    print("const NORMAL0: &'static [u16] = &[")
-    for a, b in normal0:
-        print("    0x{:x}, 0x{:x},".format(a, b))
-    print("];")
-    print("const NORMAL1: &'static [u16] = &[")
-    for a, b in normal1:
-        print("    0x{:x}, 0x{:x},".format(a, b))
-    print("];")
+    print_singletons(singletons0u, singletons0l, 'SINGLETONS0U', 'SINGLETONS0L')
+    print_singletons(singletons1u, singletons1l, 'SINGLETONS1U', 'SINGLETONS1L')
+    print_normal(normal0, 'NORMAL0')
+    print_normal(normal1, 'NORMAL1')
 
 if __name__ == '__main__':
     main()
diff --git a/src/libcollections/lib.rs b/src/libcollections/lib.rs
index 00448b6abb2..248c15e96f8 100644
--- a/src/libcollections/lib.rs
+++ b/src/libcollections/lib.rs
@@ -52,6 +52,7 @@
 #![feature(shared)]
 #![feature(slice_get_slice)]
 #![feature(slice_patterns)]
+#![feature(slice_rsplit)]
 #![cfg_attr(not(test), feature(sort_unstable))]
 #![feature(specialization)]
 #![feature(staged_api)]
@@ -62,6 +63,7 @@
 #![feature(untagged_unions)]
 #![cfg_attr(not(test), feature(str_checked_slicing))]
 #![cfg_attr(test, feature(rand, test))]
+#![feature(offset_to)]
 
 #![no_std]
 
diff --git a/src/libcollections/slice.rs b/src/libcollections/slice.rs
index 6f8843c2374..6cff315a6cc 100644
--- a/src/libcollections/slice.rs
+++ b/src/libcollections/slice.rs
@@ -115,6 +115,8 @@ pub use core::slice::{Iter, IterMut};
 pub use core::slice::{SplitMut, ChunksMut, Split};
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use core::slice::{SplitN, RSplitN, SplitNMut, RSplitNMut};
+#[unstable(feature = "slice_rsplit", issue = "41020")]
+pub use core::slice::{RSplit, RSplitMut};
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use core::slice::{from_raw_parts, from_raw_parts_mut};
 #[unstable(feature = "slice_get_slice", issue = "35729")]
@@ -780,6 +782,72 @@ impl<T> [T] {
     }
 
     /// Returns an iterator over subslices separated by elements that match
+    /// `pred`, starting at the end of the slice and working backwards.
+    /// The matched element is not contained in the subslices.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(slice_rsplit)]
+    ///
+    /// let slice = [11, 22, 33, 0, 44, 55];
+    /// let mut iter = slice.rsplit(|num| *num == 0);
+    ///
+    /// assert_eq!(iter.next().unwrap(), &[44, 55]);
+    /// assert_eq!(iter.next().unwrap(), &[11, 22, 33]);
+    /// assert_eq!(iter.next(), None);
+    /// ```
+    ///
+    /// As with `split()`, if the first or last element is matched, an empty
+    /// slice will be the first (or last) item returned by the iterator.
+    ///
+    /// ```
+    /// #![feature(slice_rsplit)]
+    ///
+    /// let v = &[0, 1, 1, 2, 3, 5, 8];
+    /// let mut it = v.rsplit(|n| *n % 2 == 0);
+    /// assert_eq!(it.next().unwrap(), &[]);
+    /// assert_eq!(it.next().unwrap(), &[3, 5]);
+    /// assert_eq!(it.next().unwrap(), &[1, 1]);
+    /// assert_eq!(it.next().unwrap(), &[]);
+    /// assert_eq!(it.next(), None);
+    /// ```
+    #[unstable(feature = "slice_rsplit", issue = "41020")]
+    #[inline]
+    pub fn rsplit<F>(&self, pred: F) -> RSplit<T, F>
+        where F: FnMut(&T) -> bool
+    {
+        core_slice::SliceExt::rsplit(self, pred)
+    }
+
+    /// Returns an iterator over mutable subslices separated by elements that
+    /// match `pred`, starting at the end of the slice and working
+    /// backwards. The matched element is not contained in the subslices.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(slice_rsplit)]
+    ///
+    /// let mut v = [100, 400, 300, 200, 600, 500];
+    ///
+    /// let mut count = 0;
+    /// for group in v.rsplit_mut(|num| *num % 3 == 0) {
+    ///     count += 1;
+    ///     group[0] = count;
+    /// }
+    /// assert_eq!(v, [3, 400, 300, 2, 600, 1]);
+    /// ```
+    ///
+    #[unstable(feature = "slice_rsplit", issue = "41020")]
+    #[inline]
+    pub fn rsplit_mut<F>(&mut self, pred: F) -> RSplitMut<T, F>
+        where F: FnMut(&T) -> bool
+    {
+        core_slice::SliceExt::rsplit_mut(self, pred)
+    }
+
+    /// Returns an iterator over subslices separated by elements that match
     /// `pred`, limited to returning at most `n` items. The matched element is
     /// not contained in the subslices.
     ///
diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs
index be613e06b02..c258ac2bdea 100644
--- a/src/libcollections/vec.rs
+++ b/src/libcollections/vec.rs
@@ -973,6 +973,29 @@ impl<T> Vec<T> {
         }
     }
 
+    /// Returns a place for insertion at the back of the `Vec`.
+    ///
+    /// Using this method with placement syntax is equivalent to [`push`](#method.push),
+    /// but may be more efficient.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(collection_placement)]
+    /// #![feature(placement_in_syntax)]
+    ///
+    /// let mut vec = vec![1, 2];
+    /// vec.place_back() <- 3;
+    /// vec.place_back() <- 4;
+    /// assert_eq!(&vec, &[1, 2, 3, 4]);
+    /// ```
+    #[unstable(feature = "collection_placement",
+               reason = "placement protocol is subject to change",
+               issue = "30172")]
+    pub fn place_back(&mut self) -> PlaceBack<T> {
+        PlaceBack { vec: self }
+    }
+
     /// Removes the last element from a vector and returns it, or [`None`] if it
     /// is empty.
     ///
@@ -1267,29 +1290,6 @@ impl<T: Clone> Vec<T> {
     pub fn extend_from_slice(&mut self, other: &[T]) {
         self.spec_extend(other.iter())
     }
-
-    /// Returns a place for insertion at the back of the `Vec`.
-    ///
-    /// Using this method with placement syntax is equivalent to [`push`](#method.push),
-    /// but may be more efficient.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// #![feature(collection_placement)]
-    /// #![feature(placement_in_syntax)]
-    ///
-    /// let mut vec = vec![1, 2];
-    /// vec.place_back() <- 3;
-    /// vec.place_back() <- 4;
-    /// assert_eq!(&vec, &[1, 2, 3, 4]);
-    /// ```
-    #[unstable(feature = "collection_placement",
-               reason = "placement protocol is subject to change",
-               issue = "30172")]
-    pub fn place_back(&mut self) -> PlaceBack<T> {
-        PlaceBack { vec: self }
-    }
 }
 
 // Set the length of the vec when the `SetLenOnDrop` value goes out of scope.
@@ -2074,14 +2074,10 @@ impl<T> Iterator for IntoIter<T> {
 
     #[inline]
     fn size_hint(&self) -> (usize, Option<usize>) {
-        let diff = (self.end as usize) - (self.ptr as usize);
-        let size = mem::size_of::<T>();
-        let exact = diff /
-                    (if size == 0 {
-                         1
-                     } else {
-                         size
-                     });
+        let exact = match self.ptr.offset_to(self.end) {
+            Some(x) => x as usize,
+            None => (self.end as usize).wrapping_sub(self.ptr as usize),
+        };
         (exact, Some(exact))
     }
 
diff --git a/src/libcore/char_private.rs b/src/libcore/char_private.rs
index ddc473592a2..2c0f449b276 100644
--- a/src/libcore/char_private.rs
+++ b/src/libcore/char_private.rs
@@ -11,38 +11,49 @@
 // NOTE: The following code was generated by "src/etc/char_private.py",
 //       do not edit directly!
 
-use slice::SliceExt;
-
-fn check(x: u16, singletons: &[u16], normal: &[u16]) -> bool {
-    for &s in singletons {
-        if x == s {
-            return false;
-        } else if x < s {
+fn check(x: u16, singletonuppers: &[(u8, u8)], singletonlowers: &[u8],
+         normal: &[u8]) -> bool {
+    let xupper = (x >> 8) as u8;
+    let mut lowerstart = 0;
+    for &(upper, lowercount) in singletonuppers {
+        let lowerend = lowerstart + lowercount as usize;
+        if xupper == upper {
+            for &lower in &singletonlowers[lowerstart..lowerend] {
+                if lower == x as u8 {
+                    return false;
+                }
+            }
+        } else if xupper < upper {
             break;
         }
+        lowerstart = lowerend;
     }
-    for w in normal.chunks(2) {
-        let start = w[0];
-        let len = w[1];
-        let difference = (x as i32) - (start as i32);
-        if 0 <= difference {
-            if difference < len as i32 {
-                return false;
-            }
+
+    let mut x = x as i32;
+    let mut normal = normal.iter().cloned();
+    let mut current = true;
+    while let Some(v) = normal.next() {
+        let len = if v & 0x80 != 0 {
+            ((v & 0x7f) as i32) << 8 | normal.next().unwrap() as i32
         } else {
+            v as i32
+        };
+        x -= len;
+        if x < 0 {
             break;
         }
+        current = !current;
     }
-    true
+    current
 }
 
 pub fn is_printable(x: char) -> bool {
     let x = x as u32;
     let lower = x as u16;
     if x < 0x10000 {
-        check(lower, SINGLETONS0, NORMAL0)
+        check(lower, SINGLETONS0U, SINGLETONS0L, NORMAL0)
     } else if x < 0x20000 {
-        check(lower, SINGLETONS1, NORMAL1)
+        check(lower, SINGLETONS1U, SINGLETONS1L, NORMAL1)
     } else {
         if 0x2a6d7 <= x && x < 0x2a700 {
             return false;
@@ -66,761 +77,446 @@ pub fn is_printable(x: char) -> bool {
     }
 }
 
-const SINGLETONS0: &'static [u16] = &[
-    0xad,
-    0x378,
-    0x379,
-    0x38b,
-    0x38d,
-    0x3a2,
-    0x530,
-    0x557,
-    0x558,
-    0x560,
-    0x588,
-    0x58b,
-    0x58c,
-    0x590,
-    0x61c,
-    0x61d,
-    0x6dd,
-    0x70e,
-    0x70f,
-    0x74b,
-    0x74c,
-    0x82e,
-    0x82f,
-    0x83f,
-    0x85c,
-    0x85d,
-    0x8b5,
-    0x8e2,
-    0x984,
-    0x98d,
-    0x98e,
-    0x991,
-    0x992,
-    0x9a9,
-    0x9b1,
-    0x9ba,
-    0x9bb,
-    0x9c5,
-    0x9c6,
-    0x9c9,
-    0x9ca,
-    0x9de,
-    0x9e4,
-    0x9e5,
-    0xa04,
-    0xa11,
-    0xa12,
-    0xa29,
-    0xa31,
-    0xa34,
-    0xa37,
-    0xa3a,
-    0xa3b,
-    0xa3d,
-    0xa49,
-    0xa4a,
-    0xa5d,
-    0xa84,
-    0xa8e,
-    0xa92,
-    0xaa9,
-    0xab1,
-    0xab4,
-    0xaba,
-    0xabb,
-    0xac6,
-    0xaca,
-    0xace,
-    0xacf,
-    0xae4,
-    0xae5,
-    0xb04,
-    0xb0d,
-    0xb0e,
-    0xb11,
-    0xb12,
-    0xb29,
-    0xb31,
-    0xb34,
-    0xb3a,
-    0xb3b,
-    0xb45,
-    0xb46,
-    0xb49,
-    0xb4a,
-    0xb5e,
-    0xb64,
-    0xb65,
-    0xb84,
-    0xb91,
-    0xb9b,
-    0xb9d,
-    0xbc9,
-    0xbce,
-    0xbcf,
-    0xc04,
-    0xc0d,
-    0xc11,
-    0xc29,
-    0xc45,
-    0xc49,
-    0xc57,
-    0xc64,
-    0xc65,
-    0xc84,
-    0xc8d,
-    0xc91,
-    0xca9,
-    0xcb4,
-    0xcba,
-    0xcbb,
-    0xcc5,
-    0xcc9,
-    0xcdf,
-    0xce4,
-    0xce5,
-    0xcf0,
-    0xd04,
-    0xd0d,
-    0xd11,
-    0xd3b,
-    0xd3c,
-    0xd45,
-    0xd49,
-    0xd64,
-    0xd65,
-    0xd80,
-    0xd81,
-    0xd84,
-    0xdb2,
-    0xdbc,
-    0xdbe,
-    0xdbf,
-    0xdd5,
-    0xdd7,
-    0xdf0,
-    0xdf1,
-    0xe83,
-    0xe85,
-    0xe86,
-    0xe89,
-    0xe8b,
-    0xe8c,
-    0xe98,
-    0xea0,
-    0xea4,
-    0xea6,
-    0xea8,
-    0xea9,
-    0xeac,
-    0xeba,
-    0xebe,
-    0xebf,
-    0xec5,
-    0xec7,
-    0xece,
-    0xecf,
-    0xeda,
-    0xedb,
-    0xf48,
-    0xf98,
-    0xfbd,
-    0xfcd,
-    0x10c6,
-    0x10ce,
-    0x10cf,
-    0x1249,
-    0x124e,
-    0x124f,
-    0x1257,
-    0x1259,
-    0x125e,
-    0x125f,
-    0x1289,
-    0x128e,
-    0x128f,
-    0x12b1,
-    0x12b6,
-    0x12b7,
-    0x12bf,
-    0x12c1,
-    0x12c6,
-    0x12c7,
-    0x12d7,
-    0x1311,
-    0x1316,
-    0x1317,
-    0x135b,
-    0x135c,
-    0x13f6,
-    0x13f7,
-    0x13fe,
-    0x13ff,
-    0x1680,
-    0x170d,
-    0x176d,
-    0x1771,
-    0x17de,
-    0x17df,
-    0x180e,
-    0x180f,
-    0x191f,
-    0x196e,
-    0x196f,
-    0x1a1c,
-    0x1a1d,
-    0x1a5f,
-    0x1a7d,
-    0x1a7e,
-    0x1aae,
-    0x1aaf,
-    0x1cf7,
-    0x1f16,
-    0x1f17,
-    0x1f1e,
-    0x1f1f,
-    0x1f46,
-    0x1f47,
-    0x1f4e,
-    0x1f4f,
-    0x1f58,
-    0x1f5a,
-    0x1f5c,
-    0x1f5e,
-    0x1f7e,
-    0x1f7f,
-    0x1fb5,
-    0x1fc5,
-    0x1fd4,
-    0x1fd5,
-    0x1fdc,
-    0x1ff0,
-    0x1ff1,
-    0x1ff5,
-    0x2072,
-    0x2073,
-    0x208f,
-    0x23ff,
-    0x2b74,
-    0x2b75,
-    0x2b96,
-    0x2b97,
-    0x2bc9,
-    0x2c2f,
-    0x2c5f,
-    0x2d26,
-    0x2d2e,
-    0x2d2f,
-    0x2da7,
-    0x2daf,
-    0x2db7,
-    0x2dbf,
-    0x2dc7,
-    0x2dcf,
-    0x2dd7,
-    0x2ddf,
-    0x2e9a,
-    0x3040,
-    0x3097,
-    0x3098,
-    0x318f,
-    0x321f,
-    0x32ff,
-    0xa7af,
-    0xa8fe,
-    0xa8ff,
-    0xa9ce,
-    0xa9ff,
-    0xaa4e,
-    0xaa4f,
-    0xaa5a,
-    0xaa5b,
-    0xab07,
-    0xab08,
-    0xab0f,
-    0xab10,
-    0xab27,
-    0xab2f,
-    0xabee,
-    0xabef,
-    0xfa6e,
-    0xfa6f,
-    0xfb37,
-    0xfb3d,
-    0xfb3f,
-    0xfb42,
-    0xfb45,
-    0xfd90,
-    0xfd91,
-    0xfdfe,
-    0xfdff,
-    0xfe53,
-    0xfe67,
-    0xfe75,
-    0xffc8,
-    0xffc9,
-    0xffd0,
-    0xffd1,
-    0xffd8,
-    0xffd9,
-    0xffe7,
-    0xfffe,
-    0xffff,
+const SINGLETONS0U: &'static [(u8, u8)] = &[
+    (0x00, 1),
+    (0x03, 5),
+    (0x05, 8),
+    (0x06, 3),
+    (0x07, 4),
+    (0x08, 7),
+    (0x09, 16),
+    (0x0a, 27),
+    (0x0b, 24),
+    (0x0c, 22),
+    (0x0d, 20),
+    (0x0e, 22),
+    (0x0f, 4),
+    (0x10, 3),
+    (0x12, 18),
+    (0x13, 9),
+    (0x16, 1),
+    (0x17, 5),
+    (0x18, 2),
+    (0x19, 3),
+    (0x1a, 7),
+    (0x1c, 1),
+    (0x1f, 22),
+    (0x20, 3),
+    (0x23, 1),
+    (0x2b, 5),
+    (0x2c, 2),
+    (0x2d, 11),
+    (0x2e, 1),
+    (0x30, 3),
+    (0x31, 1),
+    (0x32, 2),
+    (0xa7, 1),
+    (0xa8, 2),
+    (0xa9, 2),
+    (0xaa, 4),
+    (0xab, 8),
+    (0xfa, 2),
+    (0xfb, 5),
+    (0xfd, 4),
+    (0xfe, 3),
+    (0xff, 9),
 ];
-const SINGLETONS1: &'static [u16] = &[
-    0xc,
-    0x27,
-    0x3b,
-    0x3e,
-    0x4e,
-    0x4f,
-    0x18f,
-    0x39e,
-    0x49e,
-    0x49f,
-    0x806,
-    0x807,
-    0x809,
-    0x836,
-    0x83d,
-    0x83e,
-    0x856,
-    0x8f3,
-    0x9d0,
-    0x9d1,
-    0xa04,
-    0xa14,
-    0xa18,
-    0xb56,
-    0xb57,
-    0x10bd,
-    0x1135,
-    0x11ce,
-    0x11cf,
-    0x11e0,
-    0x1212,
-    0x1287,
-    0x1289,
-    0x128e,
-    0x129e,
-    0x1304,
-    0x130d,
-    0x130e,
-    0x1311,
-    0x1312,
-    0x1329,
-    0x1331,
-    0x1334,
-    0x133a,
-    0x133b,
-    0x1345,
-    0x1346,
-    0x1349,
-    0x134a,
-    0x134e,
-    0x134f,
-    0x1364,
-    0x1365,
-    0x145a,
-    0x145c,
-    0x15b6,
-    0x15b7,
-    0x1c09,
-    0x1c37,
-    0x1c90,
-    0x1c91,
-    0x1ca8,
-    0x246f,
-    0x6a5f,
-    0x6aee,
-    0x6aef,
-    0x6b5a,
-    0x6b62,
-    0xbc9a,
-    0xbc9b,
-    0xd127,
-    0xd128,
-    0xd455,
-    0xd49d,
-    0xd4a0,
-    0xd4a1,
-    0xd4a3,
-    0xd4a4,
-    0xd4a7,
-    0xd4a8,
-    0xd4ad,
-    0xd4ba,
-    0xd4bc,
-    0xd4c4,
-    0xd506,
-    0xd50b,
-    0xd50c,
-    0xd515,
-    0xd51d,
-    0xd53a,
-    0xd53f,
-    0xd545,
-    0xd551,
-    0xd6a6,
-    0xd6a7,
-    0xd7cc,
-    0xd7cd,
-    0xdaa0,
-    0xe007,
-    0xe019,
-    0xe01a,
-    0xe022,
-    0xe025,
-    0xe8c5,
-    0xe8c6,
-    0xee04,
-    0xee20,
-    0xee23,
-    0xee25,
-    0xee26,
-    0xee28,
-    0xee33,
-    0xee38,
-    0xee3a,
-    0xee48,
-    0xee4a,
-    0xee4c,
-    0xee50,
-    0xee53,
-    0xee55,
-    0xee56,
-    0xee58,
-    0xee5a,
-    0xee5c,
-    0xee5e,
-    0xee60,
-    0xee63,
-    0xee65,
-    0xee66,
-    0xee6b,
-    0xee73,
-    0xee78,
-    0xee7d,
-    0xee7f,
-    0xee8a,
-    0xeea4,
-    0xeeaa,
-    0xf0af,
-    0xf0b0,
-    0xf0c0,
-    0xf0d0,
-    0xf12f,
-    0xf91f,
-    0xf931,
-    0xf932,
-    0xf93f,
+const SINGLETONS0L: &'static [u8] = &[
+    0xad, 0x78, 0x79, 0x8b, 0x8d, 0xa2, 0x30, 0x57,
+    0x58, 0x60, 0x88, 0x8b, 0x8c, 0x90, 0x1c, 0x1d,
+    0xdd, 0x0e, 0x0f, 0x4b, 0x4c, 0x2e, 0x2f, 0x3f,
+    0x5c, 0x5d, 0xb5, 0xe2, 0x84, 0x8d, 0x8e, 0x91,
+    0x92, 0xa9, 0xb1, 0xba, 0xbb, 0xc5, 0xc6, 0xc9,
+    0xca, 0xde, 0xe4, 0xe5, 0x04, 0x11, 0x12, 0x29,
+    0x31, 0x34, 0x37, 0x3a, 0x3b, 0x3d, 0x49, 0x4a,
+    0x5d, 0x84, 0x8e, 0x92, 0xa9, 0xb1, 0xb4, 0xba,
+    0xbb, 0xc6, 0xca, 0xce, 0xcf, 0xe4, 0xe5, 0x04,
+    0x0d, 0x0e, 0x11, 0x12, 0x29, 0x31, 0x34, 0x3a,
+    0x3b, 0x45, 0x46, 0x49, 0x4a, 0x5e, 0x64, 0x65,
+    0x84, 0x91, 0x9b, 0x9d, 0xc9, 0xce, 0xcf, 0x04,
+    0x0d, 0x11, 0x29, 0x45, 0x49, 0x57, 0x64, 0x65,
+    0x84, 0x8d, 0x91, 0xa9, 0xb4, 0xba, 0xbb, 0xc5,
+    0xc9, 0xdf, 0xe4, 0xe5, 0xf0, 0x04, 0x0d, 0x11,
+    0x3b, 0x3c, 0x45, 0x49, 0x64, 0x65, 0x80, 0x81,
+    0x84, 0xb2, 0xbc, 0xbe, 0xbf, 0xd5, 0xd7, 0xf0,
+    0xf1, 0x83, 0x85, 0x86, 0x89, 0x8b, 0x8c, 0x98,
+    0xa0, 0xa4, 0xa6, 0xa8, 0xa9, 0xac, 0xba, 0xbe,
+    0xbf, 0xc5, 0xc7, 0xce, 0xcf, 0xda, 0xdb, 0x48,
+    0x98, 0xbd, 0xcd, 0xc6, 0xce, 0xcf, 0x49, 0x4e,
+    0x4f, 0x57, 0x59, 0x5e, 0x5f, 0x89, 0x8e, 0x8f,
+    0xb1, 0xb6, 0xb7, 0xbf, 0xc1, 0xc6, 0xc7, 0xd7,
+    0x11, 0x16, 0x17, 0x5b, 0x5c, 0xf6, 0xf7, 0xfe,
+    0xff, 0x80, 0x0d, 0x6d, 0x71, 0xde, 0xdf, 0x0e,
+    0x0f, 0x1f, 0x6e, 0x6f, 0x1c, 0x1d, 0x5f, 0x7d,
+    0x7e, 0xae, 0xaf, 0xf7, 0x16, 0x17, 0x1e, 0x1f,
+    0x46, 0x47, 0x4e, 0x4f, 0x58, 0x5a, 0x5c, 0x5e,
+    0x7e, 0x7f, 0xb5, 0xc5, 0xd4, 0xd5, 0xdc, 0xf0,
+    0xf1, 0xf5, 0x72, 0x73, 0x8f, 0xff, 0x74, 0x75,
+    0x96, 0x97, 0xc9, 0x2f, 0x5f, 0x26, 0x2e, 0x2f,
+    0xa7, 0xaf, 0xb7, 0xbf, 0xc7, 0xcf, 0xd7, 0xdf,
+    0x9a, 0x40, 0x97, 0x98, 0x8f, 0x1f, 0xff, 0xaf,
+    0xfe, 0xff, 0xce, 0xff, 0x4e, 0x4f, 0x5a, 0x5b,
+    0x07, 0x08, 0x0f, 0x10, 0x27, 0x2f, 0xee, 0xef,
+    0x6e, 0x6f, 0x37, 0x3d, 0x3f, 0x42, 0x45, 0x90,
+    0x91, 0xfe, 0xff, 0x53, 0x67, 0x75, 0xc8, 0xc9,
+    0xd0, 0xd1, 0xd8, 0xd9, 0xe7, 0xfe, 0xff,
 ];
-const NORMAL0: &'static [u16] = &[
-    0x0, 0x20,
-    0x7f, 0x22,
-    0x380, 0x4,
-    0x5c8, 0x8,
-    0x5eb, 0x5,
-    0x5f5, 0x11,
-    0x7b2, 0xe,
-    0x7fb, 0x5,
-    0x85f, 0x41,
-    0x8be, 0x16,
-    0x9b3, 0x3,
-    0x9cf, 0x8,
-    0x9d8, 0x4,
-    0x9fc, 0x5,
-    0xa0b, 0x4,
-    0xa43, 0x4,
-    0xa4e, 0x3,
-    0xa52, 0x7,
-    0xa5f, 0x7,
-    0xa76, 0xb,
-    0xad1, 0xf,
-    0xaf2, 0x7,
-    0xafa, 0x7,
-    0xb4e, 0x8,
-    0xb58, 0x4,
-    0xb78, 0xa,
-    0xb8b, 0x3,
-    0xb96, 0x3,
-    0xba0, 0x3,
-    0xba5, 0x3,
-    0xbab, 0x3,
-    0xbba, 0x4,
-    0xbc3, 0x3,
-    0xbd1, 0x6,
-    0xbd8, 0xe,
-    0xbfb, 0x5,
-    0xc3a, 0x3,
-    0xc4e, 0x7,
-    0xc5b, 0x5,
-    0xc70, 0x8,
-    0xcce, 0x7,
-    0xcd7, 0x7,
-    0xcf3, 0xe,
-    0xd50, 0x4,
-    0xd97, 0x3,
-    0xdc7, 0x3,
-    0xdcb, 0x4,
-    0xde0, 0x6,
-    0xdf5, 0xc,
-    0xe3b, 0x4,
-    0xe5c, 0x25,
-    0xe8e, 0x6,
-    0xee0, 0x20,
-    0xf6d, 0x4,
-    0xfdb, 0x25,
-    0x10c8, 0x5,
-    0x137d, 0x3,
-    0x139a, 0x6,
-    0x169d, 0x3,
-    0x16f9, 0x7,
-    0x1715, 0xb,
-    0x1737, 0x9,
-    0x1754, 0xc,
-    0x1774, 0xc,
-    0x17ea, 0x6,
-    0x17fa, 0x6,
-    0x181a, 0x6,
-    0x1878, 0x8,
-    0x18ab, 0x5,
-    0x18f6, 0xa,
-    0x192c, 0x4,
-    0x193c, 0x4,
-    0x1941, 0x3,
-    0x1975, 0xb,
-    0x19ac, 0x4,
-    0x19ca, 0x6,
-    0x19db, 0x3,
-    0x1a8a, 0x6,
-    0x1a9a, 0x6,
-    0x1abf, 0x41,
-    0x1b4c, 0x4,
-    0x1b7d, 0x3,
-    0x1bf4, 0x8,
-    0x1c38, 0x3,
-    0x1c4a, 0x3,
-    0x1c89, 0x37,
-    0x1cc8, 0x8,
-    0x1cfa, 0x6,
-    0x1df6, 0x5,
-    0x1fff, 0x11,
-    0x2028, 0x8,
-    0x205f, 0x11,
-    0x209d, 0x3,
-    0x20bf, 0x11,
-    0x20f1, 0xf,
-    0x218c, 0x4,
-    0x2427, 0x19,
-    0x244b, 0x15,
-    0x2bba, 0x3,
-    0x2bd2, 0x1a,
-    0x2bf0, 0x10,
-    0x2cf4, 0x5,
-    0x2d28, 0x5,
-    0x2d68, 0x7,
-    0x2d71, 0xe,
-    0x2d97, 0x9,
-    0x2e45, 0x3b,
-    0x2ef4, 0xc,
-    0x2fd6, 0x1a,
-    0x2ffc, 0x5,
-    0x3100, 0x5,
-    0x312e, 0x3,
-    0x31bb, 0x5,
-    0x31e4, 0xc,
-    0x4db6, 0xa,
-    0x9fd6, 0x2a,
-    0xa48d, 0x3,
-    0xa4c7, 0x9,
-    0xa62c, 0x14,
-    0xa6f8, 0x8,
-    0xa7b8, 0x3f,
-    0xa82c, 0x4,
-    0xa83a, 0x6,
-    0xa878, 0x8,
-    0xa8c6, 0x8,
-    0xa8da, 0x6,
-    0xa954, 0xb,
-    0xa97d, 0x3,
-    0xa9da, 0x4,
-    0xaa37, 0x9,
-    0xaac3, 0x18,
-    0xaaf7, 0xa,
-    0xab17, 0x9,
-    0xab66, 0xa,
-    0xabfa, 0x6,
-    0xd7a4, 0xc,
-    0xd7c7, 0x4,
-    0xd7fc, 0x2104,
-    0xfada, 0x26,
-    0xfb07, 0xc,
-    0xfb18, 0x5,
-    0xfbc2, 0x11,
-    0xfd40, 0x10,
-    0xfdc8, 0x28,
-    0xfe1a, 0x6,
-    0xfe6c, 0x4,
-    0xfefd, 0x4,
-    0xffbf, 0x3,
-    0xffdd, 0x3,
-    0xffef, 0xd,
+const SINGLETONS1U: &'static [(u8, u8)] = &[
+    (0x00, 6),
+    (0x01, 1),
+    (0x03, 1),
+    (0x04, 2),
+    (0x08, 8),
+    (0x09, 2),
+    (0x0a, 3),
+    (0x0b, 2),
+    (0x10, 1),
+    (0x11, 4),
+    (0x12, 5),
+    (0x13, 18),
+    (0x14, 2),
+    (0x15, 2),
+    (0x1c, 5),
+    (0x24, 1),
+    (0x6a, 3),
+    (0x6b, 2),
+    (0xbc, 2),
+    (0xd1, 2),
+    (0xd4, 12),
+    (0xd5, 9),
+    (0xd6, 2),
+    (0xd7, 2),
+    (0xda, 1),
+    (0xe0, 5),
+    (0xe8, 2),
+    (0xee, 32),
+    (0xf0, 4),
+    (0xf1, 1),
+    (0xf9, 4),
 ];
-const NORMAL1: &'static [u16] = &[
+const SINGLETONS1L: &'static [u8] = &[
+    0x0c, 0x27, 0x3b, 0x3e, 0x4e, 0x4f, 0x8f, 0x9e,
+    0x9e, 0x9f, 0x06, 0x07, 0x09, 0x36, 0x3d, 0x3e,
+    0x56, 0xf3, 0xd0, 0xd1, 0x04, 0x14, 0x18, 0x56,
+    0x57, 0xbd, 0x35, 0xce, 0xcf, 0xe0, 0x12, 0x87,
+    0x89, 0x8e, 0x9e, 0x04, 0x0d, 0x0e, 0x11, 0x12,
+    0x29, 0x31, 0x34, 0x3a, 0x3b, 0x45, 0x46, 0x49,
+    0x4a, 0x4e, 0x4f, 0x64, 0x65, 0x5a, 0x5c, 0xb6,
+    0xb7, 0x09, 0x37, 0x90, 0x91, 0xa8, 0x6f, 0x5f,
+    0xee, 0xef, 0x5a, 0x62, 0x9a, 0x9b, 0x27, 0x28,
+    0x55, 0x9d, 0xa0, 0xa1, 0xa3, 0xa4, 0xa7, 0xa8,
+    0xad, 0xba, 0xbc, 0xc4, 0x06, 0x0b, 0x0c, 0x15,
+    0x1d, 0x3a, 0x3f, 0x45, 0x51, 0xa6, 0xa7, 0xcc,
+    0xcd, 0xa0, 0x07, 0x19, 0x1a, 0x22, 0x25, 0xc5,
+    0xc6, 0x04, 0x20, 0x23, 0x25, 0x26, 0x28, 0x33,
+    0x38, 0x3a, 0x48, 0x4a, 0x4c, 0x50, 0x53, 0x55,
+    0x56, 0x58, 0x5a, 0x5c, 0x5e, 0x60, 0x63, 0x65,
+    0x66, 0x6b, 0x73, 0x78, 0x7d, 0x7f, 0x8a, 0xa4,
+    0xaa, 0xaf, 0xb0, 0xc0, 0xd0, 0x2f, 0x1f, 0x31,
+    0x32, 0x3f,
+];
+const NORMAL0: &'static [u8] = &[
+    0x00, 0x20,
+    0x5f, 0x22,
+    0x82, 0xdf, 0x04,
+    0x82, 0x44, 0x08,
+    0x1b, 0x05,
+    0x05, 0x11,
+    0x81, 0xac, 0x0e,
+    0x3b, 0x05,
+    0x5f, 0x41,
+    0x1e, 0x16,
+    0x80, 0xdf, 0x03,
+    0x19, 0x08,
+    0x01, 0x04,
+    0x20, 0x05,
+    0x0a, 0x04,
+    0x34, 0x04,
+    0x07, 0x03,
+    0x01, 0x07,
+    0x06, 0x07,
+    0x10, 0x0b,
+    0x50, 0x0f,
+    0x12, 0x07,
+    0x01, 0x07,
+    0x4d, 0x08,
+    0x02, 0x04,
+    0x1c, 0x0a,
+    0x09, 0x03,
+    0x08, 0x03,
+    0x07, 0x03,
+    0x02, 0x03,
+    0x03, 0x03,
+    0x0c, 0x04,
+    0x05, 0x03,
+    0x0b, 0x06,
+    0x01, 0x0e,
+    0x15, 0x05,
+    0x3a, 0x03,
+    0x11, 0x07,
+    0x06, 0x05,
+    0x10, 0x08,
+    0x56, 0x07,
+    0x02, 0x07,
+    0x15, 0x0e,
+    0x4f, 0x04,
+    0x43, 0x03,
+    0x2d, 0x03,
+    0x01, 0x04,
+    0x11, 0x06,
+    0x0f, 0x0c,
+    0x3a, 0x04,
+    0x1d, 0x25,
+    0x0d, 0x06,
+    0x4c, 0x20,
+    0x6d, 0x04,
+    0x6a, 0x25,
+    0x80, 0xc8, 0x05,
+    0x82, 0xb0, 0x03,
+    0x1a, 0x06,
+    0x82, 0xfd, 0x03,
+    0x59, 0x07,
+    0x15, 0x0b,
+    0x17, 0x09,
+    0x14, 0x0c,
+    0x14, 0x0c,
+    0x6a, 0x06,
+    0x0a, 0x06,
+    0x1a, 0x06,
+    0x58, 0x08,
+    0x2b, 0x05,
+    0x46, 0x0a,
+    0x2c, 0x04,
+    0x0c, 0x04,
+    0x01, 0x03,
+    0x31, 0x0b,
+    0x2c, 0x04,
+    0x1a, 0x06,
+    0x0b, 0x03,
+    0x80, 0xac, 0x06,
+    0x0a, 0x06,
+    0x1f, 0x41,
+    0x4c, 0x04,
+    0x2d, 0x03,
+    0x74, 0x08,
+    0x3c, 0x03,
+    0x0f, 0x03,
+    0x3c, 0x37,
+    0x08, 0x08,
+    0x2a, 0x06,
+    0x80, 0xf6, 0x05,
+    0x82, 0x04, 0x11,
+    0x18, 0x08,
+    0x2f, 0x11,
+    0x2d, 0x03,
+    0x1f, 0x11,
+    0x21, 0x0f,
+    0x80, 0x8c, 0x04,
+    0x82, 0x97, 0x19,
+    0x0b, 0x15,
+    0x87, 0x5a, 0x03,
+    0x15, 0x1a,
+    0x04, 0x10,
+    0x80, 0xf4, 0x05,
+    0x2f, 0x05,
+    0x3b, 0x07,
+    0x02, 0x0e,
+    0x18, 0x09,
+    0x80, 0xa5, 0x3b,
+    0x74, 0x0c,
+    0x80, 0xd6, 0x1a,
+    0x0c, 0x05,
+    0x80, 0xff, 0x05,
+    0x29, 0x03,
+    0x80, 0x8a, 0x05,
+    0x24, 0x0c,
+    0x9b, 0xc6, 0x0a,
+    0xd2, 0x16, 0x2a,
+    0x84, 0x8d, 0x03,
+    0x37, 0x09,
+    0x81, 0x5c, 0x14,
+    0x80, 0xb8, 0x08,
+    0x80, 0xb8, 0x3f,
+    0x35, 0x04,
+    0x0a, 0x06,
+    0x38, 0x08,
+    0x46, 0x08,
+    0x0c, 0x06,
+    0x74, 0x0b,
+    0x1e, 0x03,
+    0x5a, 0x04,
+    0x59, 0x09,
+    0x80, 0x83, 0x18,
+    0x1c, 0x0a,
+    0x16, 0x09,
+    0x46, 0x0a,
+    0x80, 0x8a, 0x06,
+    0xab, 0xa4, 0x0c,
+    0x17, 0x04,
+    0x31, 0xa1, 0x04,
+    0x81, 0xda, 0x26,
+    0x07, 0x0c,
+    0x05, 0x05,
+    0x80, 0xa5, 0x11,
+    0x81, 0x6d, 0x10,
+    0x78, 0x28,
+    0x2a, 0x06,
+    0x4c, 0x04,
+    0x80, 0x8d, 0x04,
+    0x80, 0xbe, 0x03,
+    0x1b, 0x03,
+    0x0f, 0x0d,
+];
+const NORMAL1: &'static [u8] = &[
+    0x5e, 0x22,
+    0x7b, 0x05,
+    0x03, 0x04,
+    0x2d, 0x03,
+    0x65, 0x04,
+    0x01, 0x2f,
+    0x2e, 0x80, 0x82,
+    0x1d, 0x03,
+    0x31, 0x0f,
+    0x1c, 0x04,
+    0x24, 0x0c,
+    0x1b, 0x05,
+    0x2b, 0x05,
+    0x44, 0x04,
+    0x0e, 0x2a,
+    0x80, 0xaa, 0x06,
+    0x24, 0x04,
+    0x24, 0x04,
+    0x28, 0x08,
+    0x34, 0x0b,
+    0x01, 0x80, 0x90,
+    0x81, 0x37, 0x09,
+    0x16, 0x0a,
+    0x08, 0x80, 0x98,
+    0x39, 0x03,
+    0x63, 0x08,
+    0x09, 0x30,
+    0x16, 0x05,
+    0x21, 0x03,
+    0x1b, 0x05,
+    0x01, 0x40,
+    0x38, 0x04,
+    0x4b, 0x05,
+    0x28, 0x04,
+    0x03, 0x04,
+    0x09, 0x08,
+    0x09, 0x07,
+    0x40, 0x20,
+    0x27, 0x04,
+    0x0c, 0x09,
+    0x36, 0x03,
+    0x3a, 0x05,
+    0x1a, 0x07,
+    0x04, 0x0c,
+    0x07, 0x50,
+    0x49, 0x37,
+    0x33, 0x0d,
+    0x33, 0x07,
+    0x06, 0x81, 0x60,
+    0x1f, 0x81, 0x81,
+    0x4e, 0x04,
+    0x1e, 0x0f,
+    0x43, 0x0e,
+    0x19, 0x07,
+    0x0a, 0x06,
+    0x44, 0x0c,
+    0x27, 0x09,
+    0x75, 0x0b,
+    0x3f, 0x41,
+    0x2a, 0x06,
+    0x3b, 0x05,
+    0x0a, 0x06,
+    0x51, 0x06,
+    0x01, 0x05,
+    0x10, 0x03,
+    0x05, 0x80, 0x8b,
+    0x5e, 0x22,
+    0x48, 0x08,
+    0x0a, 0x80, 0xa6,
     0x5e, 0x22,
-    0xfb, 0x5,
-    0x103, 0x4,
-    0x134, 0x3,
-    0x19c, 0x4,
-    0x1a1, 0x2f,
-    0x1fe, 0x82,
-    0x29d, 0x3,
-    0x2d1, 0xf,
-    0x2fc, 0x4,
-    0x324, 0xc,
-    0x34b, 0x5,
-    0x37b, 0x5,
-    0x3c4, 0x4,
-    0x3d6, 0x2a,
-    0x4aa, 0x6,
-    0x4d4, 0x4,
-    0x4fc, 0x4,
-    0x528, 0x8,
-    0x564, 0xb,
-    0x570, 0x90,
-    0x737, 0x9,
-    0x756, 0xa,
-    0x768, 0x98,
-    0x839, 0x3,
-    0x89f, 0x8,
-    0x8b0, 0x30,
-    0x8f6, 0x5,
-    0x91c, 0x3,
-    0x93a, 0x5,
-    0x940, 0x40,
-    0x9b8, 0x4,
-    0xa07, 0x5,
-    0xa34, 0x4,
-    0xa3b, 0x4,
-    0xa48, 0x8,
-    0xa59, 0x7,
-    0xaa0, 0x20,
-    0xae7, 0x4,
-    0xaf7, 0x9,
-    0xb36, 0x3,
-    0xb73, 0x5,
-    0xb92, 0x7,
-    0xb9d, 0xc,
-    0xbb0, 0x50,
-    0xc49, 0x37,
-    0xcb3, 0xd,
-    0xcf3, 0x7,
-    0xd00, 0x160,
-    0xe7f, 0x181,
-    0x104e, 0x4,
-    0x1070, 0xf,
-    0x10c2, 0xe,
-    0x10e9, 0x7,
-    0x10fa, 0x6,
-    0x1144, 0xc,
-    0x1177, 0x9,
-    0x11f5, 0xb,
-    0x123f, 0x41,
-    0x12aa, 0x6,
-    0x12eb, 0x5,
-    0x12fa, 0x6,
-    0x1351, 0x6,
-    0x1358, 0x5,
-    0x136d, 0x3,
-    0x1375, 0x8b,
-    0x145e, 0x22,
-    0x14c8, 0x8,
-    0x14da, 0xa6,
-    0x15de, 0x22,
-    0x1645, 0xb,
-    0x165a, 0x6,
-    0x166d, 0x13,
-    0x16b8, 0x8,
-    0x16ca, 0x36,
-    0x171a, 0x3,
-    0x172c, 0x4,
-    0x1740, 0x160,
-    0x18f3, 0xc,
-    0x1900, 0x1c0,
-    0x1af9, 0x107,
-    0x1c46, 0xa,
-    0x1c6d, 0x3,
-    0x1cb7, 0x349,
-    0x239a, 0x66,
-    0x2475, 0xb,
-    0x2544, 0xabc,
-    0x342f, 0xfd1,
-    0x4647, 0x21b9,
-    0x6a39, 0x7,
-    0x6a6a, 0x4,
-    0x6a70, 0x60,
-    0x6af6, 0xa,
-    0x6b46, 0xa,
-    0x6b78, 0x5,
-    0x6b90, 0x370,
-    0x6f45, 0xb,
-    0x6f7f, 0x10,
-    0x6fa0, 0x40,
-    0x6fe1, 0x1f,
-    0x87ed, 0x13,
-    0x8af3, 0x250d,
-    0xb002, 0xbfe,
-    0xbc6b, 0x5,
-    0xbc7d, 0x3,
-    0xbc89, 0x7,
-    0xbca0, 0x1360,
-    0xd0f6, 0xa,
-    0xd173, 0x8,
-    0xd1e9, 0x17,
-    0xd246, 0xba,
-    0xd357, 0x9,
-    0xd372, 0x8e,
-    0xd547, 0x3,
-    0xda8c, 0xf,
-    0xdab0, 0x550,
-    0xe02b, 0x7d5,
-    0xe8d7, 0x29,
-    0xe94b, 0x5,
-    0xe95a, 0x4,
-    0xe960, 0x4a0,
-    0xee3c, 0x6,
-    0xee43, 0x4,
-    0xee9c, 0x5,
-    0xeebc, 0x34,
-    0xeef2, 0x10e,
-    0xf02c, 0x4,
-    0xf094, 0xc,
-    0xf0f6, 0xa,
-    0xf10d, 0x3,
-    0xf16c, 0x4,
-    0xf1ad, 0x39,
-    0xf203, 0xd,
-    0xf23c, 0x4,
-    0xf249, 0x7,
-    0xf252, 0xae,
-    0xf6d3, 0xd,
-    0xf6ed, 0x3,
-    0xf6f7, 0x9,
-    0xf774, 0xc,
-    0xf7d5, 0x2b,
-    0xf80c, 0x4,
-    0xf848, 0x8,
-    0xf85a, 0x6,
-    0xf888, 0x8,
-    0xf8ae, 0x62,
-    0xf928, 0x8,
-    0xf94c, 0x4,
-    0xf95f, 0x21,
-    0xf992, 0x2e,
-    0xf9c1, 0x63f,
+    0x45, 0x0b,
+    0x0a, 0x06,
+    0x0d, 0x13,
+    0x38, 0x08,
+    0x0a, 0x36,
+    0x1a, 0x03,
+    0x0f, 0x04,
+    0x10, 0x81, 0x60,
+    0x53, 0x0c,
+    0x01, 0x81, 0xc0,
+    0x39, 0x81, 0x07,
+    0x46, 0x0a,
+    0x1d, 0x03,
+    0x47, 0x83, 0x49,
+    0x83, 0x9a, 0x66,
+    0x75, 0x0b,
+    0x80, 0xc4, 0x8a, 0xbc,
+    0x84, 0x2f, 0x8f, 0xd1,
+    0x82, 0x47, 0xa1, 0xb9,
+    0x82, 0x39, 0x07,
+    0x2a, 0x04,
+    0x02, 0x60,
+    0x26, 0x0a,
+    0x46, 0x0a,
+    0x28, 0x05,
+    0x13, 0x83, 0x70,
+    0x45, 0x0b,
+    0x2f, 0x10,
+    0x11, 0x40,
+    0x01, 0x1f,
+    0x97, 0xed, 0x13,
+    0x82, 0xf3, 0xa5, 0x0d,
+    0x02, 0x8b, 0xfe,
+    0x6b, 0x05,
+    0x0d, 0x03,
+    0x09, 0x07,
+    0x10, 0x93, 0x60,
+    0x80, 0xf6, 0x0a,
+    0x73, 0x08,
+    0x6e, 0x17,
+    0x46, 0x80, 0xba,
+    0x57, 0x09,
+    0x12, 0x80, 0x8e,
+    0x81, 0x47, 0x03,
+    0x85, 0x42, 0x0f,
+    0x15, 0x85, 0x50,
+    0x2b, 0x87, 0xd5,
+    0x80, 0xd7, 0x29,
+    0x4b, 0x05,
+    0x0a, 0x04,
+    0x02, 0x84, 0xa0,
+    0x3c, 0x06,
+    0x01, 0x04,
+    0x55, 0x05,
+    0x1b, 0x34,
+    0x02, 0x81, 0x0e,
+    0x2c, 0x04,
+    0x64, 0x0c,
+    0x56, 0x0a,
+    0x0d, 0x03,
+    0x5c, 0x04,
+    0x3d, 0x39,
+    0x1d, 0x0d,
+    0x2c, 0x04,
+    0x09, 0x07,
+    0x02, 0x80, 0xae,
+    0x83, 0xd3, 0x0d,
+    0x0d, 0x03,
+    0x07, 0x09,
+    0x74, 0x0c,
+    0x55, 0x2b,
+    0x0c, 0x04,
+    0x38, 0x08,
+    0x0a, 0x06,
+    0x28, 0x08,
+    0x1e, 0x62,
+    0x18, 0x08,
+    0x1c, 0x04,
+    0x0f, 0x21,
+    0x12, 0x2e,
+    0x01, 0x86, 0x3f,
 ];
diff --git a/src/libcore/iter/mod.rs b/src/libcore/iter/mod.rs
index 04394e0a3a8..273f9d0e6f6 100644
--- a/src/libcore/iter/mod.rs
+++ b/src/libcore/iter/mod.rs
@@ -358,12 +358,24 @@ impl<I> Iterator for Rev<I> where I: DoubleEndedIterator {
     fn next(&mut self) -> Option<<I as Iterator>::Item> { self.iter.next_back() }
     #[inline]
     fn size_hint(&self) -> (usize, Option<usize>) { self.iter.size_hint() }
+
+    fn find<P>(&mut self, predicate: P) -> Option<Self::Item>
+        where P: FnMut(&Self::Item) -> bool
+    {
+        self.iter.rfind(predicate)
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<I> DoubleEndedIterator for Rev<I> where I: DoubleEndedIterator {
     #[inline]
     fn next_back(&mut self) -> Option<<I as Iterator>::Item> { self.iter.next() }
+
+    fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item>
+        where P: FnMut(&Self::Item) -> bool
+    {
+        self.iter.find(predicate)
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
diff --git a/src/libcore/iter/traits.rs b/src/libcore/iter/traits.rs
index 34f14ef53f8..798dda19928 100644
--- a/src/libcore/iter/traits.rs
+++ b/src/libcore/iter/traits.rs
@@ -467,7 +467,7 @@ pub trait DoubleEndedIterator: Iterator {
         Self: Sized,
         P: FnMut(&Self::Item) -> bool
     {
-        for x in self.by_ref().rev() {
+        while let Some(x) = self.next_back() {
             if predicate(&x) { return Some(x) }
         }
         None
diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs
index d2830a6d00c..04480fc5d31 100644
--- a/src/libcore/ptr.rs
+++ b/src/libcore/ptr.rs
@@ -500,6 +500,44 @@ impl<T: ?Sized> *const T {
             intrinsics::arith_offset(self, count)
         }
     }
+
+    /// Calculates the distance between two pointers. The returned value is in
+    /// units of T: the distance in bytes is divided by `mem::size_of::<T>()`.
+    ///
+    /// If the address different between the two pointers ia not a multiple of
+    /// `mem::size_of::<T>()` then the result of the division is rounded towards
+    /// zero.
+    ///
+    /// This function returns `None` if `T` is a zero-sized typed.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// #![feature(offset_to)]
+    ///
+    /// fn main() {
+    ///     let a = [0; 5];
+    ///     let ptr1: *const i32 = &a[1];
+    ///     let ptr2: *const i32 = &a[3];
+    ///     assert_eq!(ptr1.offset_to(ptr2), Some(2));
+    ///     assert_eq!(ptr2.offset_to(ptr1), Some(-2));
+    ///     assert_eq!(unsafe { ptr1.offset(2) }, ptr2);
+    ///     assert_eq!(unsafe { ptr2.offset(-2) }, ptr1);
+    /// }
+    /// ```
+    #[unstable(feature = "offset_to", issue = "41079")]
+    #[inline]
+    pub fn offset_to(self, other: *const T) -> Option<isize> where T: Sized {
+        let size = mem::size_of::<T>();
+        if size == 0 {
+            None
+        } else {
+            let diff = (other as isize).wrapping_sub(self as isize);
+            Some(diff / size as isize)
+        }
+    }
 }
 
 #[lang = "mut_ptr"]
@@ -653,6 +691,44 @@ impl<T: ?Sized> *mut T {
             Some(&mut *self)
         }
     }
+
+    /// Calculates the distance between two pointers. The returned value is in
+    /// units of T: the distance in bytes is divided by `mem::size_of::<T>()`.
+    ///
+    /// If the address different between the two pointers ia not a multiple of
+    /// `mem::size_of::<T>()` then the result of the division is rounded towards
+    /// zero.
+    ///
+    /// This function returns `None` if `T` is a zero-sized typed.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// #![feature(offset_to)]
+    ///
+    /// fn main() {
+    ///     let mut a = [0; 5];
+    ///     let ptr1: *mut i32 = &mut a[1];
+    ///     let ptr2: *mut i32 = &mut a[3];
+    ///     assert_eq!(ptr1.offset_to(ptr2), Some(2));
+    ///     assert_eq!(ptr2.offset_to(ptr1), Some(-2));
+    ///     assert_eq!(unsafe { ptr1.offset(2) }, ptr2);
+    ///     assert_eq!(unsafe { ptr2.offset(-2) }, ptr1);
+    /// }
+    /// ```
+    #[unstable(feature = "offset_to", issue = "41079")]
+    #[inline]
+    pub fn offset_to(self, other: *const T) -> Option<isize> where T: Sized {
+        let size = mem::size_of::<T>();
+        if size == 0 {
+            None
+        } else {
+            let diff = (other as isize).wrapping_sub(self as isize);
+            Some(diff / size as isize)
+        }
+    }
 }
 
 // Equality for pointers
diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs
index 45667bb4299..6d598677c9b 100644
--- a/src/libcore/slice/mod.rs
+++ b/src/libcore/slice/mod.rs
@@ -81,6 +81,10 @@ pub trait SliceExt {
     fn split<P>(&self, pred: P) -> Split<Self::Item, P>
         where P: FnMut(&Self::Item) -> bool;
 
+    #[unstable(feature = "slice_rsplit", issue = "41020")]
+    fn rsplit<P>(&self, pred: P) -> RSplit<Self::Item, P>
+        where P: FnMut(&Self::Item) -> bool;
+
     #[stable(feature = "core", since = "1.6.0")]
     fn splitn<P>(&self, n: usize, pred: P) -> SplitN<Self::Item, P>
         where P: FnMut(&Self::Item) -> bool;
@@ -159,6 +163,10 @@ pub trait SliceExt {
     fn split_mut<P>(&mut self, pred: P) -> SplitMut<Self::Item, P>
         where P: FnMut(&Self::Item) -> bool;
 
+    #[unstable(feature = "slice_rsplit", issue = "41020")]
+    fn rsplit_mut<P>(&mut self, pred: P) -> RSplitMut<Self::Item, P>
+        where P: FnMut(&Self::Item) -> bool;
+
     #[stable(feature = "core", since = "1.6.0")]
     fn splitn_mut<P>(&mut self, n: usize, pred: P) -> SplitNMut<Self::Item, P>
         where P: FnMut(&Self::Item) -> bool;
@@ -294,14 +302,20 @@ impl<T> SliceExt for [T] {
     }
 
     #[inline]
+    fn rsplit<P>(&self, pred: P) -> RSplit<T, P>
+        where P: FnMut(&T) -> bool
+    {
+        RSplit { inner: self.split(pred) }
+    }
+
+    #[inline]
     fn splitn<P>(&self, n: usize, pred: P) -> SplitN<T, P>
         where P: FnMut(&T) -> bool
     {
         SplitN {
             inner: GenericSplitN {
                 iter: self.split(pred),
-                count: n,
-                invert: false
+                count: n
             }
         }
     }
@@ -312,9 +326,8 @@ impl<T> SliceExt for [T] {
     {
         RSplitN {
             inner: GenericSplitN {
-                iter: self.split(pred),
-                count: n,
-                invert: true
+                iter: self.rsplit(pred),
+                count: n
             }
         }
     }
@@ -476,14 +489,20 @@ impl<T> SliceExt for [T] {
     }
 
     #[inline]
+    fn rsplit_mut<P>(&mut self, pred: P) -> RSplitMut<T, P>
+        where P: FnMut(&T) -> bool
+    {
+        RSplitMut { inner: self.split_mut(pred) }
+    }
+
+    #[inline]
     fn splitn_mut<P>(&mut self, n: usize, pred: P) -> SplitNMut<T, P>
         where P: FnMut(&T) -> bool
     {
         SplitNMut {
             inner: GenericSplitN {
                 iter: self.split_mut(pred),
-                count: n,
-                invert: false
+                count: n
             }
         }
     }
@@ -494,9 +513,8 @@ impl<T> SliceExt for [T] {
     {
         RSplitNMut {
             inner: GenericSplitN {
-                iter: self.split_mut(pred),
-                count: n,
-                invert: true
+                iter: self.rsplit_mut(pred),
+                count: n
             }
         }
     }
@@ -1498,9 +1516,10 @@ unsafe impl<'a, T> TrustedLen for IterMut<'a, T> {}
 // Return the arithmetic difference if `T` is zero size.
 #[inline(always)]
 fn ptrdistance<T>(start: *const T, end: *const T) -> usize {
-    let diff = (end as usize).wrapping_sub(start as usize);
-    let size = mem::size_of::<T>();
-    diff / (if size == 0 { 1 } else { size })
+    match start.offset_to(end) {
+        Some(x) => x as usize,
+        None => (end as usize).wrapping_sub(start as usize),
+    }
 }
 
 // Extension methods for raw pointers, used by the iterators
@@ -1735,6 +1754,123 @@ impl<'a, T, P> DoubleEndedIterator for SplitMut<'a, T, P> where
 #[unstable(feature = "fused", issue = "35602")]
 impl<'a, T, P> FusedIterator for SplitMut<'a, T, P> where P: FnMut(&T) -> bool {}
 
+/// An iterator over subslices separated by elements that match a predicate
+/// function, starting from the end of the slice.
+///
+/// This struct is created by the [`rsplit`] method on [slices].
+///
+/// [`rsplit`]: ../../std/primitive.slice.html#method.rsplit
+/// [slices]: ../../std/primitive.slice.html
+#[unstable(feature = "slice_rsplit", issue = "41020")]
+#[derive(Clone)] // Is this correct, or does it incorrectly require `T: Clone`?
+pub struct RSplit<'a, T:'a, P> where P: FnMut(&T) -> bool {
+    inner: Split<'a, T, P>
+}
+
+#[unstable(feature = "slice_rsplit", issue = "41020")]
+impl<'a, T: 'a + fmt::Debug, P> fmt::Debug for RSplit<'a, T, P> where P: FnMut(&T) -> bool {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.debug_struct("RSplit")
+            .field("v", &self.inner.v)
+            .field("finished", &self.inner.finished)
+            .finish()
+    }
+}
+
+#[unstable(feature = "slice_rsplit", issue = "41020")]
+impl<'a, T, P> Iterator for RSplit<'a, T, P> where P: FnMut(&T) -> bool {
+    type Item = &'a [T];
+
+    #[inline]
+    fn next(&mut self) -> Option<&'a [T]> {
+        self.inner.next_back()
+    }
+
+    #[inline]
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        self.inner.size_hint()
+    }
+}
+
+#[unstable(feature = "slice_rsplit", issue = "41020")]
+impl<'a, T, P> DoubleEndedIterator for RSplit<'a, T, P> where P: FnMut(&T) -> bool {
+    #[inline]
+    fn next_back(&mut self) -> Option<&'a [T]> {
+        self.inner.next()
+    }
+}
+
+#[unstable(feature = "slice_rsplit", issue = "41020")]
+impl<'a, T, P> SplitIter for RSplit<'a, T, P> where P: FnMut(&T) -> bool {
+    #[inline]
+    fn finish(&mut self) -> Option<&'a [T]> {
+        self.inner.finish()
+    }
+}
+
+//#[unstable(feature = "fused", issue = "35602")]
+#[unstable(feature = "slice_rsplit", issue = "41020")]
+impl<'a, T, P> FusedIterator for RSplit<'a, T, P> where P: FnMut(&T) -> bool {}
+
+/// An iterator over the subslices of the vector which are separated
+/// by elements that match `pred`, starting from the end of the slice.
+///
+/// This struct is created by the [`rsplit_mut`] method on [slices].
+///
+/// [`rsplit_mut`]: ../../std/primitive.slice.html#method.rsplit_mut
+/// [slices]: ../../std/primitive.slice.html
+#[unstable(feature = "slice_rsplit", issue = "41020")]
+pub struct RSplitMut<'a, T:'a, P> where P: FnMut(&T) -> bool {
+    inner: SplitMut<'a, T, P>
+}
+
+#[unstable(feature = "slice_rsplit", issue = "41020")]
+impl<'a, T: 'a + fmt::Debug, P> fmt::Debug for RSplitMut<'a, T, P> where P: FnMut(&T) -> bool {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.debug_struct("RSplitMut")
+            .field("v", &self.inner.v)
+            .field("finished", &self.inner.finished)
+            .finish()
+    }
+}
+
+#[unstable(feature = "slice_rsplit", issue = "41020")]
+impl<'a, T, P> SplitIter for RSplitMut<'a, T, P> where P: FnMut(&T) -> bool {
+    #[inline]
+    fn finish(&mut self) -> Option<&'a mut [T]> {
+        self.inner.finish()
+    }
+}
+
+#[unstable(feature = "slice_rsplit", issue = "41020")]
+impl<'a, T, P> Iterator for RSplitMut<'a, T, P> where P: FnMut(&T) -> bool {
+    type Item = &'a mut [T];
+
+    #[inline]
+    fn next(&mut self) -> Option<&'a mut [T]> {
+        self.inner.next_back()
+    }
+
+    #[inline]
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        self.inner.size_hint()
+    }
+}
+
+#[unstable(feature = "slice_rsplit", issue = "41020")]
+impl<'a, T, P> DoubleEndedIterator for RSplitMut<'a, T, P> where
+    P: FnMut(&T) -> bool,
+{
+    #[inline]
+    fn next_back(&mut self) -> Option<&'a mut [T]> {
+        self.inner.next()
+    }
+}
+
+//#[unstable(feature = "fused", issue = "35602")]
+#[unstable(feature = "slice_rsplit", issue = "41020")]
+impl<'a, T, P> FusedIterator for RSplitMut<'a, T, P> where P: FnMut(&T) -> bool {}
+
 /// An private iterator over subslices separated by elements that
 /// match a predicate function, splitting at most a fixed number of
 /// times.
@@ -1742,7 +1878,6 @@ impl<'a, T, P> FusedIterator for SplitMut<'a, T, P> where P: FnMut(&T) -> bool {
 struct GenericSplitN<I> {
     iter: I,
     count: usize,
-    invert: bool
 }
 
 impl<T, I: SplitIter<Item=T>> Iterator for GenericSplitN<I> {
@@ -1753,10 +1888,7 @@ impl<T, I: SplitIter<Item=T>> Iterator for GenericSplitN<I> {
         match self.count {
             0 => None,
             1 => { self.count -= 1; self.iter.finish() }
-            _ => {
-                self.count -= 1;
-                if self.invert {self.iter.next_back()} else {self.iter.next()}
-            }
+            _ => { self.count -= 1; self.iter.next() }
         }
     }
 
@@ -1798,7 +1930,7 @@ impl<'a, T: 'a + fmt::Debug, P> fmt::Debug for SplitN<'a, T, P> where P: FnMut(&
 /// [slices]: ../../std/primitive.slice.html
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct RSplitN<'a, T: 'a, P> where P: FnMut(&T) -> bool {
-    inner: GenericSplitN<Split<'a, T, P>>
+    inner: GenericSplitN<RSplit<'a, T, P>>
 }
 
 #[stable(feature = "core_impl_debug", since = "1.9.0")]
@@ -1841,7 +1973,7 @@ impl<'a, T: 'a + fmt::Debug, P> fmt::Debug for SplitNMut<'a, T, P> where P: FnMu
 /// [slices]: ../../std/primitive.slice.html
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct RSplitNMut<'a, T: 'a, P> where P: FnMut(&T) -> bool {
-    inner: GenericSplitN<SplitMut<'a, T, P>>
+    inner: GenericSplitN<RSplitMut<'a, T, P>>
 }
 
 #[stable(feature = "core_impl_debug", since = "1.9.0")]
diff --git a/src/libcore/sync/atomic.rs b/src/libcore/sync/atomic.rs
index ae47e6fdfa9..4e5ddfb541e 100644
--- a/src/libcore/sync/atomic.rs
+++ b/src/libcore/sync/atomic.rs
@@ -321,7 +321,7 @@ impl AtomicBool {
         }
     }
 
-    /// Stores a value into the bool, returning the old value.
+    /// Stores a value into the bool, returning the previous value.
     ///
     /// `swap` takes an [`Ordering`] argument which describes the memory ordering
     /// of this operation.
@@ -732,7 +732,7 @@ impl<T> AtomicPtr<T> {
         }
     }
 
-    /// Stores a value into the pointer, returning the old value.
+    /// Stores a value into the pointer, returning the previous value.
     ///
     /// `swap` takes an [`Ordering`] argument which describes the memory ordering
     /// of this operation.
@@ -1047,7 +1047,7 @@ macro_rules! atomic_int {
                 unsafe { atomic_store(self.v.get(), val, order); }
             }
 
-            /// Stores a value into the atomic integer, returning the old value.
+            /// Stores a value into the atomic integer, returning the previous value.
             ///
             /// `swap` takes an [`Ordering`] argument which describes the memory ordering of this
             /// operation.
@@ -1201,7 +1201,9 @@ macro_rules! atomic_int {
                 }
             }
 
-            /// Add to the current value, returning the previous value.
+            /// Adds to the current value, returning the previous value.
+            ///
+            /// This operation wraps around on overflow.
             ///
             /// # Examples
             ///
@@ -1218,7 +1220,9 @@ macro_rules! atomic_int {
                 unsafe { atomic_add(self.v.get(), val, order) }
             }
 
-            /// Subtract from the current value, returning the previous value.
+            /// Subtracts from the current value, returning the previous value.
+            ///
+            /// This operation wraps around on overflow.
             ///
             /// # Examples
             ///
@@ -1235,7 +1239,12 @@ macro_rules! atomic_int {
                 unsafe { atomic_sub(self.v.get(), val, order) }
             }
 
-            /// Bitwise and with the current value, returning the previous value.
+            /// Bitwise "and" with the current value.
+            ///
+            /// Performs a bitwise "and" operation on the current value and the argument `val`, and
+            /// sets the new value to the result.
+            ///
+            /// Returns the previous value.
             ///
             /// # Examples
             ///
@@ -1251,7 +1260,12 @@ macro_rules! atomic_int {
                 unsafe { atomic_and(self.v.get(), val, order) }
             }
 
-            /// Bitwise or with the current value, returning the previous value.
+            /// Bitwise "or" with the current value.
+            ///
+            /// Performs a bitwise "or" operation on the current value and the argument `val`, and
+            /// sets the new value to the result.
+            ///
+            /// Returns the previous value.
             ///
             /// # Examples
             ///
@@ -1267,7 +1281,12 @@ macro_rules! atomic_int {
                 unsafe { atomic_or(self.v.get(), val, order) }
             }
 
-            /// Bitwise xor with the current value, returning the previous value.
+            /// Bitwise "xor" with the current value.
+            ///
+            /// Performs a bitwise "xor" operation on the current value and the argument `val`, and
+            /// sets the new value to the result.
+            ///
+            /// Returns the previous value.
             ///
             /// # Examples
             ///
@@ -1415,7 +1434,7 @@ unsafe fn atomic_swap<T>(dst: *mut T, val: T, order: Ordering) -> T {
     }
 }
 
-/// Returns the old value (like __sync_fetch_and_add).
+/// Returns the previous value (like __sync_fetch_and_add).
 #[inline]
 unsafe fn atomic_add<T>(dst: *mut T, val: T, order: Ordering) -> T {
     match order {
@@ -1428,7 +1447,7 @@ unsafe fn atomic_add<T>(dst: *mut T, val: T, order: Ordering) -> T {
     }
 }
 
-/// Returns the old value (like __sync_fetch_and_sub).
+/// Returns the previous value (like __sync_fetch_and_sub).
 #[inline]
 unsafe fn atomic_sub<T>(dst: *mut T, val: T, order: Ordering) -> T {
     match order {
diff --git a/src/librustc_mir/build/cfg.rs b/src/librustc_mir/build/cfg.rs
index 71e97e4bfe0..c503b8c7fe0 100644
--- a/src/librustc_mir/build/cfg.rs
+++ b/src/librustc_mir/build/cfg.rs
@@ -25,6 +25,9 @@ impl<'tcx> CFG<'tcx> {
         &mut self.basic_blocks[blk]
     }
 
+    // llvm.org/PR32488 makes this function use an excess of stack space. Mark
+    // it as #[inline(never)] to keep rustc's stack use in check.
+    #[inline(never)]
     pub fn start_new_block(&mut self) -> BasicBlock {
         self.basic_blocks.push(BasicBlockData::new(None))
     }
diff --git a/src/librustc_typeck/coherence/inherent_impls_overlap.rs b/src/librustc_typeck/coherence/inherent_impls_overlap.rs
index 4b36072243c..33280fb931a 100644
--- a/src/librustc_typeck/coherence/inherent_impls_overlap.rs
+++ b/src/librustc_typeck/coherence/inherent_impls_overlap.rs
@@ -11,7 +11,6 @@
 use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
 use rustc::hir;
 use rustc::hir::itemlikevisit::ItemLikeVisitor;
-use rustc::lint;
 use rustc::traits::{self, Reveal};
 use rustc::ty::{self, TyCtxt};
 
@@ -53,12 +52,16 @@ impl<'a, 'tcx> InherentOverlapChecker<'a, 'tcx> {
 
             for &item2 in &impl_items2[..] {
                 if (name, namespace) == name_and_namespace(item2) {
-                    let msg = format!("duplicate definitions with name `{}`", name);
-                    let node_id = self.tcx.hir.as_local_node_id(item1).unwrap();
-                    self.tcx.sess.add_lint(lint::builtin::OVERLAPPING_INHERENT_IMPLS,
-                                           node_id,
-                                           self.tcx.span_of_impl(item1).unwrap(),
-                                           msg);
+                    struct_span_err!(self.tcx.sess,
+                                     self.tcx.span_of_impl(item1).unwrap(),
+                                     E0592,
+                                     "duplicate definitions with name `{}`",
+                                     name)
+                        .span_label(self.tcx.span_of_impl(item1).unwrap(),
+                                    &format!("duplicate definitions for `{}`", name))
+                        .span_label(self.tcx.span_of_impl(item2).unwrap(),
+                                    &format!("other definition for `{}`", name))
+                        .emit();
                 }
             }
         }
diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs
index 57332170081..a06299eaefe 100644
--- a/src/libstd/collections/hash/map.rs
+++ b/src/libstd/collections/hash/map.rs
@@ -472,7 +472,7 @@ fn pop_internal<K, V>(starting_bucket: FullBucketMut<K, V>)
     }
 
     // Now we've done all our shifting. Return the value we grabbed earlier.
-    (retkey, retval, gap.into_bucket().into_table())
+    (retkey, retval, gap.into_table())
 }
 
 /// Perform robin hood bucket stealing at the given `bucket`. You must
@@ -485,14 +485,14 @@ fn robin_hood<'a, K: 'a, V: 'a>(bucket: FullBucketMut<'a, K, V>,
                                 mut key: K,
                                 mut val: V)
                                 -> FullBucketMut<'a, K, V> {
-    let start_index = bucket.index();
     let size = bucket.table().size();
-    // Save the *starting point*.
-    let mut bucket = bucket.stash();
+    let raw_capacity = bucket.table().capacity();
     // There can be at most `size - dib` buckets to displace, because
     // in the worst case, there are `size` elements and we already are
     // `displacement` buckets away from the initial one.
-    let idx_end = start_index + size - bucket.displacement();
+    let idx_end = (bucket.index() + size - bucket.displacement()) % raw_capacity;
+    // Save the *starting point*.
+    let mut bucket = bucket.stash();
 
     loop {
         let (old_hash, old_key, old_val) = bucket.replace(hash, key, val);
@@ -568,11 +568,8 @@ impl<K, V, S> HashMap<K, V, S>
     // The caller should ensure that invariants by Robin Hood Hashing hold
     // and that there's space in the underlying table.
     fn insert_hashed_ordered(&mut self, hash: SafeHash, k: K, v: V) {
-        let raw_cap = self.raw_capacity();
         let mut buckets = Bucket::new(&mut self.table, hash);
-        // note that buckets.index() keeps increasing
-        // even if the pointer wraps back to the first bucket.
-        let limit_bucket = buckets.index() + raw_cap;
+        let start_index = buckets.index();
 
         loop {
             // We don't need to compare hashes for value swap.
@@ -585,7 +582,7 @@ impl<K, V, S> HashMap<K, V, S>
                 Full(b) => b.into_bucket(),
             };
             buckets.next();
-            debug_assert!(buckets.index() < limit_bucket);
+            debug_assert!(buckets.index() != start_index);
         }
     }
 }
@@ -1244,24 +1241,25 @@ impl<K, V, S> HashMap<K, V, S>
     pub fn retain<F>(&mut self, mut f: F)
         where F: FnMut(&K, &mut V) -> bool
     {
-        if self.table.capacity() == 0 || self.table.size() == 0 {
+        if self.table.size() == 0 {
             return;
         }
+        let mut elems_left = self.table.size();
         let mut bucket = Bucket::head_bucket(&mut self.table);
         bucket.prev();
-        let tail = bucket.index();
-        loop {
+        let start_index = bucket.index();
+        while elems_left != 0 {
             bucket = match bucket.peek() {
                 Full(mut full) => {
+                    elems_left -= 1;
                     let should_remove = {
                         let (k, v) = full.read_mut();
                         !f(k, v)
                     };
                     if should_remove {
-                        let prev_idx = full.index();
                         let prev_raw = full.raw();
                         let (_, _, t) = pop_internal(full);
-                        Bucket::new_from(prev_raw, prev_idx, t)
+                        Bucket::new_from(prev_raw, t)
                     } else {
                         full.into_bucket()
                     }
@@ -1271,9 +1269,7 @@ impl<K, V, S> HashMap<K, V, S>
                 }
             };
             bucket.prev();  // reverse iteration
-            if bucket.index() == tail {
-                break;
-            }
+            debug_assert!(elems_left == 0 || bucket.index() != start_index);
         }
     }
 }
diff --git a/src/libstd/collections/hash/table.rs b/src/libstd/collections/hash/table.rs
index da5fb1a4733..9623706548b 100644
--- a/src/libstd/collections/hash/table.rs
+++ b/src/libstd/collections/hash/table.rs
@@ -113,7 +113,7 @@ impl TaggedHashUintPtr {
 /// when the RawTable is created and is accessible with the `tag` and `set_tag`
 /// functions.
 pub struct RawTable<K, V> {
-    capacity: usize,
+    capacity_mask: usize,
     size: usize,
     hashes: TaggedHashUintPtr,
 
@@ -125,10 +125,13 @@ pub struct RawTable<K, V> {
 unsafe impl<K: Send, V: Send> Send for RawTable<K, V> {}
 unsafe impl<K: Sync, V: Sync> Sync for RawTable<K, V> {}
 
+// An unsafe view of a RawTable bucket
+// Valid indexes are within [0..table_capacity)
 pub struct RawBucket<K, V> {
-    hash: *mut HashUint,
+    hash_start: *mut HashUint,
     // We use *const to ensure covariance with respect to K and V
-    pair: *const (K, V),
+    pair_start: *const (K, V),
+    idx: usize,
     _marker: marker::PhantomData<(K, V)>,
 }
 
@@ -141,7 +144,6 @@ impl<K, V> Clone for RawBucket<K, V> {
 
 pub struct Bucket<K, V, M> {
     raw: RawBucket<K, V>,
-    idx: usize,
     table: M,
 }
 
@@ -154,13 +156,11 @@ impl<K, V, M: Copy> Clone for Bucket<K, V, M> {
 
 pub struct EmptyBucket<K, V, M> {
     raw: RawBucket<K, V>,
-    idx: usize,
     table: M,
 }
 
 pub struct FullBucket<K, V, M> {
     raw: RawBucket<K, V>,
-    idx: usize,
     table: M,
 }
 
@@ -232,13 +232,17 @@ fn can_alias_safehash_as_hash() {
     assert_eq!(size_of::<SafeHash>(), size_of::<HashUint>())
 }
 
+// RawBucket methods are unsafe as it's possible to
+// make a RawBucket point to invalid memory using safe code.
 impl<K, V> RawBucket<K, V> {
-    unsafe fn offset(self, count: isize) -> RawBucket<K, V> {
-        RawBucket {
-            hash: self.hash.offset(count),
-            pair: self.pair.offset(count),
-            _marker: marker::PhantomData,
-        }
+    unsafe fn hash(&self) -> *mut HashUint {
+        self.hash_start.offset(self.idx as isize)
+    }
+    unsafe fn pair(&self) -> *mut (K, V) {
+        self.pair_start.offset(self.idx as isize) as *mut (K, V)
+    }
+    unsafe fn hash_pair(&self) -> (*mut HashUint, *mut (K, V)) {
+        (self.hash(), self.pair())
     }
 }
 
@@ -258,7 +262,7 @@ impl<K, V, M> FullBucket<K, V, M> {
     }
     /// Get the raw index.
     pub fn index(&self) -> usize {
-        self.idx
+        self.raw.idx
     }
     /// Get the raw bucket.
     pub fn raw(&self) -> RawBucket<K, V> {
@@ -280,7 +284,7 @@ impl<K, V, M> EmptyBucket<K, V, M> {
 impl<K, V, M> Bucket<K, V, M> {
     /// Get the raw index.
     pub fn index(&self) -> usize {
-        self.idx
+        self.raw.idx
     }
     /// get the table.
     pub fn into_table(self) -> M {
@@ -331,12 +335,11 @@ impl<K, V, M: Deref<Target = RawTable<K, V>>> Bucket<K, V, M> {
         Bucket::at_index(table, hash.inspect() as usize)
     }
 
-    pub fn new_from(r: RawBucket<K, V>, i: usize, t: M)
+    pub fn new_from(r: RawBucket<K, V>, t: M)
         -> Bucket<K, V, M>
     {
         Bucket {
             raw: r,
-            idx: i,
             table: t,
         }
     }
@@ -346,18 +349,16 @@ impl<K, V, M: Deref<Target = RawTable<K, V>>> Bucket<K, V, M> {
         // This is an uncommon case though, so avoid it in release builds.
         debug_assert!(table.capacity() > 0,
                       "Table should have capacity at this point");
-        let ib_index = ib_index & (table.capacity() - 1);
+        let ib_index = ib_index & table.capacity_mask;
         Bucket {
-            raw: unsafe { table.first_bucket_raw().offset(ib_index as isize) },
-            idx: ib_index,
+            raw: table.raw_bucket_at(ib_index),
             table: table,
         }
     }
 
     pub fn first(table: M) -> Bucket<K, V, M> {
         Bucket {
-            raw: table.first_bucket_raw(),
-            idx: 0,
+            raw: table.raw_bucket_at(0),
             table: table,
         }
     }
@@ -401,48 +402,30 @@ impl<K, V, M: Deref<Target = RawTable<K, V>>> Bucket<K, V, M> {
     /// the appropriate types to call most of the other functions in
     /// this module.
     pub fn peek(self) -> BucketState<K, V, M> {
-        match unsafe { *self.raw.hash } {
+        match unsafe { *self.raw.hash() } {
             EMPTY_BUCKET => {
                 Empty(EmptyBucket {
                     raw: self.raw,
-                    idx: self.idx,
                     table: self.table,
                 })
             }
             _ => {
                 Full(FullBucket {
                     raw: self.raw,
-                    idx: self.idx,
                     table: self.table,
                 })
             }
         }
     }
 
-    /// Modifies the bucket pointer in place to make it point to the next slot.
+    /// Modifies the bucket in place to make it point to the next slot.
     pub fn next(&mut self) {
-        self.idx += 1;
-        let range = self.table.capacity();
-        // This code is branchless thanks to a conditional move.
-        let dist = if self.idx & (range - 1) == 0 {
-            1 - range as isize
-        } else {
-            1
-        };
-        unsafe {
-            self.raw = self.raw.offset(dist);
-        }
+        self.raw.idx = self.raw.idx.wrapping_add(1) & self.table.capacity_mask;
     }
 
-    /// Modifies the bucket pointer in place to make it point to the previous slot.
+    /// Modifies the bucket in place to make it point to the previous slot.
     pub fn prev(&mut self) {
-        let range = self.table.capacity();
-        let new_idx = self.idx.wrapping_sub(1) & (range - 1);
-        let dist = (new_idx as isize).wrapping_sub(self.idx as isize);
-        self.idx = new_idx;
-        unsafe {
-            self.raw = self.raw.offset(dist);
-        }
+        self.raw.idx = self.raw.idx.wrapping_sub(1) & self.table.capacity_mask;
     }
 }
 
@@ -458,7 +441,6 @@ impl<K, V, M: Deref<Target = RawTable<K, V>>> EmptyBucket<K, V, M> {
     pub fn into_bucket(self) -> Bucket<K, V, M> {
         Bucket {
             raw: self.raw,
-            idx: self.idx,
             table: self.table,
         }
     }
@@ -466,7 +448,6 @@ impl<K, V, M: Deref<Target = RawTable<K, V>>> EmptyBucket<K, V, M> {
     pub fn gap_peek(self) -> Result<GapThenFull<K, V, M>, Bucket<K, V, M>> {
         let gap = EmptyBucket {
             raw: self.raw,
-            idx: self.idx,
             table: (),
         };
 
@@ -494,15 +475,14 @@ impl<K, V, M> EmptyBucket<K, V, M>
     /// Use `make_hash` to construct a `SafeHash` to pass to this function.
     pub fn put(mut self, hash: SafeHash, key: K, value: V) -> FullBucket<K, V, M> {
         unsafe {
-            *self.raw.hash = hash.inspect();
-            ptr::write(self.raw.pair as *mut (K, V), (key, value));
+            *self.raw.hash() = hash.inspect();
+            ptr::write(self.raw.pair(), (key, value));
 
             self.table.borrow_table_mut().size += 1;
         }
 
         FullBucket {
             raw: self.raw,
-            idx: self.idx,
             table: self.table,
         }
     }
@@ -510,15 +490,14 @@ impl<K, V, M> EmptyBucket<K, V, M>
     /// Puts given key, remain value uninitialized.
     /// It is only used for inplacement insertion.
     pub unsafe fn put_key(mut self, hash: SafeHash, key: K) -> FullBucket<K, V, M> {
-        *self.raw.hash = hash.inspect();
-        let pair_mut = self.raw.pair as *mut (K, V);
-        ptr::write(&mut (*pair_mut).0, key);
+        *self.raw.hash() = hash.inspect();
+        let pair_ptr = self.raw.pair();
+        ptr::write(&mut (*pair_ptr).0, key);
 
         self.table.borrow_table_mut().size += 1;
 
         FullBucket {
             raw: self.raw,
-            idx: self.idx,
             table: self.table,
         }
     }
@@ -536,7 +515,6 @@ impl<K, V, M: Deref<Target = RawTable<K, V>>> FullBucket<K, V, M> {
     pub fn into_bucket(self) -> Bucket<K, V, M> {
         Bucket {
             raw: self.raw,
-            idx: self.idx,
             table: self.table,
         }
     }
@@ -546,7 +524,6 @@ impl<K, V, M: Deref<Target = RawTable<K, V>>> FullBucket<K, V, M> {
     pub fn stash(self) -> FullBucket<K, V, Self> {
         FullBucket {
             raw: self.raw,
-            idx: self.idx,
             table: self,
         }
     }
@@ -560,17 +537,20 @@ impl<K, V, M: Deref<Target = RawTable<K, V>>> FullBucket<K, V, M> {
         // Calculates the distance one has to travel when going from
         // `hash mod capacity` onwards to `idx mod capacity`, wrapping around
         // if the destination is not reached before the end of the table.
-        (self.idx.wrapping_sub(self.hash().inspect() as usize)) & (self.table.capacity() - 1)
+        (self.raw.idx.wrapping_sub(self.hash().inspect() as usize)) & self.table.capacity_mask
     }
 
     #[inline]
     pub fn hash(&self) -> SafeHash {
-        unsafe { SafeHash { hash: *self.raw.hash } }
+        unsafe { SafeHash { hash: *self.raw.hash() } }
     }
 
     /// Gets references to the key and value at a given index.
     pub fn read(&self) -> (&K, &V) {
-        unsafe { (&(*self.raw.pair).0, &(*self.raw.pair).1) }
+        unsafe {
+            let pair_ptr = self.raw.pair();
+            (&(*pair_ptr).0, &(*pair_ptr).1)
+        }
     }
 }
 
@@ -586,11 +566,10 @@ impl<'t, K, V> FullBucket<K, V, &'t mut RawTable<K, V>> {
         self.table.size -= 1;
 
         unsafe {
-            *self.raw.hash = EMPTY_BUCKET;
-            let (k, v) = ptr::read(self.raw.pair);
+            *self.raw.hash() = EMPTY_BUCKET;
+            let (k, v) = ptr::read(self.raw.pair());
             (EmptyBucket {
                  raw: self.raw,
-                 idx: self.idx,
                  table: self.table,
              },
             k,
@@ -604,9 +583,9 @@ impl<'t, K, V> FullBucket<K, V, &'t mut RawTable<K, V>> {
     pub unsafe fn remove_key(&mut self) {
         self.table.size -= 1;
 
-        *self.raw.hash = EMPTY_BUCKET;
-        let pair_mut = self.raw.pair as *mut (K, V);
-        ptr::drop_in_place(&mut (*pair_mut).0); // only drop key
+        *self.raw.hash() = EMPTY_BUCKET;
+        let pair_ptr = self.raw.pair();
+        ptr::drop_in_place(&mut (*pair_ptr).0); // only drop key
     }
 }
 
@@ -617,8 +596,8 @@ impl<K, V, M> FullBucket<K, V, M>
 {
     pub fn replace(&mut self, h: SafeHash, k: K, v: V) -> (SafeHash, K, V) {
         unsafe {
-            let old_hash = ptr::replace(self.raw.hash as *mut SafeHash, h);
-            let (old_key, old_val) = ptr::replace(self.raw.pair as *mut (K, V), (k, v));
+            let old_hash = ptr::replace(self.raw.hash() as *mut SafeHash, h);
+            let (old_key, old_val) = ptr::replace(self.raw.pair(), (k, v));
 
             (old_hash, old_key, old_val)
         }
@@ -630,8 +609,10 @@ impl<K, V, M> FullBucket<K, V, M>
 {
     /// Gets mutable references to the key and value at a given index.
     pub fn read_mut(&mut self) -> (&mut K, &mut V) {
-        let pair_mut = self.raw.pair as *mut (K, V);
-        unsafe { (&mut (*pair_mut).0, &mut (*pair_mut).1) }
+        unsafe {
+            let pair_ptr = self.raw.pair();
+            (&mut (*pair_ptr).0, &mut (*pair_ptr).1)
+        }
     }
 }
 
@@ -644,7 +625,10 @@ impl<'t, K, V, M> FullBucket<K, V, M>
     /// in exchange for this, the returned references have a longer lifetime
     /// than the references returned by `read()`.
     pub fn into_refs(self) -> (&'t K, &'t V) {
-        unsafe { (&(*self.raw.pair).0, &(*self.raw.pair).1) }
+        unsafe {
+            let pair_ptr = self.raw.pair();
+            (&(*pair_ptr).0, &(*pair_ptr).1)
+        }
     }
 }
 
@@ -654,8 +638,10 @@ impl<'t, K, V, M> FullBucket<K, V, M>
     /// This works similarly to `into_refs`, exchanging a bucket state
     /// for mutable references into the table.
     pub fn into_mut_refs(self) -> (&'t mut K, &'t mut V) {
-        let pair_mut = self.raw.pair as *mut (K, V);
-        unsafe { (&mut (*pair_mut).0, &mut (*pair_mut).1) }
+        unsafe {
+            let pair_ptr = self.raw.pair();
+            (&mut (*pair_ptr).0, &mut (*pair_ptr).1)
+        }
     }
 }
 
@@ -667,22 +653,23 @@ impl<K, V, M> GapThenFull<K, V, M>
         &self.full
     }
 
-    pub fn into_bucket(self) -> Bucket<K, V, M> {
-        self.full.into_bucket()
+    pub fn into_table(self) -> M {
+        self.full.into_table()
     }
 
     pub fn shift(mut self) -> Result<GapThenFull<K, V, M>, Bucket<K, V, M>> {
         unsafe {
-            *self.gap.raw.hash = mem::replace(&mut *self.full.raw.hash, EMPTY_BUCKET);
-            ptr::copy_nonoverlapping(self.full.raw.pair, self.gap.raw.pair as *mut (K, V), 1);
+            let (gap_hash, gap_pair) = self.gap.raw.hash_pair();
+            let (full_hash, full_pair) = self.full.raw.hash_pair();
+            *gap_hash = mem::replace(&mut *full_hash, EMPTY_BUCKET);
+            ptr::copy_nonoverlapping(full_pair, gap_pair, 1);
         }
 
-        let FullBucket { raw: prev_raw, idx: prev_idx, .. } = self.full;
+        let FullBucket { raw: prev_raw, .. } = self.full;
 
         match self.full.next().peek() {
             Full(bucket) => {
                 self.gap.raw = prev_raw;
-                self.gap.idx = prev_idx;
 
                 self.full = bucket;
 
@@ -761,7 +748,7 @@ impl<K, V> RawTable<K, V> {
         if capacity == 0 {
             return RawTable {
                 size: 0,
-                capacity: 0,
+                capacity_mask: capacity.wrapping_sub(1),
                 hashes: TaggedHashUintPtr::new(EMPTY as *mut HashUint),
                 marker: marker::PhantomData,
             };
@@ -801,25 +788,27 @@ impl<K, V> RawTable<K, V> {
         let hashes = buffer.offset(hash_offset as isize) as *mut HashUint;
 
         RawTable {
-            capacity: capacity,
+            capacity_mask: capacity.wrapping_sub(1),
             size: 0,
             hashes: TaggedHashUintPtr::new(hashes),
             marker: marker::PhantomData,
         }
     }
 
-    fn first_bucket_raw(&self) -> RawBucket<K, V> {
-        let hashes_size = self.capacity * size_of::<HashUint>();
-        let pairs_size = self.capacity * size_of::<(K, V)>();
+    fn raw_bucket_at(&self, index: usize) -> RawBucket<K, V> {
+        let hashes_size = self.capacity() * size_of::<HashUint>();
+        let pairs_size = self.capacity() * size_of::<(K, V)>();
 
-        let buffer = self.hashes.ptr() as *mut u8;
         let (pairs_offset, _, oflo) =
             calculate_offsets(hashes_size, pairs_size, align_of::<(K, V)>());
         debug_assert!(!oflo, "capacity overflow");
+
+        let buffer = self.hashes.ptr() as *mut u8;
         unsafe {
             RawBucket {
-                hash: self.hashes.ptr(),
-                pair: buffer.offset(pairs_offset as isize) as *const _,
+                hash_start: buffer as *mut HashUint,
+                pair_start: buffer.offset(pairs_offset as isize) as *const (K, V),
+                idx: index,
                 _marker: marker::PhantomData,
             }
         }
@@ -837,7 +826,7 @@ impl<K, V> RawTable<K, V> {
 
     /// The hashtable's capacity, similar to a vector's.
     pub fn capacity(&self) -> usize {
-        self.capacity
+        self.capacity_mask.wrapping_add(1)
     }
 
     /// The number of elements ever `put` in the hashtable, minus the number
@@ -848,8 +837,8 @@ impl<K, V> RawTable<K, V> {
 
     fn raw_buckets(&self) -> RawBuckets<K, V> {
         RawBuckets {
-            raw: self.first_bucket_raw(),
-            hashes_end: unsafe { self.hashes.ptr().offset(self.capacity as isize) },
+            raw: self.raw_bucket_at(0),
+            elems_left: self.size,
             marker: marker::PhantomData,
         }
     }
@@ -857,25 +846,23 @@ impl<K, V> RawTable<K, V> {
     pub fn iter(&self) -> Iter<K, V> {
         Iter {
             iter: self.raw_buckets(),
-            elems_left: self.size(),
         }
     }
 
     pub fn iter_mut(&mut self) -> IterMut<K, V> {
         IterMut {
             iter: self.raw_buckets(),
-            elems_left: self.size(),
             _marker: marker::PhantomData,
         }
     }
 
     pub fn into_iter(self) -> IntoIter<K, V> {
-        let RawBuckets { raw, hashes_end, .. } = self.raw_buckets();
+        let RawBuckets { raw, elems_left, .. } = self.raw_buckets();
         // Replace the marker regardless of lifetime bounds on parameters.
         IntoIter {
             iter: RawBuckets {
                 raw: raw,
-                hashes_end: hashes_end,
+                elems_left: elems_left,
                 marker: marker::PhantomData,
             },
             table: self,
@@ -883,12 +870,12 @@ impl<K, V> RawTable<K, V> {
     }
 
     pub fn drain(&mut self) -> Drain<K, V> {
-        let RawBuckets { raw, hashes_end, .. } = self.raw_buckets();
+        let RawBuckets { raw, elems_left, .. } = self.raw_buckets();
         // Replace the marker regardless of lifetime bounds on parameters.
         Drain {
             iter: RawBuckets {
                 raw: raw,
-                hashes_end: hashes_end,
+                elems_left: elems_left,
                 marker: marker::PhantomData,
             },
             table: unsafe { Shared::new(self) },
@@ -900,18 +887,16 @@ impl<K, V> RawTable<K, V> {
     /// state and should only be used for dropping the table's remaining
     /// entries. It's used in the implementation of Drop.
     unsafe fn rev_drop_buckets(&mut self) {
-        let first_raw = self.first_bucket_raw();
-        let mut raw = first_raw.offset(self.capacity as isize);
+        // initialize the raw bucket past the end of the table
+        let mut raw = self.raw_bucket_at(self.capacity());
         let mut elems_left = self.size;
 
         while elems_left != 0 {
-            debug_assert!(raw.hash != first_raw.hash);
+            raw.idx -= 1;
 
-            raw = raw.offset(-1);
-
-            if *raw.hash != EMPTY_BUCKET {
+            if *raw.hash() != EMPTY_BUCKET {
                 elems_left -= 1;
-                ptr::drop_in_place(raw.pair as *mut (K, V));
+                ptr::drop_in_place(raw.pair());
             }
         }
     }
@@ -931,7 +916,7 @@ impl<K, V> RawTable<K, V> {
 /// this interface is safe, it's not used outside this module.
 struct RawBuckets<'a, K, V> {
     raw: RawBucket<K, V>,
-    hashes_end: *mut HashUint,
+    elems_left: usize,
 
     // Strictly speaking, this should be &'a (K,V), but that would
     // require that K:'a, and we often use RawBuckets<'static...> for
@@ -946,7 +931,7 @@ impl<'a, K, V> Clone for RawBuckets<'a, K, V> {
     fn clone(&self) -> RawBuckets<'a, K, V> {
         RawBuckets {
             raw: self.raw,
-            hashes_end: self.hashes_end,
+            elems_left: self.elems_left,
             marker: marker::PhantomData,
         }
     }
@@ -957,25 +942,36 @@ impl<'a, K, V> Iterator for RawBuckets<'a, K, V> {
     type Item = RawBucket<K, V>;
 
     fn next(&mut self) -> Option<RawBucket<K, V>> {
-        while self.raw.hash != self.hashes_end {
+        if self.elems_left == 0 {
+            return None;
+        }
+
+        loop {
             unsafe {
-                // We are swapping out the pointer to a bucket and replacing
-                // it with the pointer to the next one.
-                let prev = ptr::replace(&mut self.raw, self.raw.offset(1));
-                if *prev.hash != EMPTY_BUCKET {
-                    return Some(prev);
+                let item = self.raw;
+                self.raw.idx += 1;
+                if *item.hash() != EMPTY_BUCKET {
+                    self.elems_left -= 1;
+                    return Some(item);
                 }
             }
         }
+    }
+
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        (self.elems_left, Some(self.elems_left))
+    }
+}
 
-        None
+impl<'a, K, V> ExactSizeIterator for RawBuckets<'a, K, V> {
+    fn len(&self) -> usize {
+        self.elems_left
     }
 }
 
 /// Iterator over shared references to entries in a table.
 pub struct Iter<'a, K: 'a, V: 'a> {
     iter: RawBuckets<'a, K, V>,
-    elems_left: usize,
 }
 
 unsafe impl<'a, K: Sync, V: Sync> Sync for Iter<'a, K, V> {}
@@ -986,16 +982,13 @@ impl<'a, K, V> Clone for Iter<'a, K, V> {
     fn clone(&self) -> Iter<'a, K, V> {
         Iter {
             iter: self.iter.clone(),
-            elems_left: self.elems_left,
         }
     }
 }
 
-
 /// Iterator over mutable references to entries in a table.
 pub struct IterMut<'a, K: 'a, V: 'a> {
     iter: RawBuckets<'a, K, V>,
-    elems_left: usize,
     // To ensure invariance with respect to V
     _marker: marker::PhantomData<&'a mut V>,
 }
@@ -1009,7 +1002,6 @@ impl<'a, K: 'a, V: 'a> IterMut<'a, K, V> {
     pub fn iter(&self) -> Iter<K, V> {
         Iter {
             iter: self.iter.clone(),
-            elems_left: self.elems_left,
         }
     }
 }
@@ -1027,7 +1019,6 @@ impl<K, V> IntoIter<K, V> {
     pub fn iter(&self) -> Iter<K, V> {
         Iter {
             iter: self.iter.clone(),
-            elems_left: self.table.size,
         }
     }
 }
@@ -1044,11 +1035,8 @@ unsafe impl<'a, K: Send, V: Send> Send for Drain<'a, K, V> {}
 
 impl<'a, K, V> Drain<'a, K, V> {
     pub fn iter(&self) -> Iter<K, V> {
-        unsafe {
-            Iter {
-                iter: self.iter.clone(),
-                elems_left: (**self.table).size,
-            }
+        Iter {
+            iter: self.iter.clone(),
         }
     }
 }
@@ -1057,19 +1045,20 @@ impl<'a, K, V> Iterator for Iter<'a, K, V> {
     type Item = (&'a K, &'a V);
 
     fn next(&mut self) -> Option<(&'a K, &'a V)> {
-        self.iter.next().map(|bucket| {
-            self.elems_left -= 1;
-            unsafe { (&(*bucket.pair).0, &(*bucket.pair).1) }
+        self.iter.next().map(|raw| unsafe {
+            let pair_ptr = raw.pair();
+            (&(*pair_ptr).0, &(*pair_ptr).1)
         })
     }
 
     fn size_hint(&self) -> (usize, Option<usize>) {
-        (self.elems_left, Some(self.elems_left))
+        self.iter.size_hint()
     }
 }
+
 impl<'a, K, V> ExactSizeIterator for Iter<'a, K, V> {
     fn len(&self) -> usize {
-        self.elems_left
+        self.iter.len()
     }
 }
 
@@ -1077,20 +1066,20 @@ impl<'a, K, V> Iterator for IterMut<'a, K, V> {
     type Item = (&'a K, &'a mut V);
 
     fn next(&mut self) -> Option<(&'a K, &'a mut V)> {
-        self.iter.next().map(|bucket| {
-            self.elems_left -= 1;
-            let pair_mut = bucket.pair as *mut (K, V);
-            unsafe { (&(*pair_mut).0, &mut (*pair_mut).1) }
+        self.iter.next().map(|raw| unsafe {
+            let pair_ptr = raw.pair();
+            (&(*pair_ptr).0, &mut (*pair_ptr).1)
         })
     }
 
     fn size_hint(&self) -> (usize, Option<usize>) {
-        (self.elems_left, Some(self.elems_left))
+        self.iter.size_hint()
     }
 }
+
 impl<'a, K, V> ExactSizeIterator for IterMut<'a, K, V> {
     fn len(&self) -> usize {
-        self.elems_left
+        self.iter.len()
     }
 }
 
@@ -1098,23 +1087,23 @@ impl<K, V> Iterator for IntoIter<K, V> {
     type Item = (SafeHash, K, V);
 
     fn next(&mut self) -> Option<(SafeHash, K, V)> {
-        self.iter.next().map(|bucket| {
+        self.iter.next().map(|raw| {
             self.table.size -= 1;
             unsafe {
-                let (k, v) = ptr::read(bucket.pair);
-                (SafeHash { hash: *bucket.hash }, k, v)
+                let (k, v) = ptr::read(raw.pair());
+                (SafeHash { hash: *raw.hash() }, k, v)
             }
         })
     }
 
     fn size_hint(&self) -> (usize, Option<usize>) {
-        let size = self.table.size();
-        (size, Some(size))
+        self.iter.size_hint()
     }
 }
+
 impl<K, V> ExactSizeIterator for IntoIter<K, V> {
     fn len(&self) -> usize {
-        self.table.size()
+        self.iter().len()
     }
 }
 
@@ -1123,23 +1112,21 @@ impl<'a, K, V> Iterator for Drain<'a, K, V> {
 
     #[inline]
     fn next(&mut self) -> Option<(SafeHash, K, V)> {
-        self.iter.next().map(|bucket| {
-            unsafe {
-                (*self.table.as_mut_ptr()).size -= 1;
-                let (k, v) = ptr::read(bucket.pair);
-                (SafeHash { hash: ptr::replace(bucket.hash, EMPTY_BUCKET) }, k, v)
-            }
+        self.iter.next().map(|raw| unsafe {
+            (*self.table.as_mut_ptr()).size -= 1;
+            let (k, v) = ptr::read(raw.pair());
+            (SafeHash { hash: ptr::replace(&mut *raw.hash(), EMPTY_BUCKET) }, k, v)
         })
     }
 
     fn size_hint(&self) -> (usize, Option<usize>) {
-        let size = unsafe { (**self.table).size() };
-        (size, Some(size))
+        self.iter.size_hint()
     }
 }
+
 impl<'a, K, V> ExactSizeIterator for Drain<'a, K, V> {
     fn len(&self) -> usize {
-        unsafe { (**self.table).size() }
+        self.iter.len()
     }
 }
 
@@ -1152,30 +1139,21 @@ impl<'a, K: 'a, V: 'a> Drop for Drain<'a, K, V> {
 impl<K: Clone, V: Clone> Clone for RawTable<K, V> {
     fn clone(&self) -> RawTable<K, V> {
         unsafe {
-            let mut new_ht = RawTable::new_uninitialized(self.capacity());
-
-            {
-                let cap = self.capacity();
-                let mut new_buckets = Bucket::first(&mut new_ht);
-                let mut buckets = Bucket::first(self);
-                while buckets.index() != cap {
-                    match buckets.peek() {
-                        Full(full) => {
-                            let (h, k, v) = {
-                                let (k, v) = full.read();
-                                (full.hash(), k.clone(), v.clone())
-                            };
-                            *new_buckets.raw.hash = h.inspect();
-                            ptr::write(new_buckets.raw.pair as *mut (K, V), (k, v));
-                        }
-                        Empty(..) => {
-                            *new_buckets.raw.hash = EMPTY_BUCKET;
-                        }
-                    }
-                    new_buckets.next();
-                    buckets.next();
+            let cap = self.capacity();
+            let mut new_ht = RawTable::new_uninitialized(cap);
+
+            let mut new_buckets = new_ht.raw_bucket_at(0);
+            let mut buckets = self.raw_bucket_at(0);
+            while buckets.idx < cap {
+                *new_buckets.hash() = *buckets.hash();
+                if *new_buckets.hash() != EMPTY_BUCKET {
+                    let pair_ptr = buckets.pair();
+                    let kv = ((*pair_ptr).0.clone(), (*pair_ptr).1.clone());
+                    ptr::write(new_buckets.pair(), kv);
                 }
-            };
+                buckets.idx += 1;
+                new_buckets.idx += 1;
+            }
 
             new_ht.size = self.size();
 
@@ -1186,7 +1164,7 @@ impl<K: Clone, V: Clone> Clone for RawTable<K, V> {
 
 unsafe impl<#[may_dangle] K, #[may_dangle] V> Drop for RawTable<K, V> {
     fn drop(&mut self) {
-        if self.capacity == 0 {
+        if self.capacity() == 0 {
             return;
         }
 
@@ -1202,8 +1180,8 @@ unsafe impl<#[may_dangle] K, #[may_dangle] V> Drop for RawTable<K, V> {
             }
         }
 
-        let hashes_size = self.capacity * size_of::<HashUint>();
-        let pairs_size = self.capacity * size_of::<(K, V)>();
+        let hashes_size = self.capacity() * size_of::<HashUint>();
+        let pairs_size = self.capacity() * size_of::<(K, V)>();
         let (align, _, size, oflo) = calculate_allocation(hashes_size,
                                                           align_of::<HashUint>(),
                                                           pairs_size,
diff --git a/src/libstd/sys/unix/mod.rs b/src/libstd/sys/unix/mod.rs
index c57751a01d7..854d380d128 100644
--- a/src/libstd/sys/unix/mod.rs
+++ b/src/libstd/sys/unix/mod.rs
@@ -92,7 +92,7 @@ pub fn init() {
 
     #[cfg(not(any(target_os = "nacl", target_os = "emscripten", target_os="fuchsia")))]
     unsafe fn reset_sigpipe() {
-        assert!(signal(libc::SIGPIPE, libc::SIG_IGN) != !0);
+        assert!(signal(libc::SIGPIPE, libc::SIG_IGN) != libc::SIG_ERR);
     }
     #[cfg(any(target_os = "nacl", target_os = "emscripten", target_os="fuchsia"))]
     unsafe fn reset_sigpipe() {}
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index a27fc070ebe..8595bfc9f79 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -4657,25 +4657,30 @@ impl<'a> Parser<'a> {
         })
     }
 
-    fn complain_if_pub_macro(&mut self, visa: &Visibility, span: Span) {
-        match *visa {
-            Visibility::Inherited => (),
+    fn complain_if_pub_macro(&mut self, vis: &Visibility, sp: Span) {
+        if let Err(mut err) = self.complain_if_pub_macro_diag(vis, sp) {
+            err.emit();
+        }
+    }
+
+    fn complain_if_pub_macro_diag(&mut self, vis: &Visibility, sp: Span) -> PResult<'a, ()> {
+        match *vis {
+            Visibility::Inherited => Ok(()),
             _ => {
                 let is_macro_rules: bool = match self.token {
                     token::Ident(sid) => sid.name == Symbol::intern("macro_rules"),
                     _ => false,
                 };
                 if is_macro_rules {
-                    self.diagnostic().struct_span_err(span, "can't qualify macro_rules \
-                                                             invocation with `pub`")
-                                     .help("did you mean #[macro_export]?")
-                                     .emit();
+                    let mut err = self.diagnostic()
+                        .struct_span_err(sp, "can't qualify macro_rules invocation with `pub`");
+                    err.help("did you mean #[macro_export]?");
+                    Err(err)
                 } else {
-                    self.diagnostic().struct_span_err(span, "can't qualify macro \
-                                                             invocation with `pub`")
-                                     .help("try adjusting the macro to put `pub` \
-                                            inside the invocation")
-                                     .emit();
+                    let mut err = self.diagnostic()
+                        .struct_span_err(sp, "can't qualify macro invocation with `pub`");
+                    err.help("try adjusting the macro to put `pub` inside the invocation");
+                    Err(err)
                 }
             }
         }
@@ -4686,14 +4691,36 @@ impl<'a> Parser<'a> {
                          -> PResult<'a, (Ident, Vec<ast::Attribute>, ast::ImplItemKind)> {
         // code copied from parse_macro_use_or_failure... abstraction!
         if self.token.is_path_start() {
-            // method macro.
+            // Method macro.
 
             let prev_span = self.prev_span;
-            self.complain_if_pub_macro(&vis, prev_span);
+            // Before complaining about trying to set a macro as `pub`,
+            // check if `!` comes after the path.
+            let err = self.complain_if_pub_macro_diag(&vis, prev_span);
 
             let lo = self.span;
             let pth = self.parse_path(PathStyle::Mod)?;
-            self.expect(&token::Not)?;
+            let bang_err = self.expect(&token::Not);
+            if let Err(mut err) = err {
+                if let Err(mut bang_err) = bang_err {
+                    // Given this code `pub path(`, it seems like this is not setting the
+                    // visibility of a macro invocation, but rather a mistyped method declaration.
+                    // Create a diagnostic pointing out that `fn` is missing.
+                    //
+                    // x |     pub path(&self) {
+                    //   |        ^ missing `fn` for method declaration
+
+                    err.cancel();
+                    bang_err.cancel();
+                    //     pub  path(
+                    //        ^^ `sp` below will point to this
+                    let sp = prev_span.between(self.prev_span);
+                    err = self.diagnostic()
+                        .struct_span_err(sp, "missing `fn` for method declaration");
+                    err.span_label(sp, &"missing `fn`");
+                }
+                return Err(err);
+            }
 
             // eat a matched-delimiter token tree:
             let (delim, tts) = self.expect_delimited_token_tree()?;
diff --git a/src/libsyntax_pos/lib.rs b/src/libsyntax_pos/lib.rs
index 3f09b2009a7..9b88b9f7696 100644
--- a/src/libsyntax_pos/lib.rs
+++ b/src/libsyntax_pos/lib.rs
@@ -189,6 +189,30 @@ impl Span {
             Span { hi: end.hi, ..self }
         }
     }
+
+    pub fn between(self, end: Span) -> Span {
+        Span {
+            lo: self.hi,
+            hi: end.lo,
+            ctxt: if end.ctxt == SyntaxContext::empty() {
+                end.ctxt
+            } else {
+                self.ctxt
+            }
+        }
+    }
+
+    pub fn until(self, end: Span) -> Span {
+        Span {
+            lo: self.lo,
+            hi: end.lo,
+            ctxt: if end.ctxt == SyntaxContext::empty() {
+                end.ctxt
+            } else {
+                self.ctxt
+            }
+        }
+    }
 }
 
 #[derive(Clone, Debug)]
diff --git a/src/test/compile-fail/coherence-overlapping-inherent-impl-trait.rs b/src/test/ui/codemap_tests/coherence-overlapping-inherent-impl-trait.rs
index 158d3606104..a72ad0351e3 100644
--- a/src/test/compile-fail/coherence-overlapping-inherent-impl-trait.rs
+++ b/src/test/ui/codemap_tests/coherence-overlapping-inherent-impl-trait.rs
@@ -11,6 +11,6 @@
 #![allow(dead_code)]
 
 trait C {}
-impl C { fn f() {} } //~ ERROR duplicate definitions with name `f`
+impl C { fn f() {} }
 impl C { fn f() {} }
 fn main() { }
diff --git a/src/test/ui/codemap_tests/coherence-overlapping-inherent-impl-trait.stderr b/src/test/ui/codemap_tests/coherence-overlapping-inherent-impl-trait.stderr
new file mode 100644
index 00000000000..7f1ab929c6f
--- /dev/null
+++ b/src/test/ui/codemap_tests/coherence-overlapping-inherent-impl-trait.stderr
@@ -0,0 +1,10 @@
+error[E0592]: duplicate definitions with name `f`
+  --> $DIR/coherence-overlapping-inherent-impl-trait.rs:14:10
+   |
+14 | impl C { fn f() {} }
+   |          ^^^^^^^^^ duplicate definitions for `f`
+15 | impl C { fn f() {} }
+   |          --------- other definition for `f`
+
+error: aborting due to previous error
+
diff --git a/src/test/compile-fail/inherent-overlap.rs b/src/test/ui/codemap_tests/overlapping_inherent_impls.rs
index 18e77ddfd2c..a626b63b31b 100644
--- a/src/test/compile-fail/inherent-overlap.rs
+++ b/src/test/ui/codemap_tests/overlapping_inherent_impls.rs
@@ -16,7 +16,7 @@
 struct Foo;
 
 impl Foo {
-    fn id() {} //~ ERROR duplicate definitions
+    fn id() {}
 }
 
 impl Foo {
@@ -26,7 +26,7 @@ impl Foo {
 struct Bar<T>(T);
 
 impl<T> Bar<T> {
-    fn bar(&self) {} //~ ERROR duplicate definitions
+    fn bar(&self) {}
 }
 
 impl Bar<u32> {
@@ -36,7 +36,7 @@ impl Bar<u32> {
 struct Baz<T>(T);
 
 impl<T: Copy> Baz<T> {
-    fn baz(&self) {} //~ ERROR duplicate definitions
+    fn baz(&self) {}
 }
 
 impl<T> Baz<Vec<T>> {
diff --git a/src/test/ui/codemap_tests/overlapping_inherent_impls.stderr b/src/test/ui/codemap_tests/overlapping_inherent_impls.stderr
new file mode 100644
index 00000000000..de8a24cf33f
--- /dev/null
+++ b/src/test/ui/codemap_tests/overlapping_inherent_impls.stderr
@@ -0,0 +1,29 @@
+error[E0592]: duplicate definitions with name `id`
+  --> $DIR/overlapping_inherent_impls.rs:19:5
+   |
+19 |     fn id() {}
+   |     ^^^^^^^^^^ duplicate definitions for `id`
+...
+23 |     fn id() {}
+   |     ---------- other definition for `id`
+
+error[E0592]: duplicate definitions with name `bar`
+  --> $DIR/overlapping_inherent_impls.rs:29:5
+   |
+29 |     fn bar(&self) {}
+   |     ^^^^^^^^^^^^^^^^ duplicate definitions for `bar`
+...
+33 |     fn bar(&self) {}
+   |     ---------------- other definition for `bar`
+
+error[E0592]: duplicate definitions with name `baz`
+  --> $DIR/overlapping_inherent_impls.rs:39:5
+   |
+39 |     fn baz(&self) {}
+   |     ^^^^^^^^^^^^^^^^ duplicate definitions for `baz`
+...
+43 |     fn baz(&self) {}
+   |     ---------------- other definition for `baz`
+
+error: aborting due to 3 previous errors
+
diff --git a/src/test/ui/did_you_mean/issue-40006.rs b/src/test/ui/did_you_mean/issue-40006.rs
new file mode 100644
index 00000000000..cf75929bae2
--- /dev/null
+++ b/src/test/ui/did_you_mean/issue-40006.rs
@@ -0,0 +1,21 @@
+// Copyright 2017 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.
+
+struct S;
+
+impl S {
+    pub hello_method(&self) {
+        println!("Hello");
+    }
+}
+
+fn main() {
+    S.hello_method();
+}
diff --git a/src/test/ui/did_you_mean/issue-40006.stderr b/src/test/ui/did_you_mean/issue-40006.stderr
new file mode 100644
index 00000000000..460958027ad
--- /dev/null
+++ b/src/test/ui/did_you_mean/issue-40006.stderr
@@ -0,0 +1,8 @@
+error: missing `fn` for method declaration
+  --> $DIR/issue-40006.rs:14:8
+   |
+14 |     pub hello_method(&self) {
+   |        ^ missing `fn`
+
+error: aborting due to previous error
+