about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2015-03-31 05:47:35 +0000
committerbors <bors@rust-lang.org>2015-03-31 05:47:35 +0000
commitb3317d68910900f135f9f38e43a7a699bc736b4a (patch)
treefcc7af00740cd4540119a4f4bf345cd077ed269c
parent6cf3b0b74aadcc1fe87adbd2c74876a1f6c920b3 (diff)
parentdb76327ef686d81c74e74ac25028681e61badb3c (diff)
downloadrust-b3317d68910900f135f9f38e43a7a699bc736b4a.tar.gz
rust-b3317d68910900f135f9f38e43a7a699bc736b4a.zip
Auto merge of #23884 - Manishearth:rollup, r=Manishearth
- Successful merges: #23558, #23813, #23826, #23836, #23839, #23846, #23852, #23859, #23862, #23865, #23866, #23869, #23874
- Failed merges: 
-rw-r--r--mk/crates.mk21
-rw-r--r--src/doc/reference.md7
-rw-r--r--src/doc/trpl/method-syntax.md24
-rw-r--r--src/doc/trpl/ownership.md13
-rw-r--r--src/doc/trpl/testing.md6
-rw-r--r--src/liballoc/heap.rs2
-rw-r--r--src/libcollections/btree/node.rs24
-rw-r--r--src/libcollections/slice.rs20
-rw-r--r--src/libcollections/string.rs33
-rw-r--r--src/libcollections/vec.rs22
-rw-r--r--src/libcollections/vec_deque.rs16
-rw-r--r--src/libcore/error.rs29
-rw-r--r--src/libcore/fmt/float.rs4
-rw-r--r--src/libcore/intrinsics.rs20
-rw-r--r--src/libcore/mem.rs6
-rw-r--r--src/libcore/option.rs2
-rw-r--r--src/libcore/ptr.rs26
-rw-r--r--src/libcore/slice.rs6
-rw-r--r--src/libcoretest/ptr.rs9
-rw-r--r--src/librbml/lib.rs8
-rw-r--r--src/librustc/metadata/decoder.rs2
-rw-r--r--src/librustc/middle/expr_use_visitor.rs5
-rw-r--r--src/librustc/middle/mem_categorization.rs169
-rw-r--r--src/librustc_back/sha2.rs12
-rw-r--r--src/librustc_borrowck/borrowck/check_loans.rs13
-rw-r--r--src/librustc_borrowck/borrowck/gather_loans/mod.rs33
-rw-r--r--src/librustc_borrowck/borrowck/mod.rs6
-rw-r--r--src/librustc_lint/builtin.rs36
-rw-r--r--src/librustc_trans/trans/intrinsic.rs4
-rw-r--r--src/librustc_typeck/check/mod.rs16
-rw-r--r--src/librustdoc/test.rs5
-rw-r--r--src/libstd/collections/hash/table.rs4
-rw-r--r--src/libstd/io/buffered.rs4
-rw-r--r--src/libstd/io/cursor.rs2
-rw-r--r--src/libstd/io/impls.rs4
-rw-r--r--src/libstd/macros.rs4
-rw-r--r--src/libstd/old_io/buffered.rs4
-rw-r--r--src/libstd/old_io/comm_adapters.rs2
-rw-r--r--src/libstd/old_io/extensions.rs2
-rw-r--r--src/libstd/old_io/mem.rs10
-rw-r--r--src/libstd/sys/common/wtf8.rs2
-rw-r--r--src/test/bench/shootout-fasta-redux.rs5
-rw-r--r--src/test/bench/shootout-reverse-complement.rs4
-rw-r--r--src/test/compile-fail/borrowck-issue-14498.rs62
-rw-r--r--src/test/run-pass/issue-11592.rs20
-rw-r--r--src/test/run-pass/method-mut-self-modifies-mut-slice-lvalue.rs2
46 files changed, 511 insertions, 219 deletions
diff --git a/mk/crates.mk b/mk/crates.mk
index 7494a9c5f98..f594a6a19f1 100644
--- a/mk/crates.mk
+++ b/mk/crates.mk
@@ -125,13 +125,18 @@ ONLY_RLIB_rustc_bitflags := 1
 # On channels where the only usable crate is std, only build documentation for
 # std. This keeps distributions small and doesn't clutter up the API docs with
 # confusing internal details from the crates behind the facade.
+#
+# (Disabled while cmr figures out how to change rustdoc to make reexports work
+# slightly nicer. Otherwise, all cross-crate links to Vec will go to
+# libcollections, breaking them, and [src] links for anything reexported will
+# not work.)
 
-ifeq ($(CFG_RELEASE_CHANNEL),stable)
-DOC_CRATES := std
-else
-ifeq ($(CFG_RELEASE_CHANNEL),beta)
-DOC_CRATES := std
-else
+#ifeq ($(CFG_RELEASE_CHANNEL),stable)
+#DOC_CRATES := std
+#else
+#ifeq ($(CFG_RELEASE_CHANNEL),beta)
+#DOC_CRATES := std
+#else
 DOC_CRATES := $(filter-out rustc, \
 	   $(filter-out rustc_trans, \
 	   $(filter-out rustc_typeck, \
@@ -143,8 +148,8 @@ DOC_CRATES := $(filter-out rustc, \
 	   $(filter-out log, \
 	   $(filter-out getopts, \
 	   $(filter-out syntax, $(CRATES))))))))))))
-endif
-endif
+#endif
+#endif
 COMPILER_DOC_CRATES := rustc rustc_trans rustc_borrowck rustc_resolve \
                        rustc_typeck rustc_driver syntax rustc_privacy \
                        rustc_lint
diff --git a/src/doc/reference.md b/src/doc/reference.md
index 4da7d6db444..0bc4414999d 100644
--- a/src/doc/reference.md
+++ b/src/doc/reference.md
@@ -1188,12 +1188,15 @@ the guarantee that these issues are never caused by safe code.
 
 * Data races
 * Dereferencing a null/dangling raw pointer
