about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2019-10-01 22:04:23 +0000
committerbors <bors@rust-lang.org>2019-10-01 22:04:23 +0000
commit7130fc54e05e247f93c7ecc2d10f56b314c97831 (patch)
tree978f8c357723da483f92ac6791f82f5f55172f74
parent702b45e409495a41afcccbe87a251a692b0cefab (diff)
parentadc0dc5871ac49543ae94827e7c4d411756e3d47 (diff)
downloadrust-7130fc54e05e247f93c7ecc2d10f56b314c97831.tar.gz
rust-7130fc54e05e247f93c7ecc2d10f56b314c97831.zip
Auto merge of #64972 - Centril:rollup-gcawast, r=Centril
Rollup of 7 pull requests

Successful merges:

 - #63416 (apfloat: improve doc comments)
 - #64820 (BTreeSet intersection, is_subset & difference optimizations)
 - #64910 (syntax: cleanup param, method, and misc parsing)
 - #64912 (Remove unneeded `fn main` blocks from docs)
 - #64933 (Fixes #64919. Suggest fix based on operator precendence.)
 - #64943 (Add lower bound doctests for `saturating_{add,sub}` signed ints)
 - #64950 (Simplify interners)

Failed merges:

r? @ghost
-rw-r--r--src/liballoc/boxed.rs54
-rw-r--r--src/liballoc/collections/btree/map.rs2
-rw-r--r--src/liballoc/collections/btree/set.rs230
-rw-r--r--src/liballoc/rc.rs8
-rw-r--r--src/liballoc/slice.rs11
-rw-r--r--src/liballoc/str.rs6
-rw-r--r--src/liballoc/string.rs6
-rw-r--r--src/liballoc/sync.rs8
-rw-r--r--src/liballoc/tests/btree/set.rs110
-rw-r--r--src/liballoc/vec.rs44
-rw-r--r--src/libcore/any.rs90
-rw-r--r--src/libcore/char/convert.rs16
-rw-r--r--src/libcore/char/decode.rs50
-rw-r--r--src/libcore/fmt/mod.rs10
-rw-r--r--src/libcore/num/mod.rs9
-rw-r--r--src/libcore/ptr/mod.rs48
-rw-r--r--src/librustc/ty/context.rs69
-rw-r--r--src/librustc_apfloat/lib.rs3
-rw-r--r--src/librustc_typeck/check/mod.rs7
-rw-r--r--src/libstd/collections/hash/map.rs11
-rw-r--r--src/libstd/collections/hash/set.rs8
-rw-r--r--src/libstd/net/addr.rs17
-rw-r--r--src/libstd/net/ip.rs237
-rw-r--r--src/libstd/primitive_docs.rs12
-rw-r--r--src/libsyntax/parse/diagnostics.rs2
-rw-r--r--src/libsyntax/parse/parser.rs655
-rw-r--r--src/libsyntax/parse/parser/item.rs393
-rw-r--r--src/libsyntax/parse/parser/ty.rs8
-rw-r--r--src/test/ui/async-await/edition-deny-async-fns-2015.stderr12
-rw-r--r--src/test/ui/conversion-methods.stderr2
-rw-r--r--src/test/ui/infinite/infinite-autoderef.stderr2
-rw-r--r--src/test/ui/mismatched_types/abridged.rs9
-rw-r--r--src/test/ui/mismatched_types/abridged.stderr30
-rw-r--r--src/test/ui/occurs-check-2.stderr2
-rw-r--r--src/test/ui/occurs-check.stderr2
-rw-r--r--src/test/ui/span/coerce-suggestions.stderr2
36 files changed, 1093 insertions, 1092 deletions
diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs
index c61e3183409..b2789a535fe 100644
--- a/src/liballoc/boxed.rs
+++ b/src/liballoc/boxed.rs
@@ -29,10 +29,8 @@
 //!     Nil,
 //! }
 //!
-//! fn main() {
-//!     let list: List<i32> = List::Cons(1, Box::new(List::Cons(2, Box::new(List::Nil))));
-//!     println!("{:?}", list);
-//! }
+//! let list: List<i32> = List::Cons(1, Box::new(List::Cons(2, Box::new(List::Nil))));
+//! println!("{:?}", list);
 //! ```
 //!
 //! This will print `Cons(1, Cons(2, Nil))`.
