about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/bootstrap/bin/rustc.rs8
-rw-r--r--src/doc/book/borrow-and-asref.md4
-rw-r--r--src/doc/book/closures.md2
-rw-r--r--src/doc/book/error-handling.md8
-rw-r--r--src/libcollections/binary_heap.rs11
-rw-r--r--src/libcollections/btree/map.rs19
-rw-r--r--src/libcollections/fmt.rs2
-rw-r--r--src/libcollections/linked_list.rs5
-rw-r--r--src/libcollections/vec_deque.rs5
-rw-r--r--src/libcollectionstest/lib.rs3
-rw-r--r--src/libcore/cell.rs36
-rw-r--r--src/libcore/iter/traits.rs22
-rw-r--r--src/libcore/ops.rs221
-rw-r--r--src/libcoretest/cell.rs10
-rw-r--r--src/libcoretest/lib.rs1
-rw-r--r--src/librustc/middle/effect.rs2
-rw-r--r--src/librustc_errors/lib.rs9
-rw-r--r--src/librustc_mir/transform/qualify_consts.rs21
-rw-r--r--src/librustc_resolve/lib.rs6
-rw-r--r--src/librustc_typeck/check/mod.rs16
-rw-r--r--src/librustdoc/clean/mod.rs8
-rw-r--r--src/librustdoc/html/render.rs10
-rw-r--r--src/librustdoc/html/static/main.js13
-rw-r--r--src/libstd/collections/hash/map.rs19
-rw-r--r--src/libstd/ffi/os_str.rs32
-rw-r--r--src/libstd/io/mod.rs6
-rw-r--r--src/libstd/lib.rs2
-rw-r--r--src/libstd/net/ip.rs15
-rw-r--r--src/libstd/primitive_docs.rs2
-rw-r--r--src/libstd/sync/mpsc/mod.rs8
-rw-r--r--src/libstd/sys/unix/ext/process.rs2
-rw-r--r--src/libstd/sys/windows/ext/process.rs3
-rw-r--r--src/libsyntax/parse/parser.rs52
-rw-r--r--src/libsyntax/parse/token.rs10
-rw-r--r--src/libtest/lib.rs1
-rw-r--r--src/test/compile-fail/E0084.rs4
-rw-r--r--src/test/compile-fail/E0133.rs2
-rw-r--r--src/test/compile-fail/E0232.rs5
-rw-r--r--src/test/compile-fail/E0395.rs2
-rw-r--r--src/test/compile-fail/E0396.rs1
-rw-r--r--src/test/compile-fail/E0428.rs7
-rw-r--r--src/test/compile-fail/const-deref-ptr.rs1
-rw-r--r--src/test/compile-fail/enum-and-module-in-same-scope.rs3
-rw-r--r--src/test/compile-fail/issue-21546.rs6
-rw-r--r--src/test/compile-fail/issue-25826.rs1
-rw-r--r--src/test/compile-fail/issue-28776.rs2
-rw-r--r--src/test/compile-fail/trait-duplicate-methods.rs1
-rw-r--r--src/test/compile-fail/trait-safety-fn-body.rs2
-rw-r--r--src/test/compile-fail/unsafe-const-fn.rs2
-rw-r--r--src/test/parse-fail/doc-after-struct-field.rs20
-rw-r--r--src/test/parse-fail/doc-before-extern-rbrace.rs2
-rw-r--r--src/test/parse-fail/doc-before-fn-rbrace.rs16
-rw-r--r--src/test/parse-fail/doc-before-identifier.rs18
-rw-r--r--src/test/parse-fail/doc-before-mod-rbrace.rs15
-rw-r--r--src/test/parse-fail/doc-before-rbrace.rs3
-rw-r--r--src/test/parse-fail/doc-before-semi.rs3
-rw-r--r--src/test/parse-fail/doc-before-struct-rbrace-1.rs21
-rw-r--r--src/test/parse-fail/doc-before-struct-rbrace-2.rs20
-rw-r--r--src/test/rustdoc/issue-26606.rs2
-rw-r--r--src/test/rustdoc/macros.rs4
-rw-r--r--src/tools/linkchecker/Cargo.lock6
61 files changed, 579 insertions, 184 deletions
diff --git a/src/bootstrap/bin/rustc.rs b/src/bootstrap/bin/rustc.rs
index c64cbb9a74e..175e32125f2 100644
--- a/src/bootstrap/bin/rustc.rs
+++ b/src/bootstrap/bin/rustc.rs
@@ -38,13 +38,19 @@ fn main() {
     // is passed (a bit janky...)
     let target = args.windows(2).find(|w| &*w[0] == "--target")
                                 .and_then(|w| w[1].to_str());
+    let version = args.iter().find(|w| &**w == "-vV");
 
     // Build scripts always use the snapshot compiler which is guaranteed to be
     // able to produce an executable, whereas intermediate compilers may not
     // have the standard library built yet and may not be able to produce an
     // executable. Otherwise we just use the standard compiler we're
     // bootstrapping with.
-    let (rustc, libdir) = if target.is_none() {
+    //
+    // Also note that cargo will detect the version of the compiler to trigger
+    // a rebuild when the compiler changes. If this happens, we want to make
+    // sure to use the actual compiler instead of the snapshot compiler becase
+    // that's the one that's actually changing.
+    let (rustc, libdir) = if target.is_none() && version.is_none() {
         ("RUSTC_SNAPSHOT", "RUSTC_SNAPSHOT_LIBDIR")
     } else {
         ("RUSTC_REAL", "RUSTC_LIBDIR")
diff --git a/src/doc/book/borrow-and-asref.md b/src/doc/book/borrow-and-asref.md
index 1cfeb2620bd..c30b2e68665 100644
--- a/src/doc/book/borrow-and-asref.md
+++ b/src/doc/book/borrow-and-asref.md
@@ -8,7 +8,7 @@ different. Here’s a quick refresher on what these two traits mean.
 
 # Borrow
 
-The `Borrow` trait is used when you’re writing a datastructure, and you want to
+The `Borrow` trait is used when you’re writing a data structure, and you want to
 use either an owned or borrowed type as synonymous for some purpose.
 
 For example, [`HashMap`][hashmap] has a [`get` method][get] which uses `Borrow`:
@@ -86,7 +86,7 @@ We can see how they’re kind of the same: they both deal with owned and borrowe
 versions of some type. However, they’re a bit different.
 
 Choose `Borrow` when you want to abstract over different kinds of borrowing, or
-when you’re building a datastructure that treats owned and borrowed values in
+when you’re building a data structure that treats owned and borrowed values in
 equivalent ways, such as hashing and comparison.
 
 Choose `AsRef` when you want to convert something to a reference directly, and
diff --git a/src/doc/book/closures.md b/src/doc/book/closures.md
index d332cac7d8d..3ed85c1a90b 100644
--- a/src/doc/book/closures.md
+++ b/src/doc/book/closures.md
@@ -340,7 +340,7 @@ fn call_with_ref<'a, F>(some_closure:F) -> i32
     where F: Fn(&'a i32) -> i32 {
 ```
 
-However this presents a problem with in our case. When you specify the explicit
+However this presents a problem in our case. When you specify the explicit
 lifetime on a function it binds that lifetime to the *entire* scope of the function
 instead of just the invocation scope of our closure. This means that the borrow checker
 will see a mutable reference in the same lifetime as our immutable reference and fail
diff --git a/src/doc/book/error-handling.md b/src/doc/book/error-handling.md
index 6e13b464e4c..a62e1b7dfa9 100644
--- a/src/doc/book/error-handling.md
+++ b/src/doc/book/error-handling.md
@@ -59,7 +59,7 @@ handling is reducing the amount of explicit case analysis the programmer has to
 do while keeping code composable.
 
 Keeping code composable is important, because without that requirement, we
-could [`panic`](../std/macro.panic!.html) whenever we
+could [`panic`](../std/macro.panic.html) whenever we
 come across something unexpected. (`panic` causes the current task to unwind,
 and in most cases, the entire program aborts.) Here's an example:
 
@@ -944,7 +944,7 @@ macro_rules! try {
 }
 ```
 
-(The [real definition](../std/macro.try!.html) is a bit more
+(The [real definition](../std/macro.try.html) is a bit more
 sophisticated. We will address that later.)
 
 Using the `try!` macro makes it very easy to simplify our last example. Since
@@ -1271,7 +1271,7 @@ macro_rules! try {
 ```
 
 This is not its real definition. Its real definition is
-[in the standard library](../std/macro.try!.html):
+[in the standard library](../std/macro.try.html):
 
 <span id="code-try-def"></span>
 
@@ -2178,7 +2178,7 @@ heuristics!
   [`From`](../std/convert/trait.From.html)
   and
   [`Error`](../std/error/trait.Error.html)
-  impls to make the [`try!`](../std/macro.try!.html)
+  impls to make the [`try!`](../std/macro.try.html)
   macro more ergonomic.
 * If you're writing a library and your code can produce errors, define your own
   error type and implement the
diff --git a/src/libcollections/binary_heap.rs b/src/libcollections/binary_heap.rs
index b9f5c6fcab9..fe9b60c393f 100644
--- a/src/libcollections/binary_heap.rs
+++ b/src/libcollections/binary_heap.rs
@@ -223,19 +223,19 @@ pub struct BinaryHeap<T> {
 /// on `BinaryHeap`. See its documentation for details.
 ///
 /// [`peek_mut()`]: struct.BinaryHeap.html#method.peek_mut
-#[unstable(feature = "binary_heap_peek_mut", issue = "34392")]
+#[stable(feature = "binary_heap_peek_mut", since = "1.12.0")]
 pub struct PeekMut<'a, T: 'a + Ord> {
     heap: &'a mut BinaryHeap<T>
 }
 
-#[unstable(feature = "binary_heap_peek_mut", issue = "34392")]
+#[stable(feature = "binary_heap_peek_mut", since = "1.12.0")]
 impl<'a, T: Ord> Drop for PeekMut<'a, T> {
     fn drop(&mut self) {
         self.heap.sift_down(0);
     }
 }
 
-#[unstable(feature = "binary_heap_peek_mut", issue = "34392")]
+#[stable(feature = "binary_heap_peek_mut", since = "1.12.0")]
 impl<'a, T: Ord> Deref for PeekMut<'a, T> {
     type Target = T;
     fn deref(&self) -> &T {
@@ -243,7 +243,7 @@ impl<'a, T: Ord> Deref for PeekMut<'a, T> {
     }
 }
 
-#[unstable(feature = "binary_heap_peek_mut", issue = "34392")]
+#[stable(feature = "binary_heap_peek_mut", since = "1.12.0")]
 impl<'a, T: Ord> DerefMut for PeekMut<'a, T> {
     fn deref_mut(&mut self) -> &mut T {
         &mut self.heap.data[0]
@@ -366,7 +366,6 @@ impl<T: Ord> BinaryHeap<T> {
     /// Basic usage:
     ///
     /// ```
-    /// #![feature(binary_heap_peek_mut)]
     /// use std::collections::BinaryHeap;
     /// let mut heap = BinaryHeap::new();
     /// assert!(heap.peek_mut().is_none());
@@ -380,7 +379,7 @@ impl<T: Ord> BinaryHeap<T> {
     /// }
     /// assert_eq!(heap.peek(), Some(&2));
     /// ```
-    #[unstable(feature = "binary_heap_peek_mut", issue = "34392")]
+    #[stable(feature = "binary_heap_peek_mut", since = "1.12.0")]
     pub fn peek_mut(&mut self) -> Option<PeekMut<T>> {
         if self.is_empty() {
             None
diff --git a/src/libcollections/btree/map.rs b/src/libcollections/btree/map.rs
index c3a7d402375..a2e2ad37acb 100644
--- a/src/libcollections/btree/map.rs
+++ b/src/libcollections/btree/map.rs
@@ -1981,8 +1981,6 @@ impl<'a, K: Ord, V> VacantEntry<'a, K, V> {
     /// # Examples
     ///
     /// ```
-    /// #![feature(map_entry_recover_keys)]
-    ///
     /// use std::collections::BTreeMap;
     /// use std::collections::btree_map::Entry;
     ///
@@ -1992,7 +1990,7 @@ impl<'a, K: Ord, V> VacantEntry<'a, K, V> {
     ///     v.into_key();
     /// }
     /// ```
-    #[unstable(feature = "map_entry_recover_keys", issue = "34285")]
+    #[stable(feature = "map_entry_recover_keys2", since = "1.12.0")]
     pub fn into_key(self) -> K {
         self.key
     }
@@ -2074,13 +2072,18 @@ impl<'a, K: Ord, V> OccupiedEntry<'a, K, V> {
         self.handle.reborrow().into_kv().0
     }
 
+    /// Deprecated, renamed to `remove_entry`
+    #[unstable(feature = "map_entry_recover_keys", issue = "34285")]
+    #[rustc_deprecated(since = "1.12.0", reason = "renamed to `remove_entry`")]
+    pub fn remove_pair(self) -> (K, V) {
+        self.remove_entry()
+    }
+
     /// Take ownership of the key and value from the map.
     ///
     /// # Examples
     ///
     /// ```
-    /// #![feature(map_entry_recover_keys)]
-    ///
     /// use std::collections::BTreeMap;
     /// use std::collections::btree_map::Entry;
     ///
@@ -2089,14 +2092,14 @@ impl<'a, K: Ord, V> OccupiedEntry<'a, K, V> {
     ///
     /// if let Entry::Occupied(o) = map.entry("poneyland") {
     ///     // We delete the entry from the map.
-    ///     o.remove_pair();
+    ///     o.remove_entry();
     /// }
     ///
     /// // If now try to get the value, it will panic:
     /// // println!("{}", map["poneyland"]);
     /// ```
-    #[unstable(feature = "map_entry_recover_keys", issue = "34285")]
-    pub fn remove_pair(self) -> (K, V) {
+    #[stable(feature = "map_entry_recover_keys2", since = "1.12.0")]
+    pub fn remove_entry(self) -> (K, V) {
         self.remove_kv()
     }
 
diff --git a/src/libcollections/fmt.rs b/src/libcollections/fmt.rs
index be0ef85d6b1..b7cbfb60ec4 100644
--- a/src/libcollections/fmt.rs
+++ b/src/libcollections/fmt.rs
@@ -530,7 +530,7 @@ use string;
 /// assert_eq!(s, "Hello, world!");
 /// ```
 ///
-/// [format!]: ../macro.format!.html
+/// [format!]: ../macro.format.html
 #[stable(feature = "rust1", since = "1.0.0")]
 pub fn format(args: Arguments) -> string::String {
     let mut output = string::String::new();
diff --git a/src/libcollections/linked_list.rs b/src/libcollections/linked_list.rs
index 6842f02e0e1..73aa67849fd 100644
--- a/src/libcollections/linked_list.rs
+++ b/src/libcollections/linked_list.rs
@@ -379,8 +379,6 @@ impl<T> LinkedList<T> {
     /// # Examples
     ///
     /// ```
-    /// #![feature(linked_list_contains)]
-    ///
     /// use std::collections::LinkedList;
     ///
     /// let mut list: LinkedList<u32> = LinkedList::new();
@@ -392,8 +390,7 @@ impl<T> LinkedList<T> {
     /// assert_eq!(list.contains(&0), true);
     /// assert_eq!(list.contains(&10), false);
     /// ```
-    #[unstable(feature = "linked_list_contains", reason = "recently added",
-               issue = "32630")]
+    #[stable(feature = "linked_list_contains", since = "1.12.0")]
     pub fn contains(&self, x: &T) -> bool
         where T: PartialEq<T>
     {
diff --git a/src/libcollections/vec_deque.rs b/src/libcollections/vec_deque.rs
index 812a67a7e78..ce5635714b5 100644
--- a/src/libcollections/vec_deque.rs
+++ b/src/libcollections/vec_deque.rs
@@ -939,8 +939,6 @@ impl<T> VecDeque<T> {
     /// # Examples
     ///
     /// ```
-    /// #![feature(vec_deque_contains)]
-    ///
     /// use std::collections::VecDeque;
     ///
     /// let mut vector: VecDeque<u32> = VecDeque::new();
@@ -951,8 +949,7 @@ impl<T> VecDeque<T> {
     /// assert_eq!(vector.contains(&1), true);
     /// assert_eq!(vector.contains(&10), false);
     /// ```
-    #[unstable(feature = "vec_deque_contains", reason = "recently added",
-               issue = "32630")]
+    #[stable(feature = "vec_deque_contains", since = "1.12.0")]
     pub fn contains(&self, x: &T) -> bool
         where T: PartialEq<T>
     {
diff --git a/src/libcollectionstest/lib.rs b/src/libcollectionstest/lib.rs
index ab3231b2b99..f448fcf2dbf 100644
--- a/src/libcollectionstest/lib.rs
+++ b/src/libcollectionstest/lib.rs
@@ -11,7 +11,6 @@
 #![deny(warnings)]
 
 #![feature(binary_heap_extras)]
-#![feature(binary_heap_peek_mut)]
 #![feature(box_syntax)]
 #![feature(btree_range)]
 #![feature(collections)]
@@ -19,7 +18,6 @@
 #![feature(const_fn)]
 #![feature(fn_traits)]
 #![feature(enumset)]
-#![feature(linked_list_contains)]
 #![feature(pattern)]
 #![feature(rand)]
 #![feature(step_by)]
@@ -27,7 +25,6 @@
 #![feature(test)]
 #![feature(unboxed_closures)]
 #![feature(unicode)]
-#![feature(vec_deque_contains)]
 #![feature(vec_into_iter_as_slice)]
 
 extern crate collections;
diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs
index 17ec325e257..a388012e1da 100644
--- a/src/libcore/cell.rs
+++ b/src/libcore/cell.rs
@@ -233,10 +233,28 @@ impl<T:Copy> Cell<T> {
     /// ```
     #[inline]
     #[unstable(feature = "as_unsafe_cell", issue = "27708")]
+    #[rustc_deprecated(since = "1.12.0", reason = "renamed to as_ptr")]
     pub fn as_unsafe_cell(&self) -> &UnsafeCell<T> {
         &self.value
     }
 
+    /// Returns a raw pointer to the underlying data in this cell.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::cell::Cell;
+    ///
+    /// let c = Cell::new(5);
+    ///
+    /// let ptr = c.as_ptr();
+    /// ```
+    #[inline]
+    #[stable(feature = "cell_as_ptr", since = "1.12.0")]
+    pub fn as_ptr(&self) -> *mut T {
+        self.value.get()
+    }
+
     /// Returns a mutable reference to the underlying data.
     ///
     /// This call borrows `Cell` mutably (at compile-time) which guarantees
@@ -653,10 +671,28 @@ impl<T: ?Sized> RefCell<T> {
     /// ```
     #[inline]
     #[unstable(feature = "as_unsafe_cell", issue = "27708")]
+    #[rustc_deprecated(since = "1.12.0", reason = "renamed to as_ptr")]
     pub unsafe fn as_unsafe_cell(&self) -> &UnsafeCell<T> {
         &self.value
     }
 
+    /// Returns a raw pointer to the underlying data in this cell.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::cell::RefCell;
+    ///
+    /// let c = RefCell::new(5);
+    ///
+    /// let ptr = c.as_ptr();
+    /// ```
+    #[inline]
+    #[stable(feature = "cell_as_ptr", since = "1.12.0")]
+    pub fn as_ptr(&self) -> *mut T {
+        self.value.get()
+    }
+
     /// Returns a mutable reference to the underlying data.
     ///
     /// This call borrows `RefCell` mutably (at compile-time) so there is no
diff --git a/src/libcore/iter/traits.rs b/src/libcore/iter/traits.rs
index 4cbabe3f5ed..cb509156e32 100644
--- a/src/libcore/iter/traits.rs
+++ b/src/libcore/iter/traits.rs
@@ -563,10 +563,11 @@ impl<'a, I: ExactSizeIterator + ?Sized> ExactSizeIterator for &'a mut I {}
 /// implement the trait can be generated by the `sum` method. Like
 /// `FromIterator` this trait should rarely be called directly and instead
 /// interacted with through `Iterator::sum`.
-#[unstable(feature = "iter_arith_traits", issue = "34529")]
+#[stable(feature = "iter_arith_traits", since = "1.12.0")]
 pub trait Sum<A = Self>: Sized {
     /// Method which takes an iterator and generates `Self` from the elements by
     /// "summing up" the items.
+    #[stable(feature = "iter_arith_traits", since = "1.12.0")]
     fn sum<I: Iterator<Item=A>>(iter: I) -> Self;
 }
 
@@ -577,16 +578,17 @@ pub trait Sum<A = Self>: Sized {
 /// which implement the trait can be generated by the `product` method. Like
 /// `FromIterator` this trait should rarely be called directly and instead
 /// interacted with through `Iterator::product`.
-#[unstable(feature = "iter_arith_traits", issue = "34529")]
+#[stable(feature = "iter_arith_traits", since = "1.12.0")]
 pub trait Product<A = Self>: Sized {
     /// Method which takes an iterator and generates `Self` from the elements by
     /// multiplying the items.
+    #[stable(feature = "iter_arith_traits", since = "1.12.0")]
     fn product<I: Iterator<Item=A>>(iter: I) -> Self;
 }
 
 macro_rules! integer_sum_product {
     ($($a:ident)*) => ($(
-        #[unstable(feature = "iter_arith_traits", issue = "34529")]
+        #[stable(feature = "iter_arith_traits", since = "1.12.0")]
         impl Sum for $a {
             fn sum<I: Iterator<Item=$a>>(iter: I) -> $a {
                 iter.fold(0, |a, b| {
@@ -595,7 +597,7 @@ macro_rules! integer_sum_product {
             }
         }
 
-        #[unstable(feature = "iter_arith_traits", issue = "34529")]
+        #[stable(feature = "iter_arith_traits", since = "1.12.0")]
         impl Product for $a {
             fn product<I: Iterator<Item=$a>>(iter: I) -> $a {
                 iter.fold(1, |a, b| {
@@ -604,7 +606,7 @@ macro_rules! integer_sum_product {
             }
         }
 
-        #[unstable(feature = "iter_arith_traits", issue = "34529")]
+        #[stable(feature = "iter_arith_traits", since = "1.12.0")]
         impl<'a> Sum<&'a $a> for $a {
             fn sum<I: Iterator<Item=&'a $a>>(iter: I) -> $a {
                 iter.fold(0, |a, b| {
@@ -613,7 +615,7 @@ macro_rules! integer_sum_product {
             }
         }
 
-        #[unstable(feature = "iter_arith_traits", issue = "34529")]
+        #[stable(feature = "iter_arith_traits", since = "1.12.0")]
         impl<'a> Product<&'a $a> for $a {
             fn product<I: Iterator<Item=&'a $a>>(iter: I) -> $a {
                 iter.fold(1, |a, b| {
@@ -626,28 +628,28 @@ macro_rules! integer_sum_product {
 
 macro_rules! float_sum_product {
     ($($a:ident)*) => ($(
-        #[unstable(feature = "iter_arith_traits", issue = "34529")]
+        #[stable(feature = "iter_arith_traits", since = "1.12.0")]
         impl Sum for $a {
             fn sum<I: Iterator<Item=$a>>(iter: I) -> $a {
                 iter.fold(0.0, |a, b| a + b)
             }
         }
 
-        #[unstable(feature = "iter_arith_traits", issue = "34529")]
+        #[stable(feature = "iter_arith_traits", since = "1.12.0")]
         impl Product for $a {
             fn product<I: Iterator<Item=$a>>(iter: I) -> $a {
                 iter.fold(1.0, |a, b| a * b)
             }
         }
 
-        #[unstable(feature = "iter_arith_traits", issue = "34529")]
+        #[stable(feature = "iter_arith_traits", since = "1.12.0")]
         impl<'a> Sum<&'a $a> for $a {
             fn sum<I: Iterator<Item=&'a $a>>(iter: I) -> $a {
                 iter.fold(0.0, |a, b| a + *b)
             }
         }
 
-        #[unstable(feature = "iter_arith_traits", issue = "34529")]
+        #[stable(feature = "iter_arith_traits", since = "1.12.0")]
         impl<'a> Product<&'a $a> for $a {
             fn product<I: Iterator<Item=&'a $a>>(iter: I) -> $a {
                 iter.fold(1.0, |a, b| a * *b)
diff --git a/src/libcore/ops.rs b/src/libcore/ops.rs
index 4ac1b8394f4..5a1993e741c 100644
--- a/src/libcore/ops.rs
+++ b/src/libcore/ops.rs
@@ -67,8 +67,7 @@
 //! }
 //! ```
 //!
-//! See the documentation for each trait for a minimum implementation that
-//! prints something to the screen.
+//! See the documentation for each trait for an example implementation.
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
@@ -107,6 +106,13 @@ pub trait Drop {
     ///
     /// After this function is over, the memory of `self` will be deallocated.
     ///
+    /// This function cannot be called explicitly. This is compiler error
+    /// [0040]. However, the [`std::mem::drop`] function in the prelude can be
+    /// used to call the argument's `Drop` implementation.
+    ///
+    /// [0040]: https://doc.rust-lang.org/error-index.html#E0040
+    /// [`std::mem::drop`]: https://doc.rust-lang.org/std/mem/fn.drop.html
+    ///
     /// # Panics
     ///
     /// Given that a `panic!` will call `drop()` as it unwinds, any `panic!` in
@@ -171,25 +177,38 @@ macro_rules! forward_ref_binop {
 ///
 /// # Examples
 ///
-/// A trivial implementation of `Add`. When `Foo + Foo` happens, it ends up
-/// calling `add`, and therefore, `main` prints `Adding!`.
+/// This example creates a `Point` struct that implements the `Add` trait, and
+/// then demonstrates adding two `Point`s.
 ///
 /// ```
 /// use std::ops::Add;
 ///
-/// struct Foo;
+/// #[derive(Debug)]
+/// struct Point {
+///     x: i32,
+///     y: i32,
+/// }
 ///
-/// impl Add for Foo {
-///     type Output = Foo;
+/// impl Add for Point {
+///     type Output = Point;
 ///
-///     fn add(self, _rhs: Foo) -> Foo {
-///         println!("Adding!");
-///         self
+///     fn add(self, other: Point) -> Point {
+///         Point {
+///             x: self.x + other.x,
+///             y: self.y + other.y,
+///         }
+///     }
+/// }
+///
+/// impl PartialEq for Point {
+///     fn eq(&self, other: &Self) -> bool {
+///         self.x == other.x && self.y == other.y
 ///     }
 /// }
 ///
 /// fn main() {
-///     Foo + Foo;
+///     assert_eq!(Point { x: 1, y: 0 } + Point { x: 2, y: 3 },
+///                Point { x: 3, y: 3 });
 /// }
 /// ```
 #[lang = "add"]
@@ -300,6 +319,37 @@ sub_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 }
 ///     Foo * Foo;
 /// }
 /// ```
+///
+/// Note that `RHS = Self` by default, but this is not mandatory. Here is an
+/// implementation which enables multiplication of vectors by scalars, as is
+/// done in linear algebra.
+///
+/// ```
+/// use std::ops::Mul;
+///
+/// struct Scalar {value: usize};
+///
+/// #[derive(Debug)]
+/// struct Vector {value: Vec<usize>};
+///
+/// impl Mul<Vector> for Scalar {
+///     type Output = Vector;
+///
+///     fn mul(self, rhs: Vector) -> Vector {
+///         Vector {value: rhs.value.iter().map(|v| self.value * v).collect()}
+///     }
+/// }
+///
+/// impl PartialEq<Vector> for Vector {
+///     fn eq(&self, other: &Self) -> bool {
+///         self.value == other.value
+///     }
+/// }
+///
+/// let scalar = Scalar{value: 3};
+/// let vector = Vector{value: vec![2, 4, 6]};
+/// assert_eq!(scalar * vector, Vector{value: vec![6, 12, 18]});
+/// ```
 #[lang = "mul"]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub trait Mul<RHS=Self> {
@@ -354,6 +404,37 @@ mul_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 }
 ///     Foo / Foo;
 /// }
 /// ```
+///
+/// Note that `RHS = Self` by default, but this is not mandatory. Here is an
+/// implementation which enables division of vectors by scalars, as is done in
+/// linear algebra.
+///
+/// ```
+/// use std::ops::Div;
+///
+/// struct Scalar {value: f32};
+///
+/// #[derive(Debug)]
+/// struct Vector {value: Vec<f32>};
+///
+/// impl Div<Scalar> for Vector {
+///     type Output = Vector;
+///
+///     fn div(self, rhs: Scalar) -> Vector {
+///         Vector {value: self.value.iter().map(|v| v / rhs.value).collect()}
+///     }
+/// }
+///
+/// impl PartialEq<Vector> for Vector {
+///     fn eq(&self, other: &Self) -> bool {
+///         self.value == other.value
+///     }
+/// }
+///
+/// let scalar = Scalar{value: 2f32};
+/// let vector = Vector{value: vec![2f32, 4f32, 6f32]};
+/// assert_eq!(vector / scalar, Vector{value: vec![1f32, 2f32, 3f32]});
+/// ```
 #[lang = "div"]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub trait Div<RHS=Self> {
@@ -475,26 +556,37 @@ rem_impl_float! { f32 f64 }
 ///
 /// # Examples
 ///
-/// A trivial implementation of `Neg`. When `-Foo` happens, it ends up calling
-/// `neg`, and therefore, `main` prints `Negating!`.
+/// An implementation of `Neg` for `Sign`, which allows the use of `-` to
+/// negate its value.
 ///
 /// ```
 /// use std::ops::Neg;
 ///
-/// struct Foo;
+/// #[derive(Debug, PartialEq)]
+/// enum Sign {
+///     Negative,
+///     Zero,
+///     Positive,
+/// }
 ///
-/// impl Neg for Foo {
-///     type Output = Foo;
+/// impl Neg for Sign {
+///     type Output = Sign;
 ///
-///     fn neg(self) -> Foo {
-///         println!("Negating!");
-///         self
+///     fn neg(self) -> Sign {
+///         match self {
+///             Sign::Negative => Sign::Positive,
+///             Sign::Zero => Sign::Zero,
+///             Sign::Positive => Sign::Negative,
+///         }
 ///     }
 /// }
 ///
-/// fn main() {
-///     -Foo;
-/// }
+/// // a negative positive is a negative
+/// assert_eq!(-Sign::Positive, Sign::Negative);
+/// // a double negative is a positive
+/// assert_eq!(-Sign::Negative, Sign::Positive);
+/// // zero is its own negation
+/// assert_eq!(-Sign::Zero, Sign::Zero);
 /// ```
 #[lang = "neg"]
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -543,26 +635,31 @@ neg_impl_numeric! { isize i8 i16 i32 i64 f32 f64 }
 ///
 /// # Examples
 ///
-/// A trivial implementation of `Not`. When `!Foo` happens, it ends up calling
-/// `not`, and therefore, `main` prints `Not-ing!`.
+/// An implementation of `Not` for `Answer`, which enables the use of `!` to
+/// invert its value.
 ///
 /// ```
 /// use std::ops::Not;
 ///
-/// struct Foo;
+/// #[derive(Debug, PartialEq)]
+/// enum Answer {
+///     Yes,
+///     No,
+/// }
 ///
-/// impl Not for Foo {
-///     type Output = Foo;
+/// impl Not for Answer {
+///     type Output = Answer;
 ///
-///     fn not(self) -> Foo {
-///         println!("Not-ing!");
-///         self
+///     fn not(self) -> Answer {
+///         match self {
+///             Answer::Yes => Answer::No,
+///             Answer::No => Answer::Yes
+///         }
 ///     }
 /// }
 ///
-/// fn main() {
-///     !Foo;
-/// }
+/// assert_eq!(!Answer::Yes, Answer::No);
+/// assert_eq!(!Answer::No, Answer::Yes);
 /// ```
 #[lang = "not"]
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -899,25 +996,36 @@ shr_impl_all! { u8 u16 u32 u64 usize i8 i16 i32 i64 isize }
 ///
 /// # Examples
 ///
-/// A trivial implementation of `AddAssign`. When `Foo += Foo` happens, it ends up
-/// calling `add_assign`, and therefore, `main` prints `Adding!`.
+/// This example creates a `Point` struct that implements the `AddAssign`
+/// trait, and then demonstrates add-assigning to a mutable `Point`.
 ///
 /// ```
 /// use std::ops::AddAssign;
 ///
-/// struct Foo;
+/// #[derive(Debug)]
+/// struct Point {
+///     x: i32,
+///     y: i32,
+/// }
 ///
-/// impl AddAssign for Foo {
-///     fn add_assign(&mut self, _rhs: Foo) {
-///         println!("Adding!");
+/// impl AddAssign for Point {
+///     fn add_assign(&mut self, other: Point) {
+///         *self = Point {
+///             x: self.x + other.x,
+///             y: self.y + other.y,
+///         };
 ///     }
 /// }
 ///
-/// # #[allow(unused_assignments)]
-/// fn main() {
-///     let mut foo = Foo;
-///     foo += Foo;
+/// impl PartialEq for Point {
+///     fn eq(&self, other: &Self) -> bool {
+///         self.x == other.x && self.y == other.y
+///     }
 /// }
+///
+/// let mut point = Point { x: 1, y: 0 };
+/// point += Point { x: 2, y: 3 };
+/// assert_eq!(point, Point { x: 3, y: 3 });
 /// ```
 #[lang = "add_assign"]
 #[stable(feature = "op_assign_traits", since = "1.8.0")]
@@ -1467,17 +1575,30 @@ pub trait IndexMut<Idx: ?Sized>: Index<Idx> {
 ///
 /// # Examples
 ///
+/// The `..` syntax is a `RangeFull`:
+///
+/// ```
+/// assert_eq!((..), std::ops::RangeFull);
 /// ```
-/// fn main() {
-///     assert_eq!((..), std::ops::RangeFull);
 ///
-///     let arr = [0, 1, 2, 3];
-///     assert_eq!(arr[ .. ], [0,1,2,3]);  // RangeFull
-///     assert_eq!(arr[ ..3], [0,1,2  ]);
-///     assert_eq!(arr[1.. ], [  1,2,3]);
-///     assert_eq!(arr[1..3], [  1,2  ]);
+/// It does not have an `IntoIterator` implementation, so you can't use it in a
+/// `for` loop directly. This won't compile:
+///
+/// ```ignore
+/// for i in .. {
+///    // ...
 /// }
 /// ```
+///
+/// Used as a slicing index, `RangeFull` produces the full array as a slice.
+///
+/// ```
+/// let arr = [0, 1, 2, 3];
+/// assert_eq!(arr[ .. ], [0,1,2,3]);  // RangeFull
+/// assert_eq!(arr[ ..3], [0,1,2  ]);
+/// assert_eq!(arr[1.. ], [  1,2,3]);
+/// assert_eq!(arr[1..3], [  1,2  ]);
+/// ```
 #[derive(Copy, Clone, PartialEq, Eq, Hash)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct RangeFull;
diff --git a/src/libcoretest/cell.rs b/src/libcoretest/cell.rs
index a635620d12a..a7c230ba979 100644
--- a/src/libcoretest/cell.rs
+++ b/src/libcoretest/cell.rs
@@ -176,21 +176,21 @@ fn ref_mut_map_accessor() {
 }
 
 #[test]
-fn as_unsafe_cell() {
+fn as_ptr() {
     let c1: Cell<usize> = Cell::new(0);
     c1.set(1);
-    assert_eq!(1, unsafe { *c1.as_unsafe_cell().get() });
+    assert_eq!(1, unsafe { *c1.as_ptr() });
 
     let c2: Cell<usize> = Cell::new(0);
-    unsafe { *c2.as_unsafe_cell().get() = 1; }
+    unsafe { *c2.as_ptr() = 1; }
     assert_eq!(1, c2.get());
 
     let r1: RefCell<usize> = RefCell::new(0);
     *r1.borrow_mut() = 1;
-    assert_eq!(1, unsafe { *r1.as_unsafe_cell().get() });
+    assert_eq!(1, unsafe { *r1.as_ptr() });
 
     let r2: RefCell<usize> = RefCell::new(0);
-    unsafe { *r2.as_unsafe_cell().get() = 1; }
+    unsafe { *r2.as_ptr() = 1; }
     assert_eq!(1, *r2.borrow());
 }
 
diff --git a/src/libcoretest/lib.rs b/src/libcoretest/lib.rs
index 9428b4096bf..9116344c579 100644
--- a/src/libcoretest/lib.rs
+++ b/src/libcoretest/lib.rs
@@ -10,7 +10,6 @@
 
 #![deny(warnings)]
 
-#![feature(as_unsafe_cell)]
 #![feature(borrow_state)]
 #![feature(box_syntax)]
 #![feature(cell_extras)]
diff --git a/src/librustc/middle/effect.rs b/src/librustc/middle/effect.rs
index 3ca6cf03997..250ad80f5af 100644
--- a/src/librustc/middle/effect.rs
+++ b/src/librustc/middle/effect.rs
@@ -66,7 +66,7 @@ impl<'a, 'tcx> EffectCheckVisitor<'a, 'tcx> {
                 struct_span_err!(
                     self.tcx.sess, span, E0133,
                     "{} requires unsafe function or block", description)
-                    .span_label(span, &format!("unsafe call requires unsafe function or block"))
+                    .span_label(span, &description)
                     .emit();
             }
             UnsafeBlock(block_id) => {
diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs
index 172e27d56d4..4b3e53d931f 100644
--- a/src/librustc_errors/lib.rs
+++ b/src/librustc_errors/lib.rs
@@ -564,6 +564,15 @@ impl Handler {
         self.bump_err_count();
         self.panic_if_treat_err_as_bug();
     }
+    pub fn mut_span_err<'a, S: Into<MultiSpan>>(&'a self,
+                                                sp: S,
+                                                msg: &str)
+                                                -> DiagnosticBuilder<'a> {
+        let mut result = DiagnosticBuilder::new(self, Level::Error, msg);
+        result.set_span(sp);
+        self.bump_err_count();
+        result
+    }
     pub fn span_err_with_code<S: Into<MultiSpan>>(&self, sp: S, msg: &str, code: &str) {
         self.emit_with_code(&sp.into(), msg, code, Error);
         self.bump_err_count();
diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs
index 1de67922b1b..bcdc0d2ea3f 100644
--- a/src/librustc_mir/transform/qualify_consts.rs
+++ b/src/librustc_mir/transform/qualify_consts.rs
@@ -493,9 +493,13 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
                             if let ty::TyRawPtr(_) = base_ty.sty {
                                 this.add(Qualif::NOT_CONST);
                                 if this.mode != Mode::Fn {
-                                    span_err!(this.tcx.sess, this.span, E0396,
-                                              "raw pointers cannot be dereferenced in {}s",
-                                              this.mode);
+                                    struct_span_err!(this.tcx.sess,
+                                        this.span, E0396,
+                                        "raw pointers cannot be dereferenced in {}s",
+                                        this.mode)
+                                    .span_label(this.span,
+                                        &format!("dereference of raw pointer in constant"))
+                                    .emit();
                                 }
                             }
                         }
@@ -681,9 +685,14 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
 
                     self.add(Qualif::NOT_CONST);
                     if self.mode != Mode::Fn {
-                        span_err!(self.tcx.sess, self.span, E0395,
-                                  "raw pointers cannot be compared in {}s",
-                                  self.mode);
+                        struct_span_err!(
+                            self.tcx.sess, self.span, E0395,
+                            "raw pointers cannot be compared in {}s",
+                            self.mode)
+                        .span_label(
+                            self.span,
+                            &format!("comparing raw pointers in static"))
+                        .emit();
                     }
                 }
             }
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index b91ede5b2fa..af39f8a415c 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -3382,7 +3382,11 @@ impl<'a> Resolver<'a> {
             },
             (true, _) | (_, true) => struct_span_err!(self.session, span, E0260, "{}", msg),
             _ => match (old_binding.is_import(), binding.is_import()) {
-                (false, false) => struct_span_err!(self.session, span, E0428, "{}", msg),
+                (false, false) => {
+                    let mut e = struct_span_err!(self.session, span, E0428, "{}", msg);
+                    e.span_label(span, &format!("already defined"));
+                    e
+                },
                 (true, true) => {
                     let mut e = struct_span_err!(self.session, span, E0252, "{}", msg);
                     e.span_label(span, &format!("already imported"));
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index ca783455569..3d51da02b87 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -903,9 +903,12 @@ fn check_on_unimplemented<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
                 }
             }
         } else {
-            span_err!(ccx.tcx.sess, attr.span, E0232,
-                                  "this attribute must have a value, \
-                                   eg `#[rustc_on_unimplemented = \"foo\"]`")
+            struct_span_err!(
+                ccx.tcx.sess, attr.span, E0232,
+                "this attribute must have a value")
+                .span_label(attr.span, &format!("attribute requires a value"))
+                .note(&format!("eg `#[rustc_on_unimplemented = \"foo\"]`"))
+                .emit();
         }
     }
 }
@@ -1245,8 +1248,11 @@ pub fn check_enum_variants<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
     let hint = *ccx.tcx.lookup_repr_hints(def_id).get(0).unwrap_or(&attr::ReprAny);
 
     if hint != attr::ReprAny && vs.is_empty() {
-        span_err!(ccx.tcx.sess, sp, E0084,
-            "unsupported representation for zero-variant enum");
+        struct_span_err!(
+            ccx.tcx.sess, sp, E0084,
+            "unsupported representation for zero-variant enum")
+            .span_label(sp, &format!("unsupported enum representation"))
+            .emit();
     }
 
     let repr_type_ty = ccx.tcx.enum_repr_type(Some(&hint)).to_ty(ccx.tcx);
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 75d21399f05..39b1a04e98e 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -2803,7 +2803,7 @@ pub struct Macro {
 
 impl Clean<Item> for doctree::Macro {
     fn clean(&self, cx: &DocContext) -> Item {
-        let name = format!("{}!", self.name.clean(cx));
+        let name = self.name.clean(cx);
         Item {
             name: Some(name.clone()),
             attrs: self.attrs.clean(cx),
@@ -2814,8 +2814,10 @@ impl Clean<Item> for doctree::Macro {
             def_id: cx.map.local_def_id(self.id),
             inner: MacroItem(Macro {
                 source: format!("macro_rules! {} {{\n{}}}",
-                    name.trim_right_matches('!'), self.matchers.iter().map(|span|
-                        format!("    {} => {{ ... }};\n", span.to_src(cx))).collect::<String>()),
+                                name,
+                                self.matchers.iter().map(|span| {
+                                    format!("    {} => {{ ... }};\n", span.to_src(cx))
+                                }).collect::<String>()),
                 imported_from: self.imported_from.clean(cx),
             }),
         }
diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index d654429146d..e02cfb96ddd 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -1426,6 +1426,16 @@ impl Context {
                                                                 .open(&redir_dst) {
                     try_err!(layout::redirect(&mut redirect_out, file_name), &redir_dst);
                 }
+
+                // If the item is a macro, redirect from the old macro URL (with !)
+                // to the new one (without).
+                // FIXME(#35705) remove this redirect.
+                if item_type == ItemType::Macro {
+                    let redir_name = format!("{}.{}!.html", item_type, name);
+                    let redir_dst = self.dst.join(redir_name);
+                    let mut redirect_out = try_err!(File::create(&redir_dst), &redir_dst);
+                    try_err!(layout::redirect(&mut redirect_out, file_name), &redir_dst);
+                }
             }
         }
         Ok(())
diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js
index 68035e5abe4..de7e4d2483b 100644
--- a/src/librustdoc/html/static/main.js
+++ b/src/librustdoc/html/static/main.js
@@ -577,10 +577,6 @@
                         displayPath = item.path + '::';
                         href = rootPath + item.path.replace(/::/g, '/') + '/' +
                                name + '/index.html';
-                    } else if (type === 'static' || type === 'reexport') {
-                        displayPath = item.path + '::';
-                        href = rootPath + item.path.replace(/::/g, '/') +
-                               '/index.html';
                     } else if (type === "primitive") {
                         displayPath = "";
                         href = rootPath + item.path.replace(/::/g, '/') +
@@ -591,9 +587,14 @@
                     } else if (item.parent !== undefined) {
                         var myparent = item.parent;
                         var anchor = '#' + type + '.' + name;
-                        displayPath = item.path + '::' + myparent.name + '::';
+                        var parentType = itemTypes[myparent.ty];
+                        if (parentType === "primitive") {
+                            displayPath = myparent.name + '::';
+                        } else {
+                            displayPath = item.path + '::' + myparent.name + '::';
+                        }
                         href = rootPath + item.path.replace(/::/g, '/') +
-                               '/' + itemTypes[myparent.ty] +
+                               '/' + parentType +
                                '.' + myparent.name +
                                '.html' + anchor;
                     } else {
diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs
index cf6f76f914a..3d3e3941bac 100644
--- a/src/libstd/collections/hash/map.rs
+++ b/src/libstd/collections/hash/map.rs
@@ -1640,13 +1640,18 @@ impl<'a, K, V> OccupiedEntry<'a, K, V> {
         self.elem.read().0
     }
 
+    /// Deprecated, renamed to `remove_entry`
+    #[unstable(feature = "map_entry_recover_keys", issue = "34285")]
+    #[rustc_deprecated(since = "1.12.0", reason = "renamed to `remove_entry`")]
+    pub fn remove_pair(self) -> (K, V) {
+        self.remove_entry()
+    }
+
     /// Take the ownership of the key and value from the map.
     ///
     /// # Examples
     ///
     /// ```
-    /// #![feature(map_entry_recover_keys)]
-    ///
     /// use std::collections::HashMap;
     /// use std::collections::hash_map::Entry;
     ///
@@ -1655,13 +1660,13 @@ impl<'a, K, V> OccupiedEntry<'a, K, V> {
     ///
     /// if let Entry::Occupied(o) = map.entry("poneyland") {
     ///     // We delete the entry from the map.
-    ///     o.remove_pair();
+    ///     o.remove_entry();
     /// }
     ///
     /// assert_eq!(map.contains_key("poneyland"), false);
     /// ```
-    #[unstable(feature = "map_entry_recover_keys", issue = "34285")]
-    pub fn remove_pair(self) -> (K, V) {
+    #[stable(feature = "map_entry_recover_keys2", since = "1.12.0")]
+    pub fn remove_entry(self) -> (K, V) {
         pop_internal(self.elem)
     }
 
@@ -1808,8 +1813,6 @@ impl<'a, K: 'a, V: 'a> VacantEntry<'a, K, V> {
     /// # Examples
     ///
     /// ```
-    /// #![feature(map_entry_recover_keys)]
-    ///
     /// use std::collections::HashMap;
     /// use std::collections::hash_map::Entry;
     ///
@@ -1819,7 +1822,7 @@ impl<'a, K: 'a, V: 'a> VacantEntry<'a, K, V> {
     ///     v.into_key();
     /// }
     /// ```
-    #[unstable(feature = "map_entry_recover_keys", issue = "34285")]
+    #[stable(feature = "map_entry_recover_keys2", since = "1.12.0")]
     pub fn into_key(self) -> K {
         self.key
     }
diff --git a/src/libstd/ffi/os_str.rs b/src/libstd/ffi/os_str.rs
index 0d29e62485a..3d23a9a2383 100644
--- a/src/libstd/ffi/os_str.rs
+++ b/src/libstd/ffi/os_str.rs
@@ -251,6 +251,14 @@ impl Hash for OsString {
 
 impl OsStr {
     /// Coerces into an `OsStr` slice.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::ffi::OsStr;
+    ///
+    /// let os_str = OsStr::new("foo");
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn new<S: AsRef<OsStr> + ?Sized>(s: &S) -> &OsStr {
         s.as_ref()
@@ -283,6 +291,18 @@ impl OsStr {
     }
 
     /// Checks whether the `OsStr` is empty.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::ffi::OsStr;
+    ///
+    /// let os_str = OsStr::new("");
+    /// assert!(os_str.is_empty());
+    ///
+    /// let os_str = OsStr::new("foo");
+    /// assert!(!os_str.is_empty());
+    /// ```
     #[stable(feature = "osstring_simple_functions", since = "1.9.0")]
     pub fn is_empty(&self) -> bool {
         self.inner.inner.is_empty()
@@ -296,6 +316,18 @@ impl OsStr {
     /// other methods like `OsString::with_capacity` to avoid reallocations.
     ///
     /// See `OsStr` introduction for more information about encoding.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::ffi::OsStr;
+    ///
+    /// let os_str = OsStr::new("");
+    /// assert_eq!(os_str.len(), 0);
+    ///
+    /// let os_str = OsStr::new("foo");
+    /// assert_eq!(os_str.len(), 3);
+    /// ```
     #[stable(feature = "osstring_simple_functions", since = "1.9.0")]
     pub fn len(&self) -> usize {
         self.inner.inner.len()
diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs
index 88fd4186e0a..307d014fd68 100644
--- a/src/libstd/io/mod.rs
+++ b/src/libstd/io/mod.rs
@@ -236,7 +236,7 @@
 //! to read the line and print it, so we use `()`.
 //!
 //! [result]: type.Result.html
-//! [try]: ../macro.try!.html
+//! [try]: ../macro.try.html
 //!
 //! ## Platform-specific behavior
 //!
@@ -957,8 +957,8 @@ pub trait Write {
     /// explicitly be called. The [`write!`][write] macro should be favored to
     /// invoke this method instead.
     ///
-    /// [formatargs]: ../macro.format_args!.html
-    /// [write]: ../macro.write!.html
+    /// [formatargs]: ../macro.format_args.html
+    /// [write]: ../macro.write.html
     ///
     /// This function internally uses the [`write_all`][writeall] method on
     /// this trait and hence will continuously write data so long as no errors
diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs
index c05e0c3ca68..ff3b9c6d041 100644
--- a/src/libstd/lib.rs
+++ b/src/libstd/lib.rs
@@ -175,7 +175,7 @@
 //! [`atomic`]: sync/atomic/index.html
 //! [`collections`]: collections/index.html
 //! [`for`]: ../book/loops.html#for
-//! [`format!`]: macro.format!.html
+//! [`format!`]: macro.format.html
 //! [`fs`]: fs/index.html
 //! [`io`]: io/index.html
 //! [`iter`]: iter/index.html
diff --git a/src/libstd/net/ip.rs b/src/libstd/net/ip.rs
index 2a8bd0c88be..4c3b993497c 100644
--- a/src/libstd/net/ip.rs
+++ b/src/libstd/net/ip.rs
@@ -63,8 +63,7 @@ impl IpAddr {
     /// Returns true for the special 'unspecified' address ([IPv4], [IPv6]).
     /// [IPv4]: ../../std/net/struct.Ipv4Addr.html#method.is_unspecified
     /// [IPv6]: ../../std/net/struct.Ipv6Addr.html#method.is_unspecified
-    #[unstable(feature="ip", issue="27709",
-               reason="recently added and depends on unstable Ipv4Addr.is_unspecified()")]
+    #[stable(feature = "ip_shared", since = "1.12.0")]
     pub fn is_unspecified(&self) -> bool {
         match *self {
             IpAddr::V4(ref a) => a.is_unspecified(),
@@ -75,7 +74,7 @@ impl IpAddr {
     /// Returns true if this is a loopback address ([IPv4], [IPv6]).
     /// [IPv4]: ../../std/net/struct.Ipv4Addr.html#method.is_loopback
     /// [IPv6]: ../../std/net/struct.Ipv6Addr.html#method.is_loopback
-    #[unstable(feature="ip", reason="recently added", issue="27709")]
+    #[stable(feature = "ip_shared", since = "1.12.0")]
     pub fn is_loopback(&self) -> bool {
         match *self {
             IpAddr::V4(ref a) => a.is_loopback(),
@@ -86,8 +85,6 @@ impl IpAddr {
     /// Returns true if the address appears to be globally routable ([IPv4], [IPv6]).
     /// [IPv4]: ../../std/net/struct.Ipv4Addr.html#method.is_global
     /// [IPv6]: ../../std/net/struct.Ipv6Addr.html#method.is_global
-    #[unstable(feature="ip", issue="27709",
-               reason="recently added and depends on unstable Ip{v4,v6}Addr.is_global()")]
     pub fn is_global(&self) -> bool {
         match *self {
             IpAddr::V4(ref a) => a.is_global(),
@@ -98,7 +95,7 @@ impl IpAddr {
     /// Returns true if this is a multicast address ([IPv4], [IPv6]).
     /// [IPv4]: ../../std/net/struct.Ipv4Addr.html#method.is_multicast
     /// [IPv6]: ../../std/net/struct.Ipv6Addr.html#method.is_multicast
-    #[unstable(feature="ip", reason="recently added", issue="27709")]
+    #[stable(feature = "ip_shared", since = "1.12.0")]
     pub fn is_multicast(&self) -> bool {
         match *self {
             IpAddr::V4(ref a) => a.is_multicast(),
@@ -109,8 +106,6 @@ impl IpAddr {
     /// Returns true if this address is in a range designated for documentation ([IPv4], [IPv6]).
     /// [IPv4]: ../../std/net/struct.Ipv4Addr.html#method.is_documentation
     /// [IPv6]: ../../std/net/struct.Ipv6Addr.html#method.is_documentation
-    #[unstable(feature="ip", issue="27709",
-               reason="recently added and depends on unstable Ipv6Addr.is_documentation()")]
     pub fn is_documentation(&self) -> bool {
         match *self {
             IpAddr::V4(ref a) => a.is_documentation(),
@@ -147,6 +142,7 @@ impl Ipv4Addr {
     /// This property is defined in _UNIX Network Programming, Second Edition_,
     /// W. Richard Stevens, p. 891; see also [ip7]
     /// [ip7][http://man7.org/linux/man-pages/man7/ip.7.html]
+    #[stable(feature = "ip_shared", since = "1.12.0")]
     pub fn is_unspecified(&self) -> bool {
         self.inner.s_addr == 0
     }
@@ -515,8 +511,7 @@ impl Ipv6Addr {
     }
 
     /// Returns the sixteen eight-bit integers the IPv6 address consists of.
-    #[unstable(feature = "ipv6_to_octets", reason = "needs some testing",
-               issue = "32313")]
+    #[stable(feature = "ipv6_to_octets", since = "1.12.0")]
     pub fn octets(&self) -> [u8; 16] {
         self.inner.s6_addr
     }
diff --git a/src/libstd/primitive_docs.rs b/src/libstd/primitive_docs.rs
index d31a5930376..2b92da6c684 100644
--- a/src/libstd/primitive_docs.rs
+++ b/src/libstd/primitive_docs.rs
@@ -27,7 +27,7 @@
 /// assert!(!bool_val);
 /// ```
 ///
-/// [`assert!`]: macro.assert!.html
+/// [`assert!`]: macro.assert.html
 /// [`if`]: ../book/if.html
 /// [`BitAnd`]: ops/trait.BitAnd.html
 /// [`BitOr`]: ops/trait.BitOr.html
diff --git a/src/libstd/sync/mpsc/mod.rs b/src/libstd/sync/mpsc/mod.rs
index 11f785dffd1..d8b8c6a77a2 100644
--- a/src/libstd/sync/mpsc/mod.rs
+++ b/src/libstd/sync/mpsc/mod.rs
@@ -394,13 +394,15 @@ pub enum TryRecvError {
 /// This enumeration is the list of possible errors that `recv_timeout` could
 /// not return data when called.
 #[derive(PartialEq, Eq, Clone, Copy, Debug)]
-#[unstable(feature = "mpsc_recv_timeout", issue = "34029")]
+#[stable(feature = "mpsc_recv_timeout", since = "1.12.0")]
 pub enum RecvTimeoutError {
     /// This channel is currently empty, but the sender(s) have not yet
     /// disconnected, so data may yet become available.
+    #[stable(feature = "mpsc_recv_timeout", since = "1.12.0")]
     Timeout,
     /// This channel's sending half has become disconnected, and there will
     /// never be any more data received on this channel
+    #[stable(feature = "mpsc_recv_timeout", since = "1.12.0")]
     Disconnected,
 }
 
@@ -912,8 +914,6 @@ impl<T> Receiver<T> {
     /// # Examples
     ///
     /// ```no_run
-    /// #![feature(mpsc_recv_timeout)]
-    ///
     /// use std::sync::mpsc::{self, RecvTimeoutError};
     /// use std::time::Duration;
     ///
@@ -922,7 +922,7 @@ impl<T> Receiver<T> {
     /// let timeout = Duration::from_millis(100);
     /// assert_eq!(Err(RecvTimeoutError::Timeout), recv.recv_timeout(timeout));
     /// ```
-    #[unstable(feature = "mpsc_recv_timeout", issue = "34029")]
+    #[stable(feature = "mpsc_recv_timeout", since = "1.12.0")]
     pub fn recv_timeout(&self, timeout: Duration) -> Result<T, RecvTimeoutError> {
         // Do an optimistic try_recv to avoid the performance impact of
         // Instant::now() in the full-channel case.
diff --git a/src/libstd/sys/unix/ext/process.rs b/src/libstd/sys/unix/ext/process.rs
index 430ec5f94a6..dd70ba2e490 100644
--- a/src/libstd/sys/unix/ext/process.rs
+++ b/src/libstd/sys/unix/ext/process.rs
@@ -114,7 +114,7 @@ impl CommandExt for process::Command {
 pub trait ExitStatusExt {
     /// Creates a new `ExitStatus` from the raw underlying `i32` return value of
     /// a process.
-    #[unstable(feature = "exit_status_from", issue = "32713")]
+    #[stable(feature = "exit_status_from", since = "1.12.0")]
     fn from_raw(raw: i32) -> Self;
 
     /// If the process was terminated by a signal, returns that signal.
diff --git a/src/libstd/sys/windows/ext/process.rs b/src/libstd/sys/windows/ext/process.rs
index 56c6a73d4f8..98166bf8cda 100644
--- a/src/libstd/sys/windows/ext/process.rs
+++ b/src/libstd/sys/windows/ext/process.rs
@@ -83,10 +83,11 @@ impl IntoRawHandle for process::ChildStderr {
 }
 
 /// Windows-specific extensions to `std::process::ExitStatus`
-#[unstable(feature = "exit_status_from", issue = "32713")]
+#[stable(feature = "exit_status_from", since = "1.12.0")]
 pub trait ExitStatusExt {
     /// Creates a new `ExitStatus` from the raw underlying `u32` return value of
     /// a process.
+    #[stable(feature = "exit_status_from", since = "1.12.0")]
     fn from_raw(raw: u32) -> Self;
 }
 
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 126e8816d05..9443df6321b 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -520,12 +520,21 @@ impl<'a> Parser<'a> {
                 self.bug("ident interpolation not converted to real token");
             }
             _ => {
-                let mut err = self.fatal(&format!("expected identifier, found `{}`",
-                                                  self.this_token_to_string()));
-                if self.token == token::Underscore {
-                    err.note("`_` is a wildcard pattern, not an identifier");
-                }
-                Err(err)
+                let last_token = self.last_token.clone().map(|t| *t);
+                Err(match last_token {
+                    Some(token::DocComment(_)) => self.span_fatal_help(self.last_span,
+                        "found a documentation comment that doesn't document anything",
+                        "doc comments must come before what they document, maybe a comment was \
+                        intended with `//`?"),
+                    _ => {
+                        let mut err = self.fatal(&format!("expected identifier, found `{}`",
+                                                          self.this_token_to_string()));
+                        if self.token == token::Underscore {
+                            err.note("`_` is a wildcard pattern, not an identifier");
+                        }
+                        err
+                    }
+                })
             }
         }
     }
@@ -927,6 +936,7 @@ impl<'a> Parser<'a> {
         // Stash token for error recovery (sometimes; clone is not necessarily cheap).
         self.last_token = if self.token.is_ident() ||
                           self.token.is_path() ||
+                          self.token.is_doc_comment() ||
                           self.token == token::Comma {
             Some(Box::new(self.token.clone()))
         } else {
@@ -1018,6 +1028,11 @@ impl<'a> Parser<'a> {
     pub fn span_err(&self, sp: Span, m: &str) {
         self.sess.span_diagnostic.span_err(sp, m)
     }
+    pub fn span_err_help(&self, sp: Span, m: &str, h: &str) {
+        let mut err = self.sess.span_diagnostic.mut_span_err(sp, m);
+        err.help(h);
+        err.emit();
+    }
     pub fn span_bug(&self, sp: Span, m: &str) -> ! {
         self.sess.span_diagnostic.span_bug(sp, m)
     }
@@ -4021,8 +4036,14 @@ impl<'a> Parser<'a> {
                 None => {
                     let unused_attrs = |attrs: &[_], s: &mut Self| {
                         if attrs.len() > 0 {
-                            s.span_err(s.span,
-                                "expected statement after outer attribute");
+                            let last_token = s.last_token.clone().map(|t| *t);
+                            match last_token {
+                                Some(token::DocComment(_)) => s.span_err_help(s.last_span,
+                                    "found a documentation comment that doesn't document anything",
+                                    "doc comments must come before what they document, maybe a \
+                                    comment was intended with `//`?"),
+                                _ => s.span_err(s.span, "expected statement after outer attribute"),
+                            }
                         }
                     };
 
@@ -5127,14 +5148,13 @@ impl<'a> Parser<'a> {
                 self.bump();
             }
             token::CloseDelim(token::Brace) => {}
-            _ => {
-                let span = self.span;
-                let token_str = self.this_token_to_string();
-                return Err(self.span_fatal_help(span,
-                                     &format!("expected `,`, or `}}`, found `{}`",
-                                             token_str),
-                                     "struct fields should be separated by commas"))
-            }
+            token::DocComment(_) => return Err(self.span_fatal_help(self.span,
+                        "found a documentation comment that doesn't document anything",
+                        "doc comments must come before what they document, maybe a comment was \
+                        intended with `//`?")),
+            _ => return Err(self.span_fatal_help(self.span,
+                    &format!("expected `,`, or `}}`, found `{}`", self.this_token_to_string()),
+                    "struct fields should be separated by commas")),
         }
         Ok(a_var)
     }
diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs
index 6fdc9b714d3..dc0fb02ea45 100644
--- a/src/libsyntax/parse/token.rs
+++ b/src/libsyntax/parse/token.rs
@@ -203,7 +203,7 @@ impl Token {
     pub fn is_lit(&self) -> bool {
         match *self {
             Literal(_, _) => true,
-            _          => false,
+            _             => false,
         }
     }
 
@@ -215,6 +215,14 @@ impl Token {
         }
     }
 
+    /// Returns `true` if the token is a documentation comment.
+    pub fn is_doc_comment(&self) -> bool {
+        match *self {
+            DocComment(..)   => true,
+            _                => false,
+        }
+    }
+
     /// Returns `true` if the token is interpolated.
     pub fn is_interpolated(&self) -> bool {
         match *self {
diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs
index 850127d9f29..2b4193306dd 100644
--- a/src/libtest/lib.rs
+++ b/src/libtest/lib.rs
@@ -42,7 +42,6 @@
 #![feature(staged_api)]
 #![feature(question_mark)]
 #![feature(panic_unwind)]
-#![feature(mpsc_recv_timeout)]
 
 extern crate getopts;
 extern crate term;
diff --git a/src/test/compile-fail/E0084.rs b/src/test/compile-fail/E0084.rs
index c579101325f..c7c5662f1fe 100644
--- a/src/test/compile-fail/E0084.rs
+++ b/src/test/compile-fail/E0084.rs
@@ -9,7 +9,9 @@
 // except according to those terms.
 
 #[repr(i32)]
-enum Foo {} //~ ERROR E0084
+enum Foo {}
+//~^ ERROR E0084
+//~| unsupported enum representation
 
 fn main() {
 }
diff --git a/src/test/compile-fail/E0133.rs b/src/test/compile-fail/E0133.rs
index b8a4476fc59..f60d9a5083f 100644
--- a/src/test/compile-fail/E0133.rs
+++ b/src/test/compile-fail/E0133.rs
@@ -13,5 +13,5 @@ unsafe fn f() { return; }
 fn main() {
     f();
     //~^ ERROR E0133
-    //~| NOTE unsafe call requires unsafe function or block
+    //~| NOTE call to unsafe function
 }
diff --git a/src/test/compile-fail/E0232.rs b/src/test/compile-fail/E0232.rs
index efeb869d71f..ce4f4638dac 100644
--- a/src/test/compile-fail/E0232.rs
+++ b/src/test/compile-fail/E0232.rs
@@ -10,7 +10,10 @@
 
 #![feature(on_unimplemented)]
 
-#[rustc_on_unimplemented] //~ ERROR E0232
+#[rustc_on_unimplemented]
+//~^ ERROR E0232
+//~| NOTE attribute requires a value
+//~| NOTE eg `#[rustc_on_unimplemented = "foo"]`
 trait Bar {}
 
 fn main() {
diff --git a/src/test/compile-fail/E0395.rs b/src/test/compile-fail/E0395.rs
index 6ab66313a04..98f08cd68c2 100644
--- a/src/test/compile-fail/E0395.rs
+++ b/src/test/compile-fail/E0395.rs
@@ -12,6 +12,6 @@ static FOO: i32 = 42;
 static BAR: i32 = 42;
 
 static BAZ: bool = { (&FOO as *const i32) == (&BAR as *const i32) }; //~ ERROR E0395
-
+                   //~| NOTE comparing raw pointers in static
 fn main() {
 }
diff --git a/src/test/compile-fail/E0396.rs b/src/test/compile-fail/E0396.rs
index 7f34acdfb90..47080fb6e9e 100644
--- a/src/test/compile-fail/E0396.rs
+++ b/src/test/compile-fail/E0396.rs
@@ -11,6 +11,7 @@
 const REG_ADDR: *const u8 = 0x5f3759df as *const u8;
 
 const VALUE: u8 = unsafe { *REG_ADDR }; //~ ERROR E0396
+                  //~| NOTE dereference of raw pointer in constant
 
 fn main() {
 }
diff --git a/src/test/compile-fail/E0428.rs b/src/test/compile-fail/E0428.rs
index 42e237d31cb..63b4efb73f0 100644
--- a/src/test/compile-fail/E0428.rs
+++ b/src/test/compile-fail/E0428.rs
@@ -8,9 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-struct Bar;
+struct Bar; //~ previous definition of `Bar` here
+            //~| previous definition of `Bar` here
 struct Bar; //~ ERROR E0428
-            //~^ ERROR E0428
+            //~| NOTE already defined
+            //~| ERROR E0428
+            //~| NOTE already defined
 
 fn main () {
 }
diff --git a/src/test/compile-fail/const-deref-ptr.rs b/src/test/compile-fail/const-deref-ptr.rs
index fa15f3e87c6..c626801d48c 100644
--- a/src/test/compile-fail/const-deref-ptr.rs
+++ b/src/test/compile-fail/const-deref-ptr.rs
@@ -12,5 +12,6 @@
 
 fn main() {
     static C: u64 = unsafe {*(0xdeadbeef as *const u64)}; //~ ERROR E0396
+                    //~| NOTE dereference of raw pointer in constant
     println!("{}", C);
 }
diff --git a/src/test/compile-fail/enum-and-module-in-same-scope.rs b/src/test/compile-fail/enum-and-module-in-same-scope.rs
index a6793ee8b9f..527ac7505a6 100644
--- a/src/test/compile-fail/enum-and-module-in-same-scope.rs
+++ b/src/test/compile-fail/enum-and-module-in-same-scope.rs
@@ -8,11 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-enum Foo { //~ NOTE previous definition
+enum Foo { //~ NOTE previous definition of `Foo` here
     X
 }
 
 mod Foo { //~ ERROR a type named `Foo` has already been defined
+          //~| NOTE already defined
     pub static X: isize = 42;
     fn f() { f() } // Check that this does not result in a resolution error
 }
diff --git a/src/test/compile-fail/issue-21546.rs b/src/test/compile-fail/issue-21546.rs
index 11d05ceb9a0..d103d45bc4c 100644
--- a/src/test/compile-fail/issue-21546.rs
+++ b/src/test/compile-fail/issue-21546.rs
@@ -17,6 +17,7 @@ mod Foo { }
 #[allow(dead_code)]
 struct Foo;
 //~^ ERROR a module named `Foo` has already been defined in this module
+//~| NOTE already defined
 
 #[allow(non_snake_case)]
 mod Bar { }
@@ -25,6 +26,7 @@ mod Bar { }
 #[allow(dead_code)]
 struct Bar(i32);
 //~^ ERROR a module named `Bar` has already been defined
+//~| NOTE already defined
 
 
 #[allow(dead_code)]
@@ -34,6 +36,7 @@ struct Baz(i32);
 #[allow(non_snake_case)]
 mod Baz { }
 //~^ ERROR a type named `Baz` has already been defined
+//~| NOTE already defined
 
 
 #[allow(dead_code)]
@@ -43,6 +46,7 @@ struct Qux { x: bool }
 #[allow(non_snake_case)]
 mod Qux { }
 //~^ ERROR a type named `Qux` has already been defined
+//~| NOTE already defined
 
 
 #[allow(dead_code)]
@@ -52,6 +56,7 @@ struct Quux;
 #[allow(non_snake_case)]
 mod Quux { }
 //~^ ERROR a type named `Quux` has already been defined
+//~| NOTE already defined
 
 
 #[allow(dead_code)]
@@ -61,5 +66,6 @@ enum Corge { A, B }
 #[allow(non_snake_case)]
 mod Corge { }
 //~^ ERROR a type named `Corge` has already been defined
+//~| NOTE already defined
 
 fn main() { }
diff --git a/src/test/compile-fail/issue-25826.rs b/src/test/compile-fail/issue-25826.rs
index 00e1279d58a..468282fa7cc 100644
--- a/src/test/compile-fail/issue-25826.rs
+++ b/src/test/compile-fail/issue-25826.rs
@@ -12,5 +12,6 @@ fn id<T>(t: T) -> T { t }
 fn main() {
     const A: bool = id::<u8> as *const () < id::<u16> as *const ();
     //~^ ERROR raw pointers cannot be compared in constants [E0395]
+    //~^^ NOTE comparing raw pointers in static
     println!("{}", A);
 }
diff --git a/src/test/compile-fail/issue-28776.rs b/src/test/compile-fail/issue-28776.rs
index 52b0eba96cb..4a36bc88fa7 100644
--- a/src/test/compile-fail/issue-28776.rs
+++ b/src/test/compile-fail/issue-28776.rs
@@ -13,5 +13,5 @@ use std::ptr;
 fn main() {
     (&ptr::write)(1 as *mut _, 42);
     //~^ ERROR E0133
-    //~| NOTE unsafe call requires unsafe function or block
+    //~| NOTE call to unsafe function
 }
diff --git a/src/test/compile-fail/trait-duplicate-methods.rs b/src/test/compile-fail/trait-duplicate-methods.rs
index 41700b25bbb..7bcab1f6ac5 100644
--- a/src/test/compile-fail/trait-duplicate-methods.rs
+++ b/src/test/compile-fail/trait-duplicate-methods.rs
@@ -11,6 +11,7 @@
 trait Foo {
     fn orange(&self); //~ NOTE previous definition of `orange` here
     fn orange(&self); //~ ERROR a value named `orange` has already been defined in this trait
+                      //~| NOTE already define
 }
 
 fn main() {}
diff --git a/src/test/compile-fail/trait-safety-fn-body.rs b/src/test/compile-fail/trait-safety-fn-body.rs
index 0df7ee8cabe..65732a8ff69 100644
--- a/src/test/compile-fail/trait-safety-fn-body.rs
+++ b/src/test/compile-fail/trait-safety-fn-body.rs
@@ -20,7 +20,7 @@ unsafe impl UnsafeTrait for *mut isize {
         // Unsafe actions are not made legal by taking place in an unsafe trait:
         *self += 1;
         //~^ ERROR E0133
-        //~| NOTE unsafe call requires unsafe function or block
+        //~| NOTE dereference of raw pointer
     }
 }
 
diff --git a/src/test/compile-fail/unsafe-const-fn.rs b/src/test/compile-fail/unsafe-const-fn.rs
index 174939b0900..91e16592be4 100644
--- a/src/test/compile-fail/unsafe-const-fn.rs
+++ b/src/test/compile-fail/unsafe-const-fn.rs
@@ -18,7 +18,7 @@ const unsafe fn dummy(v: u32) -> u32 {
 
 const VAL: u32 = dummy(0xFFFF);
 //~^ ERROR E0133
-//~| NOTE unsafe call requires unsafe function or block
+//~| NOTE call to unsafe function
 
 fn main() {
     assert_eq!(VAL, 0xFFFF0000);
diff --git a/src/test/parse-fail/doc-after-struct-field.rs b/src/test/parse-fail/doc-after-struct-field.rs
new file mode 100644
index 00000000000..1aa6af5b78f
--- /dev/null
+++ b/src/test/parse-fail/doc-after-struct-field.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.
+
+// compile-flags: -Z continue-parse-after-error
+struct X {
+    a: u8 /** document a */,
+    //~^ ERROR found a documentation comment that doesn't document anything
+    //~| HELP maybe a comment was intended
+}
+
+fn main() {
+    let y = X {a = 1};
+}
diff --git a/src/test/parse-fail/doc-before-extern-rbrace.rs b/src/test/parse-fail/doc-before-extern-rbrace.rs
index 9e825193dc0..70da47ba9b4 100644
--- a/src/test/parse-fail/doc-before-extern-rbrace.rs
+++ b/src/test/parse-fail/doc-before-extern-rbrace.rs
@@ -12,5 +12,5 @@
 
 extern {
     /// hi
+    //~^ ERROR expected item after doc comment
 }
-//~^^ ERROR expected item after doc comment
diff --git a/src/test/parse-fail/doc-before-fn-rbrace.rs b/src/test/parse-fail/doc-before-fn-rbrace.rs
new file mode 100644
index 00000000000..bcf32612c8f
--- /dev/null
+++ b/src/test/parse-fail/doc-before-fn-rbrace.rs
@@ -0,0 +1,16 @@
+// 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.
+
+// compile-flags: -Z continue-parse-after-error
+fn main() {
+    /// document
+    //~^ ERROR found a documentation comment that doesn't document anything
+    //~| HELP maybe a comment was intended
+}
diff --git a/src/test/parse-fail/doc-before-identifier.rs b/src/test/parse-fail/doc-before-identifier.rs
new file mode 100644
index 00000000000..8f1fad91b1f
--- /dev/null
+++ b/src/test/parse-fail/doc-before-identifier.rs
@@ -0,0 +1,18 @@
+// 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.
+
+// compile-flags: -Z continue-parse-after-error
+fn /// document
+foo() {}
+//~^^ ERROR expected identifier, found `/// document`
+
+fn main() {
+    foo();
+}
diff --git a/src/test/parse-fail/doc-before-mod-rbrace.rs b/src/test/parse-fail/doc-before-mod-rbrace.rs
new file mode 100644
index 00000000000..d38d1876384
--- /dev/null
+++ b/src/test/parse-fail/doc-before-mod-rbrace.rs
@@ -0,0 +1,15 @@
+// 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.
+
+// compile-flags: -Z continue-parse-after-error
+mod Foo {
+    /// document
+    //~^ ERROR expected item after doc comment
+}
diff --git a/src/test/parse-fail/doc-before-rbrace.rs b/src/test/parse-fail/doc-before-rbrace.rs
index 295d5ae432e..48ea2b5aea1 100644
--- a/src/test/parse-fail/doc-before-rbrace.rs
+++ b/src/test/parse-fail/doc-before-rbrace.rs
@@ -12,5 +12,6 @@
 
 fn main() {
     println!("Hi"); /// hi
+    //~^ ERROR found a documentation comment that doesn't document anything
+    //~| HELP maybe a comment was intended
 }
-//~^ ERROR expected statement
diff --git a/src/test/parse-fail/doc-before-semi.rs b/src/test/parse-fail/doc-before-semi.rs
index 6a8906953be..71104b8caae 100644
--- a/src/test/parse-fail/doc-before-semi.rs
+++ b/src/test/parse-fail/doc-before-semi.rs
@@ -12,6 +12,7 @@
 
 fn main() {
     /// hi
+    //~^ ERROR found a documentation comment that doesn't document anything
+    //~| HELP maybe a comment was intended
     ;
-    //~^ ERROR expected statement
 }
diff --git a/src/test/parse-fail/doc-before-struct-rbrace-1.rs b/src/test/parse-fail/doc-before-struct-rbrace-1.rs
new file mode 100644
index 00000000000..5ba83190c8e
--- /dev/null
+++ b/src/test/parse-fail/doc-before-struct-rbrace-1.rs
@@ -0,0 +1,21 @@
+// 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.
+
+// compile-flags: -Z continue-parse-after-error
+struct X {
+    a: u8,
+    /// document
+    //~^ ERROR found a documentation comment that doesn't document anything
+    //~| HELP maybe a comment was intended
+}
+
+fn main() {
+    let y = X {a = 1};
+}
diff --git a/src/test/parse-fail/doc-before-struct-rbrace-2.rs b/src/test/parse-fail/doc-before-struct-rbrace-2.rs
new file mode 100644
index 00000000000..643e4aa17a1
--- /dev/null
+++ b/src/test/parse-fail/doc-before-struct-rbrace-2.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.
+
+// compile-flags: -Z continue-parse-after-error
+struct X {
+    a: u8 /// document
+    //~^ ERROR found a documentation comment that doesn't document anything
+    //~| HELP maybe a comment was intended
+}
+
+fn main() {
+    let y = X {a = 1};
+}
diff --git a/src/test/rustdoc/issue-26606.rs b/src/test/rustdoc/issue-26606.rs
index df40c01686d..12de7665451 100644
--- a/src/test/rustdoc/issue-26606.rs
+++ b/src/test/rustdoc/issue-26606.rs
@@ -12,7 +12,7 @@
 // ignore-cross-compile
 // build-aux-docs
 
-// @has issue_26606_macro/macro.make_item!.html
+// @has issue_26606_macro/macro.make_item.html
 #[macro_use]
 extern crate issue_26606_macro;
 
diff --git a/src/test/rustdoc/macros.rs b/src/test/rustdoc/macros.rs
index b052ad2da2f..9aeeb71707c 100644
--- a/src/test/rustdoc/macros.rs
+++ b/src/test/rustdoc/macros.rs
@@ -8,10 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// @has macros/macro.my_macro!.html //pre 'macro_rules! my_macro {'
+// @has macros/macro.my_macro.html //pre 'macro_rules! my_macro {'
 // @has - //pre '() => { ... };'
 // @has - //pre '($a:tt) => { ... };'
 // @has - //pre '($e:expr) => { ... };'
+// @has macros/macro.my_macro!.html
+// @has - //a 'macro.my_macro.html'
 #[macro_export]
 macro_rules! my_macro {
     () => [];
diff --git a/src/tools/linkchecker/Cargo.lock b/src/tools/linkchecker/Cargo.lock
index ed5fe081ffb..d71df6d3f83 100644
--- a/src/tools/linkchecker/Cargo.lock
+++ b/src/tools/linkchecker/Cargo.lock
@@ -42,3 +42,9 @@ dependencies = [
  "matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
+[metadata]
+"checksum idna 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1053236e00ce4f668aeca4a769a09b3bf5a682d802abd6f3cb39374f6b162c11"
+"checksum matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "15305656809ce5a4805b1ff2946892810992197ce1270ff79baded852187942e"
+"checksum unicode-bidi 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c1f7ceb96afdfeedee42bade65a0d585a6a0106f681b6749c8ff4daa8df30b3f"
+"checksum unicode-normalization 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "26643a2f83bac55f1976fb716c10234485f9202dcd65cfbdf9da49867b271172"
+"checksum url 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "afe9ec54bc4db14bc8744b7fed060d785ac756791450959b2248443319d5b119"