-* Mutating an immutable value/reference without `UnsafeCell`
 * Reads of [undef](http://llvm.org/docs/LangRef.html#undefined-values)
   (uninitialized) memory
 * Breaking the [pointer aliasing
   rules](http://llvm.org/docs/LangRef.html#pointer-aliasing-rules)
   with raw pointers (a subset of the rules used by C)
+* `&mut` and `&` follow LLVM’s scoped [noalias] model, except if the `&T`
+  contains an `UnsafeCell<U>`. Unsafe code must not violate these aliasing
+  guarantees.
+* Mutating an immutable value/reference without `UnsafeCell<U>`
 * Invoking undefined behavior via compiler intrinsics:
   * Indexing outside of the bounds of an object with `std::ptr::offset`
     (`offset` intrinsic), with
@@ -1210,6 +1213,8 @@ the guarantee that these issues are never caused by safe code.
   code. Rust's failure system is not compatible with exception handling in
   other languages. Unwinding must be caught and handled at FFI boundaries.
 
+[noalias]: http://llvm.org/docs/LangRef.html#noalias
+
 ##### Behaviour not considered unsafe
 
 This is a list of behaviour not considered *unsafe* in Rust terms, but that may
diff --git a/src/doc/trpl/method-syntax.md b/src/doc/trpl/method-syntax.md
index 85114b40a90..18542e58bbf 100644
--- a/src/doc/trpl/method-syntax.md
+++ b/src/doc/trpl/method-syntax.md
@@ -181,17 +181,23 @@ impl Circle {
 }
 
 struct CircleBuilder {
-    coordinate: f64,
+    x: f64,
+    y: f64,
     radius: f64,
 }
 
 impl CircleBuilder {
     fn new() -> CircleBuilder {
-        CircleBuilder { coordinate: 0.0, radius: 0.0, }
+        CircleBuilder { x: 0.0, y: 0.0, radius: 0.0, }
+    }
+
+    fn x(&mut self, coordinate: f64) -> &mut CircleBuilder {
+        self.x = coordinate;
+        self
     }
 
-    fn coordinate(&mut self, coordinate: f64) -> &mut CircleBuilder {
-        self.coordinate = coordinate;
+    fn y(&mut self, coordinate: f64) -> &mut CircleBuilder {
+        self.x = coordinate;
         self
     }
 
@@ -201,18 +207,20 @@ impl CircleBuilder {
     }
 
     fn finalize(&self) -> Circle {
-        Circle { x: self.coordinate, y: self.coordinate, radius: self.radius }
+        Circle { x: self.x, y: self.y, radius: self.radius }
     }
 }
 
 fn main() {
     let c = CircleBuilder::new()
-                .coordinate(10.0)
-                .radius(5.0)
+                .x(1.0)
+                .y(2.0)
+                .radius(2.0)
                 .finalize();
 
-
     println!("area: {}", c.area());
+    println!("x: {}", c.x);
+    println!("y: {}", c.y);
 }
 ```
 
diff --git a/src/doc/trpl/ownership.md b/src/doc/trpl/ownership.md
index b851f19d22d..f4b5495ba63 100644
--- a/src/doc/trpl/ownership.md
+++ b/src/doc/trpl/ownership.md
@@ -472,10 +472,15 @@ thread-safe counterpart of `Rc<T>`.
 
 ## Lifetime Elision
 
-Earlier, we mentioned *lifetime elision*, a feature of Rust which allows you to
-not write lifetime annotations in certain circumstances. All references have a
-lifetime, and so if you elide a lifetime (like `&T` instead of `&'a T`), Rust
-will do three things to determine what those lifetimes should be.
+Rust supports powerful local type inference in function bodies, but it’s
+forbidden in item signatures to allow reasoning about the types just based in
+the item signature alone. However, for ergonomic reasons a very restricted
+secondary inference algorithm called “lifetime elision” applies in function
+signatures. It infers only based on the signature components themselves and not
+based on the body of the function, only infers lifetime paramters, and does
+this with only three easily memorizable and unambiguous rules. This makes
+lifetime elision a shorthand for writing an item signature, while not hiding
+away the actual types involved as full local inference would if applied to it.
 
 When talking about lifetime elision, we use the term *input lifetime* and
 *output lifetime*. An *input lifetime* is a lifetime associated with a parameter
diff --git a/src/doc/trpl/testing.md b/src/doc/trpl/testing.md
index 8fb08e1c6cf..8b2c14526cb 100644
--- a/src/doc/trpl/testing.md
+++ b/src/doc/trpl/testing.md
@@ -231,7 +231,7 @@ pub fn add_two(a: i32) -> i32 {
 }
 
 #[cfg(test)]
-mod tests {
+mod test {
     use super::add_two;
 
     #[test]
@@ -241,7 +241,7 @@ mod tests {
 }
 ```
 
-There's a few changes here. The first is the introduction of a `mod tests` with
+There's a few changes here. The first is the introduction of a `mod test` with
 a `cfg` attribute. The module allows us to group all of our tests together, and
 to also define helper functions if needed, that don't become a part of the rest
 of our crate. The `cfg` attribute only compiles our test code if we're
@@ -260,7 +260,7 @@ pub fn add_two(a: i32) -> i32 {
 }
 
 #[cfg(test)]
-mod tests {
+mod test {
     use super::*;
 
     #[test]
diff --git a/src/liballoc/heap.rs b/src/liballoc/heap.rs
index 3733350412e..c6c86e46b44 100644
--- a/src/liballoc/heap.rs
+++ b/src/liballoc/heap.rs
@@ -301,7 +301,7 @@ mod imp {
             libc::realloc(ptr as *mut libc::c_void, size as libc::size_t) as *mut u8
         } else {
             let new_ptr = allocate(size, align);
-            ptr::copy(new_ptr, ptr, cmp::min(size, old_size));
+            ptr::copy(ptr, new_ptr, cmp::min(size, old_size));
             deallocate(ptr, old_size, align);
             new_ptr
         }
diff --git a/src/libcollections/btree/node.rs b/src/libcollections/btree/node.rs
index 956d4d143d2..847ee7c19ce 100644
--- a/src/libcollections/btree/node.rs
+++ b/src/libcollections/btree/node.rs
@@ -1133,13 +1133,13 @@ impl<K, V> Node<K, V> {
     #[inline]
     unsafe fn insert_kv(&mut self, index: usize, key: K, val: V) -> &mut V {
         ptr::copy(
-            self.keys_mut().as_mut_ptr().offset(index as isize + 1),
             self.keys().as_ptr().offset(index as isize),
+            self.keys_mut().as_mut_ptr().offset(index as isize + 1),
             self.len() - index
         );
         ptr::copy(
-            self.vals_mut().as_mut_ptr().offset(index as isize + 1),
             self.vals().as_ptr().offset(index as isize),
+            self.vals_mut().as_mut_ptr().offset(index as isize + 1),
             self.len() - index
         );
 
@@ -1155,8 +1155,8 @@ impl<K, V> Node<K, V> {
     #[inline]
     unsafe fn insert_edge(&mut self, index: usize, edge: Node<K, V>) {
         ptr::copy(
-            self.edges_mut().as_mut_ptr().offset(index as isize + 1),
             self.edges().as_ptr().offset(index as isize),
+            self.edges_mut().as_mut_ptr().offset(index as isize + 1),
             self.len() - index
         );
         ptr::write(self.edges_mut().get_unchecked_mut(index), edge);
@@ -1188,13 +1188,13 @@ impl<K, V> Node<K, V> {
         let val = ptr::read(self.vals().get_unchecked(index));
 
         ptr::copy(
-            self.keys_mut().as_mut_ptr().offset(index as isize),
             self.keys().as_ptr().offset(index as isize + 1),
+            self.keys_mut().as_mut_ptr().offset(index as isize),
             self.len() - index - 1
         );
         ptr::copy(
-            self.vals_mut().as_mut_ptr().offset(index as isize),
             self.vals().as_ptr().offset(index as isize + 1),
+            self.vals_mut().as_mut_ptr().offset(index as isize),
             self.len() - index - 1
         );
 
@@ -1209,8 +1209,8 @@ impl<K, V> Node<K, V> {
         let edge = ptr::read(self.edges().get_unchecked(index));
 
         ptr::copy(
-            self.edges_mut().as_mut_ptr().offset(index as isize),
             self.edges().as_ptr().offset(index as isize + 1),
+            self.edges_mut().as_mut_ptr().offset(index as isize),
             // index can be == len+1, so do the +1 first to avoid underflow.
             (self.len() + 1) - index
         );
@@ -1237,19 +1237,19 @@ impl<K, V> Node<K, V> {
             right._len = self.len() / 2;
             let right_offset = self.len() - right.len();
             ptr::copy_nonoverlapping(
-                right.keys_mut().as_mut_ptr(),
                 self.keys().as_ptr().offset(right_offset as isize),
+                right.keys_mut().as_mut_ptr(),
                 right.len()
             );
             ptr::copy_nonoverlapping(
-                right.vals_mut().as_mut_ptr(),
                 self.vals().as_ptr().offset(right_offset as isize),
+                right.vals_mut().as_mut_ptr(),
                 right.len()
             );
             if !self.is_leaf() {
                 ptr::copy_nonoverlapping(
-                    right.edges_mut().as_mut_ptr(),
                     self.edges().as_ptr().offset(right_offset as isize),
+                    right.edges_mut().as_mut_ptr(),
                     right.len() + 1
                 );
             }
@@ -1278,19 +1278,19 @@ impl<K, V> Node<K, V> {
             ptr::write(self.vals_mut().get_unchecked_mut(old_len), val);
 
             ptr::copy_nonoverlapping(
-                self.keys_mut().as_mut_ptr().offset(old_len as isize + 1),
                 right.keys().as_ptr(),
+                self.keys_mut().as_mut_ptr().offset(old_len as isize + 1),
                 right.len()
             );
             ptr::copy_nonoverlapping(
-                self.vals_mut().as_mut_ptr().offset(old_len as isize + 1),
                 right.vals().as_ptr(),
+                self.vals_mut().as_mut_ptr().offset(old_len as isize + 1),
                 right.len()
             );
             if !self.is_leaf() {
                 ptr::copy_nonoverlapping(
-                    self.edges_mut().as_mut_ptr().offset(old_len as isize + 1),
                     right.edges().as_ptr(),
+                    self.edges_mut().as_mut_ptr().offset(old_len as isize + 1),
                     right.len() + 1
                 );
             }
diff --git a/src/libcollections/slice.rs b/src/libcollections/slice.rs
index 14dcd52fe80..0ca297765ff 100644
--- a/src/libcollections/slice.rs
+++ b/src/libcollections/slice.rs
@@ -1320,10 +1320,10 @@ fn insertion_sort<T, F>(v: &mut [T], mut compare: F) where F: FnMut(&T, &T) -> O
 
             if i != j {
                 let tmp = ptr::read(read_ptr);
-                ptr::copy(buf_v.offset(j + 1),
-                          &*buf_v.offset(j),
+                ptr::copy(&*buf_v.offset(j),
+                          buf_v.offset(j + 1),
                           (i - j) as usize);
-                ptr::copy_nonoverlapping(buf_v.offset(j), &tmp, 1);
+                ptr::copy_nonoverlapping(&tmp, buf_v.offset(j), 1);
                 mem::forget(tmp);
             }
         }
@@ -1396,10 +1396,10 @@ fn merge_sort<T, F>(v: &mut [T], mut compare: F) where F: FnMut(&T, &T) -> Order
                 // j + 1 could be `len` (for the last `i`), but in
                 // that case, `i == j` so we don't copy. The
                 // `.offset(j)` is always in bounds.
-                ptr::copy(buf_dat.offset(j + 1),
-                          &*buf_dat.offset(j),
+                ptr::copy(&*buf_dat.offset(j),
+                          buf_dat.offset(j + 1),
                           i - j as usize);
-                ptr::copy_nonoverlapping(buf_dat.offset(j), read_ptr, 1);
+                ptr::copy_nonoverlapping(read_ptr, buf_dat.offset(j), 1);
             }
         }
     }
@@ -1447,11 +1447,11 @@ fn merge_sort<T, F>(v: &mut [T], mut compare: F) where F: FnMut(&T, &T) -> Order
                     if left == right_start {
                         // the number remaining in this run.
                         let elems = (right_end as usize - right as usize) / mem::size_of::<T>();
-                        ptr::copy_nonoverlapping(out, &*right, elems);
+                        ptr::copy_nonoverlapping(&*right, out, elems);
                         break;
                     } else if right == right_end {
                         let elems = (right_start as usize - left as usize) / mem::size_of::<T>();
-                        ptr::copy_nonoverlapping(out, &*left, elems);
+                        ptr::copy_nonoverlapping(&*left, out, elems);
                         break;
                     }
 
@@ -1465,7 +1465,7 @@ fn merge_sort<T, F>(v: &mut [T], mut compare: F) where F: FnMut(&T, &T) -> Order
                     } else {
                         step(&mut left)
                     };
-                    ptr::copy_nonoverlapping(out, &*to_copy, 1);
+                    ptr::copy_nonoverlapping(&*to_copy, out, 1);
                     step(&mut out);
                 }
             }
@@ -1479,7 +1479,7 @@ fn merge_sort<T, F>(v: &mut [T], mut compare: F) where F: FnMut(&T, &T) -> Order
     // write the result to `v` in one go, so that there are never two copies
     // of the same object in `v`.
     unsafe {
-        ptr::copy_nonoverlapping(v.as_mut_ptr(), &*buf_dat, len);
+        ptr::copy_nonoverlapping(&*buf_dat, v.as_mut_ptr(), len);
     }
 
     // increment the pointer, returning the old pointer.
diff --git a/src/libcollections/string.rs b/src/libcollections/string.rs
index 7131c1cd881..dbf214a712b 100644
--- a/src/libcollections/string.rs
+++ b/src/libcollections/string.rs
@@ -592,8 +592,8 @@ impl String {
         let ch = self.char_at(idx);
         let next = idx + ch.len_utf8();
         unsafe {
-            ptr::copy(self.vec.as_mut_ptr().offset(idx as isize),
-                      self.vec.as_ptr().offset(next as isize),
+            ptr::copy(self.vec.as_ptr().offset(next as isize),
+                      self.vec.as_mut_ptr().offset(idx as isize),
                       len - next);
             self.vec.set_len(len - (next - idx));
         }
@@ -622,11 +622,11 @@ impl String {
         let amt = ch.encode_utf8(&mut bits).unwrap();
 
         unsafe {
-            ptr::copy(self.vec.as_mut_ptr().offset((idx + amt) as isize),
-                      self.vec.as_ptr().offset(idx as isize),
+            ptr::copy(self.vec.as_ptr().offset(idx as isize),
+                      self.vec.as_mut_ptr().offset((idx + amt) as isize),
                       len - idx);
-            ptr::copy(self.vec.as_mut_ptr().offset(idx as isize),
-                      bits.as_ptr(),
+            ptr::copy(bits.as_ptr(),
+                      self.vec.as_mut_ptr().offset(idx as isize),
                       amt);
             self.vec.set_len(len + amt);
         }
@@ -1019,19 +1019,36 @@ impl AsRef<str> for String {
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<'a> From<&'a str> for String {
+    #[inline]
     fn from(s: &'a str) -> String {
         s.to_string()
     }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
+impl<'a> From<&'a str> for Cow<'a, str> {
+    #[inline]
+    fn from(s: &'a str) -> Cow<'a, str> {
+        Cow::Borrowed(s)
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a> From<String> for Cow<'a, str> {
+    #[inline]
+    fn from(s: String) -> Cow<'a, str> {
+        Cow::Owned(s)
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
 impl Into<Vec<u8>> for String {
     fn into(self) -> Vec<u8> {
         self.into_bytes()
     }
 }
 
-#[stable(feature = "rust1", since = "1.0.0")]
+#[unstable(feature = "into_cow", reason = "may be replaced by `convert::Into`")]
 impl IntoCow<'static, str> for String {
     #[inline]
     fn into_cow(self) -> Cow<'static, str> {
@@ -1039,7 +1056,7 @@ impl IntoCow<'static, str> for String {
     }
 }
 
-#[stable(feature = "rust1", since = "1.0.0")]
+#[unstable(feature = "into_cow", reason = "may be replaced by `convert::Into`")]
 impl<'a> IntoCow<'a, str> for &'a str {
     #[inline]
     fn into_cow(self) -> Cow<'a, str> {
diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs
index 14bc7f65e09..3595288a6c9 100644
--- a/src/libcollections/vec.rs
+++ b/src/libcollections/vec.rs
@@ -260,16 +260,17 @@ impl<T> Vec<T> {
 
     /// Creates a vector by copying the elements from a raw pointer.
     ///
-    /// This function will copy `elts` contiguous elements starting at `ptr` into a new allocation
-    /// owned by the returned `Vec<T>`. The elements of the buffer are copied into the vector
-    /// without cloning, as if `ptr::read()` were called on them.
+    /// This function will copy `elts` contiguous elements starting at `ptr`
+    /// into a new allocation owned by the returned `Vec<T>`. The elements of
+    /// the buffer are copied into the vector without cloning, as if
+    /// `ptr::read()` were called on them.
     #[inline]
     #[unstable(feature = "collections",
                reason = "may be better expressed via composition")]
     pub unsafe fn from_raw_buf(ptr: *const T, elts: usize) -> Vec<T> {
         let mut dst = Vec::with_capacity(elts);
         dst.set_len(elts);
-        ptr::copy_nonoverlapping(dst.as_mut_ptr(), ptr, elts);
+        ptr::copy_nonoverlapping(ptr, dst.as_mut_ptr(), elts);
         dst
     }
 
@@ -288,8 +289,9 @@ impl<T> Vec<T> {
         self.cap
     }
 
-    /// Reserves capacity for at least `additional` more elements to be inserted in the given
-    /// `Vec<T>`. The collection may reserve more space to avoid frequent reallocations.
+    /// Reserves capacity for at least `additional` more elements to be inserted
+    /// in the given `Vec<T>`. The collection may reserve more space to avoid
+    /// frequent reallocations.
     ///
     /// # Panics
     ///
@@ -541,7 +543,7 @@ impl<T> Vec<T> {
                 let p = self.as_mut_ptr().offset(index as isize);
                 // Shift everything over to make space. (Duplicating the
                 // `index`th element into two consecutive places.)
-                ptr::copy(p.offset(1), &*p, len - index);
+                ptr::copy(&*p, p.offset(1), len - index);
                 // Write it in, overwriting the first copy of the `index`th
                 // element.
                 ptr::write(&mut *p, element);
@@ -579,7 +581,7 @@ impl<T> Vec<T> {
                 ret = ptr::read(ptr);
 
                 // Shift everything down to fill in that spot.
-                ptr::copy(ptr, &*ptr.offset(1), len - index - 1);
+                ptr::copy(&*ptr.offset(1), ptr, len - index - 1);
             }
             self.set_len(len - 1);
             ret
@@ -721,8 +723,8 @@ impl<T> Vec<T> {
         let len = self.len();
         unsafe {
             ptr::copy_nonoverlapping(
-                self.get_unchecked_mut(len),
                 other.as_ptr(),
+                self.get_unchecked_mut(len),
                 other.len());
         }
 
@@ -1042,8 +1044,8 @@ impl<T> Vec<T> {
             other.set_len(other_len);
 
             ptr::copy_nonoverlapping(
-                other.as_mut_ptr(),
                 self.as_ptr().offset(at as isize),
+                other.as_mut_ptr(),
                 other.len());
         }
         other
diff --git a/src/libcollections/vec_deque.rs b/src/libcollections/vec_deque.rs
index 8f3f4e6b890..abe8e7cf3aa 100644
--- a/src/libcollections/vec_deque.rs
+++ b/src/libcollections/vec_deque.rs
@@ -142,8 +142,8 @@ impl<T> VecDeque<T> {
         debug_assert!(src + len <= self.cap, "dst={} src={} len={} cap={}", dst, src, len,
                       self.cap);
         ptr::copy(
-            self.ptr.offset(dst as isize),
             self.ptr.offset(src as isize),
+            self.ptr.offset(dst as isize),
             len);
     }
 
@@ -155,8 +155,8 @@ impl<T> VecDeque<T> {
         debug_assert!(src + len <= self.cap, "dst={} src={} len={} cap={}", dst, src, len,
                       self.cap);
         ptr::copy_nonoverlapping(
-            self.ptr.offset(dst as isize),
             self.ptr.offset(src as isize),
+            self.ptr.offset(dst as isize),
             len);
     }
 }
@@ -1361,21 +1361,21 @@ impl<T> VecDeque<T> {
                 // `at` lies in the first half.
                 let amount_in_first = first_len - at;
 
-                ptr::copy_nonoverlapping(*other.ptr,
-                                         first_half.as_ptr().offset(at as isize),
+                ptr::copy_nonoverlapping(first_half.as_ptr().offset(at as isize),
+                                         *other.ptr,
                                          amount_in_first);
 
                 // just take all of the second half.
-                ptr::copy_nonoverlapping(other.ptr.offset(amount_in_first as isize),
-                                         second_half.as_ptr(),
+                ptr::copy_nonoverlapping(second_half.as_ptr(),
+                                         other.ptr.offset(amount_in_first as isize),
                                          second_len);
             } else {
                 // `at` lies in the second half, need to factor in the elements we skipped
                 // in the first half.
                 let offset = at - first_len;
                 let amount_in_second = second_len - offset;
-                ptr::copy_nonoverlapping(*other.ptr,
-                                         second_half.as_ptr().offset(offset as isize),
+                ptr::copy_nonoverlapping(second_half.as_ptr().offset(offset as isize),
+                                         *other.ptr,
                                          amount_in_second);
             }
         }
diff --git a/src/libcore/error.rs b/src/libcore/error.rs
index 51f3369a75b..9430aa00668 100644
--- a/src/libcore/error.rs
+++ b/src/libcore/error.rs
@@ -48,33 +48,30 @@
 //! For example,
 //!
 //! ```
-//! # #![feature(os, old_io, old_path)]
+//! #![feature(core)]
 //! use std::error::FromError;
-//! use std::old_io::{File, IoError};
-//! use std::os::{MemoryMap, MapError};
-//! use std::old_path::Path;
+//! use std::{io, str};
+//! use std::fs::File;
 //!
 //! enum MyError {
-//!     Io(IoError),
-//!     Map(MapError)
+//!     Io(io::Error),
+//!     Utf8(str::Utf8Error),
 //! }
 //!
-//! impl FromError<IoError> for MyError {
-//!     fn from_error(err: IoError) -> MyError {
-//!         MyError::Io(err)
-//!     }
+//! impl FromError<io::Error> for MyError {
+//!     fn from_error(err: io::Error) -> MyError { MyError::Io(err) }
 //! }
 //!
-//! impl FromError<MapError> for MyError {
-//!     fn from_error(err: MapError) -> MyError {
-//!         MyError::Map(err)
-//!     }
+//! impl FromError<str::Utf8Error> for MyError {
+//!     fn from_error(err: str::Utf8Error) -> MyError { MyError::Utf8(err) }
 //! }
 //!
 //! #[allow(unused_variables)]
 //! fn open_and_map() -> Result<(), MyError> {
-//!     let f = try!(File::open(&Path::new("foo.txt")));
-//!     let m = try!(MemoryMap::new(0, &[]));
+//!     let b = b"foo.txt";
+//!     let s = try!(str::from_utf8(b));
+//!     let f = try!(File::open(s));
+//!
 //!     // do something interesting here...
 //!     Ok(())
 //! }
diff --git a/src/libcore/fmt/float.rs b/src/libcore/fmt/float.rs
index 6e82b18abc6..6a5943265ca 100644
--- a/src/libcore/fmt/float.rs
+++ b/src/libcore/fmt/float.rs
@@ -316,8 +316,8 @@ pub fn float_to_str_bytes_common<T: Float, U, F>(
 
             impl<'a> fmt::Write for Filler<'a> {
                 fn write_str(&mut self, s: &str) -> fmt::Result {
-                    slice::bytes::copy_memory(&mut self.buf[(*self.end)..],
-                                              s.as_bytes());
+                    slice::bytes::copy_memory(s.as_bytes(),
+                                              &mut self.buf[(*self.end)..]);
                     *self.end += s.len();
                     Ok(())
                 }
diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs
index 1b3c83ecf15..43cf64bf3ad 100644
--- a/src/libcore/intrinsics.rs
+++ b/src/libcore/intrinsics.rs
@@ -293,9 +293,9 @@ extern "rust-intrinsic" {
     ///         let mut t: T = mem::uninitialized();
     ///
     ///         // Perform the swap, `&mut` pointers never alias
-    ///         ptr::copy_nonoverlapping(&mut t, &*x, 1);
-    ///         ptr::copy_nonoverlapping(x, &*y, 1);
-    ///         ptr::copy_nonoverlapping(y, &t, 1);
+    ///         ptr::copy_nonoverlapping(x, &mut t, 1);
+    ///         ptr::copy_nonoverlapping(y, x, 1);
+    ///         ptr::copy_nonoverlapping(&t, y, 1);
     ///
     ///         // y and t now point to the same thing, but we need to completely forget `tmp`
     ///         // because it's no longer relevant.
@@ -304,6 +304,12 @@ extern "rust-intrinsic" {
     /// }
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[cfg(not(stage0))]
+    pub fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize);
+
+    /// dox
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[cfg(stage0)]
     pub fn copy_nonoverlapping<T>(dst: *mut T, src: *const T, count: usize);
 
     /// Copies `count * size_of<T>` bytes from `src` to `dst`. The source
@@ -329,12 +335,18 @@ extern "rust-intrinsic" {
     /// unsafe fn from_buf_raw<T>(ptr: *const T, elts: usize) -> Vec<T> {
     ///     let mut dst = Vec::with_capacity(elts);
     ///     dst.set_len(elts);
-    ///     ptr::copy(dst.as_mut_ptr(), ptr, elts);
+    ///     ptr::copy(ptr, dst.as_mut_ptr(), elts);
     ///     dst
     /// }
     /// ```
     ///
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[cfg(not(stage0))]
+    pub fn copy<T>(src: *const T, dst: *mut T, count: usize);
+
+    /// dox
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[cfg(stage0)]
     pub fn copy<T>(dst: *mut T, src: *const T, count: usize);
 
     /// Invokes memset on the specified pointer, setting `count * size_of::<T>()`
diff --git a/src/libcore/mem.rs b/src/libcore/mem.rs
index 434a5d17a92..98e8668239b 100644
--- a/src/libcore/mem.rs
+++ b/src/libcore/mem.rs
@@ -229,9 +229,9 @@ pub fn swap<T>(x: &mut T, y: &mut T) {
         let mut t: T = uninitialized();
 
         // Perform the swap, `&mut` pointers never alias
-        ptr::copy_nonoverlapping(&mut t, &*x, 1);
-        ptr::copy_nonoverlapping(x, &*y, 1);
-        ptr::copy_nonoverlapping(y, &t, 1);
+        ptr::copy_nonoverlapping(&*x, &mut t, 1);
+        ptr::copy_nonoverlapping(&*y, x, 1);
+        ptr::copy_nonoverlapping(&t, y, 1);
 
         // y and t now point to the same thing, but we need to completely forget `t`
         // because it's no longer relevant.
diff --git a/src/libcore/option.rs b/src/libcore/option.rs
index cd82936b0b3..c5102ede29f 100644
--- a/src/libcore/option.rs
+++ b/src/libcore/option.rs
@@ -333,7 +333,7 @@ impl<T> Option<T> {
         }
     }
 
-    /// Moves the value `v` out of the `Option<T>` if the content of the `Option<T>` is a `Some(v)`.
+    /// Moves the value `v` out of the `Option<T>` if it is `Some(v)`.
     ///
     /// # Panics
     ///
diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs
index 07d018dea92..41a70ef708f 100644
--- a/src/libcore/ptr.rs
+++ b/src/libcore/ptr.rs
@@ -104,11 +104,28 @@ use cmp::Ordering::{self, Less, Equal, Greater};
 // FIXME #19649: intrinsic docs don't render, so these have no docs :(
 
 #[stable(feature = "rust1", since = "1.0.0")]
+#[cfg(not(stage0))]
 pub use intrinsics::copy_nonoverlapping;
 
+/// dox
+#[cfg(stage0)]
 #[stable(feature = "rust1", since = "1.0.0")]
+pub unsafe fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize) {
+    intrinsics::copy_nonoverlapping(dst, src, count)
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+#[cfg(not(stage0))]
 pub use intrinsics::copy;
 
+/// dox
+#[cfg(stage0)]
+#[stable(feature = "rust1", since = "1.0.0")]
+pub unsafe fn copy<T>(src: *const T, dst: *mut T, count: usize) {
+    intrinsics::copy(dst, src, count)
+}
+
+
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use intrinsics::write_bytes;
 
@@ -167,12 +184,11 @@ pub unsafe fn zero_memory<T>(dst: *mut T, count: usize) {
 pub unsafe fn swap<T>(x: *mut T, y: *mut T) {
     // Give ourselves some scratch space to work with
     let mut tmp: T = mem::uninitialized();
-    let t: *mut T = &mut tmp;
 
     // Perform the swap
-    copy_nonoverlapping(t, &*x, 1);
-    copy(x, &*y, 1); // `x` and `y` may overlap
-    copy_nonoverlapping(y, &*t, 1);
+    copy_nonoverlapping(x, &mut tmp, 1);
+    copy(y, x, 1); // `x` and `y` may overlap
+    copy_nonoverlapping(&tmp, y, 1);
 
     // y and t now point to the same thing, but we need to completely forget `tmp`
     // because it's no longer relevant.
@@ -208,7 +224,7 @@ pub unsafe fn replace<T>(dest: *mut T, mut src: T) -> T {
 #[stable(feature = "rust1", since = "1.0.0")]
 pub unsafe fn read<T>(src: *const T) -> T {
     let mut tmp: T = mem::uninitialized();
-    copy_nonoverlapping(&mut tmp, src, 1);
+    copy_nonoverlapping(src, &mut tmp, 1);
     tmp
 }
 
diff --git a/src/libcore/slice.rs b/src/libcore/slice.rs
index 12cfdbf5306..223a0bdae36 100644
--- a/src/libcore/slice.rs
+++ b/src/libcore/slice.rs
@@ -1577,14 +1577,14 @@ pub mod bytes {
     ///
     /// Panics if the length of `dst` is less than the length of `src`.
     #[inline]
-    pub fn copy_memory(dst: &mut [u8], src: &[u8]) {
+    pub fn copy_memory(src: &[u8], dst: &mut [u8]) {
         let len_src = src.len();
         assert!(dst.len() >= len_src);
         // `dst` is unaliasable, so we know statically it doesn't overlap
         // with `src`.
         unsafe {
-            ptr::copy_nonoverlapping(dst.as_mut_ptr(),
-                                     src.as_ptr(),
+            ptr::copy_nonoverlapping(src.as_ptr(),
+                                     dst.as_mut_ptr(),
                                      len_src);
         }
     }
diff --git a/src/libcoretest/ptr.rs b/src/libcoretest/ptr.rs
index bdb56c9f867..8f1017c50a3 100644
--- a/src/libcoretest/ptr.rs
+++ b/src/libcoretest/ptr.rs
@@ -35,18 +35,15 @@ fn test() {
         let v0 = vec![32000u16, 32001u16, 32002u16];
         let mut v1 = vec![0u16, 0u16, 0u16];
 
-        copy(v1.as_mut_ptr().offset(1),
-             v0.as_ptr().offset(1), 1);
+        copy(v0.as_ptr().offset(1), v1.as_mut_ptr().offset(1), 1);
         assert!((v1[0] == 0u16 &&
                  v1[1] == 32001u16 &&
                  v1[2] == 0u16));
-        copy(v1.as_mut_ptr(),
-             v0.as_ptr().offset(2), 1);
+        copy(v0.as_ptr().offset(2), v1.as_mut_ptr(), 1);
         assert!((v1[0] == 32002u16 &&
                  v1[1] == 32001u16 &&
                  v1[2] == 0u16));
-        copy(v1.as_mut_ptr().offset(2),
-             v0.as_ptr(), 1);
+        copy(v0.as_ptr(), v1.as_mut_ptr().offset(2), 1);
         assert!((v1[0] == 32002u16 &&
                  v1[1] == 32001u16 &&
                  v1[2] == 32000u16));
diff --git a/src/librbml/lib.rs b/src/librbml/lib.rs
index 234b8cf5eb5..80341fa1a7a 100644
--- a/src/librbml/lib.rs
+++ b/src/librbml/lib.rs
@@ -449,21 +449,21 @@ pub mod reader {
     pub fn doc_as_u16(d: Doc) -> u16 {
         assert_eq!(d.end, d.start + 2);
         let mut b = [0; 2];
-        bytes::copy_memory(&mut b, &d.data[d.start..d.end]);
+        bytes::copy_memory(&d.data[d.start..d.end], &mut b);
         unsafe { (*(b.as_ptr() as *const u16)).to_be() }
     }
 
     pub fn doc_as_u32(d: Doc) -> u32 {
         assert_eq!(d.end, d.start + 4);
         let mut b = [0; 4];
-        bytes::copy_memory(&mut b, &d.data[d.start..d.end]);
+        bytes::copy_memory(&d.data[d.start..d.end], &mut b);
         unsafe { (*(b.as_ptr() as *const u32)).to_be() }
     }
 
     pub fn doc_as_u64(d: Doc) -> u64 {
         assert_eq!(d.end, d.start + 8);
         let mut b = [0; 8];
-        bytes::copy_memory(&mut b, &d.data[d.start..d.end]);
+        bytes::copy_memory(&d.data[d.start..d.end], &mut b);
         unsafe { (*(b.as_ptr() as *const u64)).to_be() }
     }
 
@@ -938,7 +938,7 @@ pub mod writer {
                 {
                     let last_size_pos = last_size_pos as usize;
                     let data = &self.writer.get_ref()[last_size_pos+4..cur_pos as usize];
-                    bytes::copy_memory(&mut buf, data);
+                    bytes::copy_memory(data, &mut buf);
                 }
 
                 // overwrite the size and data and continue
diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs
index fc0b8543ea6..1cff7c448a9 100644
--- a/src/librustc/metadata/decoder.rs
+++ b/src/librustc/metadata/decoder.rs
@@ -62,7 +62,7 @@ pub type Cmd<'a> = &'a crate_metadata;
 
 fn u32_from_be_bytes(bytes: &[u8]) -> u32 {
     let mut b = [0; 4];
-    bytes::copy_memory(&mut b, &bytes[..4]);
+    bytes::copy_memory(&bytes[..4], &mut b);
     unsafe { (*(b.as_ptr() as *const u32)).to_be() }
 }
 
diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs
index 36c9e582b41..e98b438d370 100644
--- a/src/librustc/middle/expr_use_visitor.rs
+++ b/src/librustc/middle/expr_use_visitor.rs
@@ -885,6 +885,11 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
         }
     }
 
+    // When this returns true, it means that the expression *is* a
+    // method-call (i.e. via the operator-overload).  This true result
+    // also implies that walk_overloaded_operator already took care of
+    // recursively processing the input arguments, and thus the caller
+    // should not do so.
     fn walk_overloaded_operator(&mut self,
                                 expr: &ast::Expr,
                                 receiver: &ast::Expr,
diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs
index 2d9bb2af1b2..3738e38f687 100644
--- a/src/librustc/middle/mem_categorization.rs
+++ b/src/librustc/middle/mem_categorization.rs
@@ -71,6 +71,8 @@ pub use self::Note::*;
 pub use self::deref_kind::*;
 pub use self::categorization::*;
 
+use self::Aliasability::*;
+
 use middle::check_const;
 use middle::def;
 use middle::region;
@@ -295,23 +297,29 @@ pub trait Typer<'tcx> : ty::ClosureTyper<'tcx> {
 
 impl MutabilityCategory {
     pub fn from_mutbl(m: ast::Mutability) -> MutabilityCategory {
-        match m {
+        let ret = match m {
             MutImmutable => McImmutable,
             MutMutable => McDeclared
-        }
+        };
+        debug!("MutabilityCategory::{}({:?}) => {:?}",
+               "from_mutbl", m, ret);
+        ret
     }
 
     pub fn from_borrow_kind(borrow_kind: ty::BorrowKind) -> MutabilityCategory {
-        match borrow_kind {
+        let ret = match borrow_kind {
             ty::ImmBorrow => McImmutable,
             ty::UniqueImmBorrow => McImmutable,
             ty::MutBorrow => McDeclared,
-        }
+        };
+        debug!("MutabilityCategory::{}({:?}) => {:?}",
+               "from_borrow_kind", borrow_kind, ret);
+        ret
     }
 
-    pub fn from_pointer_kind(base_mutbl: MutabilityCategory,
-                             ptr: PointerKind) -> MutabilityCategory {
-        match ptr {
+    fn from_pointer_kind(base_mutbl: MutabilityCategory,
+                         ptr: PointerKind) -> MutabilityCategory {
+        let ret = match ptr {
             Unique => {
                 base_mutbl.inherit()
             }
@@ -321,11 +329,14 @@ impl MutabilityCategory {
             UnsafePtr(m) => {
                 MutabilityCategory::from_mutbl(m)
             }
-        }
+        };
+        debug!("MutabilityCategory::{}({:?}, {:?}) => {:?}",
+               "from_pointer_kind", base_mutbl, ptr, ret);
+        ret
     }
 
     fn from_local(tcx: &ty::ctxt, id: ast::NodeId) -> MutabilityCategory {
-        match tcx.map.get(id) {
+        let ret = match tcx.map.get(id) {
             ast_map::NodeLocal(p) | ast_map::NodeArg(p) => match p.node {
                 ast::PatIdent(bind_mode, _, _) => {
                     if bind_mode == ast::BindByValue(ast::MutMutable) {
@@ -337,30 +348,39 @@ impl MutabilityCategory {
                 _ => tcx.sess.span_bug(p.span, "expected identifier pattern")
             },
             _ => tcx.sess.span_bug(tcx.map.span(id), "expected identifier pattern")
-        }
+        };
+        debug!("MutabilityCategory::{}(tcx, id={:?}) => {:?}",
+               "from_local", id, ret);
+        ret
     }
 
     pub fn inherit(&self) -> MutabilityCategory {
-        match *self {
+        let ret = match *self {
             McImmutable => McImmutable,
             McDeclared => McInherited,
             McInherited => McInherited,
-        }
+        };
+        debug!("{:?}.inherit() => {:?}", self, ret);
+        ret
     }
 
     pub fn is_mutable(&self) -> bool {
-        match *self {
+        let ret = match *self {
             McImmutable => false,
             McInherited => true,
             McDeclared => true,
-        }
+        };
+        debug!("{:?}.is_mutable() => {:?}", self, ret);
+        ret
     }
 
     pub fn is_immutable(&self) -> bool {
-        match *self {
+        let ret = match *self {
             McImmutable => true,
             McDeclared | McInherited => false
-        }
+        };
+        debug!("{:?}.is_immutable() => {:?}", self, ret);
+        ret
     }
 
     pub fn to_user_str(&self) -> &'static str {
@@ -733,7 +753,9 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
             }
         };
 
-        Ok(Rc::new(cmt_result))
+        let ret = Rc::new(cmt_result);
+        debug!("cat_upvar ret={}", ret.repr(self.tcx()));
+        Ok(ret)
     }
 
     fn env_deref(&self,
@@ -794,14 +816,18 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
             McDeclared | McInherited => { }
         }
 
-        cmt_ {
+        let ret = cmt_ {
             id: id,
             span: span,
             cat: cat_deref(Rc::new(cmt_result), 0, env_ptr),
             mutbl: deref_mutbl,
             ty: var_ty,
             note: NoteClosureEnv(upvar_id)
-        }
+        };
+
+        debug!("env_deref ret {}", ret.repr(self.tcx()));
+
+        ret
     }
 
     pub fn cat_rvalue_node(&self,
@@ -831,7 +857,9 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
                 }
             }
         };
-        self.cat_rvalue(id, span, re, expr_ty)
+        let ret = self.cat_rvalue(id, span, re, expr_ty);
+        debug!("cat_rvalue_node ret {}", ret.repr(self.tcx()));
+        ret
     }
 
     pub fn cat_rvalue(&self,
@@ -839,14 +867,16 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
                       span: Span,
                       temp_scope: ty::Region,
                       expr_ty: Ty<'tcx>) -> cmt<'tcx> {
-        Rc::new(cmt_ {
+        let ret = Rc::new(cmt_ {
             id:cmt_id,
             span:span,
             cat:cat_rvalue(temp_scope),
             mutbl:McDeclared,
             ty:expr_ty,
             note: NoteNone
-        })
+        });
+        debug!("cat_rvalue ret {}", ret.repr(self.tcx()));
+        ret
     }
 
     pub fn cat_field<N:ast_node>(&self,
@@ -855,14 +885,16 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
                                  f_name: ast::Name,
                                  f_ty: Ty<'tcx>)
                                  -> cmt<'tcx> {
-        Rc::new(cmt_ {
+        let ret = Rc::new(cmt_ {
             id: node.id(),
             span: node.span(),
             mutbl: base_cmt.mutbl.inherit(),
             cat: cat_interior(base_cmt, InteriorField(NamedField(f_name))),
             ty: f_ty,
             note: NoteNone
-        })
+        });
+        debug!("cat_field ret {}", ret.repr(self.tcx()));
+        ret
     }
 
     pub fn cat_tup_field<N:ast_node>(&self,
@@ -871,14 +903,16 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
                                      f_idx: usize,
                                      f_ty: Ty<'tcx>)
                                      -> cmt<'tcx> {
-        Rc::new(cmt_ {
+        let ret = Rc::new(cmt_ {
             id: node.id(),
             span: node.span(),
             mutbl: base_cmt.mutbl.inherit(),
             cat: cat_interior(base_cmt, InteriorField(PositionalField(f_idx))),
             ty: f_ty,
             note: NoteNone
-        })
+        });
+        debug!("cat_tup_field ret {}", ret.repr(self.tcx()));
+        ret
     }
 
     fn cat_deref<N:ast_node>(&self,
@@ -913,10 +947,14 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
         };
         let base_cmt_ty = base_cmt.ty;
         match ty::deref(base_cmt_ty, true) {
-            Some(mt) => self.cat_deref_common(node, base_cmt, deref_cnt,
+            Some(mt) => {
+                let ret = self.cat_deref_common(node, base_cmt, deref_cnt,
                                               mt.ty,
                                               deref_context,
-                                              /* implicit: */ false),
+                                                /* implicit: */ false);
+                debug!("cat_deref ret {}", ret.repr(self.tcx()));
+                ret
+            }
             None => {
                 debug!("Explicit deref of non-derefable type: {}",
                        base_cmt_ty.repr(self.tcx()));
@@ -954,14 +992,16 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
                 (base_cmt.mutbl.inherit(), cat_interior(base_cmt, interior))
             }
         };
-        Ok(Rc::new(cmt_ {
+        let ret = Rc::new(cmt_ {
             id: node.id(),
             span: node.span(),
             cat: cat,
             mutbl: m,
             ty: deref_ty,
             note: NoteNone
-        }))
+        });
+        debug!("cat_deref_common ret {}", ret.repr(self.tcx()));
+        Ok(ret)
     }
 
     pub fn cat_index<N:ast_node>(&self,
@@ -1009,8 +1049,10 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
         };
 
         let m = base_cmt.mutbl.inherit();
-        return Ok(interior(elt, base_cmt.clone(), base_cmt.ty,
-                           m, context, element_ty));
+        let ret = interior(elt, base_cmt.clone(), base_cmt.ty,
+                           m, context, element_ty);
+        debug!("cat_index ret {}", ret.repr(self.tcx()));
+        return Ok(ret);
 
         fn interior<'tcx, N: ast_node>(elt: &N,
                                        of_cmt: cmt<'tcx>,
@@ -1039,14 +1081,14 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
                              context: InteriorOffsetKind)
                              -> McResult<cmt<'tcx>>
     {
-        match try!(deref_kind(base_cmt.ty, Some(context))) {
+        let ret = match try!(deref_kind(base_cmt.ty, Some(context))) {
             deref_ptr(ptr) => {
                 // for unique ptrs, we inherit mutability from the
                 // owning reference.
                 let m = MutabilityCategory::from_pointer_kind(base_cmt.mutbl, ptr);
 
                 // the deref is explicit in the resulting cmt
-                Ok(Rc::new(cmt_ {
+                Rc::new(cmt_ {
                     id:elt.id(),
                     span:elt.span(),
                     cat:cat_deref(base_cmt.clone(), 0, ptr),
@@ -1056,13 +1098,15 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
                         None => self.tcx().sess.bug("Found non-derefable type")
                     },
                     note: NoteNone
-                }))
+                })
             }
 
             deref_interior(_) => {
-                Ok(base_cmt)
+                base_cmt
             }
-        }
+        };
+        debug!("deref_vec ret {}", ret.repr(self.tcx()));
+        Ok(ret)
     }
 
     /// Given a pattern P like: `[_, ..Q, _]`, where `vec_cmt` is the cmt for `P`, `slice_pat` is
@@ -1112,14 +1156,16 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
                                         interior_ty: Ty<'tcx>,
                                         interior: InteriorKind)
                                         -> cmt<'tcx> {
-        Rc::new(cmt_ {
+        let ret = Rc::new(cmt_ {
             id: node.id(),
             span: node.span(),
             mutbl: base_cmt.mutbl.inherit(),
             cat: cat_interior(base_cmt, interior),
             ty: interior_ty,
             note: NoteNone
-        })
+        });
+        debug!("cat_imm_interior ret={}", ret.repr(self.tcx()));
+        ret
     }
 
     pub fn cat_downcast<N:ast_node>(&self,
@@ -1128,14 +1174,16 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
                                     downcast_ty: Ty<'tcx>,
                                     variant_did: ast::DefId)
                                     -> cmt<'tcx> {
-        Rc::new(cmt_ {
+        let ret = Rc::new(cmt_ {
             id: node.id(),
             span: node.span(),
             mutbl: base_cmt.mutbl.inherit(),
             cat: cat_downcast(base_cmt, variant_did),
             ty: downcast_ty,
             note: NoteNone
-        })
+        });
+        debug!("cat_downcast ret={}", ret.repr(self.tcx()));
+        ret
     }
 
     pub fn cat_pattern<F>(&self, cmt: cmt<'tcx>, pat: &ast::Pat, mut op: F) -> McResult<()>
@@ -1341,17 +1389,25 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
     }
 }
 
-#[derive(Copy)]
+#[derive(Copy, Clone, Debug)]
 pub enum InteriorSafety {
     InteriorUnsafe,
     InteriorSafe
 }
 
-#[derive(Copy)]
+#[derive(Clone, Debug)]
+pub enum Aliasability {
+    FreelyAliasable(AliasableReason),
+    NonAliasable,
+    ImmutableUnique(Box<Aliasability>),
+}
+
+#[derive(Copy, Clone, Debug)]
 pub enum AliasableReason {
     AliasableBorrowed,
     AliasableClosure(ast::NodeId), // Aliasable due to capture Fn closure env
     AliasableOther,
+    UnaliasableImmutable, // Created as needed upon seeing ImmutableUnique
     AliasableStatic(InteriorSafety),
     AliasableStaticMut(InteriorSafety),
 }
@@ -1380,9 +1436,9 @@ impl<'tcx> cmt_<'tcx> {
         }
     }
 
-    /// Returns `Some(_)` if this lvalue represents a freely aliasable pointer type.
+    /// Returns `FreelyAliasable(_)` if this lvalue represents a freely aliasable pointer type.
     pub fn freely_aliasable(&self, ctxt: &ty::ctxt<'tcx>)
-                            -> Option<AliasableReason> {
+                            -> Aliasability {
         // Maybe non-obvious: copied upvars can only be considered
         // non-aliasable in once closures, since any other kind can be
         // aliased and eventually recused.
@@ -1393,17 +1449,27 @@ impl<'tcx> cmt_<'tcx> {
             cat_deref(ref b, _, BorrowedPtr(ty::UniqueImmBorrow, _)) |
             cat_deref(ref b, _, Implicit(ty::UniqueImmBorrow, _)) |
             cat_downcast(ref b, _) |
-            cat_deref(ref b, _, Unique) |
             cat_interior(ref b, _) => {
                 // Aliasability depends on base cmt
                 b.freely_aliasable(ctxt)
             }
 
+            cat_deref(ref b, _, Unique) => {
+                let sub = b.freely_aliasable(ctxt);
+                if b.mutbl.is_mutable() {
+                    // Aliasability depends on base cmt alone
+                    sub
+                } else {
+                    // Do not allow mutation through an immutable box.
+                    ImmutableUnique(Box::new(sub))
+                }
+            }
+
             cat_rvalue(..) |
             cat_local(..) |
             cat_upvar(..) |
             cat_deref(_, _, UnsafePtr(..)) => { // yes, it's aliasable, but...
-                None
+                NonAliasable
             }
 
             cat_static_item(..) => {
@@ -1414,17 +1480,18 @@ impl<'tcx> cmt_<'tcx> {
                 };
 
                 if self.mutbl.is_mutable() {
-                    Some(AliasableStaticMut(int_safe))
+                    FreelyAliasable(AliasableStaticMut(int_safe))
                 } else {
-                    Some(AliasableStatic(int_safe))
+                    FreelyAliasable(AliasableStatic(int_safe))
                 }
             }
 
             cat_deref(ref base, _, BorrowedPtr(ty::ImmBorrow, _)) |
             cat_deref(ref base, _, Implicit(ty::ImmBorrow, _)) => {
                 match base.cat {
-                    cat_upvar(Upvar{ id, .. }) => Some(AliasableClosure(id.closure_expr_id)),
-                    _ => Some(AliasableBorrowed)
+                    cat_upvar(Upvar{ id, .. }) =>
+                        FreelyAliasable(AliasableClosure(id.closure_expr_id)),
+                    _ => FreelyAliasable(AliasableBorrowed)
                 }
             }
         }
diff --git a/src/librustc_back/sha2.rs b/src/librustc_back/sha2.rs
index c7049f750fc..f0e1427e6db 100644
--- a/src/librustc_back/sha2.rs
+++ b/src/librustc_back/sha2.rs
@@ -139,15 +139,15 @@ impl FixedBuffer for FixedBuffer64 {
             let buffer_remaining = size - self.buffer_idx;
             if input.len() >= buffer_remaining {
                     copy_memory(
-                        &mut self.buffer[self.buffer_idx..size],
-                        &input[..buffer_remaining]);
+                        &input[..buffer_remaining],
+                        &mut self.buffer[self.buffer_idx..size]);
                 self.buffer_idx = 0;
                 func(&self.buffer);
                 i += buffer_remaining;
             } else {
                 copy_memory(
-                    &mut self.buffer[self.buffer_idx..self.buffer_idx + input.len()],
-                    input);
+                    input,
+                    &mut self.buffer[self.buffer_idx..self.buffer_idx + input.len()]);
                 self.buffer_idx += input.len();
                 return;
             }
@@ -165,8 +165,8 @@ impl FixedBuffer for FixedBuffer64 {
         // be empty.
         let input_remaining = input.len() - i;
         copy_memory(
-            &mut self.buffer[..input_remaining],
-            &input[i..]);
+            &input[i..],
+            &mut self.buffer[..input_remaining]);
         self.buffer_idx += input_remaining;
     }
 
diff --git a/src/librustc_borrowck/borrowck/check_loans.rs b/src/librustc_borrowck/borrowck/check_loans.rs
index f268a957fe8..ce7b492c51a 100644
--- a/src/librustc_borrowck/borrowck/check_loans.rs
+++ b/src/librustc_borrowck/borrowck/check_loans.rs
@@ -943,13 +943,20 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
                                                       cmt: mc::cmt<'tcx>)
                                                       -> bool {
             match cmt.freely_aliasable(this.tcx()) {
-                None => {
+                mc::Aliasability::NonAliasable => {
                     return true;
                 }
-                Some(mc::AliasableStaticMut(..)) => {
+                mc::Aliasability::FreelyAliasable(mc::AliasableStaticMut(..)) => {
                     return true;
                 }
-                Some(cause) => {
+                mc::Aliasability::ImmutableUnique(_) => {
+                    this.bccx.report_aliasability_violation(
+                        span,
+                        MutabilityViolation,
+                        mc::AliasableReason::UnaliasableImmutable);
+                    return false;
+                }
+                mc::Aliasability::FreelyAliasable(cause) => {
                     this.bccx.report_aliasability_violation(
                         span,
                         MutabilityViolation,
diff --git a/src/librustc_borrowck/borrowck/gather_loans/mod.rs b/src/librustc_borrowck/borrowck/gather_loans/mod.rs
index bbdec402bdc..733d486d2d2 100644
--- a/src/librustc_borrowck/borrowck/gather_loans/mod.rs
+++ b/src/librustc_borrowck/borrowck/gather_loans/mod.rs
@@ -151,10 +151,11 @@ impl<'a, 'tcx> euv::Delegate<'tcx> for GatherLoanCtxt<'a, 'tcx> {
               assignee_cmt: mc::cmt<'tcx>,
               mode: euv::MutateMode)
     {
-        debug!("mutate(assignment_id={}, assignee_cmt={})",
-               assignment_id, assignee_cmt.repr(self.tcx()));
+        let opt_lp = opt_loan_path(&assignee_cmt);
+        debug!("mutate(assignment_id={}, assignee_cmt={}) opt_lp={:?}",
+               assignment_id, assignee_cmt.repr(self.tcx()), opt_lp);
 
-        match opt_loan_path(&assignee_cmt) {
+        match opt_lp {
             Some(lp) => {
                 gather_moves::gather_assignment(self.bccx, &self.move_data,
                                                 assignment_id, assignment_span,
@@ -181,12 +182,16 @@ fn check_aliasability<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
                                 req_kind: ty::BorrowKind)
                                 -> Result<(),()> {
 
-    match (cmt.freely_aliasable(bccx.tcx), req_kind) {
-        (None, _) => {
+    let aliasability = cmt.freely_aliasable(bccx.tcx);
+    debug!("check_aliasability aliasability={:?} req_kind={:?}",
+           aliasability, req_kind);
+
+    match (aliasability, req_kind) {
+        (mc::Aliasability::NonAliasable, _) => {
             /* Uniquely accessible path -- OK for `&` and `&mut` */
             Ok(())
         }
-        (Some(mc::AliasableStatic(safety)), ty::ImmBorrow) => {
+        (mc::Aliasability::FreelyAliasable(mc::AliasableStatic(safety)), ty::ImmBorrow) => {
             // Borrow of an immutable static item:
             match safety {
                 mc::InteriorUnsafe => {
@@ -202,13 +207,20 @@ fn check_aliasability<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
                 }
             }
         }
-        (Some(mc::AliasableStaticMut(..)), _) => {
+        (mc::Aliasability::FreelyAliasable(mc::AliasableStaticMut(..)), _) => {
             // Even touching a static mut is considered unsafe. We assume the
             // user knows what they're doing in these cases.
             Ok(())
         }
-        (Some(alias_cause), ty::UniqueImmBorrow) |
-        (Some(alias_cause), ty::MutBorrow) => {
+        (mc::Aliasability::ImmutableUnique(_), ty::MutBorrow) => {
+            bccx.report_aliasability_violation(
+                        borrow_span,
+                        BorrowViolation(loan_cause),
+                        mc::AliasableReason::UnaliasableImmutable);
+            Err(())
+        }
+        (mc::Aliasability::FreelyAliasable(alias_cause), ty::UniqueImmBorrow) |
+        (mc::Aliasability::FreelyAliasable(alias_cause), ty::MutBorrow) => {
             bccx.report_aliasability_violation(
                         borrow_span,
                         BorrowViolation(loan_cause),
@@ -376,7 +388,8 @@ impl<'a, 'tcx> GatherLoanCtxt<'a, 'tcx> {
                                       req_kind: ty::BorrowKind)
                                       -> Result<(),()> {
             //! Implements the M-* rules in README.md.
-
+            debug!("check_mutability(cause={:?} cmt={} req_kind={:?}",
+                   cause, cmt.repr(bccx.tcx), req_kind);
             match req_kind {
                 ty::UniqueImmBorrow | ty::ImmBorrow => {
                     match cmt.mutbl {
diff --git a/src/librustc_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs
index b5ceff6124d..268e469b7f9 100644
--- a/src/librustc_borrowck/borrowck/mod.rs
+++ b/src/librustc_borrowck/borrowck/mod.rs
@@ -844,6 +844,12 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
                     &format!("{} in an aliasable location",
                              prefix));
             }
+            mc::AliasableReason::UnaliasableImmutable => {
+                self.tcx.sess.span_err(
+                    span,
+                    &format!("{} in an immutable container",
+                             prefix));
+            }
             mc::AliasableClosure(id) => {
                 self.tcx.sess.span_err(span,
                                        &format!("{} in a captured outer \
diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs
index f9ad6690f6b..586a1eb085c 100644
--- a/src/librustc_lint/builtin.rs
+++ b/src/librustc_lint/builtin.rs
@@ -39,7 +39,7 @@ use util::ppaux::ty_to_string;
 use util::nodemap::{FnvHashMap, NodeSet};
 use lint::{Level, Context, LintPass, LintArray, Lint};
 
-use std::collections::BitSet;
+use std::collections::{HashSet, BitSet};
 use std::collections::hash_map::Entry::{Occupied, Vacant};
 use std::num::SignedInt;
 use std::{cmp, slice};
@@ -1437,6 +1437,9 @@ pub struct MissingDoc {
     /// Stack of whether #[doc(hidden)] is set
     /// at each level which has lint attributes.
     doc_hidden_stack: Vec<bool>,
+
+    /// Private traits or trait items that leaked through. Don't check their methods.
+    private_traits: HashSet<ast::NodeId>,
 }
 
 impl MissingDoc {
@@ -1445,6 +1448,7 @@ impl MissingDoc {
             struct_def_stack: vec!(),
             in_variant: false,
             doc_hidden_stack: vec!(false),
+            private_traits: HashSet::new(),
         }
     }
 
@@ -1531,18 +1535,46 @@ impl LintPass for MissingDoc {
             ast::ItemMod(..) => "a module",
             ast::ItemEnum(..) => "an enum",
             ast::ItemStruct(..) => "a struct",
-            ast::ItemTrait(..) => "a trait",
+            ast::ItemTrait(_, _, _, ref items) => {
+                // Issue #11592, traits are always considered exported, even when private.
+                if it.vis == ast::Visibility::Inherited {
+                    self.private_traits.insert(it.id);
+                    for itm in items {
+                        self.private_traits.insert(itm.id);
+                    }
+                    return
+                }
+                "a trait"
+            },
             ast::ItemTy(..) => "a type alias",
+            ast::ItemImpl(_, _, _, Some(ref trait_ref), _, ref impl_items) => {
+                // If the trait is private, add the impl items to private_traits so they don't get
+                // reported for missing docs.
+                let real_trait = ty::trait_ref_to_def_id(cx.tcx, trait_ref);
+                match cx.tcx.map.find(real_trait.node) {
+                    Some(ast_map::NodeItem(item)) => if item.vis == ast::Visibility::Inherited {
+                        for itm in impl_items {
+                            self.private_traits.insert(itm.id);
+                        }
+                    },
+                    _ => { }
+                }
+                return
+            },
             _ => return
         };
+
         self.check_missing_docs_attrs(cx, Some(it.id), &it.attrs, it.span, desc);
     }
 
     fn check_trait_item(&mut self, cx: &Context, trait_item: &ast::TraitItem) {
+        if self.private_traits.contains(&trait_item.id) { return }
+
         let desc = match trait_item.node {
             ast::MethodTraitItem(..) => "a trait method",
             ast::TypeTraitItem(..) => "an associated type"
         };
+
         self.check_missing_docs_attrs(cx, Some(trait_item.id),
                                       &trait_item.attrs,
                                       trait_item.span, desc);
diff --git a/src/librustc_trans/trans/intrinsic.rs b/src/librustc_trans/trans/intrinsic.rs
index cfd5b6c13d8..62a6ede4c2f 100644
--- a/src/librustc_trans/trans/intrinsic.rs
+++ b/src/librustc_trans/trans/intrinsic.rs
@@ -398,8 +398,8 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
                            false,
                            false,
                            *substs.types.get(FnSpace, 0),
-                           llargs[0],
                            llargs[1],
+                           llargs[0],
                            llargs[2],
                            call_debug_location)
         }
@@ -408,8 +408,8 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
                            true,
                            false,
                            *substs.types.get(FnSpace, 0),
-                           llargs[0],
                            llargs[1],
+                           llargs[0],
                            llargs[2],
                            call_debug_location)
         }
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 1f992b9c3ae..8a61142c173 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -5080,7 +5080,21 @@ pub fn check_intrinsic_type(ccx: &CrateCtxt, it: &ast::ForeignItem) {
                    mutbl: ast::MutImmutable
                }))
             }
-            "copy" | "copy_nonoverlapping" |
+            "copy" | "copy_nonoverlapping" => {
+              (1,
+               vec!(
+                  ty::mk_ptr(tcx, ty::mt {
+                      ty: param(ccx, 0),
+                      mutbl: ast::MutImmutable
+                  }),
+                  ty::mk_ptr(tcx, ty::mt {
+                      ty: param(ccx, 0),
+                      mutbl: ast::MutMutable
+                  }),
+                  tcx.types.usize,
+               ),
+               ty::mk_nil(tcx))
+            }
             "volatile_copy_memory" | "volatile_copy_nonoverlapping_memory" => {
               (1,
                vec!(
diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs
index 702a32be586..babbe15b17d 100644
--- a/src/librustdoc/test.rs
+++ b/src/librustdoc/test.rs
@@ -243,8 +243,9 @@ fn runtest(test: &str, cratename: &str, libs: SearchPaths,
             if should_panic && out.status.success() {
                 panic!("test executable succeeded when it should have failed");
             } else if !should_panic && !out.status.success() {
-                panic!("test executable failed:\n{:?}",
-                      str::from_utf8(&out.stdout));
+                panic!("test executable failed:\n{}\n{}",
+                       str::from_utf8(&out.stdout).unwrap_or(""),
+                       str::from_utf8(&out.stderr).unwrap_or(""));
             }
         }
     }
diff --git a/src/libstd/collections/hash/table.rs b/src/libstd/collections/hash/table.rs
index 8f659334538..aa3195cbf01 100644
--- a/src/libstd/collections/hash/table.rs
+++ b/src/libstd/collections/hash/table.rs
@@ -480,8 +480,8 @@ impl<K, V, M: Deref<Target=RawTable<K, V>>> GapThenFull<K, V, M> {
     pub fn shift(mut self) -> Option<GapThenFull<K, V, M>> {
         unsafe {
             *self.gap.raw.hash = mem::replace(&mut *self.full.raw.hash, EMPTY_BUCKET);
-            ptr::copy_nonoverlapping(self.gap.raw.key, self.full.raw.key, 1);
-            ptr::copy_nonoverlapping(self.gap.raw.val, self.full.raw.val, 1);
+            ptr::copy_nonoverlapping(self.full.raw.key, self.gap.raw.key, 1);
+            ptr::copy_nonoverlapping(self.full.raw.val, self.gap.raw.val, 1);
         }
 
         let FullBucket { raw: prev_raw, idx: prev_idx, .. } = self.full;
diff --git a/src/libstd/io/buffered.rs b/src/libstd/io/buffered.rs
index 98581fc43f8..8eea06bf6b0 100644
--- a/src/libstd/io/buffered.rs
+++ b/src/libstd/io/buffered.rs
@@ -177,8 +177,8 @@ impl<W: Write> BufWriter<W> {
         if written > 0 {
             // NB: would be better expressed as .remove(0..n) if it existed
             unsafe {
-                ptr::copy(self.buf.as_mut_ptr(),
-                          self.buf.as_ptr().offset(written as isize),
+                ptr::copy(self.buf.as_ptr().offset(written as isize),
+                          self.buf.as_mut_ptr(),
                           len - written);
             }
         }
diff --git a/src/libstd/io/cursor.rs b/src/libstd/io/cursor.rs
index 79f0af670b4..c8a41beecbc 100644
--- a/src/libstd/io/cursor.rs
+++ b/src/libstd/io/cursor.rs
@@ -151,7 +151,7 @@ impl Write for Cursor<Vec<u8>> {
         // there (left), and what will be appended on the end (right)
         let space = self.inner.len() - pos as usize;
         let (left, right) = buf.split_at(cmp::min(space, buf.len()));
-        slice::bytes::copy_memory(&mut self.inner[(pos as usize)..], left);
+        slice::bytes::copy_memory(left, &mut self.inner[(pos as usize)..]);
         self.inner.push_all(right);
 
         // Bump us forward
diff --git a/src/libstd/io/impls.rs b/src/libstd/io/impls.rs
index ce03e26866b..52daba36213 100644
--- a/src/libstd/io/impls.rs
+++ b/src/libstd/io/impls.rs
@@ -149,7 +149,7 @@ impl<'a> Read for &'a [u8] {
     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
         let amt = cmp::min(buf.len(), self.len());
         let (a, b) = self.split_at(amt);
-        slice::bytes::copy_memory(buf, a);
+        slice::bytes::copy_memory(a, buf);
         *self = b;
         Ok(amt)
     }
@@ -170,7 +170,7 @@ impl<'a> Write for &'a mut [u8] {
     fn write(&mut self, data: &[u8]) -> io::Result<usize> {
         let amt = cmp::min(data.len(), self.len());
         let (a, b) = mem::replace(self, &mut []).split_at_mut(amt);
-        slice::bytes::copy_memory(a, &data[..amt]);
+        slice::bytes::copy_memory(&data[..amt], a);
         *self = b;
         Ok(amt)
     }
diff --git a/src/libstd/macros.rs b/src/libstd/macros.rs
index 52492a019a2..645bc5db753 100644
--- a/src/libstd/macros.rs
+++ b/src/libstd/macros.rs
@@ -64,6 +64,10 @@ macro_rules! panic {
 ///
 /// Equivalent to the `println!` macro except that a newline is not printed at
 /// the end of the message.
+///
+/// Note that stdout is frequently line-buffered by default so it may be
+/// necessary to use `io::stdout().flush()` to ensure the output is emitted
+/// immediately.
 #[macro_export]
 #[stable(feature = "rust1", since = "1.0.0")]
 #[allow_internal_unstable]
diff --git a/src/libstd/old_io/buffered.rs b/src/libstd/old_io/buffered.rs
index b8b7df75003..ad6cac62173 100644
--- a/src/libstd/old_io/buffered.rs
+++ b/src/libstd/old_io/buffered.rs
@@ -118,7 +118,7 @@ impl<R: Reader> Reader for BufferedReader<R> {
         let nread = {
             let available = try!(self.fill_buf());
             let nread = cmp::min(available.len(), buf.len());
-            slice::bytes::copy_memory(buf, &available[..nread]);
+            slice::bytes::copy_memory(&available[..nread], buf);
             nread
         };
         self.pos += nread;
@@ -225,7 +225,7 @@ impl<W: Writer> Writer for BufferedWriter<W> {
             self.inner.as_mut().unwrap().write_all(buf)
         } else {
             let dst = &mut self.buf[self.pos..];
-            slice::bytes::copy_memory(dst, buf);
+            slice::bytes::copy_memory(buf, dst);
             self.pos += buf.len();
             Ok(())
         }
diff --git a/src/libstd/old_io/comm_adapters.rs b/src/libstd/old_io/comm_adapters.rs
index 35bc58fecd2..5ebf931e95c 100644
--- a/src/libstd/old_io/comm_adapters.rs
+++ b/src/libstd/old_io/comm_adapters.rs
@@ -91,7 +91,7 @@ impl Reader for ChanReader {
                 Some(src) => {
                     let dst = &mut buf[num_read..];
                     let count = cmp::min(src.len(), dst.len());
-                    bytes::copy_memory(dst, &src[..count]);
+                    bytes::copy_memory(&src[..count], dst);
                     count
                 },
                 None => 0,
diff --git a/src/libstd/old_io/extensions.rs b/src/libstd/old_io/extensions.rs
index 441f0a7536e..0e5dd3aa4aa 100644
--- a/src/libstd/old_io/extensions.rs
+++ b/src/libstd/old_io/extensions.rs
@@ -171,7 +171,7 @@ pub fn u64_from_be_bytes(data: &[u8], start: usize, size: usize) -> u64 {
     unsafe {
         let ptr = data.as_ptr().offset(start as isize);
         let out = buf.as_mut_ptr();
-        copy_nonoverlapping(out.offset((8 - size) as isize), ptr, size);
+        copy_nonoverlapping(ptr, out.offset((8 - size) as isize), size);
         (*(out as *const u64)).to_be()
     }
 }
diff --git a/src/libstd/old_io/mem.rs b/src/libstd/old_io/mem.rs
index 5f20c383bb7..64803191d4f 100644
--- a/src/libstd/old_io/mem.rs
+++ b/src/libstd/old_io/mem.rs
@@ -168,7 +168,7 @@ impl Reader for MemReader {
             let input = &self.buf[self.pos.. self.pos + write_len];
             let output = &mut buf[..write_len];
             assert_eq!(input.len(), output.len());
-            slice::bytes::copy_memory(output, input);
+            slice::bytes::copy_memory(input, output);
         }
         self.pos += write_len;
         assert!(self.pos <= self.buf.len());
@@ -212,7 +212,7 @@ impl<'a> Reader for &'a [u8] {
         {
             let input = &self[..write_len];
             let output = &mut buf[.. write_len];
-            slice::bytes::copy_memory(output, input);
+            slice::bytes::copy_memory(input, output);
         }
 
         *self = &self[write_len..];
@@ -287,13 +287,13 @@ impl<'a> Writer for BufWriter<'a> {
         let src_len = src.len();
 
         if dst_len >= src_len {
-            slice::bytes::copy_memory(dst, src);
+            slice::bytes::copy_memory(src, dst);
 
             self.pos += src_len;
 
             Ok(())
         } else {
-            slice::bytes::copy_memory(dst, &src[..dst_len]);
+            slice::bytes::copy_memory(&src[..dst_len], dst);
 
             self.pos += dst_len;
 
@@ -360,7 +360,7 @@ impl<'a> Reader for BufReader<'a> {
             let input = &self.buf[self.pos.. self.pos + write_len];
             let output = &mut buf[..write_len];
             assert_eq!(input.len(), output.len());
-            slice::bytes::copy_memory(output, input);
+            slice::bytes::copy_memory(input, output);
         }
         self.pos += write_len;
         assert!(self.pos <= self.buf.len());
diff --git a/src/libstd/sys/common/wtf8.rs b/src/libstd/sys/common/wtf8.rs
index 315df411179..8f788988e55 100644
--- a/src/libstd/sys/common/wtf8.rs
+++ b/src/libstd/sys/common/wtf8.rs
@@ -344,8 +344,8 @@ impl Wtf8Buf {
                 Some((surrogate_pos, _)) => {
                     pos = surrogate_pos + 3;
                     slice::bytes::copy_memory(
+                        UTF8_REPLACEMENT_CHARACTER,
                         &mut self.bytes[surrogate_pos .. pos],
-                        UTF8_REPLACEMENT_CHARACTER
                     );
                 },
                 None => return unsafe { String::from_utf8_unchecked(self.bytes) }
diff --git a/src/test/bench/shootout-fasta-redux.rs b/src/test/bench/shootout-fasta-redux.rs
index 709b23ef9dd..7c4cc0eaab7 100644
--- a/src/test/bench/shootout-fasta-redux.rs
+++ b/src/test/bench/shootout-fasta-redux.rs
@@ -126,10 +126,9 @@ impl<'a, W: Writer> RepeatFasta<'a, W> {
         let mut buf = repeat(0).take(alu_len + LINE_LEN).collect::<Vec<_>>();
         let alu: &[u8] = self.alu.as_bytes();
 
-        copy_memory(&mut buf, alu);
+        copy_memory(alu, &mut buf);
         let buf_len = buf.len();
-        copy_memory(&mut buf[alu_len..buf_len],
-                    &alu[..LINE_LEN]);
+        copy_memory(&alu[..LINE_LEN], &mut buf[alu_len..buf_len]);
 
         let mut pos = 0;
         let mut bytes;
diff --git a/src/test/bench/shootout-reverse-complement.rs b/src/test/bench/shootout-reverse-complement.rs
index 82ea234f6dd..cda90c08f23 100644
--- a/src/test/bench/shootout-reverse-complement.rs
+++ b/src/test/bench/shootout-reverse-complement.rs
@@ -181,8 +181,8 @@ fn reverse_complement(seq: &mut [u8], tables: &Tables) {
     let mut i = LINE_LEN;
     while i < len {
         unsafe {
-            copy(seq.as_mut_ptr().offset((i - off + 1) as isize),
-                 seq.as_ptr().offset((i - off) as isize), off);
+            copy(seq.as_ptr().offset((i - off) as isize),
+                 seq.as_mut_ptr().offset((i - off + 1) as isize), off);
             *seq.get_unchecked_mut(i - off) = b'\n';
         }
         i += LINE_LEN + 1;
diff --git a/src/test/compile-fail/borrowck-issue-14498.rs b/src/test/compile-fail/borrowck-issue-14498.rs
index 8278b4fb971..64033623fe2 100644
--- a/src/test/compile-fail/borrowck-issue-14498.rs
+++ b/src/test/compile-fail/borrowck-issue-14498.rs
@@ -9,56 +9,116 @@
 // except according to those terms.
 
 // This tests that we can't modify Box<&mut T> contents while they
-// are borrowed.
+// are borrowed (#14498).
+//
+// Also includes tests of the errors reported when the Box in question
+// is immutable (#14270).
 
 #![feature(box_syntax)]
 
 struct A { a: isize }
 struct B<'a> { a: Box<&'a mut isize> }
 
+fn indirect_write_to_imm_box() {
+    let mut x: isize = 1;
+    let y: Box<_> = box &mut x;
+    let p = &y;
+    ***p = 2; //~ ERROR cannot assign to data in an immutable container
+    drop(p);
+}
+
 fn borrow_in_var_from_var() {
     let mut x: isize = 1;
+    let mut y: Box<_> = box &mut x;
+    let p = &y;
+    let q = &***p;
+    **y = 2; //~ ERROR cannot assign to `**y` because it is borrowed
+    drop(p);
+    drop(q);
+}
+
+fn borrow_in_var_from_var_via_imm_box() {
+    let mut x: isize = 1;
     let y: Box<_> = box &mut x;
     let p = &y;
     let q = &***p;
     **y = 2; //~ ERROR cannot assign to `**y` because it is borrowed
+    //~^         ERROR cannot assign to data in an immutable container
     drop(p);
     drop(q);
 }
 
 fn borrow_in_var_from_field() {
     let mut x = A { a: 1 };
+    let mut y: Box<_> = box &mut x.a;
+    let p = &y;
+    let q = &***p;
+    **y = 2; //~ ERROR cannot assign to `**y` because it is borrowed
+    drop(p);
+    drop(q);
+}
+
+fn borrow_in_var_from_field_via_imm_box() {
+    let mut x = A { a: 1 };
     let y: Box<_> = box &mut x.a;
     let p = &y;
     let q = &***p;
     **y = 2; //~ ERROR cannot assign to `**y` because it is borrowed
+    //~^         ERROR cannot assign to data in an immutable container
     drop(p);
     drop(q);
 }
 
 fn borrow_in_field_from_var() {
     let mut x: isize = 1;
+    let mut y = B { a: box &mut x };
+    let p = &y.a;
+    let q = &***p;
+    **y.a = 2; //~ ERROR cannot assign to `**y.a` because it is borrowed
+    drop(p);
+    drop(q);
+}
+
+fn borrow_in_field_from_var_via_imm_box() {
+    let mut x: isize = 1;
     let y = B { a: box &mut x };
     let p = &y.a;
     let q = &***p;
     **y.a = 2; //~ ERROR cannot assign to `**y.a` because it is borrowed
+    //~^           ERROR cannot assign to data in an immutable container
     drop(p);
     drop(q);
 }
 
 fn borrow_in_field_from_field() {
     let mut x = A { a: 1 };
+    let mut y = B { a: box &mut x.a };
+    let p = &y.a;
+    let q = &***p;
+    **y.a = 2; //~ ERROR cannot assign to `**y.a` because it is borrowed
+    drop(p);
+    drop(q);
+}
+
+fn borrow_in_field_from_field_via_imm_box() {
+    let mut x = A { a: 1 };
     let y = B { a: box &mut x.a };
     let p = &y.a;
     let q = &***p;
     **y.a = 2; //~ ERROR cannot assign to `**y.a` because it is borrowed
+    //~^           ERROR cannot assign to data in an immutable container
     drop(p);
     drop(q);
 }
 
 fn main() {
+    indirect_write_to_imm_box();
     borrow_in_var_from_var();
+    borrow_in_var_from_var_via_imm_box();
     borrow_in_var_from_field();
+    borrow_in_var_from_field_via_imm_box();
     borrow_in_field_from_var();
+    borrow_in_field_from_var_via_imm_box();
     borrow_in_field_from_field();
+    borrow_in_field_from_field_via_imm_box();
 }
diff --git a/src/test/run-pass/issue-11592.rs b/src/test/run-pass/issue-11592.rs
new file mode 100644
index 00000000000..432e7ff2025
--- /dev/null
+++ b/src/test/run-pass/issue-11592.rs
@@ -0,0 +1,20 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Ensure the private trait Bar isn't complained about.
+
+#![deny(missing_docs)]
+
+mod foo {
+    trait Bar { fn bar(&self) { } }
+    impl Bar for i8 { fn bar(&self) { } }
+}
+
+fn main() { }
diff --git a/src/test/run-pass/method-mut-self-modifies-mut-slice-lvalue.rs b/src/test/run-pass/method-mut-self-modifies-mut-slice-lvalue.rs
index e013c5b0be7..7cc762c9348 100644
--- a/src/test/run-pass/method-mut-self-modifies-mut-slice-lvalue.rs
+++ b/src/test/run-pass/method-mut-self-modifies-mut-slice-lvalue.rs
@@ -26,7 +26,7 @@ trait MyWriter {
 
 impl<'a> MyWriter for &'a mut [u8] {
     fn my_write(&mut self, buf: &[u8]) -> IoResult<()> {
-        slice::bytes::copy_memory(*self, buf);
+        slice::bytes::copy_memory(buf, *self);
 
         let write_len = buf.len();
         unsafe {