@@ -375,14 +373,12 @@ impl<T: ?Sized> Box<T> {
     /// ```
     /// #![feature(box_into_raw_non_null)]
     ///
-    /// fn main() {
-    ///     let x = Box::new(5);
-    ///     let ptr = Box::into_raw_non_null(x);
+    /// let x = Box::new(5);
+    /// let ptr = Box::into_raw_non_null(x);
     ///
-    ///     // Clean up the memory by converting the NonNull pointer back
-    ///     // into a Box and letting the Box be dropped.
-    ///     let x = unsafe { Box::from_raw(ptr.as_ptr()) };
-    /// }
+    /// // Clean up the memory by converting the NonNull pointer back
+    /// // into a Box and letting the Box be dropped.
+    /// let x = unsafe { Box::from_raw(ptr.as_ptr()) };
     /// ```
     #[unstable(feature = "box_into_raw_non_null", issue = "47336")]
     #[inline]
@@ -428,23 +424,19 @@ impl<T: ?Sized> Box<T> {
     /// Simple usage:
     ///
     /// ```
-    /// fn main() {
-    ///     let x = Box::new(41);
-    ///     let static_ref: &'static mut usize = Box::leak(x);
-    ///     *static_ref += 1;
-    ///     assert_eq!(*static_ref, 42);
-    /// }
+    /// let x = Box::new(41);
+    /// let static_ref: &'static mut usize = Box::leak(x);
+    /// *static_ref += 1;
+    /// assert_eq!(*static_ref, 42);
     /// ```
     ///
     /// Unsized data:
     ///
     /// ```
-    /// fn main() {
-    ///     let x = vec![1, 2, 3].into_boxed_slice();
-    ///     let static_ref = Box::leak(x);
-    ///     static_ref[0] = 4;
-    ///     assert_eq!(*static_ref, [4, 2, 3]);
-    /// }
+    /// let x = vec![1, 2, 3].into_boxed_slice();
+    /// let static_ref = Box::leak(x);
+    /// static_ref[0] = 4;
+    /// assert_eq!(*static_ref, [4, 2, 3]);
     /// ```
     #[stable(feature = "box_leak", since = "1.26.0")]
     #[inline]
@@ -780,11 +772,9 @@ impl Box<dyn Any> {
     ///     }
     /// }
     ///
-    /// fn main() {
-    ///     let my_string = "Hello World".to_string();
-    ///     print_if_string(Box::new(my_string));
-    ///     print_if_string(Box::new(0i8));
-    /// }
+    /// let my_string = "Hello World".to_string();
+    /// print_if_string(Box::new(my_string));
+    /// print_if_string(Box::new(0i8));
     /// ```
     pub fn downcast<T: Any>(self) -> Result<Box<T>, Box<dyn Any>> {
         if self.is::<T>() {
@@ -814,11 +804,9 @@ impl Box<dyn Any + Send> {
     ///     }
     /// }
     ///
-    /// fn main() {
-    ///     let my_string = "Hello World".to_string();
-    ///     print_if_string(Box::new(my_string));
-    ///     print_if_string(Box::new(0i8));
-    /// }
+    /// let my_string = "Hello World".to_string();
+    /// print_if_string(Box::new(my_string));
+    /// print_if_string(Box::new(0i8));
     /// ```
     pub fn downcast<T: Any>(self) -> Result<Box<T>, Box<dyn Any + Send>> {
         <Box<dyn Any>>::downcast(self).map_err(|s| unsafe {
diff --git a/src/liballoc/collections/btree/map.rs b/src/liballoc/collections/btree/map.rs
index ddf012d1502..83fd4485f73 100644
--- a/src/liballoc/collections/btree/map.rs
+++ b/src/liballoc/collections/btree/map.rs
@@ -2226,14 +2226,12 @@ impl<'a, K: Ord, V: Default> Entry<'a, K, V> {
     /// # Examples
     ///
     /// ```
-    /// # fn main() {
     /// use std::collections::BTreeMap;
     ///
     /// let mut map: BTreeMap<&str, Option<usize>> = BTreeMap::new();
     /// map.entry("poneyland").or_default();
     ///
     /// assert_eq!(map["poneyland"], None);
-    /// # }
     /// ```
     pub fn or_default(self) -> &'a mut V {
         match self {
diff --git a/src/liballoc/collections/btree/set.rs b/src/liballoc/collections/btree/set.rs
index 0cb91ba4c81..8250fc38ccd 100644
--- a/src/liballoc/collections/btree/set.rs
+++ b/src/liballoc/collections/btree/set.rs
@@ -122,13 +122,16 @@ pub struct Difference<'a, T: 'a> {
 }
 enum DifferenceInner<'a, T: 'a> {
     Stitch {
+        // iterate all of self and some of other, spotting matches along the way
         self_iter: Iter<'a, T>,
         other_iter: Peekable<Iter<'a, T>>,
     },
     Search {
+        // iterate a small set, look up in the large set
         self_iter: Iter<'a, T>,
         other_set: &'a BTreeSet<T>,
     },
+    Iterate(Iter<'a, T>), // simply stream self's elements
 }
 
 #[stable(feature = "collection_debug", since = "1.17.0")]
@@ -147,6 +150,7 @@ impl<T: fmt::Debug> fmt::Debug for Difference<'_, T> {
                 self_iter,
                 other_set: _,
             } => f.debug_tuple("Difference").field(&self_iter).finish(),
+            DifferenceInner::Iterate(iter) => f.debug_tuple("Difference").field(&iter).finish(),
         }
     }
 }
@@ -187,13 +191,16 @@ pub struct Intersection<'a, T: 'a> {
 }
 enum IntersectionInner<'a, T: 'a> {
     Stitch {
+        // iterate similarly sized sets jointly, spotting matches along the way
         a: Iter<'a, T>,
         b: Iter<'a, T>,
     },
     Search {
+        // iterate a small set, look up in the large set
         small_iter: Iter<'a, T>,
         large_set: &'a BTreeSet<T>,
     },
+    Answer(Option<&'a T>), // return a specific value or emptiness
 }
 
 #[stable(feature = "collection_debug", since = "1.17.0")]
@@ -212,6 +219,9 @@ impl<T: fmt::Debug> fmt::Debug for Intersection<'_, T> {
                 small_iter,
                 large_set: _,
             } => f.debug_tuple("Intersection").field(&small_iter).finish(),
+            IntersectionInner::Answer(answer) => {
+                f.debug_tuple("Intersection").field(&answer).finish()
+            }
         }
     }
 }
@@ -314,24 +324,51 @@ impl<T: Ord> BTreeSet<T> {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn difference<'a>(&'a self, other: &'a BTreeSet<T>) -> Difference<'a, T> {
-        if self.len() > other.len() / ITER_PERFORMANCE_TIPPING_SIZE_DIFF {
-            // Self is bigger than or not much smaller than other set.
-            // Iterate both sets jointly, spotting matches along the way.
-            Difference {
-                inner: DifferenceInner::Stitch {
-                    self_iter: self.iter(),
-                    other_iter: other.iter().peekable(),
-                },
-            }
+        let (self_min, self_max) = if let (Some(self_min), Some(self_max)) =
+            (self.iter().next(), self.iter().next_back())
+        {
+            (self_min, self_max)
         } else {
-            // Self is much smaller than other set, or both sets are empty.
-            // Iterate the small set, searching for matches in the large set.
-            Difference {
-                inner: DifferenceInner::Search {
-                    self_iter: self.iter(),
-                    other_set: other,
-                },
-            }
+            return Difference {
+                inner: DifferenceInner::Iterate(self.iter()),
+            };
+        };
+        let (other_min, other_max) = if let (Some(other_min), Some(other_max)) =
+            (other.iter().next(), other.iter().next_back())
+        {
+            (other_min, other_max)
+        } else {
+            return Difference {
+                inner: DifferenceInner::Iterate(self.iter()),
+            };
+        };
+        Difference {
+            inner: match (self_min.cmp(other_max), self_max.cmp(other_min)) {
+                (Greater, _) | (_, Less) => DifferenceInner::Iterate(self.iter()),
+                (Equal, _) => {
+                    let mut self_iter = self.iter();
+                    self_iter.next();
+                    DifferenceInner::Iterate(self_iter)
+                }
+                (_, Equal) => {
+                    let mut self_iter = self.iter();
+                    self_iter.next_back();
+                    DifferenceInner::Iterate(self_iter)
+                }
+                _ => {
+                    if self.len() <= other.len() / ITER_PERFORMANCE_TIPPING_SIZE_DIFF {
+                        DifferenceInner::Search {
+                            self_iter: self.iter(),
+                            other_set: other,
+                        }
+                    } else {
+                        DifferenceInner::Stitch {
+                            self_iter: self.iter(),
+                            other_iter: other.iter().peekable(),
+                        }
+                    }
+                }
+            },
         }
     }
 
@@ -387,29 +424,48 @@ impl<T: Ord> BTreeSet<T> {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn intersection<'a>(&'a self, other: &'a BTreeSet<T>) -> Intersection<'a, T> {
-        let (small, other) = if self.len() <= other.len() {
-            (self, other)
+        let (self_min, self_max) = if let (Some(self_min), Some(self_max)) =
+            (self.iter().next(), self.iter().next_back())
+        {
+            (self_min, self_max)
         } else {
-            (other, self)
+            return Intersection {
+                inner: IntersectionInner::Answer(None),
+            };
         };
-        if small.len() > other.len() / ITER_PERFORMANCE_TIPPING_SIZE_DIFF {
-            // Small set is not much smaller than other set.
-            // Iterate both sets jointly, spotting matches along the way.
-            Intersection {
-                inner: IntersectionInner::Stitch {
-                    a: small.iter(),
-                    b: other.iter(),
-                },
-            }
+        let (other_min, other_max) = if let (Some(other_min), Some(other_max)) =
+            (other.iter().next(), other.iter().next_back())
+        {
+            (other_min, other_max)
         } else {
-            // Big difference in number of elements, or both sets are empty.
-            // Iterate the small set, searching for matches in the large set.
-            Intersection {
-                inner: IntersectionInner::Search {
-                    small_iter: small.iter(),
-                    large_set: other,
-                },
-            }
+            return Intersection {
+                inner: IntersectionInner::Answer(None),
+            };
+        };
+        Intersection {
+            inner: match (self_min.cmp(other_max), self_max.cmp(other_min)) {
+                (Greater, _) | (_, Less) => IntersectionInner::Answer(None),
+                (Equal, _) => IntersectionInner::Answer(Some(self_min)),
+                (_, Equal) => IntersectionInner::Answer(Some(self_max)),
+                _ => {
+                    if self.len() <= other.len() / ITER_PERFORMANCE_TIPPING_SIZE_DIFF {
+                        IntersectionInner::Search {
+                            small_iter: self.iter(),
+                            large_set: other,
+                        }
+                    } else if other.len() <= self.len() / ITER_PERFORMANCE_TIPPING_SIZE_DIFF {
+                        IntersectionInner::Search {
+                            small_iter: other.iter(),
+                            large_set: self,
+                        }
+                    } else {
+                        IntersectionInner::Stitch {
+                            a: self.iter(),
+                            b: other.iter(),
+                        }
+                    }
+                }
+            },
         }
     }
 
@@ -544,43 +600,61 @@ impl<T: Ord> BTreeSet<T> {
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn is_subset(&self, other: &BTreeSet<T>) -> bool {
         // Same result as self.difference(other).next().is_none()
-        // but the 3 paths below are faster (in order: hugely, 20%, 5%).
+        // but the code below is faster (hugely in some cases).
         if self.len() > other.len() {
-            false
-        } else if self.len() > other.len() / ITER_PERFORMANCE_TIPPING_SIZE_DIFF {
-            // Self is not much smaller than other set.
-            // Stolen from TreeMap
-            let mut x = self.iter();
-            let mut y = other.iter();
-            let mut a = x.next();
-            let mut b = y.next();
-            while a.is_some() {
-                if b.is_none() {
+            return false;
+        }
+        let (self_min, self_max) = if let (Some(self_min), Some(self_max)) =
+            (self.iter().next(), self.iter().next_back())
+        {
+            (self_min, self_max)
+        } else {
+            return true; // self is empty
+        };
+        let (other_min, other_max) = if let (Some(other_min), Some(other_max)) =
+            (other.iter().next(), other.iter().next_back())
+        {
+            (other_min, other_max)
+        } else {
+            return false; // other is empty
+        };
+        let mut self_iter = self.iter();
+        match self_min.cmp(other_min) {
+            Less => return false,
+            Equal => {
+                self_iter.next();
+            }
+            Greater => (),
+        }
+        match self_max.cmp(other_max) {
+            Greater => return false,
+            Equal => {
+                self_iter.next_back();
+            }
+            Less => (),
+        }
+        if self_iter.len() <= other.len() / ITER_PERFORMANCE_TIPPING_SIZE_DIFF {
+            // Big difference in number of elements.
+            for next in self_iter {
+                if !other.contains(next) {
                     return false;
                 }
-
-                let a1 = a.unwrap();
-                let b1 = b.unwrap();
-
-                match b1.cmp(a1) {
-                    Less => (),
-                    Greater => return false,
-                    Equal => a = x.next(),
-                }
-
-                b = y.next();
             }
-            true
         } else {
-            // Big difference in number of elements, or both sets are empty.
-            // Iterate the small set, searching for matches in the large set.
-            for next in self {
-                if !other.contains(next) {
-                    return false;
+            // Self is not much smaller than other set.
+            let mut other_iter = other.iter();
+            other_iter.next();
+            other_iter.next_back();
+            let mut self_next = self_iter.next();
+            while let Some(self1) = self_next {
+                match other_iter.next().map_or(Less, |other1| self1.cmp(other1)) {
+                    Less => return false,
+                    Equal => self_next = self_iter.next(),
+                    Greater => (),
                 }
             }
-            true
         }
+        true
     }
 
     /// Returns `true` if the set is a superset of another,
@@ -1120,6 +1194,7 @@ impl<T> Clone for Difference<'_, T> {
                     self_iter: self_iter.clone(),
                     other_set,
                 },
+                DifferenceInner::Iterate(iter) => DifferenceInner::Iterate(iter.clone()),
             },
         }
     }
@@ -1138,7 +1213,7 @@ impl<'a, T: Ord> Iterator for Difference<'a, T> {
                 loop {
                     match other_iter
                         .peek()
-                        .map_or(Less, |other_next| Ord::cmp(self_next, other_next))
+                        .map_or(Less, |other_next| self_next.cmp(other_next))
                     {
                         Less => return Some(self_next),
                         Equal => {
@@ -1160,6 +1235,7 @@ impl<'a, T: Ord> Iterator for Difference<'a, T> {
                     return Some(self_next);
                 }
             },
+            DifferenceInner::Iterate(iter) => iter.next(),
         }
     }
 
@@ -1167,12 +1243,13 @@ impl<'a, T: Ord> Iterator for Difference<'a, T> {
         let (self_len, other_len) = match &self.inner {
             DifferenceInner::Stitch {
                 self_iter,
-                other_iter
+                other_iter,
             } => (self_iter.len(), other_iter.len()),
             DifferenceInner::Search {
                 self_iter,
-                other_set
+                other_set,
             } => (self_iter.len(), other_set.len()),
+            DifferenceInner::Iterate(iter) => (iter.len(), 0),
         };
         (self_len.saturating_sub(other_len), Some(self_len))
     }
@@ -1234,6 +1311,7 @@ impl<T> Clone for Intersection<'_, T> {
                     small_iter: small_iter.clone(),
                     large_set,
                 },
+                IntersectionInner::Answer(answer) => IntersectionInner::Answer(answer.clone()),
             },
         }
     }
@@ -1251,7 +1329,7 @@ impl<'a, T: Ord> Iterator for Intersection<'a, T> {
                 let mut a_next = a.next()?;
                 let mut b_next = b.next()?;
                 loop {
-                    match Ord::cmp(a_next, b_next) {
+                    match a_next.cmp(b_next) {
                         Less => a_next = a.next()?,
                         Greater => b_next = b.next()?,
                         Equal => return Some(a_next),
@@ -1267,15 +1345,17 @@ impl<'a, T: Ord> Iterator for Intersection<'a, T> {
                     return Some(small_next);
                 }
             },
+            IntersectionInner::Answer(answer) => answer.take(),
         }
     }
 
     fn size_hint(&self) -> (usize, Option<usize>) {
-        let min_len = match &self.inner {
-            IntersectionInner::Stitch { a, b } => min(a.len(), b.len()),
-            IntersectionInner::Search { small_iter, .. } => small_iter.len(),
-        };
-        (0, Some(min_len))
+        match &self.inner {
+            IntersectionInner::Stitch { a, b } => (0, Some(min(a.len(), b.len()))),
+            IntersectionInner::Search { small_iter, .. } => (0, Some(small_iter.len())),
+            IntersectionInner::Answer(None) => (0, Some(0)),
+            IntersectionInner::Answer(Some(_)) => (1, Some(1)),
+        }
     }
 }
 
diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs
index f234ac5ebe5..a28c6d22abb 100644
--- a/src/liballoc/rc.rs
+++ b/src/liballoc/rc.rs
@@ -861,11 +861,9 @@ impl Rc<dyn Any> {
     ///     }
     /// }
     ///
-    /// fn main() {
-    ///     let my_string = "Hello World".to_string();
-    ///     print_if_string(Rc::new(my_string));
-    ///     print_if_string(Rc::new(0i8));
-    /// }
+    /// let my_string = "Hello World".to_string();
+    /// print_if_string(Rc::new(my_string));
+    /// print_if_string(Rc::new(0i8));
     /// ```
     pub fn downcast<T: Any>(self) -> Result<Rc<T>, Rc<dyn Any>> {
         if (*self).is::<T>() {
diff --git a/src/liballoc/slice.rs b/src/liballoc/slice.rs
index 881d499c074..4e4a285c21d 100644
--- a/src/liballoc/slice.rs
+++ b/src/liballoc/slice.rs
@@ -412,20 +412,15 @@ impl<T> [T] {
     ///
     /// ```
     /// #![feature(repeat_generic_slice)]
-    ///
-    /// fn main() {
-    ///     assert_eq!([1, 2].repeat(3), vec![1, 2, 1, 2, 1, 2]);
-    /// }
+    /// assert_eq!([1, 2].repeat(3), vec![1, 2, 1, 2, 1, 2]);
     /// ```
     ///
     /// A panic upon overflow:
     ///
     /// ```should_panic
     /// #![feature(repeat_generic_slice)]
-    /// fn main() {
-    ///     // this will panic at runtime
-    ///     b"0123456789abcdef".repeat(usize::max_value());
-    /// }
+    /// // this will panic at runtime
+    /// b"0123456789abcdef".repeat(usize::max_value());
     /// ```
     #[unstable(feature = "repeat_generic_slice",
                reason = "it's on str, why not on slice?",
diff --git a/src/liballoc/str.rs b/src/liballoc/str.rs
index 9a1342c30d5..9231c2d3f1d 100644
--- a/src/liballoc/str.rs
+++ b/src/liballoc/str.rs
@@ -500,10 +500,8 @@ impl str {
     /// A panic upon overflow:
     ///
     /// ```should_panic
-    /// fn main() {
-    ///     // this will panic at runtime
-    ///     "0123456789abcdef".repeat(usize::max_value());
-    /// }
+    /// // this will panic at runtime
+    /// "0123456789abcdef".repeat(usize::max_value());
     /// ```
     #[stable(feature = "repeat_str", since = "1.16.0")]
     pub fn repeat(&self, n: usize) -> String {
diff --git a/src/liballoc/string.rs b/src/liballoc/string.rs
index abe50fdb7a3..639124e26cc 100644
--- a/src/liballoc/string.rs
+++ b/src/liballoc/string.rs
@@ -164,10 +164,8 @@ use crate::vec::Vec;
 ///
 /// fn example_func<A: TraitExample>(example_arg: A) {}
 ///
-/// fn main() {
-///     let example_string = String::from("example_string");
-///     example_func(&example_string);
-/// }
+/// let example_string = String::from("example_string");
+/// example_func(&example_string);
 /// ```
 ///
 /// There are two options that would work instead. The first would be to
diff --git a/src/liballoc/sync.rs b/src/liballoc/sync.rs
index 45f98162e4c..5977e69b7fa 100644
--- a/src/liballoc/sync.rs
+++ b/src/liballoc/sync.rs
@@ -1244,11 +1244,9 @@ impl Arc<dyn Any + Send + Sync> {
     ///     }
     /// }
     ///
-    /// fn main() {
-    ///     let my_string = "Hello World".to_string();
-    ///     print_if_string(Arc::new(my_string));
-    ///     print_if_string(Arc::new(0i8));
-    /// }
+    /// let my_string = "Hello World".to_string();
+    /// print_if_string(Arc::new(my_string));
+    /// print_if_string(Arc::new(0i8));
     /// ```
     pub fn downcast<T>(self) -> Result<Arc<T>, Self>
     where
diff --git a/src/liballoc/tests/btree/set.rs b/src/liballoc/tests/btree/set.rs
index 35db18c39c8..5c611fd21d2 100644
--- a/src/liballoc/tests/btree/set.rs
+++ b/src/liballoc/tests/btree/set.rs
@@ -48,7 +48,9 @@ fn check<F>(a: &[i32], b: &[i32], expected: &[i32], f: F)
     f(&set_a,
       &set_b,
       &mut |&x| {
-          assert_eq!(x, expected[i]);
+          if i < expected.len() {
+              assert_eq!(x, expected[i]);
+          }
           i += 1;
           true
       });
@@ -74,20 +76,20 @@ fn test_intersection() {
         return;
     }
 
-    let large = (0..1000).collect::<Vec<_>>();
+    let large = (0..100).collect::<Vec<_>>();
     check_intersection(&[], &large, &[]);
     check_intersection(&large, &[], &[]);
     check_intersection(&[-1], &large, &[]);
     check_intersection(&large, &[-1], &[]);
     check_intersection(&[0], &large, &[0]);
     check_intersection(&large, &[0], &[0]);
-    check_intersection(&[999], &large, &[999]);
-    check_intersection(&large, &[999], &[999]);
-    check_intersection(&[1000], &large, &[]);
-    check_intersection(&large, &[1000], &[]);
-    check_intersection(&[11, 5000, 1, 3, 77, 8924, 103],
+    check_intersection(&[99], &large, &[99]);
+    check_intersection(&large, &[99], &[99]);
+    check_intersection(&[100], &large, &[]);
+    check_intersection(&large, &[100], &[]);
+    check_intersection(&[11, 5000, 1, 3, 77, 8924],
                        &large,
-                       &[1, 3, 11, 77, 103]);
+                       &[1, 3, 11, 77]);
 }
 
 #[test]
@@ -95,10 +97,15 @@ fn test_intersection_size_hint() {
     let x: BTreeSet<i32> = [3, 4].iter().copied().collect();
     let y: BTreeSet<i32> = [1, 2, 3].iter().copied().collect();
     let mut iter = x.intersection(&y);
-    assert_eq!(iter.size_hint(), (0, Some(2)));
+    assert_eq!(iter.size_hint(), (1, Some(1)));
     assert_eq!(iter.next(), Some(&3));
     assert_eq!(iter.size_hint(), (0, Some(0)));
     assert_eq!(iter.next(), None);
+
+    iter = y.intersection(&y);
+    assert_eq!(iter.size_hint(), (0, Some(3)));
+    assert_eq!(iter.next(), Some(&1));
+    assert_eq!(iter.size_hint(), (0, Some(2)));
 }
 
 #[test]
@@ -111,6 +118,9 @@ fn test_difference() {
     check_difference(&[1, 12], &[], &[1, 12]);
     check_difference(&[], &[1, 2, 3, 9], &[]);
     check_difference(&[1, 3, 5, 9, 11], &[3, 9], &[1, 5, 11]);
+    check_difference(&[1, 3, 5, 9, 11], &[3, 6, 9], &[1, 5, 11]);
+    check_difference(&[1, 3, 5, 9, 11], &[0, 1], &[3, 5, 9, 11]);
+    check_difference(&[1, 3, 5, 9, 11], &[11, 12], &[1, 3, 5, 9]);
     check_difference(&[-5, 11, 22, 33, 40, 42],
                      &[-12, -5, 14, 23, 34, 38, 39, 50],
                      &[11, 22, 33, 40, 42]);
@@ -119,18 +129,82 @@ fn test_difference() {
         return;
     }
 
-    let large = (0..1000).collect::<Vec<_>>();
+    let large = (0..100).collect::<Vec<_>>();
     check_difference(&[], &large, &[]);
     check_difference(&[-1], &large, &[-1]);
     check_difference(&[0], &large, &[]);
-    check_difference(&[999], &large, &[]);
-    check_difference(&[1000], &large, &[1000]);
-    check_difference(&[11, 5000, 1, 3, 77, 8924, 103],
+    check_difference(&[99], &large, &[]);
+    check_difference(&[100], &large, &[100]);
+    check_difference(&[11, 5000, 1, 3, 77, 8924],
                      &large,
                      &[5000, 8924]);
     check_difference(&large, &[], &large);
     check_difference(&large, &[-1], &large);
-    check_difference(&large, &[1000], &large);
+    check_difference(&large, &[100], &large);
+}
+
+#[test]
+fn test_difference_size_hint() {
+    let s246: BTreeSet<i32> = [2, 4, 6].iter().copied().collect();
+    let s23456: BTreeSet<i32> = (2..=6).collect();
+    let mut iter = s246.difference(&s23456);
+    assert_eq!(iter.size_hint(), (0, Some(3)));
+    assert_eq!(iter.next(), None);
+
+    let s12345: BTreeSet<i32> = (1..=5).collect();
+    iter = s246.difference(&s12345);
+    assert_eq!(iter.size_hint(), (0, Some(3)));
+    assert_eq!(iter.next(), Some(&6));
+    assert_eq!(iter.size_hint(), (0, Some(0)));
+    assert_eq!(iter.next(), None);
+
+    let s34567: BTreeSet<i32> = (3..=7).collect();
+    iter = s246.difference(&s34567);
+    assert_eq!(iter.size_hint(), (0, Some(3)));
+    assert_eq!(iter.next(), Some(&2));
+    assert_eq!(iter.size_hint(), (0, Some(2)));
+    assert_eq!(iter.next(), None);
+
+    let s1: BTreeSet<i32> = (-9..=1).collect();
+    iter = s246.difference(&s1);
+    assert_eq!(iter.size_hint(), (3, Some(3)));
+
+    let s2: BTreeSet<i32> = (-9..=2).collect();
+    iter = s246.difference(&s2);
+    assert_eq!(iter.size_hint(), (2, Some(2)));
+    assert_eq!(iter.next(), Some(&4));
+    assert_eq!(iter.size_hint(), (1, Some(1)));
+
+    let s23: BTreeSet<i32> = (2..=3).collect();
+    iter = s246.difference(&s23);
+    assert_eq!(iter.size_hint(), (1, Some(3)));
+    assert_eq!(iter.next(), Some(&4));
+    assert_eq!(iter.size_hint(), (1, Some(1)));
+
+    let s4: BTreeSet<i32> = (4..=4).collect();
+    iter = s246.difference(&s4);
+    assert_eq!(iter.size_hint(), (2, Some(3)));
+    assert_eq!(iter.next(), Some(&2));
+    assert_eq!(iter.size_hint(), (1, Some(2)));
+    assert_eq!(iter.next(), Some(&6));
+    assert_eq!(iter.size_hint(), (0, Some(0)));
+    assert_eq!(iter.next(), None);
+
+    let s56: BTreeSet<i32> = (5..=6).collect();
+    iter = s246.difference(&s56);
+    assert_eq!(iter.size_hint(), (1, Some(3)));
+    assert_eq!(iter.next(), Some(&2));
+    assert_eq!(iter.size_hint(), (0, Some(2)));
+
+    let s6: BTreeSet<i32> = (6..=19).collect();
+    iter = s246.difference(&s6);
+    assert_eq!(iter.size_hint(), (2, Some(2)));
+    assert_eq!(iter.next(), Some(&2));
+    assert_eq!(iter.size_hint(), (1, Some(1)));
+
+    let s7: BTreeSet<i32> = (7..=19).collect();
+    iter = s246.difference(&s7);
+    assert_eq!(iter.size_hint(), (3, Some(3)));
 }
 
 #[test]
@@ -188,23 +262,23 @@ fn test_is_subset() {
     assert_eq!(is_subset(&[1, 2], &[1, 2]), true);
     assert_eq!(is_subset(&[1, 2], &[2, 3]), false);
     assert_eq!(is_subset(&[-5, 11, 22, 33, 40, 42],
-                         &[-12, -5, 14, 23, 11, 34, 22, 38, 33, 42, 39, 40]),
+                         &[-12, -5, 11, 14, 22, 23, 33, 34, 38, 39, 40, 42]),
                true);
     assert_eq!(is_subset(&[-5, 11, 22, 33, 40, 42],
-                         &[-12, -5, 14, 23, 34, 38, 22, 11]),
+                         &[-12, -5, 11, 14, 22, 23, 34, 38]),
                false);
 
     if cfg!(miri) { // Miri is too slow
         return;
     }
 
-    let large = (0..1000).collect::<Vec<_>>();
+    let large = (0..100).collect::<Vec<_>>();
     assert_eq!(is_subset(&[], &large), true);
     assert_eq!(is_subset(&large, &[]), false);
     assert_eq!(is_subset(&[-1], &large), false);
     assert_eq!(is_subset(&[0], &large), true);
     assert_eq!(is_subset(&[1, 2], &large), true);
-    assert_eq!(is_subset(&[999, 1000], &large), false);
+    assert_eq!(is_subset(&[99, 100], &large), false);
 }
 
 #[test]
diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs
index 7c6ded08bba..6350b189c5f 100644
--- a/src/liballoc/vec.rs
+++ b/src/liballoc/vec.rs
@@ -389,28 +389,26 @@ impl<T> Vec<T> {
     /// use std::ptr;
     /// use std::mem;
     ///
-    /// fn main() {
-    ///     let mut v = vec![1, 2, 3];
-    ///
-    ///     // Pull out the various important pieces of information about `v`
-    ///     let p = v.as_mut_ptr();
-    ///     let len = v.len();
-    ///     let cap = v.capacity();
+    /// let mut v = vec![1, 2, 3];
     ///
-    ///     unsafe {
-    ///         // Cast `v` into the void: no destructor run, so we are in
-    ///         // complete control of the allocation to which `p` points.
-    ///         mem::forget(v);
+    /// // Pull out the various important pieces of information about `v`
+    /// let p = v.as_mut_ptr();
+    /// let len = v.len();
+    /// let cap = v.capacity();
     ///
-    ///         // Overwrite memory with 4, 5, 6
-    ///         for i in 0..len as isize {
-    ///             ptr::write(p.offset(i), 4 + i);
-    ///         }
+    /// unsafe {
+    ///     // Cast `v` into the void: no destructor run, so we are in
+    ///     // complete control of the allocation to which `p` points.
+    ///     mem::forget(v);
     ///
-    ///         // Put everything back together into a Vec
-    ///         let rebuilt = Vec::from_raw_parts(p, len, cap);
-    ///         assert_eq!(rebuilt, [4, 5, 6]);
+    ///     // Overwrite memory with 4, 5, 6
+    ///     for i in 0..len as isize {
+    ///         ptr::write(p.offset(i), 4 + i);
     ///     }
+    ///
+    ///     // Put everything back together into a Vec
+    ///     let rebuilt = Vec::from_raw_parts(p, len, cap);
+    ///     assert_eq!(rebuilt, [4, 5, 6]);
     /// }
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -1391,12 +1389,10 @@ impl<T> Vec<T> {
     /// ```
     /// #![feature(vec_leak)]
     ///
-    /// fn main() {
-    ///     let x = vec![1, 2, 3];
-    ///     let static_ref: &'static mut [usize] = Vec::leak(x);
-    ///     static_ref[0] += 1;
-    ///     assert_eq!(static_ref, &[2, 2, 3]);
-    /// }
+    /// let x = vec![1, 2, 3];
+    /// let static_ref: &'static mut [usize] = Vec::leak(x);
+    /// static_ref[0] += 1;
+    /// assert_eq!(static_ref, &[2, 2, 3]);
     /// ```
     #[unstable(feature = "vec_leak", issue = "62195")]
     #[inline]
diff --git a/src/libcore/any.rs b/src/libcore/any.rs
index 0afbf4f1346..85b59162620 100644
--- a/src/libcore/any.rs
+++ b/src/libcore/any.rs
@@ -87,10 +87,8 @@ pub trait Any: 'static {
     ///     TypeId::of::<String>() == s.type_id()
     /// }
     ///
-    /// fn main() {
-    ///     assert_eq!(is_string(&0), false);
-    ///     assert_eq!(is_string(&"cookie monster".to_string()), true);
-    /// }
+    /// assert_eq!(is_string(&0), false);
+    /// assert_eq!(is_string(&"cookie monster".to_string()), true);
     /// ```
     #[stable(feature = "get_type_id", since = "1.34.0")]
     fn type_id(&self) -> TypeId;
@@ -145,10 +143,8 @@ impl dyn Any {
     ///     }
     /// }
     ///
-    /// fn main() {
-    ///     is_string(&0);
-    ///     is_string(&"cookie monster".to_string());
-    /// }
+    /// is_string(&0);
+    /// is_string(&"cookie monster".to_string());
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
@@ -179,10 +175,8 @@ impl dyn Any {
     ///     }
     /// }
     ///
-    /// fn main() {
-    ///     print_if_string(&0);
-    ///     print_if_string(&"cookie monster".to_string());
-    /// }
+    /// print_if_string(&0);
+    /// print_if_string(&"cookie monster".to_string());
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
@@ -210,16 +204,14 @@ impl dyn Any {
     ///     }
     /// }
     ///
-    /// fn main() {
-    ///     let mut x = 10u32;
-    ///     let mut s = "starlord".to_string();
+    /// let mut x = 10u32;
+    /// let mut s = "starlord".to_string();
     ///
-    ///     modify_if_u32(&mut x);
-    ///     modify_if_u32(&mut s);
+    /// modify_if_u32(&mut x);
+    /// modify_if_u32(&mut s);
     ///
-    ///     assert_eq!(x, 42);
-    ///     assert_eq!(&s, "starlord");
-    /// }
+    /// assert_eq!(x, 42);
+    /// assert_eq!(&s, "starlord");
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
@@ -250,10 +242,8 @@ impl dyn Any+Send {
     ///     }
     /// }
     ///
-    /// fn main() {
-    ///     is_string(&0);
-    ///     is_string(&"cookie monster".to_string());
-    /// }
+    /// is_string(&0);
+    /// is_string(&"cookie monster".to_string());
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
@@ -276,10 +266,8 @@ impl dyn Any+Send {
     ///     }
     /// }
     ///
-    /// fn main() {
-    ///     print_if_string(&0);
-    ///     print_if_string(&"cookie monster".to_string());
-    /// }
+    /// print_if_string(&0);
+    /// print_if_string(&"cookie monster".to_string());
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
@@ -300,16 +288,14 @@ impl dyn Any+Send {
     ///     }
     /// }
     ///
-    /// fn main() {
-    ///     let mut x = 10u32;
-    ///     let mut s = "starlord".to_string();
+    /// let mut x = 10u32;
+    /// let mut s = "starlord".to_string();
     ///
-    ///     modify_if_u32(&mut x);
-    ///     modify_if_u32(&mut s);
+    /// modify_if_u32(&mut x);
+    /// modify_if_u32(&mut s);
     ///
-    ///     assert_eq!(x, 42);
-    ///     assert_eq!(&s, "starlord");
-    /// }
+    /// assert_eq!(x, 42);
+    /// assert_eq!(&s, "starlord");
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
@@ -334,10 +320,8 @@ impl dyn Any+Send+Sync {
     ///     }
     /// }
     ///
-    /// fn main() {
-    ///     is_string(&0);
-    ///     is_string(&"cookie monster".to_string());
-    /// }
+    /// is_string(&0);
+    /// is_string(&"cookie monster".to_string());
     /// ```
     #[stable(feature = "any_send_sync_methods", since = "1.28.0")]
     #[inline]
@@ -360,10 +344,8 @@ impl dyn Any+Send+Sync {
     ///     }
     /// }
     ///
-    /// fn main() {
-    ///     print_if_string(&0);
-    ///     print_if_string(&"cookie monster".to_string());
-    /// }
+    /// print_if_string(&0);
+    /// print_if_string(&"cookie monster".to_string());
     /// ```
     #[stable(feature = "any_send_sync_methods", since = "1.28.0")]
     #[inline]
@@ -384,16 +366,14 @@ impl dyn Any+Send+Sync {
     ///     }
     /// }
     ///
-    /// fn main() {
-    ///     let mut x = 10u32;
-    ///     let mut s = "starlord".to_string();
+    /// let mut x = 10u32;
+    /// let mut s = "starlord".to_string();
     ///
-    ///     modify_if_u32(&mut x);
-    ///     modify_if_u32(&mut s);
+    /// modify_if_u32(&mut x);
+    /// modify_if_u32(&mut s);
     ///
-    ///     assert_eq!(x, 42);
-    ///     assert_eq!(&s, "starlord");
-    /// }
+    /// assert_eq!(x, 42);
+    /// assert_eq!(&s, "starlord");
     /// ```
     #[stable(feature = "any_send_sync_methods", since = "1.28.0")]
     #[inline]
@@ -437,10 +417,8 @@ impl TypeId {
     ///     TypeId::of::<String>() == TypeId::of::<T>()
     /// }
     ///
-    /// fn main() {
-    ///     assert_eq!(is_string(&0), false);
-    ///     assert_eq!(is_string(&"cookie monster".to_string()), true);
-    /// }
+    /// assert_eq!(is_string(&0), false);
+    /// assert_eq!(is_string(&"cookie monster".to_string()), true);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     #[rustc_const_unstable(feature="const_type_id")]
diff --git a/src/libcore/char/convert.rs b/src/libcore/char/convert.rs
index 0a870c67518..c456e14db12 100644
--- a/src/libcore/char/convert.rs
+++ b/src/libcore/char/convert.rs
@@ -111,11 +111,9 @@ impl From<char> for u32 {
     /// ```
     /// use std::mem;
     ///
-    /// fn main() {
-    ///     let c = 'c';
-    ///     let u = u32::from(c);
-    ///     assert!(4 == mem::size_of_val(&u))
-    /// }
+    /// let c = 'c';
+    /// let u = u32::from(c);
+    /// assert!(4 == mem::size_of_val(&u))
     /// ```
     #[inline]
     fn from(c: char) -> Self {
@@ -150,11 +148,9 @@ impl From<u8> for char {
     /// ```
     /// use std::mem;
     ///
-    /// fn main() {
-    ///     let u = 32 as u8;
-    ///     let c = char::from(u);
-    ///     assert!(4 == mem::size_of_val(&c))
-    /// }
+    /// let u = 32 as u8;
+    /// let c = char::from(u);
+    /// assert!(4 == mem::size_of_val(&c))
     /// ```
     #[inline]
     fn from(i: u8) -> Self {
diff --git a/src/libcore/char/decode.rs b/src/libcore/char/decode.rs
index 23059243c61..b71c9c2c40b 100644
--- a/src/libcore/char/decode.rs
+++ b/src/libcore/char/decode.rs
@@ -31,21 +31,23 @@ pub struct DecodeUtf16Error {
 /// ```
 /// use std::char::decode_utf16;
 ///
-/// fn main() {
-///     // 𝄞mus<invalid>ic<invalid>
-///     let v = [0xD834, 0xDD1E, 0x006d, 0x0075,
-///              0x0073, 0xDD1E, 0x0069, 0x0063,
-///              0xD834];
+/// // 𝄞mus<invalid>ic<invalid>
+/// let v = [
+///     0xD834, 0xDD1E, 0x006d, 0x0075, 0x0073, 0xDD1E, 0x0069, 0x0063, 0xD834,
+/// ];
 ///
-///     assert_eq!(decode_utf16(v.iter().cloned())
-///                            .map(|r| r.map_err(|e| e.unpaired_surrogate()))
-///                            .collect::<Vec<_>>(),
-///                vec![Ok('𝄞'),
-///                     Ok('m'), Ok('u'), Ok('s'),
-///                     Err(0xDD1E),
-///                     Ok('i'), Ok('c'),
-///                     Err(0xD834)]);
-/// }
+/// assert_eq!(
+///     decode_utf16(v.iter().cloned())
+///         .map(|r| r.map_err(|e| e.unpaired_surrogate()))
+///         .collect::<Vec<_>>(),
+///     vec![
+///         Ok('𝄞'),
+///         Ok('m'), Ok('u'), Ok('s'),
+///         Err(0xDD1E),
+///         Ok('i'), Ok('c'),
+///         Err(0xD834)
+///     ]
+/// );
 /// ```
 ///
 /// A lossy decoder can be obtained by replacing `Err` results with the replacement character:
@@ -53,17 +55,17 @@ pub struct DecodeUtf16Error {
 /// ```
 /// use std::char::{decode_utf16, REPLACEMENT_CHARACTER};
 ///
-/// fn main() {
-///     // 𝄞mus<invalid>ic<invalid>
-///     let v = [0xD834, 0xDD1E, 0x006d, 0x0075,
-///              0x0073, 0xDD1E, 0x0069, 0x0063,
-///              0xD834];
+/// // 𝄞mus<invalid>ic<invalid>
+/// let v = [
+///     0xD834, 0xDD1E, 0x006d, 0x0075, 0x0073, 0xDD1E, 0x0069, 0x0063, 0xD834,
+/// ];
 ///
-///     assert_eq!(decode_utf16(v.iter().cloned())
-///                    .map(|r| r.unwrap_or(REPLACEMENT_CHARACTER))
-///                    .collect::<String>(),
-///                "𝄞mus�ic�");
-/// }
+/// assert_eq!(
+///     decode_utf16(v.iter().cloned())
+///        .map(|r| r.unwrap_or(REPLACEMENT_CHARACTER))
+///        .collect::<String>(),
+///     "𝄞mus�ic�"
+/// );
 /// ```
 #[stable(feature = "decode_utf16", since = "1.9.0")]
 #[inline]
diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs
index aafa35873bb..5dfdd162306 100644
--- a/src/libcore/fmt/mod.rs
+++ b/src/libcore/fmt/mod.rs
@@ -1532,12 +1532,10 @@ impl<'a> Formatter<'a> {
     ///     }
     /// }
     ///
-    /// fn main() {
-    ///     assert_eq!(&format!("{:<}", Foo), "left");
-    ///     assert_eq!(&format!("{:>}", Foo), "right");
-    ///     assert_eq!(&format!("{:^}", Foo), "center");
-    ///     assert_eq!(&format!("{}", Foo), "into the void");
-    /// }
+    /// assert_eq!(&format!("{:<}", Foo), "left");
+    /// assert_eq!(&format!("{:>}", Foo), "right");
+    /// assert_eq!(&format!("{:^}", Foo), "center");
+    /// assert_eq!(&format!("{}", Foo), "into the void");
     /// ```
     #[stable(feature = "fmt_flags_align", since = "1.28.0")]
     pub fn align(&self) -> Option<Alignment> {
diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs
index 933a2a12473..83ffa8f8a84 100644
--- a/src/libcore/num/mod.rs
+++ b/src/libcore/num/mod.rs
@@ -938,7 +938,9 @@ Basic usage:
 ```
 ", $Feature, "assert_eq!(100", stringify!($SelfT), ".saturating_add(1), 101);
 assert_eq!(", stringify!($SelfT), "::max_value().saturating_add(100), ", stringify!($SelfT),
-"::max_value());",
+"::max_value());
+assert_eq!(", stringify!($SelfT), "::min_value().saturating_add(-1), ", stringify!($SelfT),
+"::min_value());",
 $EndFeature, "
 ```"),
 
@@ -952,7 +954,6 @@ $EndFeature, "
             }
         }
 
-
         doc_comment! {
             concat!("Saturating integer subtraction. Computes `self - rhs`, saturating at the
 numeric bounds instead of overflowing.
@@ -964,7 +965,9 @@ Basic usage:
 ```
 ", $Feature, "assert_eq!(100", stringify!($SelfT), ".saturating_sub(127), -27);
 assert_eq!(", stringify!($SelfT), "::min_value().saturating_sub(100), ", stringify!($SelfT),
-"::min_value());",
+"::min_value());
+assert_eq!(", stringify!($SelfT), "::max_value().saturating_sub(-1), ", stringify!($SelfT),
+"::max_value());",
 $EndFeature, "
 ```"),
             #[stable(feature = "rust1", since = "1.0.0")]
diff --git a/src/libcore/ptr/mod.rs b/src/libcore/ptr/mod.rs
index 13ccc9b252a..93391918595 100644
--- a/src/libcore/ptr/mod.rs
+++ b/src/libcore/ptr/mod.rs
@@ -2732,31 +2732,29 @@ impl<T: ?Sized> Eq for *mut T {}
 /// impl Trait for Wrapper {}
 /// impl Trait for i32 {}
 ///
-/// fn main() {
-///     let wrapper = Wrapper { member: 10 };
-///
-///     // Pointers have equal addresses.
-///     assert!(std::ptr::eq(
-///         &wrapper as *const Wrapper as *const u8,
-///         &wrapper.member as *const i32 as *const u8
-///     ));
-///
-///     // Objects have equal addresses, but `Trait` has different implementations.
-///     assert!(!std::ptr::eq(
-///         &wrapper as &dyn Trait,
-///         &wrapper.member as &dyn Trait,
-///     ));
-///     assert!(!std::ptr::eq(
-///         &wrapper as &dyn Trait as *const dyn Trait,
-///         &wrapper.member as &dyn Trait as *const dyn Trait,
-///     ));
-///
-///     // Converting the reference to a `*const u8` compares by address.
-///     assert!(std::ptr::eq(
-///         &wrapper as &dyn Trait as *const dyn Trait as *const u8,
-///         &wrapper.member as &dyn Trait as *const dyn Trait as *const u8,
-///     ));
-/// }
+/// let wrapper = Wrapper { member: 10 };
+///
+/// // Pointers have equal addresses.
+/// assert!(std::ptr::eq(
+///     &wrapper as *const Wrapper as *const u8,
+///     &wrapper.member as *const i32 as *const u8
+/// ));
+///
+/// // Objects have equal addresses, but `Trait` has different implementations.
+/// assert!(!std::ptr::eq(
+///     &wrapper as &dyn Trait,
+///     &wrapper.member as &dyn Trait,
+/// ));
+/// assert!(!std::ptr::eq(
+///     &wrapper as &dyn Trait as *const dyn Trait,
+///     &wrapper.member as &dyn Trait as *const dyn Trait,
+/// ));
+///
+/// // Converting the reference to a `*const u8` compares by address.
+/// assert!(std::ptr::eq(
+///     &wrapper as &dyn Trait as *const dyn Trait as *const u8,
+///     &wrapper.member as &dyn Trait as *const dyn Trait as *const u8,
+/// ));
 /// ```
 #[stable(feature = "ptr_eq", since = "1.17.0")]
 #[inline]
diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs
index ffe1a11e81a..87b9917f340 100644
--- a/src/librustc/ty/context.rs
+++ b/src/librustc/ty/context.rs
@@ -2189,44 +2189,29 @@ impl<'tcx> Borrow<[Goal<'tcx>]> for Interned<'tcx, List<Goal<'tcx>>> {
     }
 }
 
-macro_rules! intern_method {
-    ($lt_tcx:tt, $name:ident: $method:ident($alloc:ty,
-                                            $alloc_method:expr,
-                                            $alloc_to_key:expr) -> $ty:ty) => {
-        impl<$lt_tcx> TyCtxt<$lt_tcx> {
-            pub fn $method(self, v: $alloc) -> &$lt_tcx $ty {
-                let key = ($alloc_to_key)(&v);
-
-                self.interners.$name.intern_ref(key, || {
-                    Interned($alloc_method(&self.interners.arena, v))
-
-                }).0
-            }
-        }
-    }
-}
-
 macro_rules! direct_interners {
-    ($lt_tcx:tt, $($name:ident: $method:ident($ty:ty)),+) => {
-        $(impl<$lt_tcx> PartialEq for Interned<$lt_tcx, $ty> {
+    ($($name:ident: $method:ident($ty:ty)),+) => {
+        $(impl<'tcx> PartialEq for Interned<'tcx, $ty> {
             fn eq(&self, other: &Self) -> bool {
                 self.0 == other.0
             }
         }
 
-        impl<$lt_tcx> Eq for Interned<$lt_tcx, $ty> {}
+        impl<'tcx> Eq for Interned<'tcx, $ty> {}
 
-        impl<$lt_tcx> Hash for Interned<$lt_tcx, $ty> {
+        impl<'tcx> Hash for Interned<'tcx, $ty> {
             fn hash<H: Hasher>(&self, s: &mut H) {
                 self.0.hash(s)
             }
         }
 
-        intern_method!(
-            $lt_tcx,
-            $name: $method($ty,
-                           |a: &$lt_tcx SyncDroplessArena, v| -> &$lt_tcx $ty { a.alloc(v) },
-                           |x| x) -> $ty);)+
+        impl<'tcx> TyCtxt<'tcx> {
+            pub fn $method(self, v: $ty) -> &'tcx $ty {
+                self.interners.$name.intern_ref(&v, || {
+                    Interned(self.interners.arena.alloc(v))
+                }).0
+            }
+        })+
     }
 }
 
@@ -2234,7 +2219,7 @@ pub fn keep_local<'tcx, T: ty::TypeFoldable<'tcx>>(x: &T) -> bool {
     x.has_type_flags(ty::TypeFlags::KEEP_IN_LOCAL_TCX)
 }
 
-direct_interners!('tcx,
+direct_interners!(
     region: mk_region(RegionKind),
     goal: mk_goal(GoalKind<'tcx>),
     const_: mk_const(Const<'tcx>)
@@ -2242,37 +2227,27 @@ direct_interners!('tcx,
 
 macro_rules! slice_interners {
     ($($field:ident: $method:ident($ty:ty)),+) => (
-        $(intern_method!( 'tcx, $field: $method(
-            &[$ty],
-            |a, v| List::from_arena(a, v),
-            Deref::deref) -> List<$ty>);)+
+        $(impl<'tcx> TyCtxt<'tcx> {
+            pub fn $method(self, v: &[$ty]) -> &'tcx List<$ty> {
+                self.interners.$field.intern_ref(v, || {
+                    Interned(List::from_arena(&self.interners.arena, v))
+                }).0
+            }
+        })+
     );
 }
 
 slice_interners!(
-    existential_predicates: _intern_existential_predicates(ExistentialPredicate<'tcx>),
-    predicates: _intern_predicates(Predicate<'tcx>),
     type_list: _intern_type_list(Ty<'tcx>),
     substs: _intern_substs(GenericArg<'tcx>),
+    canonical_var_infos: _intern_canonical_var_infos(CanonicalVarInfo),
+    existential_predicates: _intern_existential_predicates(ExistentialPredicate<'tcx>),
+    predicates: _intern_predicates(Predicate<'tcx>),
     clauses: _intern_clauses(Clause<'tcx>),
     goal_list: _intern_goals(Goal<'tcx>),
     projs: _intern_projs(ProjectionKind)
 );
 
-// This isn't a perfect fit: `CanonicalVarInfo` slices are always
-// allocated in the global arena, so this `intern_method!` macro is
-// overly general. However, we just return `false` for the code that checks
-// whether they belong in the thread-local arena, so no harm done, and
-// seems better than open-coding the rest.
-intern_method! {
-    'tcx,
-    canonical_var_infos: _intern_canonical_var_infos(
-        &[CanonicalVarInfo],
-        |a, v| List::from_arena(a, v),
-        Deref::deref
-    ) -> List<CanonicalVarInfo>
-}
-
 impl<'tcx> TyCtxt<'tcx> {
     /// Given a `fn` type, returns an equivalent `unsafe fn` type;
     /// that is, a `fn` type that is equivalent in every way for being
diff --git a/src/librustc_apfloat/lib.rs b/src/librustc_apfloat/lib.rs
index 1190cea21ac..5efe4fda8cc 100644
--- a/src/librustc_apfloat/lib.rs
+++ b/src/librustc_apfloat/lib.rs
@@ -555,12 +555,13 @@ pub trait Float
     fn ilogb(self) -> ExpInt;
 
     /// Returns: self * 2<sup>exp</sup> for integral exponents.
+    /// Equivalent to C standard library function `ldexp`.
     fn scalbn_r(self, exp: ExpInt, round: Round) -> Self;
     fn scalbn(self, exp: ExpInt) -> Self {
         self.scalbn_r(exp, Round::NearestTiesToEven)
     }
 
-    /// Equivalent of C standard library function.
+    /// Equivalent to C standard library function with the same name.
     ///
     /// While the C standard says exp is an unspecified value for infinity and nan,
     /// this returns INT_MAX for infinities, and INT_MIN for NaNs (see `ilogb`).
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index be5723959fb..720d31310a1 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -128,6 +128,7 @@ use syntax::attr;
 use syntax::feature_gate::{GateIssue, emit_feature_err};
 use syntax::source_map::{DUMMY_SP, original_sp};
 use syntax::symbol::{kw, sym};
+use syntax::util::parser::ExprPrecedence;
 
 use std::cell::{Cell, RefCell, Ref, RefMut};
 use std::collections::hash_map::Entry;
@@ -4345,7 +4346,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                                 let max_len = receiver.rfind(".").unwrap();
                                 format!("{}{}", &receiver[..max_len], method_call)
                             } else {
-                                format!("{}{}", receiver, method_call)
+                                if expr.precedence().order() < ExprPrecedence::MethodCall.order() {
+                                    format!("({}){}", receiver, method_call)
+                                } else {
+                                    format!("{}{}", receiver, method_call)
+                                }
                             };
                             Some(if is_struct_pat_shorthand_field {
                                 format!("{}: {}", receiver, sugg)
diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs
index 69abbde9e6e..ff50051ef50 100644
--- a/src/libstd/collections/hash/map.rs
+++ b/src/libstd/collections/hash/map.rs
@@ -192,14 +192,9 @@ use crate::sys;
 /// ```
 /// use std::collections::HashMap;
 ///
-/// fn main() {
-///     let timber_resources: HashMap<&str, i32> =
-///     [("Norway", 100),
-///      ("Denmark", 50),
-///      ("Iceland", 10)]
-///      .iter().cloned().collect();
-///     // use the values stored in map
-/// }
+/// let timber_resources: HashMap<&str, i32> = [("Norway", 100), ("Denmark", 50), ("Iceland", 10)]
+///     .iter().cloned().collect();
+/// // use the values stored in map
 /// ```
 
 #[derive(Clone)]
diff --git a/src/libstd/collections/hash/set.rs b/src/libstd/collections/hash/set.rs
index 26db651ef89..092fb443468 100644
--- a/src/libstd/collections/hash/set.rs
+++ b/src/libstd/collections/hash/set.rs
@@ -93,11 +93,9 @@ use super::map::{self, HashMap, Keys, RandomState};
 /// ```
 /// use std::collections::HashSet;
 ///
-/// fn main() {
-///     let viking_names: HashSet<&'static str> =
-///         [ "Einar", "Olaf", "Harald" ].iter().cloned().collect();
-///     // use the values stored in the set
-/// }
+/// let viking_names: HashSet<&'static str> =
+///     [ "Einar", "Olaf", "Harald" ].iter().cloned().collect();
+/// // use the values stored in the set
 /// ```
 ///
 /// [`Cell`]: ../../std/cell/struct.Cell.html
diff --git a/src/libstd/net/addr.rs b/src/libstd/net/addr.rs
index ca86a175058..f9255b82fc8 100644
--- a/src/libstd/net/addr.rs
+++ b/src/libstd/net/addr.rs
@@ -217,11 +217,9 @@ impl SocketAddr {
     /// ```
     /// use std::net::{IpAddr, Ipv4Addr, SocketAddr};
     ///
-    /// fn main() {
-    ///     let socket = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8080);
-    ///     assert_eq!(socket.is_ipv4(), true);
-    ///     assert_eq!(socket.is_ipv6(), false);
-    /// }
+    /// let socket = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8080);
+    /// assert_eq!(socket.is_ipv4(), true);
+    /// assert_eq!(socket.is_ipv6(), false);
     /// ```
     #[stable(feature = "sockaddr_checker", since = "1.16.0")]
     pub fn is_ipv4(&self) -> bool {
@@ -244,12 +242,9 @@ impl SocketAddr {
     /// ```
     /// use std::net::{IpAddr, Ipv6Addr, SocketAddr};
     ///
-    /// fn main() {
-    ///     let socket = SocketAddr::new(
-    ///                      IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 65535, 0, 1)), 8080);
-    ///     assert_eq!(socket.is_ipv4(), false);
-    ///     assert_eq!(socket.is_ipv6(), true);
-    /// }
+    /// let socket = SocketAddr::new(IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 65535, 0, 1)), 8080);
+    /// assert_eq!(socket.is_ipv4(), false);
+    /// assert_eq!(socket.is_ipv6(), true);
     /// ```
     #[stable(feature = "sockaddr_checker", since = "1.16.0")]
     pub fn is_ipv6(&self) -> bool {
diff --git a/src/libstd/net/ip.rs b/src/libstd/net/ip.rs
index 6b504056e5f..70b68d13485 100644
--- a/src/libstd/net/ip.rs
+++ b/src/libstd/net/ip.rs
@@ -197,11 +197,8 @@ impl IpAddr {
     ///
     /// use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
     ///
-    /// fn main() {
-    ///     assert_eq!(IpAddr::V4(Ipv4Addr::new(80, 9, 12, 3)).is_global(), true);
-    ///     assert_eq!(IpAddr::V6(Ipv6Addr::new(0, 0, 0x1c9, 0, 0, 0xafc8, 0, 0x1)).is_global(),
-    ///                true);
-    /// }
+    /// assert_eq!(IpAddr::V4(Ipv4Addr::new(80, 9, 12, 3)).is_global(), true);
+    /// assert_eq!(IpAddr::V6(Ipv6Addr::new(0, 0, 0x1c9, 0, 0, 0xafc8, 0, 0x1)).is_global(), true);
     /// ```
     pub fn is_global(&self) -> bool {
         match self {
@@ -251,11 +248,11 @@ impl IpAddr {
     ///
     /// use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
     ///
-    /// fn main() {
-    ///     assert_eq!(IpAddr::V4(Ipv4Addr::new(203, 0, 113, 6)).is_documentation(), true);
-    ///     assert_eq!(IpAddr::V6(Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 0))
-    ///                       .is_documentation(), true);
-    /// }
+    /// assert_eq!(IpAddr::V4(Ipv4Addr::new(203, 0, 113, 6)).is_documentation(), true);
+    /// assert_eq!(
+    ///     IpAddr::V6(Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 0)).is_documentation(),
+    ///     true
+    /// );
     /// ```
     pub fn is_documentation(&self) -> bool {
         match self {
@@ -275,11 +272,8 @@ impl IpAddr {
     /// ```
     /// use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
     ///
-    /// fn main() {
-    ///     assert_eq!(IpAddr::V4(Ipv4Addr::new(203, 0, 113, 6)).is_ipv4(), true);
-    ///     assert_eq!(IpAddr::V6(Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 0)).is_ipv4(),
-    ///                false);
-    /// }
+    /// assert_eq!(IpAddr::V4(Ipv4Addr::new(203, 0, 113, 6)).is_ipv4(), true);
+    /// assert_eq!(IpAddr::V6(Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 0)).is_ipv4(), false);
     /// ```
     #[stable(feature = "ipaddr_checker", since = "1.16.0")]
     pub fn is_ipv4(&self) -> bool {
@@ -300,11 +294,8 @@ impl IpAddr {
     /// ```
     /// use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
     ///
-    /// fn main() {
-    ///     assert_eq!(IpAddr::V4(Ipv4Addr::new(203, 0, 113, 6)).is_ipv6(), false);
-    ///     assert_eq!(IpAddr::V6(Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 0)).is_ipv6(),
-    ///                true);
-    /// }
+    /// assert_eq!(IpAddr::V4(Ipv4Addr::new(203, 0, 113, 6)).is_ipv6(), false);
+    /// assert_eq!(IpAddr::V6(Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 0)).is_ipv6(), true);
     /// ```
     #[stable(feature = "ipaddr_checker", since = "1.16.0")]
     pub fn is_ipv6(&self) -> bool {
@@ -526,48 +517,46 @@ impl Ipv4Addr {
     ///
     /// use std::net::Ipv4Addr;
     ///
-    /// fn main() {
-    ///     // private addresses are not global
-    ///     assert_eq!(Ipv4Addr::new(10, 254, 0, 0).is_global(), false);
-    ///     assert_eq!(Ipv4Addr::new(192, 168, 10, 65).is_global(), false);
-    ///     assert_eq!(Ipv4Addr::new(172, 16, 10, 65).is_global(), false);
+    /// // private addresses are not global
+    /// assert_eq!(Ipv4Addr::new(10, 254, 0, 0).is_global(), false);
+    /// assert_eq!(Ipv4Addr::new(192, 168, 10, 65).is_global(), false);
+    /// assert_eq!(Ipv4Addr::new(172, 16, 10, 65).is_global(), false);
     ///
-    ///     // the 0.0.0.0/8 block is not global
-    ///     assert_eq!(Ipv4Addr::new(0, 1, 2, 3).is_global(), false);
-    ///     // in particular, the unspecified address is not global
-    ///     assert_eq!(Ipv4Addr::new(0, 0, 0, 0).is_global(), false);
+    /// // the 0.0.0.0/8 block is not global
+    /// assert_eq!(Ipv4Addr::new(0, 1, 2, 3).is_global(), false);
+    /// // in particular, the unspecified address is not global
+    /// assert_eq!(Ipv4Addr::new(0, 0, 0, 0).is_global(), false);
     ///
-    ///     // the loopback address is not global
-    ///     assert_eq!(Ipv4Addr::new(127, 0, 0, 1).is_global(), false);
+    /// // the loopback address is not global
+    /// assert_eq!(Ipv4Addr::new(127, 0, 0, 1).is_global(), false);
     ///
-    ///     // link local addresses are not global
-    ///     assert_eq!(Ipv4Addr::new(169, 254, 45, 1).is_global(), false);
+    /// // link local addresses are not global
+    /// assert_eq!(Ipv4Addr::new(169, 254, 45, 1).is_global(), false);
     ///
-    ///     // the broadcast address is not global
-    ///     assert_eq!(Ipv4Addr::new(255, 255, 255, 255).is_global(), false);
+    /// // the broadcast address is not global
+    /// assert_eq!(Ipv4Addr::new(255, 255, 255, 255).is_global(), false);
     ///
-    ///     // the broadcast address is not global
-    ///     assert_eq!(Ipv4Addr::new(192, 0, 2, 255).is_global(), false);
-    ///     assert_eq!(Ipv4Addr::new(198, 51, 100, 65).is_global(), false);
-    ///     assert_eq!(Ipv4Addr::new(203, 0, 113, 6).is_global(), false);
+    /// // the broadcast address is not global
+    /// assert_eq!(Ipv4Addr::new(192, 0, 2, 255).is_global(), false);
+    /// assert_eq!(Ipv4Addr::new(198, 51, 100, 65).is_global(), false);
+    /// assert_eq!(Ipv4Addr::new(203, 0, 113, 6).is_global(), false);
     ///
-    ///     // shared addresses are not global
-    ///     assert_eq!(Ipv4Addr::new(100, 100, 0, 0).is_global(), false);
+    /// // shared addresses are not global
+    /// assert_eq!(Ipv4Addr::new(100, 100, 0, 0).is_global(), false);
     ///
-    ///     // addresses reserved for protocol assignment are not global
-    ///     assert_eq!(Ipv4Addr::new(192, 0, 0, 0).is_global(), false);
-    ///     assert_eq!(Ipv4Addr::new(192, 0, 0, 255).is_global(), false);
+    /// // addresses reserved for protocol assignment are not global
+    /// assert_eq!(Ipv4Addr::new(192, 0, 0, 0).is_global(), false);
+    /// assert_eq!(Ipv4Addr::new(192, 0, 0, 255).is_global(), false);
     ///
-    ///     // addresses reserved for future use are not global
-    ///     assert_eq!(Ipv4Addr::new(250, 10, 20, 30).is_global(), false);
+    /// // addresses reserved for future use are not global
+    /// assert_eq!(Ipv4Addr::new(250, 10, 20, 30).is_global(), false);
     ///
-    ///     // addresses reserved for network devices benchmarking are not global
-    ///     assert_eq!(Ipv4Addr::new(198, 18, 0, 0).is_global(), false);
+    /// // addresses reserved for network devices benchmarking are not global
+    /// assert_eq!(Ipv4Addr::new(198, 18, 0, 0).is_global(), false);
     ///
-    ///     // All the other addresses are global
-    ///     assert_eq!(Ipv4Addr::new(1, 1, 1, 1).is_global(), true);
-    ///     assert_eq!(Ipv4Addr::new(80, 9, 12, 3).is_global(), true);
-    /// }
+    /// // All the other addresses are global
+    /// assert_eq!(Ipv4Addr::new(1, 1, 1, 1).is_global(), true);
+    /// assert_eq!(Ipv4Addr::new(80, 9, 12, 3).is_global(), true);
     /// ```
     pub fn is_global(&self) -> bool {
         // check if this address is 192.0.0.9 or 192.0.0.10. These addresses are the only two
@@ -600,11 +589,9 @@ impl Ipv4Addr {
     /// #![feature(ip)]
     /// use std::net::Ipv4Addr;
     ///
-    /// fn main() {
-    ///     assert_eq!(Ipv4Addr::new(100, 64, 0, 0).is_shared(), true);
-    ///     assert_eq!(Ipv4Addr::new(100, 127, 255, 255).is_shared(), true);
-    ///     assert_eq!(Ipv4Addr::new(100, 128, 0, 0).is_shared(), false);
-    /// }
+    /// assert_eq!(Ipv4Addr::new(100, 64, 0, 0).is_shared(), true);
+    /// assert_eq!(Ipv4Addr::new(100, 127, 255, 255).is_shared(), true);
+    /// assert_eq!(Ipv4Addr::new(100, 128, 0, 0).is_shared(), false);
     /// ```
     pub fn is_shared(&self) -> bool {
         self.octets()[0] == 100 && (self.octets()[1] & 0b1100_0000 == 0b0100_0000)
@@ -631,14 +618,12 @@ impl Ipv4Addr {
     /// #![feature(ip)]
     /// use std::net::Ipv4Addr;
     ///
-    /// fn main() {
-    ///     assert_eq!(Ipv4Addr::new(192, 0, 0, 0).is_ietf_protocol_assignment(), true);
-    ///     assert_eq!(Ipv4Addr::new(192, 0, 0, 8).is_ietf_protocol_assignment(), true);
-    ///     assert_eq!(Ipv4Addr::new(192, 0, 0, 9).is_ietf_protocol_assignment(), true);
-    ///     assert_eq!(Ipv4Addr::new(192, 0, 0, 255).is_ietf_protocol_assignment(), true);
-    ///     assert_eq!(Ipv4Addr::new(192, 0, 1, 0).is_ietf_protocol_assignment(), false);
-    ///     assert_eq!(Ipv4Addr::new(191, 255, 255, 255).is_ietf_protocol_assignment(), false);
-    /// }
+    /// assert_eq!(Ipv4Addr::new(192, 0, 0, 0).is_ietf_protocol_assignment(), true);
+    /// assert_eq!(Ipv4Addr::new(192, 0, 0, 8).is_ietf_protocol_assignment(), true);
+    /// assert_eq!(Ipv4Addr::new(192, 0, 0, 9).is_ietf_protocol_assignment(), true);
+    /// assert_eq!(Ipv4Addr::new(192, 0, 0, 255).is_ietf_protocol_assignment(), true);
+    /// assert_eq!(Ipv4Addr::new(192, 0, 1, 0).is_ietf_protocol_assignment(), false);
+    /// assert_eq!(Ipv4Addr::new(191, 255, 255, 255).is_ietf_protocol_assignment(), false);
     /// ```
     pub fn is_ietf_protocol_assignment(&self) -> bool {
         self.octets()[0] == 192 && self.octets()[1] == 0 && self.octets()[2] == 0
@@ -658,12 +643,10 @@ impl Ipv4Addr {
     /// #![feature(ip)]
     /// use std::net::Ipv4Addr;
     ///
-    /// fn main() {
-    ///     assert_eq!(Ipv4Addr::new(198, 17, 255, 255).is_benchmarking(), false);
-    ///     assert_eq!(Ipv4Addr::new(198, 18, 0, 0).is_benchmarking(), true);
-    ///     assert_eq!(Ipv4Addr::new(198, 19, 255, 255).is_benchmarking(), true);
-    ///     assert_eq!(Ipv4Addr::new(198, 20, 0, 0).is_benchmarking(), false);
-    /// }
+    /// assert_eq!(Ipv4Addr::new(198, 17, 255, 255).is_benchmarking(), false);
+    /// assert_eq!(Ipv4Addr::new(198, 18, 0, 0).is_benchmarking(), true);
+    /// assert_eq!(Ipv4Addr::new(198, 19, 255, 255).is_benchmarking(), true);
+    /// assert_eq!(Ipv4Addr::new(198, 20, 0, 0).is_benchmarking(), false);
     /// ```
     pub fn is_benchmarking(&self) -> bool {
         self.octets()[0] == 198 && (self.octets()[1] & 0xfe) == 18
@@ -690,15 +673,12 @@ impl Ipv4Addr {
     /// #![feature(ip)]
     /// use std::net::Ipv4Addr;
     ///
-    /// fn main() {
-    ///     assert_eq!(Ipv4Addr::new(240, 0, 0, 0).is_reserved(), true);
-    ///     assert_eq!(Ipv4Addr::new(255, 255, 255, 254).is_reserved(), true);
+    /// assert_eq!(Ipv4Addr::new(240, 0, 0, 0).is_reserved(), true);
+    /// assert_eq!(Ipv4Addr::new(255, 255, 255, 254).is_reserved(), true);
     ///
-    ///     assert_eq!(Ipv4Addr::new(239, 255, 255, 255).is_reserved(), false);
-    ///     // The broadcast address is not considered as reserved for future use by this
-    ///     // implementation
-    ///     assert_eq!(Ipv4Addr::new(255, 255, 255, 255).is_reserved(), false);
-    /// }
+    /// assert_eq!(Ipv4Addr::new(239, 255, 255, 255).is_reserved(), false);
+    /// // The broadcast address is not considered as reserved for future use by this implementation
+    /// assert_eq!(Ipv4Addr::new(255, 255, 255, 255).is_reserved(), false);
     /// ```
     pub fn is_reserved(&self) -> bool {
         self.octets()[0] & 240 == 240 && !self.is_broadcast()
@@ -788,8 +768,10 @@ impl Ipv4Addr {
     /// ```
     /// use std::net::{Ipv4Addr, Ipv6Addr};
     ///
-    /// assert_eq!(Ipv4Addr::new(192, 0, 2, 255).to_ipv6_compatible(),
-    ///            Ipv6Addr::new(0, 0, 0, 0, 0, 0, 49152, 767));
+    /// assert_eq!(
+    ///     Ipv4Addr::new(192, 0, 2, 255).to_ipv6_compatible(),
+    ///     Ipv6Addr::new(0, 0, 0, 0, 0, 0, 49152, 767)
+    /// );
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn to_ipv6_compatible(&self) -> Ipv6Addr {
@@ -1161,11 +1143,9 @@ impl Ipv6Addr {
     ///
     /// use std::net::Ipv6Addr;
     ///
-    /// fn main() {
-    ///     assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).is_global(), true);
-    ///     assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0x1).is_global(), false);
-    ///     assert_eq!(Ipv6Addr::new(0, 0, 0x1c9, 0, 0, 0xafc8, 0, 0x1).is_global(), true);
-    /// }
+    /// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).is_global(), true);
+    /// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0x1).is_global(), false);
+    /// assert_eq!(Ipv6Addr::new(0, 0, 0x1c9, 0, 0, 0xafc8, 0, 0x1).is_global(), true);
     /// ```
     pub fn is_global(&self) -> bool {
         match self.multicast_scope() {
@@ -1189,11 +1169,8 @@ impl Ipv6Addr {
     ///
     /// use std::net::Ipv6Addr;
     ///
-    /// fn main() {
-    ///     assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).is_unique_local(),
-    ///                false);
-    ///     assert_eq!(Ipv6Addr::new(0xfc02, 0, 0, 0, 0, 0, 0, 0).is_unique_local(), true);
-    /// }
+    /// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).is_unique_local(), false);
+    /// assert_eq!(Ipv6Addr::new(0xfc02, 0, 0, 0, 0, 0, 0, 0).is_unique_local(), true);
     /// ```
     pub fn is_unique_local(&self) -> bool {
         (self.segments()[0] & 0xfe00) == 0xfc00
@@ -1223,21 +1200,19 @@ impl Ipv6Addr {
     ///
     /// use std::net::Ipv6Addr;
     ///
-    /// fn main() {
-    ///     let ip = Ipv6Addr::new(0xfe80, 0, 0, 0, 0, 0, 0, 0);
-    ///     assert!(ip.is_unicast_link_local_strict());
+    /// let ip = Ipv6Addr::new(0xfe80, 0, 0, 0, 0, 0, 0, 0);
+    /// assert!(ip.is_unicast_link_local_strict());
     ///
-    ///     let ip = Ipv6Addr::new(0xfe80, 0, 0, 0, 0xffff, 0xffff, 0xffff, 0xffff);
-    ///     assert!(ip.is_unicast_link_local_strict());
+    /// let ip = Ipv6Addr::new(0xfe80, 0, 0, 0, 0xffff, 0xffff, 0xffff, 0xffff);
+    /// assert!(ip.is_unicast_link_local_strict());
     ///
-    ///     let ip = Ipv6Addr::new(0xfe80, 0, 0, 1, 0, 0, 0, 0);
-    ///     assert!(!ip.is_unicast_link_local_strict());
-    ///     assert!(ip.is_unicast_link_local());
+    /// let ip = Ipv6Addr::new(0xfe80, 0, 0, 1, 0, 0, 0, 0);
+    /// assert!(!ip.is_unicast_link_local_strict());
+    /// assert!(ip.is_unicast_link_local());
     ///
-    ///     let ip = Ipv6Addr::new(0xfe81, 0, 0, 0, 0, 0, 0, 0);
-    ///     assert!(!ip.is_unicast_link_local_strict());
-    ///     assert!(ip.is_unicast_link_local());
-    /// }
+    /// let ip = Ipv6Addr::new(0xfe81, 0, 0, 0, 0, 0, 0, 0);
+    /// assert!(!ip.is_unicast_link_local_strict());
+    /// assert!(ip.is_unicast_link_local());
     /// ```
     ///
     /// # See also
@@ -1284,21 +1259,19 @@ impl Ipv6Addr {
     ///
     /// use std::net::Ipv6Addr;
     ///
-    /// fn main() {
-    ///     let ip = Ipv6Addr::new(0xfe80, 0, 0, 0, 0, 0, 0, 0);
-    ///     assert!(ip.is_unicast_link_local());
+    /// let ip = Ipv6Addr::new(0xfe80, 0, 0, 0, 0, 0, 0, 0);
+    /// assert!(ip.is_unicast_link_local());
     ///
-    ///     let ip = Ipv6Addr::new(0xfe80, 0, 0, 0, 0xffff, 0xffff, 0xffff, 0xffff);
-    ///     assert!(ip.is_unicast_link_local());
+    /// let ip = Ipv6Addr::new(0xfe80, 0, 0, 0, 0xffff, 0xffff, 0xffff, 0xffff);
+    /// assert!(ip.is_unicast_link_local());
     ///
-    ///     let ip = Ipv6Addr::new(0xfe80, 0, 0, 1, 0, 0, 0, 0);
-    ///     assert!(ip.is_unicast_link_local());
-    ///     assert!(!ip.is_unicast_link_local_strict());
+    /// let ip = Ipv6Addr::new(0xfe80, 0, 0, 1, 0, 0, 0, 0);
+    /// assert!(ip.is_unicast_link_local());
+    /// assert!(!ip.is_unicast_link_local_strict());
     ///
-    ///     let ip = Ipv6Addr::new(0xfe81, 0, 0, 0, 0, 0, 0, 0);
-    ///     assert!(ip.is_unicast_link_local());
-    ///     assert!(!ip.is_unicast_link_local_strict());
-    /// }
+    /// let ip = Ipv6Addr::new(0xfe81, 0, 0, 0, 0, 0, 0, 0);
+    /// assert!(ip.is_unicast_link_local());
+    /// assert!(!ip.is_unicast_link_local_strict());
     /// ```
     ///
     /// # See also
@@ -1336,11 +1309,11 @@ impl Ipv6Addr {
     ///
     /// use std::net::Ipv6Addr;
     ///
-    /// fn main() {
-    ///     assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).is_unicast_site_local(),
-    ///                false);
-    ///     assert_eq!(Ipv6Addr::new(0xfec2, 0, 0, 0, 0, 0, 0, 0).is_unicast_site_local(), true);
-    /// }
+    /// assert_eq!(
+    ///     Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).is_unicast_site_local(),
+    ///     false
+    /// );
+    /// assert_eq!(Ipv6Addr::new(0xfec2, 0, 0, 0, 0, 0, 0, 0).is_unicast_site_local(), true);
     /// ```
     ///
     /// # Warning
@@ -1369,11 +1342,8 @@ impl Ipv6Addr {
     ///
     /// use std::net::Ipv6Addr;
     ///
-    /// fn main() {
-    ///     assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).is_documentation(),
-    ///                false);
-    ///     assert_eq!(Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 0).is_documentation(), true);
-    /// }
+    /// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).is_documentation(), false);
+    /// assert_eq!(Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 0).is_documentation(), true);
     /// ```
     pub fn is_documentation(&self) -> bool {
         (self.segments()[0] == 0x2001) && (self.segments()[1] == 0xdb8)
@@ -1407,11 +1377,8 @@ impl Ipv6Addr {
     ///
     /// use std::net::Ipv6Addr;
     ///
-    /// fn main() {
-    ///     assert_eq!(Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 0).is_unicast_global(), false);
-    ///     assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).is_unicast_global(),
-    ///                true);
-    /// }
+    /// assert_eq!(Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 0).is_unicast_global(), false);
+    /// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).is_unicast_global(), true);
     /// ```
     pub fn is_unicast_global(&self) -> bool {
         !self.is_multicast()
@@ -1431,11 +1398,11 @@ impl Ipv6Addr {
     ///
     /// use std::net::{Ipv6Addr, Ipv6MulticastScope};
     ///
-    /// fn main() {
-    ///     assert_eq!(Ipv6Addr::new(0xff0e, 0, 0, 0, 0, 0, 0, 0).multicast_scope(),
-    ///                              Some(Ipv6MulticastScope::Global));
-    ///     assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).multicast_scope(), None);
-    /// }
+    /// assert_eq!(
+    ///     Ipv6Addr::new(0xff0e, 0, 0, 0, 0, 0, 0, 0).multicast_scope(),
+    ///     Some(Ipv6MulticastScope::Global)
+    /// );
+    /// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).multicast_scope(), None);
     /// ```
     pub fn multicast_scope(&self) -> Option<Ipv6MulticastScope> {
         if self.is_multicast() {
diff --git a/src/libstd/primitive_docs.rs b/src/libstd/primitive_docs.rs
index 3e389c40fbc..a72951c0346 100644
--- a/src/libstd/primitive_docs.rs
+++ b/src/libstd/primitive_docs.rs
@@ -426,14 +426,12 @@ mod prim_unit { }
 ///
 /// use std::mem;
 ///
-/// fn main() {
-///     unsafe {
-///         let my_num: *mut i32 = libc::malloc(mem::size_of::<i32>()) as *mut i32;
-///         if my_num.is_null() {
-///             panic!("failed to allocate memory");
-///         }
-///         libc::free(my_num as *mut libc::c_void);
+/// unsafe {
+///     let my_num: *mut i32 = libc::malloc(mem::size_of::<i32>()) as *mut i32;
+///     if my_num.is_null() {
+///         panic!("failed to allocate memory");
 ///     }
+///     libc::free(my_num as *mut libc::c_void);
 /// }
 /// ```
 ///
diff --git a/src/libsyntax/parse/diagnostics.rs b/src/libsyntax/parse/diagnostics.rs
index ec5d00e0952..e8d7b7663ed 100644
--- a/src/libsyntax/parse/diagnostics.rs
+++ b/src/libsyntax/parse/diagnostics.rs
@@ -1180,7 +1180,7 @@ impl<'a> Parser<'a> {
         }
     }
 
-    crate fn expected_semi_or_open_brace(&mut self) -> PResult<'a, ast::TraitItem> {
+    crate fn expected_semi_or_open_brace<T>(&mut self) -> PResult<'a, T> {
         let token_str = self.this_token_descr();
         let mut err = self.fatal(&format!("expected `;` or `{{`, found {}", token_str));
         err.span_label(self.token.span, "expected `;` or `{`");
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 2fb6f197dad..95f84d5cb33 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -511,13 +511,15 @@ impl<'a> Parser<'a> {
         is_present
     }
 
+    /// If the next token is the given keyword, returns `true` without eating it.
+    /// An expectation is also added for diagnostics purposes.
     fn check_keyword(&mut self, kw: Symbol) -> bool {
         self.expected_tokens.push(TokenType::Keyword(kw));
         self.token.is_keyword(kw)
     }
 
-    /// If the next token is the given keyword, eats it and returns
-    /// `true`. Otherwise, returns `false`.
+    /// If the next token is the given keyword, eats it and returns `true`.
+    /// Otherwise, returns `false`. An expectation is also added for diagnostics purposes.
     pub fn eat_keyword(&mut self, kw: Symbol) -> bool {
         if self.check_keyword(kw) {
             self.bump();
@@ -547,40 +549,38 @@ impl<'a> Parser<'a> {
         }
     }
 
-    crate fn check_ident(&mut self) -> bool {
-        if self.token.is_ident() {
+    fn check_or_expected(&mut self, ok: bool, typ: TokenType) -> bool {
+        if ok {
             true
         } else {
-            self.expected_tokens.push(TokenType::Ident);
+            self.expected_tokens.push(typ);
             false
         }
     }
 
+    crate fn check_ident(&mut self) -> bool {
+        self.check_or_expected(self.token.is_ident(), TokenType::Ident)
+    }
+
     fn check_path(&mut self) -> bool {
-        if self.token.is_path_start() {
-            true
-        } else {
-            self.expected_tokens.push(TokenType::Path);
-            false
-        }
+        self.check_or_expected(self.token.is_path_start(), TokenType::Path)
     }
 
     fn check_type(&mut self) -> bool {
-        if self.token.can_begin_type() {
-            true
-        } else {
-            self.expected_tokens.push(TokenType::Type);
-            false
-        }
+        self.check_or_expected(self.token.can_begin_type(), TokenType::Type)
     }
 
     fn check_const_arg(&mut self) -> bool {
-        if self.token.can_begin_const_arg() {
-            true
-        } else {
-            self.expected_tokens.push(TokenType::Const);
-            false
-        }
+        self.check_or_expected(self.token.can_begin_const_arg(), TokenType::Const)
+    }
+
+    /// Checks to see if the next token is either `+` or `+=`.
+    /// Otherwise returns `false`.
+    fn check_plus(&mut self) -> bool {
+        self.check_or_expected(
+            self.token.is_like_plus(),
+            TokenType::Token(token::BinOp(token::Plus)),
+        )
     }
 
     /// Expects and consumes a `+`. if `+=` is seen, replaces it with a `=`
@@ -604,18 +604,6 @@ impl<'a> Parser<'a> {
         }
     }
 
-    /// Checks to see if the next token is either `+` or `+=`.
-    /// Otherwise returns `false`.
-    fn check_plus(&mut self) -> bool {
-        if self.token.is_like_plus() {
-            true
-        }
-        else {
-            self.expected_tokens.push(TokenType::Token(token::BinOp(token::Plus)));
-            false
-        }
-    }
-
     /// Expects and consumes an `&`. If `&&` is seen, replaces it with a single
     /// `&` and continues. If an `&` is not seen, signals an error.
     fn expect_and(&mut self) -> PResult<'a, ()> {
@@ -910,15 +898,15 @@ impl<'a> Parser<'a> {
         self.expected_tokens.clear();
     }
 
-    pub fn look_ahead<R, F>(&self, dist: usize, f: F) -> R where
-        F: FnOnce(&Token) -> R,
-    {
+    /// Look-ahead `dist` tokens of `self.token` and get access to that token there.
+    /// When `dist == 0` then the current token is looked at.
+    pub fn look_ahead<R>(&self, dist: usize, looker: impl FnOnce(&Token) -> R) -> R {
         if dist == 0 {
-            return f(&self.token);
+            return looker(&self.token);
         }
 
         let frame = &self.token_cursor.frame;
-        f(&match frame.tree_cursor.look_ahead(dist - 1) {
+        looker(&match frame.tree_cursor.look_ahead(dist - 1) {
             Some(tree) => match tree {
                 TokenTree::Token(token) => token,
                 TokenTree::Delimited(dspan, delim, _) =>
@@ -954,109 +942,6 @@ impl<'a> Parser<'a> {
         }
     }
 
-    fn is_named_argument(&self) -> bool {
-        let offset = match self.token.kind {
-            token::Interpolated(ref nt) => match **nt {
-                token::NtPat(..) => return self.look_ahead(1, |t| t == &token::Colon),
-                _ => 0,
-            }
-            token::BinOp(token::And) | token::AndAnd => 1,
-            _ if self.token.is_keyword(kw::Mut) => 1,
-            _ => 0,
-        };
-
-        self.look_ahead(offset, |t| t.is_ident()) &&
-        self.look_ahead(offset + 1, |t| t == &token::Colon)
-    }
-
-    /// Skips unexpected attributes and doc comments in this position and emits an appropriate
-    /// error.
-    /// This version of parse param doesn't necessarily require identifier names.
-    fn parse_param_general(
-        &mut self,
-        is_self_allowed: bool,
-        is_trait_item: bool,
-        allow_c_variadic: bool,
-        is_name_required: impl Fn(&token::Token) -> bool,
-    ) -> PResult<'a, Param> {
-        let lo = self.token.span;
-        let attrs = self.parse_outer_attributes()?;
-
-        // Possibly parse `self`. Recover if we parsed it and it wasn't allowed here.
-        if let Some(mut param) = self.parse_self_param()? {
-            param.attrs = attrs.into();
-            return if is_self_allowed {
-                Ok(param)
-            } else {
-                self.recover_bad_self_param(param, is_trait_item)
-            };
-        }
-
-        let is_name_required = is_name_required(&self.token);
-        let (pat, ty) = if is_name_required || self.is_named_argument() {
-            debug!("parse_param_general parse_pat (is_name_required:{})", is_name_required);
-
-            let pat = self.parse_fn_param_pat()?;
-            if let Err(mut err) = self.expect(&token::Colon) {
-                if let Some(ident) = self.parameter_without_type(
-                    &mut err,
-                    pat,
-                    is_name_required,
-                    is_trait_item,
-                ) {
-                    err.emit();
-                    return Ok(dummy_arg(ident));
-                } else {
-                    return Err(err);
-                }
-            }
-
-            self.eat_incorrect_doc_comment_for_param_type();
-            (pat, self.parse_ty_common(true, true, allow_c_variadic)?)
-        } else {
-            debug!("parse_param_general ident_to_pat");
-            let parser_snapshot_before_ty = self.clone();
-            self.eat_incorrect_doc_comment_for_param_type();
-            let mut ty = self.parse_ty_common(true, true, allow_c_variadic);
-            if ty.is_ok() && self.token != token::Comma &&
-               self.token != token::CloseDelim(token::Paren) {
-                // This wasn't actually a type, but a pattern looking like a type,
-                // so we are going to rollback and re-parse for recovery.
-                ty = self.unexpected();
-            }
-            match ty {
-                Ok(ty) => {
-                    let ident = Ident::new(kw::Invalid, self.prev_span);
-                    let bm = BindingMode::ByValue(Mutability::Immutable);
-                    let pat = self.mk_pat_ident(ty.span, bm, ident);
-                    (pat, ty)
-                }
-                Err(mut err) => {
-                    // If this is a C-variadic argument and we hit an error, return the
-                    // error.
-                    if self.token == token::DotDotDot {
-                        return Err(err);
-                    }
-                    // Recover from attempting to parse the argument as a type without pattern.
-                    err.cancel();
-                    mem::replace(self, parser_snapshot_before_ty);
-                    self.recover_arg_parse()?
-                }
-            }
-        };
-
-        let span = lo.to(self.token.span);
-
-        Ok(Param {
-            attrs: attrs.into(),
-            id: ast::DUMMY_NODE_ID,
-            is_placeholder: false,
-            pat,
-            span,
-            ty,
-        })
-    }
-
     /// Parses mutability (`mut` or nothing).
     fn parse_mutability(&mut self) -> Mutability {
         if self.eat_keyword(kw::Mut) {
@@ -1066,6 +951,17 @@ impl<'a> Parser<'a> {
         }
     }
 
+    /// Possibly parses mutability (`const` or `mut`).
+    fn parse_const_or_mut(&mut self) -> Option<Mutability> {
+        if self.eat_keyword(kw::Mut) {
+            Some(Mutability::Mutable)
+        } else if self.eat_keyword(kw::Const) {
+            Some(Mutability::Immutable)
+        } else {
+            None
+        }
+    }
+
     fn parse_field_name(&mut self) -> PResult<'a, Ident> {
         if let token::Literal(token::Lit { kind: token::Integer, symbol, suffix }) =
                 self.token.kind {
@@ -1100,9 +996,10 @@ impl<'a> Parser<'a> {
         Ok((delim, tts.into()))
     }
 
-    fn parse_or_use_outer_attributes(&mut self,
-                                     already_parsed_attrs: Option<ThinVec<Attribute>>)
-                                     -> PResult<'a, ThinVec<Attribute>> {
+    fn parse_or_use_outer_attributes(
+        &mut self,
+        already_parsed_attrs: Option<ThinVec<Attribute>>,
+    ) -> PResult<'a, ThinVec<Attribute>> {
         if let Some(attrs) = already_parsed_attrs {
             Ok(attrs)
         } else {
@@ -1189,53 +1086,52 @@ impl<'a> Parser<'a> {
     /// Evaluates the closure with restrictions in place.
     ///
     /// Afters the closure is evaluated, restrictions are reset.
-    fn with_res<F, T>(&mut self, r: Restrictions, f: F) -> T
-        where F: FnOnce(&mut Self) -> T
-    {
+    fn with_res<T>(&mut self, res: Restrictions, f: impl FnOnce(&mut Self) -> T) -> T {
         let old = self.restrictions;
-        self.restrictions = r;
-        let r = f(self);
+        self.restrictions = res;
+        let res = f(self);
         self.restrictions = old;
-        return r;
-
+        res
     }
 
-    fn parse_fn_params(&mut self, named_params: bool, allow_c_variadic: bool)
-                     -> PResult<'a, Vec<Param>> {
+    fn parse_fn_params(
+        &mut self,
+        named_params: bool,
+        allow_c_variadic: bool,
+    ) -> PResult<'a, Vec<Param>> {
         let sp = self.token.span;
+        let do_not_enforce_named_params_for_c_variadic = |token: &token::Token| {
+            match token.kind {
+                token::DotDotDot => false,
+                _ => named_params,
+            }
+        };
         let mut c_variadic = false;
-        let (params, _): (Vec<Option<Param>>, _) = self.parse_paren_comma_seq(|p| {
-            let do_not_enforce_named_arguments_for_c_variadic =
-                |token: &token::Token| -> bool {
-                    if token == &token::DotDotDot {
-                        false
-                    } else {
-                        named_params
-                    }
-                };
+        let (params, _) = self.parse_paren_comma_seq(|p| {
             match p.parse_param_general(
                 false,
                 false,
                 allow_c_variadic,
-                do_not_enforce_named_arguments_for_c_variadic
+                do_not_enforce_named_params_for_c_variadic,
             ) {
-                Ok(param) => {
+                Ok(param) => Ok(
                     if let TyKind::CVarArgs = param.ty.kind {
                         c_variadic = true;
                         if p.token != token::CloseDelim(token::Paren) {
-                            let span = p.token.span;
-                            p.span_err(span,
-                                "`...` must be the last argument of a C-variadic function");
+                            p.span_err(
+                                p.token.span,
+                                "`...` must be the last argument of a C-variadic function",
+                            );
                             // FIXME(eddyb) this should probably still push `CVarArgs`.
                             // Maybe AST validation/HIR lowering should emit the above error?
-                            Ok(None)
+                            None
                         } else {
-                            Ok(Some(param))
+                            Some(param)
                         }
                     } else {
-                        Ok(Some(param))
+                        Some(param)
                     }
-                },
+                ),
                 Err(mut e) => {
                     e.emit();
                     let lo = p.prev_span;
@@ -1251,26 +1147,169 @@ impl<'a> Parser<'a> {
         let params: Vec<_> = params.into_iter().filter_map(|x| x).collect();
 
         if c_variadic && params.len() <= 1 {
-            self.span_err(sp,
-                          "C-variadic function must be declared with at least one named argument");
+            self.span_err(
+                sp,
+                "C-variadic function must be declared with at least one named argument",
+            );
         }
 
         Ok(params)
     }
 
+    /// Parses the parameter list and result type of a function that may have a `self` parameter.
+    fn parse_fn_decl_with_self(
+        &mut self,
+        is_name_required: impl Copy + Fn(&token::Token) -> bool,
+    ) -> PResult<'a, P<FnDecl>> {
+        // Parse the arguments, starting out with `self` being allowed...
+        let mut is_self_allowed = true;
+        let (mut inputs, _): (Vec<_>, _) = self.parse_paren_comma_seq(|p| {
+            let res = p.parse_param_general(is_self_allowed, true, false, is_name_required);
+            // ...but now that we've parsed the first argument, `self` is no longer allowed.
+            is_self_allowed = false;
+            res
+        })?;
+
+        // Replace duplicated recovered params with `_` pattern to avoid unecessary errors.
+        self.deduplicate_recovered_params_names(&mut inputs);
+
+        Ok(P(FnDecl {
+            inputs,
+            output: self.parse_ret_ty(true)?,
+        }))
+    }
+
+    /// Skips unexpected attributes and doc comments in this position and emits an appropriate
+    /// error.
+    /// This version of parse param doesn't necessarily require identifier names.
+    fn parse_param_general(
+        &mut self,
+        is_self_allowed: bool,
+        is_trait_item: bool,
+        allow_c_variadic: bool,
+        is_name_required: impl Fn(&token::Token) -> bool,
+    ) -> PResult<'a, Param> {
+        let lo = self.token.span;
+        let attrs = self.parse_outer_attributes()?;
+
+        // Possibly parse `self`. Recover if we parsed it and it wasn't allowed here.
+        if let Some(mut param) = self.parse_self_param()? {
+            param.attrs = attrs.into();
+            return if is_self_allowed {
+                Ok(param)
+            } else {
+                self.recover_bad_self_param(param, is_trait_item)
+            };
+        }
+
+        let is_name_required = is_name_required(&self.token);
+        let (pat, ty) = if is_name_required || self.is_named_param() {
+            debug!("parse_param_general parse_pat (is_name_required:{})", is_name_required);
+
+            let pat = self.parse_fn_param_pat()?;
+            if let Err(mut err) = self.expect(&token::Colon) {
+                if let Some(ident) = self.parameter_without_type(
+                    &mut err,
+                    pat,
+                    is_name_required,
+                    is_trait_item,
+                ) {
+                    err.emit();
+                    return Ok(dummy_arg(ident));
+                } else {
+                    return Err(err);
+                }
+            }
+
+            self.eat_incorrect_doc_comment_for_param_type();
+            (pat, self.parse_ty_common(true, true, allow_c_variadic)?)
+        } else {
+            debug!("parse_param_general ident_to_pat");
+            let parser_snapshot_before_ty = self.clone();
+            self.eat_incorrect_doc_comment_for_param_type();
+            let mut ty = self.parse_ty_common(true, true, allow_c_variadic);
+            if ty.is_ok() && self.token != token::Comma &&
+               self.token != token::CloseDelim(token::Paren) {
+                // This wasn't actually a type, but a pattern looking like a type,
+                // so we are going to rollback and re-parse for recovery.
+                ty = self.unexpected();
+            }
+            match ty {
+                Ok(ty) => {
+                    let ident = Ident::new(kw::Invalid, self.prev_span);
+                    let bm = BindingMode::ByValue(Mutability::Immutable);
+                    let pat = self.mk_pat_ident(ty.span, bm, ident);
+                    (pat, ty)
+                }
+                // If this is a C-variadic argument and we hit an error, return the error.
+                Err(err) if self.token == token::DotDotDot => return Err(err),
+                // Recover from attempting to parse the argument as a type without pattern.
+                Err(mut err) => {
+                    err.cancel();
+                    mem::replace(self, parser_snapshot_before_ty);
+                    self.recover_arg_parse()?
+                }
+            }
+        };
+
+        let span = lo.to(self.token.span);
+
+        Ok(Param {
+            attrs: attrs.into(),
+            id: ast::DUMMY_NODE_ID,
+            is_placeholder: false,
+            pat,
+            span,
+            ty,
+        })
+    }
+
     /// Returns the parsed optional self parameter and whether a self shortcut was used.
     ///
     /// See `parse_self_param_with_attrs` to collect attributes.
     fn parse_self_param(&mut self) -> PResult<'a, Option<Param>> {
-        let expect_ident = |this: &mut Self| match this.token.kind {
-            // Preserve hygienic context.
-            token::Ident(name, _) =>
-                { let span = this.token.span; this.bump(); Ident::new(name, span) }
-            _ => unreachable!()
+        // Extract an identifier *after* having confirmed that the token is one.
+        let expect_self_ident = |this: &mut Self| {
+            match this.token.kind {
+                // Preserve hygienic context.
+                token::Ident(name, _) => {
+                    let span = this.token.span;
+                    this.bump();
+                    Ident::new(name, span)
+                }
+                _ => unreachable!(),
+            }
+        };
+        // Is `self` `n` tokens ahead?
+        let is_isolated_self = |this: &Self, n| {
+            this.is_keyword_ahead(n, &[kw::SelfLower])
+            && this.look_ahead(n + 1, |t| t != &token::ModSep)
         };
-        let isolated_self = |this: &mut Self, n| {
-            this.look_ahead(n, |t| t.is_keyword(kw::SelfLower)) &&
-            this.look_ahead(n + 1, |t| t != &token::ModSep)
+        // Is `mut self` `n` tokens ahead?
+        let is_isolated_mut_self = |this: &Self, n| {
+            this.is_keyword_ahead(n, &[kw::Mut])
+            && is_isolated_self(this, n + 1)
+        };
+        // Parse `self` or `self: TYPE`. We already know the current token is `self`.
+        let parse_self_possibly_typed = |this: &mut Self, m| {
+            let eself_ident = expect_self_ident(this);
+            let eself_hi = this.prev_span;
+            let eself = if this.eat(&token::Colon) {
+                SelfKind::Explicit(this.parse_ty()?, m)
+            } else {
+                SelfKind::Value(m)
+            };
+            Ok((eself, eself_ident, eself_hi))
+        };
+        // Recover for the grammar `*self`, `*const self`, and `*mut self`.
+        let recover_self_ptr = |this: &mut Self| {
+            let msg = "cannot pass `self` by raw pointer";
+            let span = this.token.span;
+            this.struct_span_err(span, msg)
+                .span_label(span, msg)
+                .emit();
+
+            Ok((SelfKind::Value(Mutability::Immutable), expect_self_ident(this), this.prev_span))
         };
 
         // Parse optional `self` parameter of a method.
@@ -1279,88 +1318,54 @@ impl<'a> Parser<'a> {
         let eself_lo = self.token.span;
         let (eself, eself_ident, eself_hi) = match self.token.kind {
             token::BinOp(token::And) => {
-                // `&self`
-                // `&mut self`
-                // `&'lt self`
-                // `&'lt mut self`
-                // `&not_self`
-                (if isolated_self(self, 1) {
+                let eself = if is_isolated_self(self, 1) {
+                    // `&self`
                     self.bump();
                     SelfKind::Region(None, Mutability::Immutable)
-                } else if self.is_keyword_ahead(1, &[kw::Mut]) &&
-                          isolated_self(self, 2) {
+                } else if is_isolated_mut_self(self, 1) {
+                    // `&mut self`
                     self.bump();
                     self.bump();
                     SelfKind::Region(None, Mutability::Mutable)
-                } else if self.look_ahead(1, |t| t.is_lifetime()) &&
-                          isolated_self(self, 2) {
+                } else if self.look_ahead(1, |t| t.is_lifetime()) && is_isolated_self(self, 2) {
+                    // `&'lt self`
                     self.bump();
                     let lt = self.expect_lifetime();
                     SelfKind::Region(Some(lt), Mutability::Immutable)
-                } else if self.look_ahead(1, |t| t.is_lifetime()) &&
-                          self.is_keyword_ahead(2, &[kw::Mut]) &&
-                          isolated_self(self, 3) {
+                } else if self.look_ahead(1, |t| t.is_lifetime()) && is_isolated_mut_self(self, 2) {
+                    // `&'lt mut self`
                     self.bump();
                     let lt = self.expect_lifetime();
                     self.bump();
                     SelfKind::Region(Some(lt), Mutability::Mutable)
                 } else {
+                    // `&not_self`
                     return Ok(None);
-                }, expect_ident(self), self.prev_span)
+                };
+                (eself, expect_self_ident(self), self.prev_span)
             }
-            token::BinOp(token::Star) => {
-                // `*self`
-                // `*const self`
-                // `*mut self`
-                // `*not_self`
-                // Emit special error for `self` cases.
-                let msg = "cannot pass `self` by raw pointer";
-                (if isolated_self(self, 1) {
-                    self.bump();
-                    self.struct_span_err(self.token.span, msg)
-                        .span_label(self.token.span, msg)
-                        .emit();
-                    SelfKind::Value(Mutability::Immutable)
-                } else if self.look_ahead(1, |t| t.is_mutability()) &&
-                          isolated_self(self, 2) {
-                    self.bump();
-                    self.bump();
-                    self.struct_span_err(self.token.span, msg)
-                        .span_label(self.token.span, msg)
-                        .emit();
-                    SelfKind::Value(Mutability::Immutable)
-                } else {
-                    return Ok(None);
-                }, expect_ident(self), self.prev_span)
+            // `*self`
+            token::BinOp(token::Star) if is_isolated_self(self, 1) => {
+                self.bump();
+                recover_self_ptr(self)?
             }
-            token::Ident(..) => {
-                if isolated_self(self, 0) {
-                    // `self`
-                    // `self: TYPE`
-                    let eself_ident = expect_ident(self);
-                    let eself_hi = self.prev_span;
-                    (if self.eat(&token::Colon) {
-                        let ty = self.parse_ty()?;
-                        SelfKind::Explicit(ty, Mutability::Immutable)
-                    } else {
-                        SelfKind::Value(Mutability::Immutable)
-                    }, eself_ident, eself_hi)
-                } else if self.token.is_keyword(kw::Mut) &&
-                          isolated_self(self, 1) {
-                    // `mut self`
-                    // `mut self: TYPE`
-                    self.bump();
-                    let eself_ident = expect_ident(self);
-                    let eself_hi = self.prev_span;
-                    (if self.eat(&token::Colon) {
-                        let ty = self.parse_ty()?;
-                        SelfKind::Explicit(ty, Mutability::Mutable)
-                    } else {
-                        SelfKind::Value(Mutability::Mutable)
-                    }, eself_ident, eself_hi)
-                } else {
-                    return Ok(None);
-                }
+            // `*mut self` and `*const self`
+            token::BinOp(token::Star) if
+                self.look_ahead(1, |t| t.is_mutability())
+                && is_isolated_self(self, 2) =>
+            {
+                self.bump();
+                self.bump();
+                recover_self_ptr(self)?
+            }
+            // `self` and `self: TYPE`
+            token::Ident(..) if is_isolated_self(self, 0) => {
+                parse_self_possibly_typed(self, Mutability::Immutable)?
+            }
+            // `mut self` and `mut self: TYPE`
+            token::Ident(..) if is_isolated_mut_self(self, 0) => {
+                self.bump();
+                parse_self_possibly_typed(self, Mutability::Mutable)?
             }
             _ => return Ok(None),
         };
@@ -1369,27 +1374,19 @@ impl<'a> Parser<'a> {
         Ok(Some(Param::from_self(ThinVec::default(), eself, eself_ident)))
     }
 
-    /// Parses the parameter list and result type of a function that may have a `self` parameter.
-    fn parse_fn_decl_with_self(
-        &mut self,
-        is_name_required: impl Copy + Fn(&token::Token) -> bool,
-    ) -> PResult<'a, P<FnDecl>> {
-        // Parse the arguments, starting out with `self` being allowed...
-        let mut is_self_allowed = true;
-        let (mut inputs, _): (Vec<_>, _) = self.parse_paren_comma_seq(|p| {
-            let res = p.parse_param_general(is_self_allowed, true, false, is_name_required);
-            // ...but now that we've parsed the first argument, `self` is no longer allowed.
-            is_self_allowed = false;
-            res
-        })?;
-
-        // Replace duplicated recovered params with `_` pattern to avoid unecessary errors.
-        self.deduplicate_recovered_params_names(&mut inputs);
+    fn is_named_param(&self) -> bool {
+        let offset = match self.token.kind {
+            token::Interpolated(ref nt) => match **nt {
+                token::NtPat(..) => return self.look_ahead(1, |t| t == &token::Colon),
+                _ => 0,
+            }
+            token::BinOp(token::And) | token::AndAnd => 1,
+            _ if self.token.is_keyword(kw::Mut) => 1,
+            _ => 0,
+        };
 
-        Ok(P(FnDecl {
-            inputs,
-            output: self.parse_ret_ty(true)?,
-        }))
+        self.look_ahead(offset, |t| t.is_ident()) &&
+        self.look_ahead(offset + 1, |t| t == &token::Colon)
     }
 
     fn is_crate_vis(&self) -> bool {
@@ -1423,100 +1420,107 @@ impl<'a> Parser<'a> {
             // `()` or a tuple might be allowed. For example, `struct Struct(pub (), pub (usize));`.
             // Because of this, we only `bump` the `(` if we're assured it is appropriate to do so
             // by the following tokens.
-            if self.is_keyword_ahead(1, &[kw::Crate]) &&
-                self.look_ahead(2, |t| t != &token::ModSep) // account for `pub(crate::foo)`
+            if self.is_keyword_ahead(1, &[kw::Crate])
+                && self.look_ahead(2, |t| t != &token::ModSep) // account for `pub(crate::foo)`
             {
-                // `pub(crate)`
+                // Parse `pub(crate)`.
                 self.bump(); // `(`
                 self.bump(); // `crate`
                 self.expect(&token::CloseDelim(token::Paren))?; // `)`
-                let vis = respan(
-                    lo.to(self.prev_span),
-                    VisibilityKind::Crate(CrateSugar::PubCrate),
-                );
-                return Ok(vis)
+                let vis = VisibilityKind::Crate(CrateSugar::PubCrate);
+                return Ok(respan(lo.to(self.prev_span), vis));
             } else if self.is_keyword_ahead(1, &[kw::In]) {
-                // `pub(in path)`
+                // Parse `pub(in path)`.
                 self.bump(); // `(`
                 self.bump(); // `in`
                 let path = self.parse_path(PathStyle::Mod)?; // `path`
                 self.expect(&token::CloseDelim(token::Paren))?; // `)`
-                let vis = respan(lo.to(self.prev_span), VisibilityKind::Restricted {
+                let vis = VisibilityKind::Restricted {
                     path: P(path),
                     id: ast::DUMMY_NODE_ID,
-                });
-                return Ok(vis)
-            } else if self.look_ahead(2, |t| t == &token::CloseDelim(token::Paren)) &&
-                      self.is_keyword_ahead(1, &[kw::Super, kw::SelfLower])
+                };
+                return Ok(respan(lo.to(self.prev_span), vis));
+            } else if self.look_ahead(2, |t| t == &token::CloseDelim(token::Paren))
+                && self.is_keyword_ahead(1, &[kw::Super, kw::SelfLower])
             {
-                // `pub(self)` or `pub(super)`
+                // Parse `pub(self)` or `pub(super)`.
                 self.bump(); // `(`
                 let path = self.parse_path(PathStyle::Mod)?; // `super`/`self`
                 self.expect(&token::CloseDelim(token::Paren))?; // `)`
-                let vis = respan(lo.to(self.prev_span), VisibilityKind::Restricted {
+                let vis = VisibilityKind::Restricted {
                     path: P(path),
                     id: ast::DUMMY_NODE_ID,
-                });
-                return Ok(vis)
-            } else if !can_take_tuple {  // Provide this diagnostic if this is not a tuple struct
-                // `pub(something) fn ...` or `struct X { pub(something) y: Z }`
-                self.bump(); // `(`
-                let msg = "incorrect visibility restriction";
-                let suggestion = r##"some possible visibility restrictions are:
-`pub(crate)`: visible only on the current crate
-`pub(super)`: visible only in the current module's parent
-`pub(in path::to::module)`: visible only on the specified path"##;
-                let path = self.parse_path(PathStyle::Mod)?;
-                let sp = path.span;
-                let help_msg = format!("make this visible only to module `{}` with `in`", path);
-                self.expect(&token::CloseDelim(token::Paren))?;  // `)`
-                struct_span_err!(self.sess.span_diagnostic, sp, E0704, "{}", msg)
-                    .help(suggestion)
-                    .span_suggestion(
-                        sp,
-                        &help_msg,
-                        format!("in {}", path),
-                        Applicability::MachineApplicable,
-                    )
-                    .emit(); // Emit diagnostic, but continue with public visibility.
+                };
+                return Ok(respan(lo.to(self.prev_span), vis));
+            } else if !can_take_tuple { // Provide this diagnostic if this is not a tuple struct.
+                self.recover_incorrect_vis_restriction()?;
+                // Emit diagnostic, but continue with public visibility.
             }
         }
 
         Ok(respan(lo, VisibilityKind::Public))
     }
 
+    /// Recovery for e.g. `pub(something) fn ...` or `struct X { pub(something) y: Z }`
+    fn recover_incorrect_vis_restriction(&mut self) -> PResult<'a, ()> {
+        self.bump(); // `(`
+        let path = self.parse_path(PathStyle::Mod)?;
+        self.expect(&token::CloseDelim(token::Paren))?;  // `)`
+
+        let msg = "incorrect visibility restriction";
+        let suggestion = r##"some possible visibility restrictions are:
+`pub(crate)`: visible only on the current crate
+`pub(super)`: visible only in the current module's parent
+`pub(in path::to::module)`: visible only on the specified path"##;
+
+        struct_span_err!(self.sess.span_diagnostic, path.span, E0704, "{}", msg)
+            .help(suggestion)
+            .span_suggestion(
+                path.span,
+                &format!("make this visible only to module `{}` with `in`", path),
+                format!("in {}", path),
+                Applicability::MachineApplicable,
+            )
+            .emit();
+
+        Ok(())
+    }
+
     /// Parses a string as an ABI spec on an extern type or module. Consumes
     /// the `extern` keyword, if one is found.
     fn parse_opt_abi(&mut self) -> PResult<'a, Option<Abi>> {
         match self.token.kind {
             token::Literal(token::Lit { kind: token::Str, symbol, suffix }) |
             token::Literal(token::Lit { kind: token::StrRaw(..), symbol, suffix }) => {
-                let sp = self.token.span;
-                self.expect_no_suffix(sp, "an ABI spec", suffix);
+                self.expect_no_suffix(self.token.span, "an ABI spec", suffix);
                 self.bump();
                 match abi::lookup(&symbol.as_str()) {
                     Some(abi) => Ok(Some(abi)),
                     None => {
-                        let prev_span = self.prev_span;
-                        struct_span_err!(
-                            self.sess.span_diagnostic,
-                            prev_span,
-                            E0703,
-                            "invalid ABI: found `{}`",
-                            symbol
-                        )
-                        .span_label(prev_span, "invalid ABI")
-                        .help(&format!("valid ABIs: {}", abi::all_names().join(", ")))
-                        .emit();
+                        self.error_on_invalid_abi(symbol);
                         Ok(None)
                     }
                 }
             }
-
             _ => Ok(None),
         }
     }
 
+    /// Emit an error where `symbol` is an invalid ABI.
+    fn error_on_invalid_abi(&self, symbol: Symbol) {
+        let prev_span = self.prev_span;
+        struct_span_err!(
+            self.sess.span_diagnostic,
+            prev_span,
+            E0703,
+            "invalid ABI: found `{}`",
+            symbol
+        )
+        .span_label(prev_span, "invalid ABI")
+        .help(&format!("valid ABIs: {}", abi::all_names().join(", ")))
+        .emit();
+    }
+
     /// We are parsing `async fn`. If we are on Rust 2015, emit an error.
     fn ban_async_in_2015(&self, async_span: Span) {
         if async_span.rust_2015() {
@@ -1530,9 +1534,10 @@ impl<'a> Parser<'a> {
         }
     }
 
-    fn collect_tokens<F, R>(&mut self, f: F) -> PResult<'a, (R, TokenStream)>
-        where F: FnOnce(&mut Self) -> PResult<'a, R>
-    {
+    fn collect_tokens<R>(
+        &mut self,
+        f: impl FnOnce(&mut Self) -> PResult<'a, R>,
+    ) -> PResult<'a, (R, TokenStream)> {
         // Record all tokens we parse when parsing this item.
         let mut tokens = Vec::new();
         let prev_collecting = match self.token_cursor.frame.last_token {
diff --git a/src/libsyntax/parse/parser/item.rs b/src/libsyntax/parse/parser/item.rs
index 64c494416ff..c00a5807d52 100644
--- a/src/libsyntax/parse/parser/item.rs
+++ b/src/libsyntax/parse/parser/item.rs
@@ -7,7 +7,7 @@ use crate::ast::{
     Item, ItemKind, ImplItem, TraitItem, TraitItemKind,
     UseTree, UseTreeKind, PathSegment,
     IsAuto, Constness, IsAsync, Unsafety, Defaultness,
-    Visibility, VisibilityKind, Mutability, FnDecl, FnHeader,
+    Visibility, VisibilityKind, Mutability, FnDecl, FnHeader, MethodSig, Block,
     ForeignItem, ForeignItemKind,
     Ty, TyKind, Generics, GenericBounds, TraitRef,
     EnumDef, VariantData, StructField, AnonConst,
@@ -18,7 +18,7 @@ use crate::parse::token;
 use crate::parse::parser::maybe_append;
 use crate::parse::diagnostics::Error;
 use crate::tokenstream::{TokenTree, TokenStream};
-use crate::source_map::{respan, Span, Spanned};
+use crate::source_map::{respan, Span};
 use crate::symbol::{kw, sym};
 
 use std::mem;
@@ -122,19 +122,13 @@ impl<'a> Parser<'a> {
             if self.eat_keyword(kw::Fn) {
                 // EXTERN FUNCTION ITEM
                 let fn_span = self.prev_span;
-                let abi = opt_abi.unwrap_or(Abi::C);
-                let (ident, item_, extra_attrs) =
-                    self.parse_item_fn(Unsafety::Normal,
-                                       respan(fn_span, IsAsync::NotAsync),
-                                       respan(fn_span, Constness::NotConst),
-                                       abi)?;
-                let prev_span = self.prev_span;
-                let item = self.mk_item(lo.to(prev_span),
-                                        ident,
-                                        item_,
-                                        visibility,
-                                        maybe_append(attrs, extra_attrs));
-                return Ok(Some(item));
+                let header = FnHeader {
+                    unsafety: Unsafety::Normal,
+                    asyncness: respan(fn_span, IsAsync::NotAsync),
+                    constness: respan(fn_span, Constness::NotConst),
+                    abi: opt_abi.unwrap_or(Abi::C),
+                };
+                return self.parse_item_fn(lo, visibility, attrs, header);
             } else if self.check(&token::OpenDelim(token::Brace)) {
                 return Ok(Some(
                     self.parse_item_foreign_mod(lo, opt_abi, visibility, attrs, extern_sp)?,
@@ -149,13 +143,9 @@ impl<'a> Parser<'a> {
             // STATIC ITEM
             let m = self.parse_mutability();
             let (ident, item_, extra_attrs) = self.parse_item_const(Some(m))?;
-            let prev_span = self.prev_span;
-            let item = self.mk_item(lo.to(prev_span),
-                                    ident,
-                                    item_,
-                                    visibility,
-                                    maybe_append(attrs, extra_attrs));
-            return Ok(Some(item));
+            let span = lo.to(self.prev_span);
+            let attrs = maybe_append(attrs, extra_attrs);
+            return Ok(Some(self.mk_item(span, ident, item_, visibility, attrs)));
         }
         if self.eat_keyword(kw::Const) {
             let const_span = self.prev_span;
@@ -165,18 +155,13 @@ impl<'a> Parser<'a> {
                 // CONST FUNCTION ITEM
                 let unsafety = self.parse_unsafety();
                 self.bump();
-                let (ident, item_, extra_attrs) =
-                    self.parse_item_fn(unsafety,
-                                       respan(const_span, IsAsync::NotAsync),
-                                       respan(const_span, Constness::Const),
-                                       Abi::Rust)?;
-                let prev_span = self.prev_span;
-                let item = self.mk_item(lo.to(prev_span),
-                                        ident,
-                                        item_,
-                                        visibility,
-                                        maybe_append(attrs, extra_attrs));
-                return Ok(Some(item));
+                let header = FnHeader {
+                    unsafety,
+                    asyncness: respan(const_span, IsAsync::NotAsync),
+                    constness: respan(const_span, Constness::Const),
+                    abi: Abi::Rust,
+                };
+                return self.parse_item_fn(lo, visibility, attrs, header);
             }
 
             // CONST ITEM
@@ -193,13 +178,9 @@ impl<'a> Parser<'a> {
                     .emit();
             }
             let (ident, item_, extra_attrs) = self.parse_item_const(None)?;
-            let prev_span = self.prev_span;
-            let item = self.mk_item(lo.to(prev_span),
-                                    ident,
-                                    item_,
-                                    visibility,
-                                    maybe_append(attrs, extra_attrs));
-            return Ok(Some(item));
+            let span = lo.to(self.prev_span);
+            let attrs = maybe_append(attrs, extra_attrs);
+            return Ok(Some(self.mk_item(span, ident, item_, visibility, attrs)));
         }
 
         // Parses `async unsafe? fn`.
@@ -213,22 +194,18 @@ impl<'a> Parser<'a> {
                 let unsafety = self.parse_unsafety(); // `unsafe`?
                 self.expect_keyword(kw::Fn)?; // `fn`
                 let fn_span = self.prev_span;
-                let (ident, item_, extra_attrs) =
-                    self.parse_item_fn(unsafety,
-                                    respan(async_span, IsAsync::Async {
-                                        closure_id: DUMMY_NODE_ID,
-                                        return_impl_trait_id: DUMMY_NODE_ID,
-                                    }),
-                                    respan(fn_span, Constness::NotConst),
-                                    Abi::Rust)?;
-                let prev_span = self.prev_span;
-                let item = self.mk_item(lo.to(prev_span),
-                                        ident,
-                                        item_,
-                                        visibility,
-                                        maybe_append(attrs, extra_attrs));
+                let asyncness = respan(async_span, IsAsync::Async {
+                    closure_id: DUMMY_NODE_ID,
+                    return_impl_trait_id: DUMMY_NODE_ID,
+                });
                 self.ban_async_in_2015(async_span);
-                return Ok(Some(item));
+                let header = FnHeader {
+                    unsafety,
+                    asyncness,
+                    constness: respan(fn_span, Constness::NotConst),
+                    abi: Abi::Rust,
+                };
+                return self.parse_item_fn(lo, visibility, attrs, header);
             }
         }
         if self.check_keyword(kw::Unsafe) &&
@@ -243,15 +220,10 @@ impl<'a> Parser<'a> {
                 self.expect_keyword(kw::Trait)?;
                 IsAuto::Yes
             };
-            let (ident, item_, extra_attrs) =
-                self.parse_item_trait(is_auto, Unsafety::Unsafe)?;
-            let prev_span = self.prev_span;
-            let item = self.mk_item(lo.to(prev_span),
-                                    ident,
-                                    item_,
-                                    visibility,
-                                    maybe_append(attrs, extra_attrs));
-            return Ok(Some(item));
+            let (ident, item_, extra_attrs) = self.parse_item_trait(is_auto, Unsafety::Unsafe)?;
+            let span = lo.to(self.prev_span);
+            let attrs = maybe_append(attrs, extra_attrs);
+            return Ok(Some(self.mk_item(span, ident, item_, visibility, attrs)));
         }
         if self.check_keyword(kw::Impl) ||
            self.check_keyword(kw::Unsafe) &&
@@ -262,27 +234,22 @@ impl<'a> Parser<'a> {
             let defaultness = self.parse_defaultness();
             let unsafety = self.parse_unsafety();
             self.expect_keyword(kw::Impl)?;
-            let (ident, item, extra_attrs) = self.parse_item_impl(unsafety, defaultness)?;
+            let (ident, item_, extra_attrs) = self.parse_item_impl(unsafety, defaultness)?;
             let span = lo.to(self.prev_span);
-            return Ok(Some(self.mk_item(span, ident, item, visibility,
-                                        maybe_append(attrs, extra_attrs))));
+            let attrs = maybe_append(attrs, extra_attrs);
+            return Ok(Some(self.mk_item(span, ident, item_, visibility, attrs)));
         }
         if self.check_keyword(kw::Fn) {
             // FUNCTION ITEM
             self.bump();
             let fn_span = self.prev_span;
-            let (ident, item_, extra_attrs) =
-                self.parse_item_fn(Unsafety::Normal,
-                                   respan(fn_span, IsAsync::NotAsync),
-                                   respan(fn_span, Constness::NotConst),
-                                   Abi::Rust)?;
-            let prev_span = self.prev_span;
-            let item = self.mk_item(lo.to(prev_span),
-                                    ident,
-                                    item_,
-                                    visibility,
-                                    maybe_append(attrs, extra_attrs));
-            return Ok(Some(item));
+            let header = FnHeader {
+                unsafety: Unsafety::Normal,
+                asyncness: respan(fn_span, IsAsync::NotAsync),
+                constness: respan(fn_span, Constness::NotConst),
+                abi: Abi::Rust,
+            };
+            return self.parse_item_fn(lo, visibility, attrs, header);
         }
         if self.check_keyword(kw::Unsafe)
             && self.look_ahead(1, |t| *t != token::OpenDelim(token::Brace)) {
@@ -297,30 +264,20 @@ impl<'a> Parser<'a> {
             };
             self.expect_keyword(kw::Fn)?;
             let fn_span = self.prev_span;
-            let (ident, item_, extra_attrs) =
-                self.parse_item_fn(Unsafety::Unsafe,
-                                   respan(fn_span, IsAsync::NotAsync),
-                                   respan(fn_span, Constness::NotConst),
-                                   abi)?;
-            let prev_span = self.prev_span;
-            let item = self.mk_item(lo.to(prev_span),
-                                    ident,
-                                    item_,
-                                    visibility,
-                                    maybe_append(attrs, extra_attrs));
-            return Ok(Some(item));
+            let header = FnHeader {
+                unsafety: Unsafety::Unsafe,
+                asyncness: respan(fn_span, IsAsync::NotAsync),
+                constness: respan(fn_span, Constness::NotConst),
+                abi,
+            };
+            return self.parse_item_fn(lo, visibility, attrs, header);
         }
         if self.eat_keyword(kw::Mod) {
             // MODULE ITEM
-            let (ident, item_, extra_attrs) =
-                self.parse_item_mod(&attrs[..])?;
-            let prev_span = self.prev_span;
-            let item = self.mk_item(lo.to(prev_span),
-                                    ident,
-                                    item_,
-                                    visibility,
-                                    maybe_append(attrs, extra_attrs));
-            return Ok(Some(item));
+            let (ident, item_, extra_attrs) = self.parse_item_mod(&attrs[..])?;
+            let span = lo.to(self.prev_span);
+            let attrs = maybe_append(attrs, extra_attrs);
+            return Ok(Some(self.mk_item(span, ident, item_, visibility, attrs)));
         }
         if let Some(type_) = self.eat_type() {
             let (ident, alias, generics) = type_?;
@@ -329,24 +286,15 @@ impl<'a> Parser<'a> {
                 AliasKind::Weak(ty) => ItemKind::TyAlias(ty, generics),
                 AliasKind::OpaqueTy(bounds) => ItemKind::OpaqueTy(bounds, generics),
             };
-            let prev_span = self.prev_span;
-            let item = self.mk_item(lo.to(prev_span),
-                                    ident,
-                                    item_,
-                                    visibility,
-                                    attrs);
-            return Ok(Some(item));
+            let span = lo.to(self.prev_span);
+            return Ok(Some(self.mk_item(span, ident, item_, visibility, attrs)));
         }
         if self.eat_keyword(kw::Enum) {
             // ENUM ITEM
             let (ident, item_, extra_attrs) = self.parse_item_enum()?;
-            let prev_span = self.prev_span;
-            let item = self.mk_item(lo.to(prev_span),
-                                    ident,
-                                    item_,
-                                    visibility,
-                                    maybe_append(attrs, extra_attrs));
-            return Ok(Some(item));
+            let span = lo.to(self.prev_span);
+            let attrs = maybe_append(attrs, extra_attrs);
+            return Ok(Some(self.mk_item(span, ident, item_, visibility, attrs)));
         }
         if self.check_keyword(kw::Trait)
             || (self.check_keyword(kw::Auto)
@@ -360,38 +308,25 @@ impl<'a> Parser<'a> {
                 IsAuto::Yes
             };
             // TRAIT ITEM
-            let (ident, item_, extra_attrs) =
-                self.parse_item_trait(is_auto, Unsafety::Normal)?;
-            let prev_span = self.prev_span;
-            let item = self.mk_item(lo.to(prev_span),
-                                    ident,
-                                    item_,
-                                    visibility,
-                                    maybe_append(attrs, extra_attrs));
-            return Ok(Some(item));
+            let (ident, item_, extra_attrs) = self.parse_item_trait(is_auto, Unsafety::Normal)?;
+            let span = lo.to(self.prev_span);
+            let attrs = maybe_append(attrs, extra_attrs);
+            return Ok(Some(self.mk_item(span, ident, item_, visibility, attrs)));
         }
         if self.eat_keyword(kw::Struct) {
             // STRUCT ITEM
             let (ident, item_, extra_attrs) = self.parse_item_struct()?;
-            let prev_span = self.prev_span;
-            let item = self.mk_item(lo.to(prev_span),
-                                    ident,
-                                    item_,
-                                    visibility,
-                                    maybe_append(attrs, extra_attrs));
-            return Ok(Some(item));
+            let span = lo.to(self.prev_span);
+            let attrs = maybe_append(attrs, extra_attrs);
+            return Ok(Some(self.mk_item(span, ident, item_, visibility, attrs)));
         }
         if self.is_union_item() {
             // UNION ITEM
             self.bump();
             let (ident, item_, extra_attrs) = self.parse_item_union()?;
-            let prev_span = self.prev_span;
-            let item = self.mk_item(lo.to(prev_span),
-                                    ident,
-                                    item_,
-                                    visibility,
-                                    maybe_append(attrs, extra_attrs));
-            return Ok(Some(item));
+            let span = lo.to(self.prev_span);
+            let attrs = maybe_append(attrs, extra_attrs);
+            return Ok(Some(self.mk_item(span, ident, item_, visibility, attrs)));
         }
         if let Some(macro_def) = self.eat_macro_def(&attrs, &visibility, lo)? {
             return Ok(Some(macro_def));
@@ -848,29 +783,37 @@ impl<'a> Parser<'a> {
     }
 
     /// Parses a method or a macro invocation in a trait impl.
-    fn parse_impl_method(&mut self, vis: &Visibility, at_end: &mut bool)
-                         -> PResult<'a, (Ident, Vec<Attribute>, Generics, ast::ImplItemKind)> {
+    fn parse_impl_method(
+        &mut self,
+        vis: &Visibility,
+        at_end: &mut bool
+    ) -> PResult<'a, (Ident, Vec<Attribute>, Generics, ast::ImplItemKind)> {
         // FIXME: code copied from `parse_macro_use_or_failure` -- use abstraction!
         if let Some(mac) = self.parse_assoc_macro_invoc("impl", Some(vis), at_end)? {
             // method macro
-            Ok((Ident::invalid(), vec![], Generics::default(),
-                ast::ImplItemKind::Macro(mac)))
+            Ok((Ident::invalid(), vec![], Generics::default(), ast::ImplItemKind::Macro(mac)))
         } else {
-            let (constness, unsafety, asyncness, abi) = self.parse_fn_front_matter()?;
-            let ident = self.parse_ident()?;
-            let mut generics = self.parse_generics()?;
-            let decl = self.parse_fn_decl_with_self(|_| true)?;
-            generics.where_clause = self.parse_where_clause()?;
+            let (ident, sig, generics) = self.parse_method_sig(|_| true)?;
             *at_end = true;
             let (inner_attrs, body) = self.parse_inner_attrs_and_block()?;
-            let header = ast::FnHeader { abi, unsafety, constness, asyncness };
-            Ok((ident, inner_attrs, generics, ast::ImplItemKind::Method(
-                ast::MethodSig { header, decl },
-                body
-            )))
+            Ok((ident, inner_attrs, generics, ast::ImplItemKind::Method(sig, body)))
         }
     }
 
+    /// Parse the "signature", including the identifier, parameters, and generics
+    /// of a method. The body is not parsed as that differs between `trait`s and `impl`s.
+    fn parse_method_sig(
+        &mut self,
+        is_name_required: impl Copy + Fn(&token::Token) -> bool,
+    ) -> PResult<'a, (Ident, MethodSig, Generics)> {
+        let header = self.parse_fn_front_matter()?;
+        let (ident, mut generics) = self.parse_fn_header()?;
+        let decl = self.parse_fn_decl_with_self(is_name_required)?;
+        let sig = MethodSig { header, decl };
+        generics.where_clause = self.parse_where_clause()?;
+        Ok((ident, sig, generics))
+    }
+
     /// Parses all the "front matter" for a `fn` declaration, up to
     /// and including the `fn` keyword:
     ///
@@ -879,14 +822,7 @@ impl<'a> Parser<'a> {
     /// - `const unsafe fn`
     /// - `extern fn`
     /// - etc.
-    fn parse_fn_front_matter(&mut self)
-        -> PResult<'a, (
-            Spanned<Constness>,
-            Unsafety,
-            Spanned<IsAsync>,
-            Abi
-        )>
-    {
+    fn parse_fn_front_matter(&mut self) -> PResult<'a, FnHeader> {
         let is_const_fn = self.eat_keyword(kw::Const);
         let const_span = self.prev_span;
         let asyncness = self.parse_asyncness();
@@ -911,7 +847,7 @@ impl<'a> Parser<'a> {
             // account for this.
             if !self.expect_one_of(&[], &[])? { unreachable!() }
         }
-        Ok((constness, unsafety, asyncness, abi))
+        Ok(FnHeader { constness, unsafety, asyncness, abi })
     }
 
     /// Parses `trait Foo { ... }` or `trait Foo = Bar;`.
@@ -1025,59 +961,12 @@ impl<'a> Parser<'a> {
             // trait item macro.
             (Ident::invalid(), ast::TraitItemKind::Macro(mac), Generics::default())
         } else {
-            let (constness, unsafety, asyncness, abi) = self.parse_fn_front_matter()?;
-
-            let ident = self.parse_ident()?;
-            let mut generics = self.parse_generics()?;
-
             // This is somewhat dubious; We don't want to allow
             // argument names to be left off if there is a definition...
             //
             // We don't allow argument names to be left off in edition 2018.
-            let decl = self.parse_fn_decl_with_self(|t| t.span.rust_2018())?;
-            generics.where_clause = self.parse_where_clause()?;
-
-            let sig = ast::MethodSig {
-                header: FnHeader {
-                    unsafety,
-                    constness,
-                    abi,
-                    asyncness,
-                },
-                decl,
-            };
-
-            let body = match self.token.kind {
-                token::Semi => {
-                    self.bump();
-                    *at_end = true;
-                    debug!("parse_trait_methods(): parsing required method");
-                    None
-                }
-                token::OpenDelim(token::Brace) => {
-                    debug!("parse_trait_methods(): parsing provided method");
-                    *at_end = true;
-                    let (inner_attrs, body) = self.parse_inner_attrs_and_block()?;
-                    attrs.extend(inner_attrs.iter().cloned());
-                    Some(body)
-                }
-                token::Interpolated(ref nt) => {
-                    match **nt {
-                        token::NtBlock(..) => {
-                            *at_end = true;
-                            let (inner_attrs, body) = self.parse_inner_attrs_and_block()?;
-                            attrs.extend(inner_attrs.iter().cloned());
-                            Some(body)
-                        }
-                        _ => {
-                            return self.expected_semi_or_open_brace();
-                        }
-                    }
-                }
-                _ => {
-                    return self.expected_semi_or_open_brace();
-                }
-            };
+            let (ident, sig, generics) = self.parse_method_sig(|t| t.span.rust_2018())?;
+            let body = self.parse_trait_method_body(at_end, &mut attrs)?;
             (ident, ast::TraitItemKind::Method(sig, body), generics)
         };
 
@@ -1092,6 +981,43 @@ impl<'a> Parser<'a> {
         })
     }
 
+    /// Parse the "body" of a method in a trait item definition.
+    /// This can either be `;` when there's no body,
+    /// or e.g. a block when the method is a provided one.
+    fn parse_trait_method_body(
+        &mut self,
+        at_end: &mut bool,
+        attrs: &mut Vec<Attribute>,
+    ) -> PResult<'a, Option<P<Block>>> {
+        Ok(match self.token.kind {
+            token::Semi => {
+                debug!("parse_trait_method_body(): parsing required method");
+                self.bump();
+                *at_end = true;
+                None
+            }
+            token::OpenDelim(token::Brace) => {
+                debug!("parse_trait_method_body(): parsing provided method");
+                *at_end = true;
+                let (inner_attrs, body) = self.parse_inner_attrs_and_block()?;
+                attrs.extend(inner_attrs.iter().cloned());
+                Some(body)
+            }
+            token::Interpolated(ref nt) => {
+                match **nt {
+                    token::NtBlock(..) => {
+                        *at_end = true;
+                        let (inner_attrs, body) = self.parse_inner_attrs_and_block()?;
+                        attrs.extend(inner_attrs.iter().cloned());
+                        Some(body)
+                    }
+                    _ => return self.expected_semi_or_open_brace(),
+                }
+            }
+            _ => return self.expected_semi_or_open_brace(),
+        })
+    }
+
     /// Parses the following grammar:
     ///
     ///     TraitItemAssocTy = Ident ["<"...">"] [":" [GenericBounds]] ["where" ...] ["=" Ty]
@@ -1261,18 +1187,29 @@ impl<'a> Parser<'a> {
     /// Parses an item-position function declaration.
     fn parse_item_fn(
         &mut self,
-        unsafety: Unsafety,
-        asyncness: Spanned<IsAsync>,
-        constness: Spanned<Constness>,
-        abi: Abi
-    ) -> PResult<'a, ItemInfo> {
+        lo: Span,
+        vis: Visibility,
+        attrs: Vec<Attribute>,
+        header: FnHeader,
+    ) -> PResult<'a, Option<P<Item>>> {
+        let allow_c_variadic = header.abi == Abi::C && header.unsafety == Unsafety::Unsafe;
+        let (ident, decl, generics) = self.parse_fn_sig(allow_c_variadic)?;
+        let (inner_attrs, body) = self.parse_inner_attrs_and_block()?;
+        let span = lo.to(self.prev_span);
+        let kind = ItemKind::Fn(decl, header, generics, body);
+        let attrs = maybe_append(attrs, Some(inner_attrs));
+        Ok(Some(self.mk_item(span, ident, kind, vis, attrs)))
+    }
+
+    /// Parse the "signature", including the identifier, parameters, and generics of a function.
+    fn parse_fn_sig(
+        &mut self,
+        allow_c_variadic: bool,
+    ) -> PResult<'a, (Ident, P<FnDecl>, Generics)> {
         let (ident, mut generics) = self.parse_fn_header()?;
-        let allow_c_variadic = abi == Abi::C && unsafety == Unsafety::Unsafe;
         let decl = self.parse_fn_decl(allow_c_variadic)?;
         generics.where_clause = self.parse_where_clause()?;
-        let (inner_attrs, body) = self.parse_inner_attrs_and_block()?;
-        let header = FnHeader { unsafety, asyncness, constness, abi };
-        Ok((ident, ItemKind::Fn(decl, header, generics, body), Some(inner_attrs)))
+        Ok((ident, decl, generics))
     }
 
     /// Parses the name and optional generic types of a function header.
@@ -1282,14 +1219,11 @@ impl<'a> Parser<'a> {
         Ok((id, generics))
     }
 
-    /// Parses the argument list and result type of a function declaration.
+    /// Parses the parameter list and result type of a function declaration.
     fn parse_fn_decl(&mut self, allow_c_variadic: bool) -> PResult<'a, P<FnDecl>> {
-        let args = self.parse_fn_params(true, allow_c_variadic)?;
-        let ret_ty = self.parse_ret_ty(true)?;
-
         Ok(P(FnDecl {
-            inputs: args,
-            output: ret_ty,
+            inputs: self.parse_fn_params(true, allow_c_variadic)?,
+            output: self.parse_ret_ty(true)?,
         }))
     }
 
@@ -1397,18 +1331,15 @@ impl<'a> Parser<'a> {
         extern_sp: Span,
     ) -> PResult<'a, ForeignItem> {
         self.expect_keyword(kw::Fn)?;
-
-        let (ident, mut generics) = self.parse_fn_header()?;
-        let decl = self.parse_fn_decl(true)?;
-        generics.where_clause = self.parse_where_clause()?;
-        let hi = self.token.span;
+        let (ident, decl, generics) = self.parse_fn_sig(true)?;
+        let span = lo.to(self.token.span);
         self.parse_semi_or_incorrect_foreign_fn_body(&ident, extern_sp)?;
         Ok(ast::ForeignItem {
             ident,
             attrs,
             kind: ForeignItemKind::Fn(decl, generics),
             id: DUMMY_NODE_ID,
-            span: lo.to(hi),
+            span,
             vis,
         })
     }
diff --git a/src/libsyntax/parse/parser/ty.rs b/src/libsyntax/parse/parser/ty.rs
index c52d3733b5e..41ee2a1599d 100644
--- a/src/libsyntax/parse/parser/ty.rs
+++ b/src/libsyntax/parse/parser/ty.rs
@@ -231,11 +231,7 @@ impl<'a> Parser<'a> {
     }
 
     fn parse_ptr(&mut self) -> PResult<'a, MutTy> {
-        let mutbl = if self.eat_keyword(kw::Mut) {
-            Mutability::Mutable
-        } else if self.eat_keyword(kw::Const) {
-            Mutability::Immutable
-        } else {
+        let mutbl = self.parse_const_or_mut().unwrap_or_else(|| {
             let span = self.prev_span;
             let msg = "expected mut or const in raw pointer type";
             self.struct_span_err(span, msg)
@@ -243,7 +239,7 @@ impl<'a> Parser<'a> {
                 .help("use `*mut T` or `*const T` as appropriate")
                 .emit();
             Mutability::Immutable
-        };
+        });
         let t = self.parse_ty_no_plus()?;
         Ok(MutTy { ty: t, mutbl })
     }
diff --git a/src/test/ui/async-await/edition-deny-async-fns-2015.stderr b/src/test/ui/async-await/edition-deny-async-fns-2015.stderr
index d3f88af09d1..7633825eb32 100644
--- a/src/test/ui/async-await/edition-deny-async-fns-2015.stderr
+++ b/src/test/ui/async-await/edition-deny-async-fns-2015.stderr
@@ -11,18 +11,18 @@ LL | fn baz() { async fn foo() {} }
    |            ^^^^^
 
 error[E0670]: `async fn` is not permitted in the 2015 edition
-  --> $DIR/edition-deny-async-fns-2015.rs:8:5
-   |
-LL |     async fn bar() {}
-   |     ^^^^^
-
-error[E0670]: `async fn` is not permitted in the 2015 edition
   --> $DIR/edition-deny-async-fns-2015.rs:7:1
    |
 LL | async fn async_baz() {
    | ^^^^^
 
 error[E0670]: `async fn` is not permitted in the 2015 edition
+  --> $DIR/edition-deny-async-fns-2015.rs:8:5
+   |
+LL |     async fn bar() {}
+   |     ^^^^^
+
+error[E0670]: `async fn` is not permitted in the 2015 edition
   --> $DIR/edition-deny-async-fns-2015.rs:14:5
    |
 LL |     async fn foo() {}
diff --git a/src/test/ui/conversion-methods.stderr b/src/test/ui/conversion-methods.stderr
index b9662e76074..5c666afb89a 100644
--- a/src/test/ui/conversion-methods.stderr
+++ b/src/test/ui/conversion-methods.stderr
@@ -41,7 +41,7 @@ LL |     let _prove_piercing_earnest: Vec<usize> = &[1, 2, 3];
    |                                               ^^^^^^^^^^
    |                                               |
    |                                               expected struct `std::vec::Vec`, found reference
-   |                                               help: try using a conversion method: `&[1, 2, 3].to_vec()`
+   |                                               help: try using a conversion method: `(&[1, 2, 3]).to_vec()`
    |
    = note: expected type `std::vec::Vec<usize>`
               found type `&[{integer}; 3]`
diff --git a/src/test/ui/infinite/infinite-autoderef.stderr b/src/test/ui/infinite/infinite-autoderef.stderr
index a2ad58a7e46..f4567554d0d 100644
--- a/src/test/ui/infinite/infinite-autoderef.stderr
+++ b/src/test/ui/infinite/infinite-autoderef.stderr
@@ -5,7 +5,7 @@ LL |         x = box x;
    |             ^^^^^
    |             |
    |             cyclic type of infinite size
-   |             help: try using a conversion method: `box x.to_string()`
+   |             help: try using a conversion method: `(box x).to_string()`
 
 error[E0055]: reached the recursion limit while auto-dereferencing `Foo`
   --> $DIR/infinite-autoderef.rs:25:5
diff --git a/src/test/ui/mismatched_types/abridged.rs b/src/test/ui/mismatched_types/abridged.rs
index 41ab6d4c578..9a5c183ca34 100644
--- a/src/test/ui/mismatched_types/abridged.rs
+++ b/src/test/ui/mismatched_types/abridged.rs
@@ -50,4 +50,13 @@ fn e() -> X<X<String, String>, String> {
     x //~ ERROR mismatched types
 }
 
+fn f() -> String {
+    1+2 //~ ERROR mismatched types
+}
+
+
+fn g() -> String {
+    -2 //~ ERROR mismatched types
+}
+
 fn main() {}
diff --git a/src/test/ui/mismatched_types/abridged.stderr b/src/test/ui/mismatched_types/abridged.stderr
index b7f3b3dde8a..ded12d89c09 100644
--- a/src/test/ui/mismatched_types/abridged.stderr
+++ b/src/test/ui/mismatched_types/abridged.stderr
@@ -66,6 +66,34 @@ LL |     x
    = note: expected type `X<X<_, std::string::String>, _>`
               found type `X<X<_, {integer}>, _>`
 
-error: aborting due to 6 previous errors
+error[E0308]: mismatched types
+  --> $DIR/abridged.rs:54:5
+   |
+LL | fn f() -> String {
+   |           ------ expected `std::string::String` because of return type
+LL |     1+2
+   |     ^^^
+   |     |
+   |     expected struct `std::string::String`, found integer
+   |     help: try using a conversion method: `(1+2).to_string()`
+   |
+   = note: expected type `std::string::String`
+              found type `{integer}`
+
+error[E0308]: mismatched types
+  --> $DIR/abridged.rs:59:5
+   |
+LL | fn g() -> String {
+   |           ------ expected `std::string::String` because of return type
+LL |     -2
+   |     ^^
+   |     |
+   |     expected struct `std::string::String`, found integer
+   |     help: try using a conversion method: `(-2).to_string()`
+   |
+   = note: expected type `std::string::String`
+              found type `{integer}`
+
+error: aborting due to 8 previous errors
 
 For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/occurs-check-2.stderr b/src/test/ui/occurs-check-2.stderr
index 74e29a5aea7..7f93697c6f7 100644
--- a/src/test/ui/occurs-check-2.stderr
+++ b/src/test/ui/occurs-check-2.stderr
@@ -5,7 +5,7 @@ LL |     f = box g;
    |         ^^^^^
    |         |
    |         cyclic type of infinite size
-   |         help: try using a conversion method: `box g.to_string()`
+   |         help: try using a conversion method: `(box g).to_string()`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/occurs-check.stderr b/src/test/ui/occurs-check.stderr
index 61ce61b1cbe..01e2b1f7749 100644
--- a/src/test/ui/occurs-check.stderr
+++ b/src/test/ui/occurs-check.stderr
@@ -5,7 +5,7 @@ LL |     f = box f;
    |         ^^^^^
    |         |
    |         cyclic type of infinite size
-   |         help: try using a conversion method: `box f.to_string()`
+   |         help: try using a conversion method: `(box f).to_string()`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/span/coerce-suggestions.stderr b/src/test/ui/span/coerce-suggestions.stderr
index 996d80a07e0..0d15a2a753e 100644
--- a/src/test/ui/span/coerce-suggestions.stderr
+++ b/src/test/ui/span/coerce-suggestions.stderr
@@ -44,7 +44,7 @@ LL |     f = box f;
    |         ^^^^^
    |         |
    |         cyclic type of infinite size
-   |         help: try using a conversion method: `box f.to_string()`
+   |         help: try using a conversion method: `(box f).to_string()`
 
 error[E0308]: mismatched types
   --> $DIR/coerce-suggestions.rs:21:9