diff --git a/src/libcore/iter/adapters/mod.rs b/src/libcore/iter/adapters/mod.rs
index 8eae52ffd3277..af46e6df2942b 100644
--- a/src/libcore/iter/adapters/mod.rs
+++ b/src/libcore/iter/adapters/mod.rs
@@ -485,6 +485,39 @@ impl<I> Iterator for StepBy<I> where I: Iterator {
     }
 }
 
+impl<I> StepBy<I> where I: ExactSizeIterator {
+    // The zero-based index starting from the end of the iterator of the
+    // last element. Used in the `DoubleEndedIterator` implementation.
+    fn next_back_index(&self) -> usize {
+        let rem = self.iter.len() % (self.step + 1);
+        if self.first_take {
+            if rem == 0 { self.step } else { rem - 1 }
+        } else {
+            rem
+        }
+    }
+}
+
+#[stable(feature = "double_ended_step_by_iterator", since = "1.38.0")]
+impl<I> DoubleEndedIterator for StepBy<I> where I: DoubleEndedIterator + ExactSizeIterator {
+    #[inline]
+    fn next_back(&mut self) -> Option<Self::Item> {
+        self.iter.nth_back(self.next_back_index())
+    }
+
+    #[inline]
+    fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
+        // `self.iter.nth_back(usize::MAX)` does the right thing here when `n`
+        // is out of bounds because the length of `self.iter` does not exceed
+        // `usize::MAX` (because `I: ExactSizeIterator`) and `nth_back` is
+        // zero-indexed
+        let n = n
+            .saturating_mul(self.step + 1)
+            .saturating_add(self.next_back_index());
+        self.iter.nth_back(n)
+    }
+}
+
 // StepBy can only make the iterator shorter, so the len will still fit.
 #[stable(feature = "iterator_step_by", since = "1.28.0")]
 impl<I> ExactSizeIterator for StepBy<I> where I: ExactSizeIterator {}
@@ -1158,6 +1191,45 @@ impl<I: Iterator> Iterator for Peekable<I> {
     }
 }
 
+#[stable(feature = "double_ended_peek_iterator", since = "1.38.0")]
+impl<I> DoubleEndedIterator for Peekable<I> where I: DoubleEndedIterator {
+    #[inline]
+    fn next_back(&mut self) -> Option<Self::Item> {
+        self.iter.next_back().or_else(|| self.peeked.take().and_then(|x| x))
+    }
+
+    #[inline]
+    fn try_rfold<B, F, R>(&mut self, init: B, mut f: F) -> R where
+        Self: Sized, F: FnMut(B, Self::Item) -> R, R: Try<Ok=B>
+    {
+        match self.peeked.take() {
+            Some(None) => return Try::from_ok(init),
+            Some(Some(v)) => match self.iter.try_rfold(init, &mut f).into_result() {
+                Ok(acc) => f(acc, v),
+                Err(e) => {
+                    self.peeked = Some(Some(v));
+                    Try::from_error(e)
+                }
+            },
+            None => self.iter.try_rfold(init, f),
+        }
+    }
+
+    #[inline]
+    fn rfold<Acc, Fold>(self, init: Acc, mut fold: Fold) -> Acc
+        where Fold: FnMut(Acc, Self::Item) -> Acc,
+    {
+        match self.peeked {
+            Some(None) => return init,
+            Some(Some(v)) => {
+                let acc = self.iter.rfold(init, &mut fold);
+                fold(acc, v)
+            }
+            None => self.iter.rfold(init, fold),
+        }
+    }
+}
+
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<I: ExactSizeIterator> ExactSizeIterator for Peekable<I> {}
 
@@ -1627,6 +1699,51 @@ impl<I> Iterator for Take<I> where I: Iterator{
     }
 }
 
+#[stable(feature = "double_ended_take_iterator", since = "1.38.0")]
+impl<I> DoubleEndedIterator for Take<I> where I: DoubleEndedIterator + ExactSizeIterator {
+    #[inline]
+    fn next_back(&mut self) -> Option<Self::Item> {
+        if self.n == 0 {
+            None
+        } else {
+            let n = self.n;
+            self.n -= 1;
+            self.iter.nth_back(self.iter.len().saturating_sub(n))
+        }
+    }
+
+    #[inline]
+    fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
+        let len = self.iter.len();
+        if self.n > n {
+            let m = len.saturating_sub(self.n) + n;
+            self.n -= n + 1;
+            self.iter.nth_back(m)
+        } else {
+            if len > 0 {
+                self.iter.nth_back(len - 1);
+            }
+            None
+        }
+    }
+
+    #[inline]
+    fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R where
+        Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try<Ok = Acc>
+    {
+        if self.n == 0 {
+            Try::from_ok(init)
+        } else {
+            let len = self.iter.len();
+            if len > self.n && self.iter.nth_back(len - self.n - 1).is_none() {
+                Try::from_ok(init)
+            } else {
+                self.iter.try_rfold(init, fold)
+            }
+        }
+    }
+}
+
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<I> ExactSizeIterator for Take<I> where I: ExactSizeIterator {}
 
diff --git a/src/libcore/ptr/mod.rs b/src/libcore/ptr/mod.rs
index 0ec4dd47b1ff0..fa55bbf9c1650 100644
--- a/src/libcore/ptr/mod.rs
+++ b/src/libcore/ptr/mod.rs
@@ -1606,10 +1606,12 @@ impl<T: ?Sized> *const T {
     /// `align`.
     ///
     /// If it is not possible to align the pointer, the implementation returns
-    /// `usize::max_value()`.
+    /// `usize::max_value()`. It is permissible for the implementation to *always*
+    /// return `usize::max_value()`. Only your algorithm's performance can depend
+    /// on getting a usable offset here, not its correctness.
     ///
     /// The offset is expressed in number of `T` elements, and not bytes. The value returned can be
-    /// used with the `add` method.
+    /// used with the `wrapping_add` method.
     ///
     /// There are no guarantees whatsoever that offsetting the pointer will not overflow or go
     /// beyond the allocation that the pointer points into. It is up to the caller to ensure that
@@ -2407,10 +2409,12 @@ impl<T: ?Sized> *mut T {
     /// `align`.
     ///
     /// If it is not possible to align the pointer, the implementation returns
-    /// `usize::max_value()`.
+    /// `usize::max_value()`. It is permissible for the implementation to *always*
+    /// return `usize::max_value()`. Only your algorithm's performance can depend
+    /// on getting a usable offset here, not its correctness.
     ///
     /// The offset is expressed in number of `T` elements, and not bytes. The value returned can be
-    /// used with the `add` method.
+    /// used with the `wrapping_add` method.
     ///
     /// There are no guarantees whatsoever that offsetting the pointer will not overflow or go
     /// beyond the allocation that the pointer points into. It is up to the caller to ensure that
diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs
index c8257d30488a9..d5a34ea2bd5a1 100644
--- a/src/libcore/slice/mod.rs
+++ b/src/libcore/slice/mod.rs
@@ -2308,9 +2308,10 @@ impl<T> [T] {
     /// maintained.
     ///
     /// This method splits the slice into three distinct slices: prefix, correctly aligned middle
-    /// slice of a new type, and the suffix slice. The method does a best effort to make the
-    /// middle slice the greatest length possible for a given type and input slice, but only
-    /// your algorithm's performance should depend on that, not its correctness.
+    /// slice of a new type, and the suffix slice. The method may make the middle slice the greatest
+    /// length possible for a given type and input slice, but only your algorithm's performance
+    /// should depend on that, not its correctness. It is permissible for all of the input data to
+    /// be returned as the prefix or suffix slice.
     ///
     /// This method has no purpose when either input element `T` or output element `U` are
     /// zero-sized and will return the original slice without splitting anything.
@@ -2361,9 +2362,10 @@ impl<T> [T] {
     /// maintained.
     ///
     /// This method splits the slice into three distinct slices: prefix, correctly aligned middle
-    /// slice of a new type, and the suffix slice. The method does a best effort to make the
-    /// middle slice the greatest length possible for a given type and input slice, but only
-    /// your algorithm's performance should depend on that, not its correctness.
+    /// slice of a new type, and the suffix slice. The method may make the middle slice the greatest
+    /// length possible for a given type and input slice, but only your algorithm's performance
+    /// should depend on that, not its correctness. It is permissible for all of the input data to
+    /// be returned as the prefix or suffix slice.
     ///
     /// This method has no purpose when either input element `T` or output element `U` are
     /// zero-sized and will return the original slice without splitting anything.
diff --git a/src/libcore/tests/iter.rs b/src/libcore/tests/iter.rs
index b7b0849e2129b..e27e160560714 100644
--- a/src/libcore/tests/iter.rs
+++ b/src/libcore/tests/iter.rs
@@ -188,6 +188,19 @@ fn test_iterator_step_by() {
     assert_eq!(it.next(), Some(6));
     assert_eq!(it.next(), Some(9));
     assert_eq!(it.next(), None);
+
+    let mut it = (0..3).step_by(1);
+    assert_eq!(it.next_back(), Some(2));
+    assert_eq!(it.next_back(), Some(1));
+    assert_eq!(it.next_back(), Some(0));
+    assert_eq!(it.next_back(), None);
+
+    let mut it = (0..11).step_by(3);
+    assert_eq!(it.next_back(), Some(9));
+    assert_eq!(it.next_back(), Some(6));
+    assert_eq!(it.next_back(), Some(3));
+    assert_eq!(it.next_back(), Some(0));
+    assert_eq!(it.next_back(), None);
 }
 
 #[test]
@@ -252,6 +265,31 @@ fn test_iterator_step_by_nth_overflow() {
     assert_eq!(it.0, (usize::MAX as Bigger) * 1);
 }
 
+#[test]
+fn test_iterator_step_by_nth_back() {
+    let mut it = (0..16).step_by(5);
+    assert_eq!(it.nth_back(0), Some(15));
+    assert_eq!(it.nth_back(0), Some(10));
+    assert_eq!(it.nth_back(0), Some(5));
+    assert_eq!(it.nth_back(0), Some(0));
+    assert_eq!(it.nth_back(0), None);
+
+    let mut it = (0..16).step_by(5);
+    assert_eq!(it.next(), Some(0)); // to set `first_take` to `false`
+    assert_eq!(it.nth_back(0), Some(15));
+    assert_eq!(it.nth_back(0), Some(10));
+    assert_eq!(it.nth_back(0), Some(5));
+    assert_eq!(it.nth_back(0), None);
+
+    let it = || (0..18).step_by(5);
+    assert_eq!(it().nth_back(0), Some(15));
+    assert_eq!(it().nth_back(1), Some(10));
+    assert_eq!(it().nth_back(2), Some(5));
+    assert_eq!(it().nth_back(3), Some(0));
+    assert_eq!(it().nth_back(4), None);
+    assert_eq!(it().nth_back(42), None);
+}
+
 #[test]
 #[should_panic]
 fn test_iterator_step_by_zero() {
@@ -465,8 +503,8 @@ fn test_iterator_filter_fold() {
 #[test]
 fn test_iterator_peekable() {
     let xs = vec![0, 1, 2, 3, 4, 5];
-    let mut it = xs.iter().cloned().peekable();
 
+    let mut it = xs.iter().cloned().peekable();
     assert_eq!(it.len(), 6);
     assert_eq!(it.peek().unwrap(), &0);
     assert_eq!(it.len(), 6);
@@ -492,6 +530,33 @@ fn test_iterator_peekable() {
     assert_eq!(it.len(), 0);
     assert!(it.next().is_none());
     assert_eq!(it.len(), 0);
+
+    let mut it = xs.iter().cloned().peekable();
+    assert_eq!(it.len(), 6);
+    assert_eq!(it.peek().unwrap(), &0);
+    assert_eq!(it.len(), 6);
+    assert_eq!(it.next_back().unwrap(), 5);
+    assert_eq!(it.len(), 5);
+    assert_eq!(it.next_back().unwrap(), 4);
+    assert_eq!(it.len(), 4);
+    assert_eq!(it.next_back().unwrap(), 3);
+    assert_eq!(it.len(), 3);
+    assert_eq!(it.peek().unwrap(), &0);
+    assert_eq!(it.len(), 3);
+    assert_eq!(it.peek().unwrap(), &0);
+    assert_eq!(it.len(), 3);
+    assert_eq!(it.next_back().unwrap(), 2);
+    assert_eq!(it.len(), 2);
+    assert_eq!(it.next_back().unwrap(), 1);
+    assert_eq!(it.len(), 1);
+    assert_eq!(it.peek().unwrap(), &0);
+    assert_eq!(it.len(), 1);
+    assert_eq!(it.next_back().unwrap(), 0);
+    assert_eq!(it.len(), 0);
+    assert!(it.peek().is_none());
+    assert_eq!(it.len(), 0);
+    assert!(it.next_back().is_none());
+    assert_eq!(it.len(), 0);
 }
 
 #[test]
@@ -564,6 +629,18 @@ fn test_iterator_peekable_fold() {
     assert_eq!(i, xs.len());
 }
 
+#[test]
+fn test_iterator_peekable_rfold() {
+    let xs = [0, 1, 2, 3, 4, 5];
+    let mut it = xs.iter().peekable();
+    assert_eq!(it.peek(), Some(&&0));
+    let i = it.rfold(0, |i, &x| {
+        assert_eq!(x, xs[xs.len() - 1 - i]);
+        i + 1
+    });
+    assert_eq!(i, xs.len());
+}
+
 /// This is an iterator that follows the Iterator contract,
 /// but it is not fused. After having returned None once, it will start
 /// producing elements if .next() is called again.
@@ -812,13 +889,25 @@ fn test_iterator_skip_fold() {
 fn test_iterator_take() {
     let xs = [0, 1, 2, 3, 5, 13, 15, 16, 17, 19];
     let ys = [0, 1, 2, 3, 5];
-    let mut it = xs.iter().take(5);
+
+    let mut it = xs.iter().take(ys.len());
     let mut i = 0;
-    assert_eq!(it.len(), 5);
+    assert_eq!(it.len(), ys.len());
     while let Some(&x) = it.next() {
         assert_eq!(x, ys[i]);
         i += 1;
-        assert_eq!(it.len(), 5-i);
+        assert_eq!(it.len(), ys.len() - i);
+    }
+    assert_eq!(i, ys.len());
+    assert_eq!(it.len(), 0);
+
+    let mut it = xs.iter().take(ys.len());
+    let mut i = 0;
+    assert_eq!(it.len(), ys.len());
+    while let Some(&x) = it.next_back() {
+        i += 1;
+        assert_eq!(x, ys[ys.len() - i]);
+        assert_eq!(it.len(), ys.len() - i);
     }
     assert_eq!(i, ys.len());
     assert_eq!(it.len(), 0);
@@ -848,19 +937,51 @@ fn test_iterator_take_nth() {
     }
 }
 
+#[test]
+fn test_iterator_take_nth_back() {
+    let xs = [0, 1, 2, 4, 5];
+    let mut it = xs.iter();
+    {
+        let mut take = it.by_ref().take(3);
+        let mut i = 0;
+        while let Some(&x) = take.nth_back(0) {
+            i += 1;
+            assert_eq!(x, 3 - i);
+        }
+    }
+    assert_eq!(it.nth_back(0), None);
+
+    let xs = [0, 1, 2, 3, 4];
+    let mut it = xs.iter().take(7);
+    assert_eq!(it.nth_back(1), Some(&3));
+    assert_eq!(it.nth_back(1), Some(&1));
+    assert_eq!(it.nth_back(1), None);
+}
+
 #[test]
 fn test_iterator_take_short() {
     let xs = [0, 1, 2, 3];
-    let ys = [0, 1, 2, 3];
+
     let mut it = xs.iter().take(5);
     let mut i = 0;
-    assert_eq!(it.len(), 4);
+    assert_eq!(it.len(), xs.len());
     while let Some(&x) = it.next() {
-        assert_eq!(x, ys[i]);
+        assert_eq!(x, xs[i]);
         i += 1;
-        assert_eq!(it.len(), 4-i);
+        assert_eq!(it.len(), xs.len() - i);
     }
-    assert_eq!(i, ys.len());
+    assert_eq!(i, xs.len());
+    assert_eq!(it.len(), 0);
+
+    let mut it = xs.iter().take(5);
+    let mut i = 0;
+    assert_eq!(it.len(), xs.len());
+    while let Some(&x) = it.next_back() {
+        i += 1;
+        assert_eq!(x, xs[xs.len() - i]);
+        assert_eq!(it.len(), xs.len() - i);
+    }
+    assert_eq!(i, xs.len());
     assert_eq!(it.len(), 0);
 }
 
@@ -2278,17 +2399,50 @@ fn test_enumerate_try_folds() {
 }
 
 #[test]
-fn test_peek_try_fold() {
+fn test_peek_try_folds() {
     let f = &|acc, x| i32::checked_add(2*acc, x);
+
     assert_eq!((1..20).peekable().try_fold(7, f), (1..20).try_fold(7, f));
+    assert_eq!((1..20).peekable().try_rfold(7, f), (1..20).try_rfold(7, f));
+
     let mut iter = (1..20).peekable();
     assert_eq!(iter.peek(), Some(&1));
     assert_eq!(iter.try_fold(7, f), (1..20).try_fold(7, f));
 
+    let mut iter = (1..20).peekable();
+    assert_eq!(iter.peek(), Some(&1));
+    assert_eq!(iter.try_rfold(7, f), (1..20).try_rfold(7, f));
+
     let mut iter = [100, 20, 30, 40, 50, 60, 70].iter().cloned().peekable();
     assert_eq!(iter.peek(), Some(&100));
     assert_eq!(iter.try_fold(0, i8::checked_add), None);
     assert_eq!(iter.peek(), Some(&40));
+
+    let mut iter = [100, 20, 30, 40, 50, 60, 70].iter().cloned().peekable();
+    assert_eq!(iter.peek(), Some(&100));
+    assert_eq!(iter.try_rfold(0, i8::checked_add), None);
+    assert_eq!(iter.peek(), Some(&100));
+    assert_eq!(iter.next_back(), Some(50));
+
+    let mut iter = (2..5).peekable();
+    assert_eq!(iter.peek(), Some(&2));
+    assert_eq!(iter.try_for_each(Err), Err(2));
+    assert_eq!(iter.peek(), Some(&3));
+    assert_eq!(iter.try_for_each(Err), Err(3));
+    assert_eq!(iter.peek(), Some(&4));
+    assert_eq!(iter.try_for_each(Err), Err(4));
+    assert_eq!(iter.peek(), None);
+    assert_eq!(iter.try_for_each(Err), Ok(()));
+
+    let mut iter = (2..5).peekable();
+    assert_eq!(iter.peek(), Some(&2));
+    assert_eq!(iter.try_rfold((), |(), x| Err(x)), Err(4));
+    assert_eq!(iter.peek(), Some(&2));
+    assert_eq!(iter.try_rfold((), |(), x| Err(x)), Err(3));
+    assert_eq!(iter.peek(), Some(&2));
+    assert_eq!(iter.try_rfold((), |(), x| Err(x)), Err(2));
+    assert_eq!(iter.peek(), None);
+    assert_eq!(iter.try_rfold((), |(), x| Err(x)), Ok(()));
 }
 
 #[test]
@@ -2371,13 +2525,25 @@ fn test_skip_nth_back() {
 fn test_take_try_folds() {
     let f = &|acc, x| i32::checked_add(2*acc, x);
     assert_eq!((10..30).take(10).try_fold(7, f), (10..20).try_fold(7, f));
-    //assert_eq!((10..30).take(10).try_rfold(7, f), (10..20).try_rfold(7, f));
+    assert_eq!((10..30).take(10).try_rfold(7, f), (10..20).try_rfold(7, f));
 
     let mut iter = (10..30).take(20);
     assert_eq!(iter.try_fold(0, i8::checked_add), None);
     assert_eq!(iter.next(), Some(20));
-    //assert_eq!(iter.try_rfold(0, i8::checked_add), None);
-    //assert_eq!(iter.next_back(), Some(24));
+    assert_eq!(iter.try_rfold(0, i8::checked_add), None);
+    assert_eq!(iter.next_back(), Some(24));
+
+    let mut iter = (2..20).take(3);
+    assert_eq!(iter.try_for_each(Err), Err(2));
+    assert_eq!(iter.try_for_each(Err), Err(3));
+    assert_eq!(iter.try_for_each(Err), Err(4));
+    assert_eq!(iter.try_for_each(Err), Ok(()));
+
+    let mut iter = (2..20).take(3).rev();
+    assert_eq!(iter.try_for_each(Err), Err(4));
+    assert_eq!(iter.try_for_each(Err), Err(3));
+    assert_eq!(iter.try_for_each(Err), Err(2));
+    assert_eq!(iter.try_for_each(Err), Ok(()));
 }
 
 #[test]
diff --git a/src/libcore/tests/ptr.rs b/src/libcore/tests/ptr.rs
index 569b3197d09bd..1a6be3a9bbd03 100644
--- a/src/libcore/tests/ptr.rs
+++ b/src/libcore/tests/ptr.rs
@@ -145,7 +145,6 @@ fn test_as_ref() {
 }
 
 #[test]
-#[cfg(not(miri))] // This test is UB according to Stacked Borrows
 fn test_as_mut() {
     unsafe {
         let p: *mut isize = null_mut();
@@ -164,7 +163,7 @@ fn test_as_mut() {
         // Pointers to unsized types -- slices
         let s: &mut [u8] = &mut [1, 2, 3];
         let ms: *mut [u8] = s;
-        assert_eq!(ms.as_mut(), Some(s));
+        assert_eq!(ms.as_mut(), Some(&mut [1, 2, 3][..]));
 
         let mz: *mut [u8] = &mut [];
         assert_eq!(mz.as_mut(), Some(&mut [][..]));
diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs
index 5031e6dbd87d2..493083c680aad 100644
--- a/src/librustc/hir/lowering.rs
+++ b/src/librustc/hir/lowering.rs
@@ -5176,11 +5176,10 @@ impl<'a> LoweringContext<'a> {
                 let attr = {
                     // `allow(unreachable_code)`
                     let allow = {
-                        let allow_ident = Ident::with_empty_ctxt(sym::allow).with_span_pos(e.span);
-                        let uc_ident = Ident::with_empty_ctxt(sym::unreachable_code)
-                            .with_span_pos(e.span);
+                        let allow_ident = Ident::new(sym::allow, e.span);
+                        let uc_ident = Ident::new(sym::unreachable_code, e.span);
                         let uc_nested = attr::mk_nested_word_item(uc_ident);
-                        attr::mk_list_item(e.span, allow_ident, vec![uc_nested])
+                        attr::mk_list_item(allow_ident, vec![uc_nested])
                     };
                     attr::mk_attr_outer(allow)
                 };
diff --git a/src/librustc/ich/impls_syntax.rs b/src/librustc/ich/impls_syntax.rs
index 0c9c9adcf9da6..5cc8324b31606 100644
--- a/src/librustc/ich/impls_syntax.rs
+++ b/src/librustc/ich/impls_syntax.rs
@@ -363,7 +363,8 @@ impl<'a> HashStable<StableHashingContext<'a>> for token::TokenKind {
             }
 
             token::DocComment(val) |
-            token::Shebang(val) => val.hash_stable(hcx, hasher),
+            token::Shebang(val) |
+            token::Unknown(val) => val.hash_stable(hcx, hasher),
         }
     }
 }
diff --git a/src/librustc/infer/lexical_region_resolve/README.md b/src/librustc/infer/lexical_region_resolve/README.md
index 56320636a6743..7eb4da86ec081 100644
--- a/src/librustc/infer/lexical_region_resolve/README.md
+++ b/src/librustc/infer/lexical_region_resolve/README.md
@@ -6,7 +6,7 @@
 > As of edition 2018, region inference is done using Non-lexical lifetimes,
 > which is described in the guide and [this RFC].
 
-[rustc guide]: https://rust-lang.github.io/rustc-guide/mir/borrowck.html
+[rustc guide]: https://rust-lang.github.io/rustc-guide/borrow_check/region_inference.html
 [this RFC]: https://github.com/rust-lang/rfcs/blob/master/text/2094-nll.md
 
 ## Terminology
diff --git a/src/librustc/traits/specialize/mod.rs b/src/librustc/traits/specialize/mod.rs
index 8a84fca143809..f0389bb037ac5 100644
--- a/src/librustc/traits/specialize/mod.rs
+++ b/src/librustc/traits/specialize/mod.rs
@@ -366,13 +366,8 @@ pub(super) fn specialization_graph_provider(
                     }
                 }
 
-                let access_levels = tcx.privacy_access_levels(impl_def_id.krate);
-                if let Some(id) = tcx.hir().as_local_hir_id(impl_def_id) {
-                    if access_levels.is_exported(id) || access_levels.is_public(id) {
-                        for cause in &overlap.intercrate_ambiguity_causes {
-                            cause.add_intercrate_ambiguity_hint(&mut err);
-                        }
-                    }
+                for cause in &overlap.intercrate_ambiguity_causes {
+                    cause.add_intercrate_ambiguity_hint(&mut err);
                 }
 
                 if overlap.involves_placeholder {
diff --git a/src/librustc_mir/borrow_check/conflict_errors.rs b/src/librustc_mir/borrow_check/conflict_errors.rs
index 77e5ac2f86514..4217a29bc663c 100644
--- a/src/librustc_mir/borrow_check/conflict_errors.rs
+++ b/src/librustc_mir/borrow_check/conflict_errors.rs
@@ -105,6 +105,9 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                 format!("{} occurs due to use{}", desired_action.as_noun(), use_spans.describe()),
             );
 
+            // This error should not be downgraded to a warning,
+            // even in migrate mode.
+            self.disable_error_downgrading();
             err.buffer(&mut self.errors_buffer);
         } else {
             if let Some((reported_place, _)) = self.move_error_reported.get(&move_out_indices) {
diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs
index 340ca5747d843..de27aec2b2990 100644
--- a/src/librustc_mir/borrow_check/mod.rs
+++ b/src/librustc_mir/borrow_check/mod.rs
@@ -253,6 +253,7 @@ fn do_mir_borrowck<'a, 'tcx>(
         move_error_reported: BTreeMap::new(),
         uninitialized_error_reported: Default::default(),
         errors_buffer,
+        disable_error_downgrading: false,
         nonlexical_regioncx: regioncx,
         used_mut: Default::default(),
         used_mut_upvars: SmallVec::new(),
@@ -364,7 +365,7 @@ fn do_mir_borrowck<'a, 'tcx>(
     if !mbcx.errors_buffer.is_empty() {
         mbcx.errors_buffer.sort_by_key(|diag| diag.span.primary_span());
 
-        if tcx.migrate_borrowck() {
+        if !mbcx.disable_error_downgrading && tcx.migrate_borrowck() {
             // When borrowck=migrate, check if AST-borrowck would
             // error on the given code.
 
@@ -481,6 +482,9 @@ crate struct MirBorrowckCtxt<'cx, 'tcx> {
     uninitialized_error_reported: FxHashSet<PlaceRef<'cx, 'tcx>>,
     /// Errors to be reported buffer
     errors_buffer: Vec<Diagnostic>,
+    /// If there are no errors reported by the HIR borrow checker, we downgrade
+    /// all NLL errors to warnings. Setting this flag disables downgrading.
+    disable_error_downgrading: bool,
     /// This field keeps track of all the local variables that are declared mut and are mutated.
     /// Used for the warning issued by an unused mutable local variable.
     used_mut: FxHashSet<Local>,
@@ -921,6 +925,12 @@ impl InitializationRequiringAction {
 }
 
 impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
+    /// If there are no errors reported by the HIR borrow checker, we downgrade
+    /// all NLL errors to warnings. Calling this disables downgrading.
+    crate fn disable_error_downgrading(&mut self)  {
+        self.disable_error_downgrading = true;
+    }
+
     /// Checks an access to the given place to see if it is allowed. Examines the set of borrows
     /// that are in scope, as well as which paths have been initialized, to ensure that (a) the
     /// place is initialized and (b) it is not borrowed in some way that would prevent this
diff --git a/src/librustc_mir/interpret/snapshot.rs b/src/librustc_mir/interpret/snapshot.rs
index 70a297c866280..fad9fafbb0803 100644
--- a/src/librustc_mir/interpret/snapshot.rs
+++ b/src/librustc_mir/interpret/snapshot.rs
@@ -305,7 +305,7 @@ impl_stable_hash_for!(enum crate::interpret::eval_context::StackPopCleanup {
 #[derive(Eq, PartialEq)]
 struct FrameSnapshot<'a, 'tcx> {
     instance: &'a ty::Instance<'tcx>,
-    span: &'a Span,
+    span: Span,
     return_to_block: &'a StackPopCleanup,
     return_place: Option<Place<(), AllocIdSnapshot<'a>>>,
     locals: IndexVec<mir::Local, LocalValue<(), AllocIdSnapshot<'a>>>,
@@ -345,7 +345,7 @@ impl<'a, 'mir, 'tcx, Ctx> Snapshot<'a, Ctx> for &'a Frame<'mir, 'tcx>
 
         FrameSnapshot {
             instance,
-            span,
+            span: *span,
             return_to_block,
             block,
             stmt: *stmt,
diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs
index 163d10b9bd5f3..dcfc80968f31c 100644
--- a/src/librustc_mir/transform/qualify_consts.rs
+++ b/src/librustc_mir/transform/qualify_consts.rs
@@ -182,16 +182,17 @@ trait Qualif {
 
     fn in_projection_structurally(
         cx: &ConstCx<'_, 'tcx>,
-        base: &PlaceBase<'tcx>,
-        proj: &Projection<'tcx>,
+        place: PlaceRef<'_, 'tcx>,
     ) -> bool {
+        let proj = place.projection.as_ref().unwrap();
+
         let base_qualif = Self::in_place(cx, PlaceRef {
-            base,
+            base: place.base,
             projection: &proj.base,
         });
         let qualif = base_qualif && Self::mask_for_ty(
             cx,
-            Place::ty_from(&base, &proj.base, cx.body, cx.tcx)
+            Place::ty_from(place.base, &proj.base, cx.body, cx.tcx)
                 .projection_ty(cx.tcx, &proj.elem)
                 .ty,
         );
@@ -208,10 +209,9 @@ trait Qualif {
 
     fn in_projection(
         cx: &ConstCx<'_, 'tcx>,
-        base: &PlaceBase<'tcx>,
-        proj: &Projection<'tcx>,
+        place: PlaceRef<'_, 'tcx>,
     ) -> bool {
-        Self::in_projection_structurally(cx, base, proj)
+        Self::in_projection_structurally(cx, place)
     }
 
     fn in_place(cx: &ConstCx<'_, 'tcx>, place: PlaceRef<'_, 'tcx>) -> bool {
@@ -234,9 +234,9 @@ trait Qualif {
                 Self::in_static(cx, static_)
             },
             PlaceRef {
-                base,
-                projection: Some(proj),
-            } => Self::in_projection(cx, base, proj),
+                base: _,
+                projection: Some(_),
+            } => Self::in_projection(cx, place),
         }
     }
 
@@ -448,9 +448,10 @@ impl Qualif for IsNotPromotable {
 
     fn in_projection(
         cx: &ConstCx<'_, 'tcx>,
-        base: &PlaceBase<'tcx>,
-        proj: &Projection<'tcx>,
+        place: PlaceRef<'_, 'tcx>,
     ) -> bool {
+        let proj = place.projection.as_ref().unwrap();
+
         match proj.elem {
             ProjectionElem::Deref |
             ProjectionElem::Downcast(..) => return true,
@@ -461,7 +462,7 @@ impl Qualif for IsNotPromotable {
 
             ProjectionElem::Field(..) => {
                 if cx.mode == Mode::NonConstFn {
-                    let base_ty = Place::ty_from(base, &proj.base, cx.body, cx.tcx).ty;
+                    let base_ty = Place::ty_from(place.base, &proj.base, cx.body, cx.tcx).ty;
                     if let Some(def) = base_ty.ty_adt_def() {
                         // No promotion of union field accesses.
                         if def.is_union() {
@@ -472,7 +473,7 @@ impl Qualif for IsNotPromotable {
             }
         }
 
-        Self::in_projection_structurally(cx, base, proj)
+        Self::in_projection_structurally(cx, place)
     }
 
     fn in_rvalue(cx: &ConstCx<'_, 'tcx>, rvalue: &Rvalue<'tcx>) -> bool {
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index 1a203e73f0a86..1908d85e4ff2a 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -171,7 +171,7 @@ enum ResolutionError<'a> {
     GenericParamsFromOuterFunction(Res),
     /// Error E0403: the name is already used for a type or const parameter in this generic
     /// parameter list.
-    NameAlreadyUsedInParameterList(Name, &'a Span),
+    NameAlreadyUsedInParameterList(Name, Span),
     /// Error E0407: method is not a member of trait.
     MethodNotMemberOfTrait(Name, &'a str),
     /// Error E0437: type is not a member of trait.
@@ -297,7 +297,7 @@ fn resolve_struct_error<'sess, 'a>(resolver: &'sess Resolver<'_>,
                                             parameter in this list of generic parameters",
                                             name);
              err.span_label(span, "already used");
-             err.span_label(first_use_span.clone(), format!("first use of `{}`", name));
+             err.span_label(first_use_span, format!("first use of `{}`", name));
              err
         }
         ResolutionError::MethodNotMemberOfTrait(method, trait_) => {
@@ -2853,7 +2853,7 @@ impl<'a> Resolver<'a> {
                                 let span = seen_bindings.get(&ident).unwrap();
                                 let err = ResolutionError::NameAlreadyUsedInParameterList(
                                     ident.name,
-                                    span,
+                                    *span,
                                 );
                                 resolve_error(self, param.ident.span, err);
                             }
@@ -2875,7 +2875,7 @@ impl<'a> Resolver<'a> {
                                 let span = seen_bindings.get(&ident).unwrap();
                                 let err = ResolutionError::NameAlreadyUsedInParameterList(
                                     ident.name,
-                                    span,
+                                    *span,
                                 );
                                 resolve_error(self, param.ident.span, err);
                             }
diff --git a/src/librustdoc/clean/cfg/tests.rs b/src/librustdoc/clean/cfg/tests.rs
index d0df9f8f7e410..405144b444f09 100644
--- a/src/librustdoc/clean/cfg/tests.rs
+++ b/src/librustdoc/clean/cfg/tests.rs
@@ -211,7 +211,6 @@ fn test_parse_ok() {
 fn test_parse_err() {
     with_default_globals(|| {
         let mi = attr::mk_name_value_item(
-            DUMMY_SP,
             Ident::from_str("foo"),
             LitKind::Bool(false),
             DUMMY_SP,
diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs
index 8132074d6e0e7..5d86ee9721b75 100644
--- a/src/librustdoc/html/highlight.rs
+++ b/src/librustdoc/html/highlight.rs
@@ -44,7 +44,7 @@ pub fn render_with_highlighting(
 
         let mut highlighted_source = vec![];
         if classifier.write_source(&mut highlighted_source).is_err() {
-            Err(classifier.lexer.buffer_fatal_errors())
+            Err(())
         } else {
             Ok(String::from_utf8_lossy(&highlighted_source).into_owned())
         }
@@ -59,14 +59,9 @@ pub fn render_with_highlighting(
             }
             write_footer(&mut out).unwrap();
         }
-        Err(errors) => {
-            // If errors are encountered while trying to highlight, cancel the errors and just emit
-            // the unhighlighted source. The errors will have already been reported in the
-            // `check-code-block-syntax` pass.
-            for mut error in errors {
-                error.cancel();
-            }
-
+        Err(()) => {
+            // If errors are encountered while trying to highlight, just emit
+            // the unhighlighted source.
             write!(out, "<pre><code>{}</code></pre>", src).unwrap();
         }
     }
@@ -192,14 +187,20 @@ impl<'a> Classifier<'a> {
         if let Some(token) = self.peek_token.take() {
             return Ok(token);
         }
-        self.lexer.try_next_token().map_err(|()| HighlightError::LexError)
+        let token = self.lexer.next_token();
+        if let token::Unknown(..) = &token.kind {
+            return Err(HighlightError::LexError);
+        }
+        Ok(token)
     }
 
     fn peek(&mut self) -> Result<&Token, HighlightError> {
         if self.peek_token.is_none() {
-            self.peek_token = Some(
-                self.lexer.try_next_token().map_err(|()| HighlightError::LexError)?
-            );
+            let token = self.lexer.next_token();
+            if let token::Unknown(..) = &token.kind {
+                return Err(HighlightError::LexError);
+            }
+            self.peek_token = Some(token);
         }
         Ok(self.peek_token.as_ref().unwrap())
     }
@@ -237,7 +238,7 @@ impl<'a> Classifier<'a> {
                 return Ok(());
             },
 
-            token::Whitespace => Class::None,
+            token::Whitespace | token::Unknown(..) => Class::None,
             token::Comment => Class::Comment,
             token::DocComment(..) => Class::DocComment,
 
diff --git a/src/librustdoc/passes/check_code_block_syntax.rs b/src/librustdoc/passes/check_code_block_syntax.rs
index 0488153e7cb73..357e17d2d1bc4 100644
--- a/src/librustdoc/passes/check_code_block_syntax.rs
+++ b/src/librustdoc/passes/check_code_block_syntax.rs
@@ -32,24 +32,20 @@ impl<'a, 'tcx> SyntaxChecker<'a, 'tcx> {
             dox[code_block.code].to_owned(),
         );
 
-        let errors = {
+        let has_errors = {
+            let mut has_errors = false;
             let mut lexer = Lexer::new(&sess, source_file, None);
-            while let Ok(token::Token { kind, .. }) = lexer.try_next_token() {
-                if kind == token::Eof {
-                    break;
+            loop  {
+                match lexer.next_token().kind {
+                    token::Eof => break,
+                    token::Unknown(..) => has_errors = true,
+                    _ => (),
                 }
             }
-
-            let errors = lexer.buffer_fatal_errors();
-
-            if !errors.is_empty() {
-                Err(errors)
-            } else {
-                Ok(())
-            }
+            has_errors
         };
 
-        if let Err(errors) = errors {
+        if has_errors {
             let mut diag = if let Some(sp) =
                 super::source_span_for_markdown_range(self.cx, &dox, &code_block.range, &item.attrs)
             {
@@ -58,11 +54,6 @@ impl<'a, 'tcx> SyntaxChecker<'a, 'tcx> {
                     .sess()
                     .struct_span_warn(sp, "could not parse code block as Rust code");
 
-                for mut err in errors {
-                    diag.note(&format!("error from rustc: {}", err.message()));
-                    err.cancel();
-                }
-
                 if code_block.syntax.is_none() && code_block.is_fenced {
                     let sp = sp.from_inner(InnerSpan::new(0, 3));
                     diag.span_suggestion(
@@ -82,11 +73,6 @@ impl<'a, 'tcx> SyntaxChecker<'a, 'tcx> {
                     "doc comment contains an invalid Rust code block",
                 );
 
-                for mut err in errors {
-                    // Don't bother reporting the error, because we can't show where it happened.
-                    err.cancel();
-                }
-
                 if code_block.syntax.is_none() && code_block.is_fenced {
                     diag.help("mark blocks that do not contain Rust code as text: ```text");
                 }
diff --git a/src/libstd/path.rs b/src/libstd/path.rs
index 126bc3754dabc..56fde77daac58 100644
--- a/src/libstd/path.rs
+++ b/src/libstd/path.rs
@@ -1819,6 +1819,8 @@ impl Path {
     /// Yields a [`&str`] slice if the `Path` is valid unicode.
     ///
     /// This conversion may entail doing a check for UTF-8 validity.
+    /// Note that validation is performed because non-UTF-8 strings are
+    /// perfectly valid for some OS.
     ///
     /// [`&str`]: ../primitive.str.html
     ///
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index 849e77c4f3112..052eb55b40811 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -1284,15 +1284,6 @@ pub enum Movability {
     Movable,
 }
 
-/// Whether an `await` comes from `await!` or `.await` syntax.
-/// FIXME: this should be removed when support for legacy `await!` is removed.
-/// https://github.com/rust-lang/rust/issues/60610
-#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, Copy)]
-pub enum AwaitOrigin {
-    FieldLike,
-    MacroLike,
-}
-
 pub type Mac = Spanned<Mac_>;
 
 /// Represents a macro invocation. The `Path` indicates which macro
diff --git a/src/libsyntax/attr/mod.rs b/src/libsyntax/attr/mod.rs
index 3e56136b17108..a9d3227b3a8f4 100644
--- a/src/libsyntax/attr/mod.rs
+++ b/src/libsyntax/attr/mod.rs
@@ -347,16 +347,17 @@ impl Attribute {
 
 pub fn mk_name_value_item_str(ident: Ident, value: Spanned<Symbol>) -> MetaItem {
     let lit_kind = LitKind::Str(value.node, ast::StrStyle::Cooked);
-    mk_name_value_item(ident.span.to(value.span), ident, lit_kind, value.span)
+    mk_name_value_item(ident, lit_kind, value.span)
 }
 
-pub fn mk_name_value_item(span: Span, ident: Ident, lit_kind: LitKind, lit_span: Span) -> MetaItem {
+pub fn mk_name_value_item(ident: Ident, lit_kind: LitKind, lit_span: Span) -> MetaItem {
     let lit = Lit::from_lit_kind(lit_kind, lit_span);
+    let span = ident.span.to(lit_span);
     MetaItem { path: Path::from_ident(ident), span, node: MetaItemKind::NameValue(lit) }
 }
 
-pub fn mk_list_item(span: Span, ident: Ident, items: Vec<NestedMetaItem>) -> MetaItem {
-    MetaItem { path: Path::from_ident(ident), span, node: MetaItemKind::List(items) }
+pub fn mk_list_item(ident: Ident, items: Vec<NestedMetaItem>) -> MetaItem {
+    MetaItem { path: Path::from_ident(ident), span: ident.span, node: MetaItemKind::List(items) }
 }
 
 pub fn mk_word_item(ident: Ident) -> MetaItem {
@@ -367,7 +368,7 @@ pub fn mk_nested_word_item(ident: Ident) -> NestedMetaItem {
     NestedMetaItem::MetaItem(mk_word_item(ident))
 }
 
-pub fn mk_attr_id() -> AttrId {
+crate fn mk_attr_id() -> AttrId {
     use std::sync::atomic::AtomicUsize;
     use std::sync::atomic::Ordering;
 
diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs
index 59e13fdc8f163..db562840e8d3b 100644
--- a/src/libsyntax/ext/build.rs
+++ b/src/libsyntax/ext/build.rs
@@ -879,13 +879,12 @@ impl<'a> ExtCtxt<'a> {
 
     pub fn meta_list(&self, sp: Span, name: ast::Name, mis: Vec<ast::NestedMetaItem>)
                  -> ast::MetaItem {
-        attr::mk_list_item(sp, Ident::new(name, sp), mis)
+        attr::mk_list_item(Ident::new(name, sp), mis)
     }
 
     pub fn meta_name_value(&self, span: Span, name: ast::Name, lit_kind: ast::LitKind)
                        -> ast::MetaItem {
-        attr::mk_name_value_item(span, Ident::new(name, span),
-                                 lit_kind, span)
+        attr::mk_name_value_item(Ident::new(name, span), lit_kind, span)
     }
 
     pub fn item_use(&self, sp: Span,
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index d2807e4a4b5fa..964c81dd46641 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -1272,7 +1272,7 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
                             ];
 
                             let include_ident = Ident::with_empty_ctxt(sym::include);
-                            let item = attr::mk_list_item(DUMMY_SP, include_ident, include_info);
+                            let item = attr::mk_list_item(include_ident, include_info);
                             items.push(ast::NestedMetaItem::MetaItem(item));
                         }
                         Err(e) => {
@@ -1333,7 +1333,7 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
                 }
             }
 
-            let meta = attr::mk_list_item(DUMMY_SP, Ident::with_empty_ctxt(sym::doc), items);
+            let meta = attr::mk_list_item(Ident::with_empty_ctxt(sym::doc), items);
             *at = attr::Attribute {
                 span: at.span,
                 id: at.id,
diff --git a/src/libsyntax/ext/proc_macro_server.rs b/src/libsyntax/ext/proc_macro_server.rs
index 8d0023c9ab1eb..36621ce777510 100644
--- a/src/libsyntax/ext/proc_macro_server.rs
+++ b/src/libsyntax/ext/proc_macro_server.rs
@@ -184,7 +184,7 @@ impl FromInternal<(TreeAndJoint, &'_ ParseSess, &'_ mut Vec<Self>)>
             }
 
             OpenDelim(..) | CloseDelim(..) => unreachable!(),
-            Whitespace | Comment | Shebang(..) | Eof => unreachable!(),
+            Whitespace | Comment | Shebang(..) | Unknown(..) | Eof => unreachable!(),
         }
     }
 }
diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs
index 950b1b2ff5340..e86d4c7fde683 100644
--- a/src/libsyntax/parse/lexer/mod.rs
+++ b/src/libsyntax/parse/lexer/mod.rs
@@ -3,7 +3,7 @@ use crate::parse::token::{self, Token, TokenKind};
 use crate::symbol::{sym, Symbol};
 use crate::parse::unescape_error_reporting::{emit_unescape_error, push_escaped_char};
 
-use errors::{FatalError, Diagnostic, DiagnosticBuilder};
+use errors::{FatalError, DiagnosticBuilder};
 use syntax_pos::{BytePos, Pos, Span, NO_EXPANSION};
 use rustc_lexer::Base;
 use rustc_lexer::unescape;
@@ -39,7 +39,6 @@ pub struct StringReader<'a> {
     pos: BytePos,
     /// Stop reading src at this index.
     end_src_index: usize,
-    fatal_errs: Vec<DiagnosticBuilder<'a>>,
     /// Source text to tokenize.
     src: Lrc<String>,
     override_span: Option<Span>,
@@ -62,7 +61,6 @@ impl<'a> StringReader<'a> {
             pos: source_file.start_pos,
             end_src_index: src.len(),
             src,
-            fatal_errs: Vec::new(),
             override_span,
         }
     }
@@ -89,29 +87,17 @@ impl<'a> StringReader<'a> {
         self.override_span.unwrap_or_else(|| Span::new(lo, hi, NO_EXPANSION))
     }
 
-    fn unwrap_or_abort(&mut self, res: Result<Token, ()>) -> Token {
-        match res {
-            Ok(tok) => tok,
-            Err(_) => {
-                self.emit_fatal_errors();
-                FatalError.raise();
-            }
-        }
-    }
-
     /// Returns the next token, including trivia like whitespace or comments.
     ///
     /// `Err(())` means that some errors were encountered, which can be
     /// retrieved using `buffer_fatal_errors`.
-    pub fn try_next_token(&mut self) -> Result<Token, ()> {
-        assert!(self.fatal_errs.is_empty());
-
+    pub fn next_token(&mut self) -> Token {
         let start_src_index = self.src_index(self.pos);
         let text: &str = &self.src[start_src_index..self.end_src_index];
 
         if text.is_empty() {
             let span = self.mk_sp(self.pos, self.pos);
-            return Ok(Token::new(token::Eof, span));
+            return Token::new(token::Eof, span);
         }
 
         {
@@ -125,7 +111,7 @@ impl<'a> StringReader<'a> {
                     let kind = token::Shebang(sym);
 
                     let span = self.mk_sp(start, self.pos);
-                    return Ok(Token::new(kind, span));
+                    return Token::new(kind, span);
                 }
             }
         }
@@ -139,39 +125,10 @@ impl<'a> StringReader<'a> {
 
         // This could use `?`, but that makes code significantly (10-20%) slower.
         // https://github.com/rust-lang/rust/issues/37939
-        let kind = match self.cook_lexer_token(token.kind, start) {
-            Ok(it) => it,
-            Err(err) => return Err(self.fatal_errs.push(err)),
-        };
+        let kind = self.cook_lexer_token(token.kind, start);
 
         let span = self.mk_sp(start, self.pos);
-        Ok(Token::new(kind, span))
-    }
-
-    /// Returns the next token, including trivia like whitespace or comments.
-    ///
-    /// Aborts in case of an error.
-    pub fn next_token(&mut self) -> Token {
-        let res = self.try_next_token();
-        self.unwrap_or_abort(res)
-    }
-
-    fn emit_fatal_errors(&mut self) {
-        for err in &mut self.fatal_errs {
-            err.emit();
-        }
-
-        self.fatal_errs.clear();
-    }
-
-    pub fn buffer_fatal_errors(&mut self) -> Vec<Diagnostic> {
-        let mut buffer = Vec::new();
-
-        for err in self.fatal_errs.drain(..) {
-            err.buffer(&mut buffer);
-        }
-
-        buffer
+        Token::new(kind, span)
     }
 
     /// Report a fatal lexical error with a given span.
@@ -218,8 +175,8 @@ impl<'a> StringReader<'a> {
         &self,
         token: rustc_lexer::TokenKind,
         start: BytePos,
-    ) -> Result<TokenKind, DiagnosticBuilder<'a>> {
-        let kind = match token {
+    ) -> TokenKind {
+        match token {
             rustc_lexer::TokenKind::LineComment => {
                 let string = self.str_from(start);
                 // comments with only more "/"s are not doc comments
@@ -396,16 +353,12 @@ impl<'a> StringReader<'a> {
                 // this should be inside `rustc_lexer`. However, we should first remove compound
                 // tokens like `<<` from `rustc_lexer`, and then add fancier error recovery to it,
                 // as there will be less overall work to do this way.
-                return match unicode_chars::check_for_substitution(self, start, c, &mut err) {
-                    Some(token) => {
-                        err.emit();
-                        Ok(token)
-                    }
-                    None => Err(err),
-                }
+                let token = unicode_chars::check_for_substitution(self, start, c, &mut err)
+                    .unwrap_or_else(|| token::Unknown(self.symbol_from(start)));
+                err.emit();
+                token
             }
-        };
-        Ok(kind)
+        }
     }
 
     fn cook_lexer_literal(
diff --git a/src/libsyntax/parse/lexer/tokentrees.rs b/src/libsyntax/parse/lexer/tokentrees.rs
index 830fbec58ded9..37e67a2729e6d 100644
--- a/src/libsyntax/parse/lexer/tokentrees.rs
+++ b/src/libsyntax/parse/lexer/tokentrees.rs
@@ -217,7 +217,7 @@ impl<'a> TokenTreesReader<'a> {
         loop {
             let token = self.string_reader.next_token();
             match token.kind {
-                token::Whitespace | token::Comment | token::Shebang(_) => {
+                token::Whitespace | token::Comment | token::Shebang(_) | token::Unknown(_) => {
                     self.joint_to_prev = NonJoint;
                 }
                 _ => {
diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs
index 73adb5c947c0b..be800b4de66af 100644
--- a/src/libsyntax/parse/token.rs
+++ b/src/libsyntax/parse/token.rs
@@ -255,6 +255,8 @@ pub enum TokenKind {
     /// A comment.
     Comment,
     Shebang(ast::Name),
+    /// A completely invalid token which should be skipped.
+    Unknown(ast::Name),
 
     Eof,
 }
@@ -603,7 +605,7 @@ impl Token {
             DotDotEq | Comma | Semi | ModSep | RArrow | LArrow | FatArrow | Pound | Dollar |
             Question | OpenDelim(..) | CloseDelim(..) |
             Literal(..) | Ident(..) | Lifetime(..) | Interpolated(..) | DocComment(..) |
-            Whitespace | Comment | Shebang(..) | Eof => return None,
+            Whitespace | Comment | Shebang(..) | Unknown(..) | Eof => return None,
         };
 
         Some(Token::new(kind, self.span.to(joint.span)))
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index 2ef8a919b9c56..bda761244d5ca 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -15,7 +15,7 @@ use crate::tokenstream::{self, TokenStream, TokenTree};
 
 use rustc_target::spec::abi::{self, Abi};
 use syntax_pos::{self, BytePos};
-use syntax_pos::{DUMMY_SP, FileName, Span};
+use syntax_pos::{FileName, Span};
 
 use std::borrow::Cow;
 
@@ -124,8 +124,7 @@ pub fn print_crate<'a>(cm: &'a SourceMap,
 
         // #![feature(prelude_import)]
         let pi_nested = attr::mk_nested_word_item(ast::Ident::with_empty_ctxt(sym::prelude_import));
-        let list = attr::mk_list_item(
-            DUMMY_SP, ast::Ident::with_empty_ctxt(sym::feature), vec![pi_nested]);
+        let list = attr::mk_list_item(ast::Ident::with_empty_ctxt(sym::feature), vec![pi_nested]);
         let fake_attr = attr::mk_attr_inner(list);
         s.print_attribute(&fake_attr);
 
@@ -288,6 +287,7 @@ fn token_kind_to_string_ext(tok: &TokenKind, convert_dollar_crate: Option<Span>)
         token::Whitespace           => " ".to_string(),
         token::Comment              => "/* */".to_string(),
         token::Shebang(s)           => format!("/* shebang: {}*/", s),
+        token::Unknown(s)           => s.to_string(),
 
         token::Interpolated(ref nt) => nonterminal_to_string(nt),
     }
diff --git a/src/libsyntax_ext/test_harness.rs b/src/libsyntax_ext/test_harness.rs
index 4b3903c7ad7d3..eec8a3f802343 100644
--- a/src/libsyntax_ext/test_harness.rs
+++ b/src/libsyntax_ext/test_harness.rs
@@ -157,8 +157,7 @@ impl MutVisitor for EntryPointCleaner {
                 item.map(|ast::Item {id, ident, attrs, node, vis, span, tokens}| {
                     let allow_ident = Ident::with_empty_ctxt(sym::allow);
                     let dc_nested = attr::mk_nested_word_item(Ident::from_str("dead_code"));
-                    let allow_dead_code_item = attr::mk_list_item(DUMMY_SP, allow_ident,
-                                                                  vec![dc_nested]);
+                    let allow_dead_code_item = attr::mk_list_item(allow_ident, vec![dc_nested]);
                     let allow_dead_code = attr::mk_attr_outer(allow_dead_code_item);
 
                     ast::Item {
diff --git a/src/test/COMPILER_TESTS.md b/src/test/COMPILER_TESTS.md
index c4ca478134399..3f47ca834cda6 100644
--- a/src/test/COMPILER_TESTS.md
+++ b/src/test/COMPILER_TESTS.md
@@ -1,4 +1,4 @@
 # Compiler Test Documentation
 
-Documentation the compiler testing framework has moved to
+Documentation for the compiler testing framework can be found in
 [the rustc guide](https://rust-lang.github.io/rustc-guide/tests/intro.html).
diff --git a/src/test/rustdoc-ui/invalid-syntax.stderr b/src/test/rustdoc-ui/invalid-syntax.stderr
index b4ed747b44c81..3bebbecb9dfcf 100644
--- a/src/test/rustdoc-ui/invalid-syntax.stderr
+++ b/src/test/rustdoc-ui/invalid-syntax.stderr
@@ -1,3 +1,21 @@
+error: unknown start of token: \
+ --> <doctest>:1:1
+  |
+1 | \__________pkt->size___________/          \_result->size_/ \__pkt->size__/
+  | ^
+
+error: unknown start of token: \
+ --> <doctest>:1:43
+  |
+1 | \__________pkt->size___________/          \_result->size_/ \__pkt->size__/
+  |                                           ^
+
+error: unknown start of token: \
+ --> <doctest>:1:60
+  |
+1 | \__________pkt->size___________/          \_result->size_/ \__pkt->size__/
+  |                                                            ^
+
 warning: could not parse code block as Rust code
   --> $DIR/invalid-syntax.rs:3:5
    |
@@ -6,13 +24,31 @@ LL |   /// ```
 LL | | /// \__________pkt->size___________/          \_result->size_/ \__pkt->size__/
 LL | | /// ```
    | |_______^
-   |
-   = note: error from rustc: unknown start of token: \
 help: mark blocks that do not contain Rust code as text
    |
 LL | /// ```text
    |     ^^^^^^^
 
+error: unknown start of token: `
+ --> <doctest>:3:30
+  |
+3 |    |     ^^^^^^ did you mean `baz::foobar`?
+  |                              ^
+help: Unicode character '`' (Grave Accent) looks like ''' (Single Quote), but it is not
+  |
+3 |    |     ^^^^^^ did you mean 'baz::foobar`?
+  |                              ^
+
+error: unknown start of token: `
+ --> <doctest>:3:42
+  |
+3 |    |     ^^^^^^ did you mean `baz::foobar`?
+  |                                          ^
+help: Unicode character '`' (Grave Accent) looks like ''' (Single Quote), but it is not
+  |
+3 |    |     ^^^^^^ did you mean `baz::foobar'?
+  |                                          ^
+
 warning: could not parse code block as Rust code
   --> $DIR/invalid-syntax.rs:8:5
    |
@@ -23,13 +59,17 @@ LL | | /// LL | use foobar::Baz;
 LL | | ///    |     ^^^^^^ did you mean `baz::foobar`?
 LL | | /// ```
    | |_______^
-   |
-   = note: error from rustc: unknown start of token: `
 help: mark blocks that do not contain Rust code as text
    |
 LL | /// ```text
    |     ^^^^^^^
 
+error: unknown start of token: \
+ --> <doctest>:1:1
+  |
+1 | \_
+  | ^
+
 warning: could not parse code block as Rust code
   --> $DIR/invalid-syntax.rs:19:5
    |
@@ -38,13 +78,17 @@ LL |   /// ```
 LL | | /// \_
 LL | | /// ```
    | |_______^
-   |
-   = note: error from rustc: unknown start of token: \
 help: mark blocks that do not contain Rust code as text
    |
 LL | /// ```text
    |     ^^^^^^^
 
+error: unknown start of token: \
+ --> <doctest>:1:1
+  |
+1 | \_
+  | ^
+
 warning: could not parse code block as Rust code
   --> $DIR/invalid-syntax.rs:32:5
    |
@@ -53,8 +97,12 @@ LL |   /// ```rust
 LL | | /// \_
 LL | | /// ```
    | |_______^
-   |
-   = note: error from rustc: unknown start of token: \
+
+error: unknown start of token: \
+ --> <doctest>:2:5
+  |
+2 |     \_
+  |     ^
 
 warning: could not parse code block as Rust code
   --> $DIR/invalid-syntax.rs:41:9
@@ -63,16 +111,48 @@ LL |   ///     code with bad syntax
    |  _________^
 LL | | ///     \_
    | |__________^
-   |
-   = note: error from rustc: unknown start of token: \
+
+error: unknown start of token: `
+ --> <doctest>:1:1
+  |
+1 | ```
+  | ^
+help: Unicode character '`' (Grave Accent) looks like ''' (Single Quote), but it is not
+  |
+1 | '``
+  | ^
+
+error: unknown start of token: `
+ --> <doctest>:1:2
+  |
+1 | ```
+  |  ^
+help: Unicode character '`' (Grave Accent) looks like ''' (Single Quote), but it is not
+  |
+1 | `'`
+  |  ^
+
+error: unknown start of token: `
+ --> <doctest>:1:3
+  |
+1 | ```
+  |   ^
+help: Unicode character '`' (Grave Accent) looks like ''' (Single Quote), but it is not
+  |
+1 | ``'
+  |   ^
 
 warning: could not parse code block as Rust code
   --> $DIR/invalid-syntax.rs:55:9
    |
 LL | ///     ```
    |         ^^^
-   |
-   = note: error from rustc: unknown start of token: `
+
+error: unknown start of token: \
+ --> <doctest>:1:1
+  |
+1 | \_
+  | ^
 
 warning: could not parse code block as Rust code
   --> $DIR/invalid-syntax.rs:58:5
@@ -82,8 +162,12 @@ LL |   /// ```edition2018
 LL | | /// \_
 LL | | /// ```
    | |_______^
-   |
-   = note: error from rustc: unknown start of token: \
+
+error: unknown start of token: \
+ --> <doctest>:1:1
+  |
+1 | \_
+  | ^
 
 warning: doc comment contains an invalid Rust code block
   --> $DIR/invalid-syntax.rs:63:1
@@ -95,3 +179,59 @@ LL | | #[doc = "```"]
    |
    = help: mark blocks that do not contain Rust code as text: ```text
 
+error: unknown start of token: \
+ --> <rustdoc-highlighting>:1:1
+  |
+1 | \_
+  | ^
+
+error: unknown start of token: \
+ --> <rustdoc-highlighting>:1:1
+  |
+1 | \_
+  | ^
+
+error: unknown start of token: `
+ --> <rustdoc-highlighting>:1:1
+  |
+1 | ```
+  | ^
+help: Unicode character '`' (Grave Accent) looks like ''' (Single Quote), but it is not
+  |
+1 | '``
+  | ^
+
+error: unknown start of token: \
+ --> <rustdoc-highlighting>:2:1
+  |
+2 | \_
+  | ^
+
+error: unknown start of token: \
+ --> <rustdoc-highlighting>:1:1
+  |
+1 | \_
+  | ^
+
+error: unknown start of token: \
+ --> <rustdoc-highlighting>:1:1
+  |
+1 | \_
+  | ^
+
+error: unknown start of token: `
+ --> <rustdoc-highlighting>:3:30
+  |
+3 |    |     ^^^^^^ did you mean `baz::foobar`?
+  |                              ^
+help: Unicode character '`' (Grave Accent) looks like ''' (Single Quote), but it is not
+  |
+3 |    |     ^^^^^^ did you mean 'baz::foobar`?
+  |                              ^
+
+error: unknown start of token: \
+ --> <rustdoc-highlighting>:1:1
+  |
+1 | \__________pkt->size___________/          \_result->size_/ \__pkt->size__/
+  | ^
+
diff --git a/src/test/ui/async-await/partial-initialization-across-await.rs b/src/test/ui/async-await/partial-initialization-across-await.rs
new file mode 100644
index 0000000000000..40f9f5202e77c
--- /dev/null
+++ b/src/test/ui/async-await/partial-initialization-across-await.rs
@@ -0,0 +1,44 @@
+// Test that we don't allow awaiting from an async fn while a local is partially
+// initialized.
+
+// edition:2018
+
+#![feature(async_await)]
+
+struct S { x: i32, y: i32 }
+struct T(i32, i32);
+
+async fn noop() {}
+
+async fn test_tuple() {
+    let mut t: (i32, i32);
+    t.0 = 42;
+    //~^ ERROR assign to part of possibly uninitialized variable: `t` [E0381]
+    noop().await;
+    t.1 = 88;
+    let _ = t;
+}
+
+async fn test_tuple_struct() {
+    let mut t: T;
+    t.0 = 42;
+    //~^ ERROR assign to part of possibly uninitialized variable: `t` [E0381]
+    noop().await;
+    t.1 = 88;
+    let _ = t;
+}
+
+async fn test_struct() {
+    let mut t: S;
+    t.x = 42;
+    //~^ ERROR assign to part of possibly uninitialized variable: `t` [E0381]
+    noop().await;
+    t.y = 88;
+    let _ = t;
+}
+
+fn main() {
+    let _ = test_tuple();
+    let _ = test_tuple_struct();
+    let _ = test_struct();
+}
diff --git a/src/test/ui/async-await/partial-initialization-across-await.stderr b/src/test/ui/async-await/partial-initialization-across-await.stderr
new file mode 100644
index 0000000000000..fe79eb08befaa
--- /dev/null
+++ b/src/test/ui/async-await/partial-initialization-across-await.stderr
@@ -0,0 +1,21 @@
+error[E0381]: assign to part of possibly uninitialized variable: `t`
+  --> $DIR/partial-initialization-across-await.rs:15:5
+   |
+LL |     t.0 = 42;
+   |     ^^^^^^^^ use of possibly uninitialized `t`
+
+error[E0381]: assign to part of possibly uninitialized variable: `t`
+  --> $DIR/partial-initialization-across-await.rs:24:5
+   |
+LL |     t.0 = 42;
+   |     ^^^^^^^^ use of possibly uninitialized `t`
+
+error[E0381]: assign to part of possibly uninitialized variable: `t`
+  --> $DIR/partial-initialization-across-await.rs:33:5
+   |
+LL |     t.x = 42;
+   |     ^^^^^^^^ use of possibly uninitialized `t`
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0381`.
diff --git a/src/test/ui/borrowck/disallow-possibly-uninitialized.rs b/src/test/ui/borrowck/disallow-possibly-uninitialized.rs
new file mode 100644
index 0000000000000..a987c00b09191
--- /dev/null
+++ b/src/test/ui/borrowck/disallow-possibly-uninitialized.rs
@@ -0,0 +1,22 @@
+// Test that we don't allow partial initialization.
+// This may be relaxed in the future (see #54987).
+
+fn main() {
+    let mut t: (u64, u64);
+    t.0 = 1;
+    //~^ ERROR assign to part of possibly uninitialized variable: `t` [E0381]
+    t.1 = 1;
+
+    let mut t: (u64, u64);
+    t.1 = 1;
+    //~^ ERROR assign to part of possibly uninitialized variable: `t` [E0381]
+    t.0 = 1;
+
+    let mut t: (u64, u64);
+    t.0 = 1;
+    //~^ ERROR assign to part of possibly uninitialized variable: `t` [E0381]
+
+    let mut t: (u64,);
+    t.0 = 1;
+    //~^ ERROR assign to part of possibly uninitialized variable: `t` [E0381]
+}
diff --git a/src/test/ui/borrowck/disallow-possibly-uninitialized.stderr b/src/test/ui/borrowck/disallow-possibly-uninitialized.stderr
new file mode 100644
index 0000000000000..a32b17b165934
--- /dev/null
+++ b/src/test/ui/borrowck/disallow-possibly-uninitialized.stderr
@@ -0,0 +1,27 @@
+error[E0381]: assign to part of possibly uninitialized variable: `t`
+  --> $DIR/disallow-possibly-uninitialized.rs:6:5
+   |
+LL |     t.0 = 1;
+   |     ^^^^^^^ use of possibly uninitialized `t`
+
+error[E0381]: assign to part of possibly uninitialized variable: `t`
+  --> $DIR/disallow-possibly-uninitialized.rs:11:5
+   |
+LL |     t.1 = 1;
+   |     ^^^^^^^ use of possibly uninitialized `t`
+
+error[E0381]: assign to part of possibly uninitialized variable: `t`
+  --> $DIR/disallow-possibly-uninitialized.rs:16:5
+   |
+LL |     t.0 = 1;
+   |     ^^^^^^^ use of possibly uninitialized `t`
+
+error[E0381]: assign to part of possibly uninitialized variable: `t`
+  --> $DIR/disallow-possibly-uninitialized.rs:20:5
+   |
+LL |     t.0 = 1;
+   |     ^^^^^^^ use of possibly uninitialized `t`
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0381`.
diff --git a/src/test/ui/coherence/coherence-overlap-upstream.old.stderr b/src/test/ui/coherence/coherence-overlap-upstream.old.stderr
index dea948ff8abbb..6c3484c2d8c4d 100644
--- a/src/test/ui/coherence/coherence-overlap-upstream.old.stderr
+++ b/src/test/ui/coherence/coherence-overlap-upstream.old.stderr
@@ -5,6 +5,8 @@ LL | impl<T> Foo for T where T: Remote {}
    | --------------------------------- first implementation here
 LL | impl Foo for i16 {}
    | ^^^^^^^^^^^^^^^^ conflicting implementation for `i16`
+   |
+   = note: upstream crates may add new impl of trait `coherence_lib::Remote` for type `i16` in future versions
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/coherence/coherence-overlap-upstream.re.stderr b/src/test/ui/coherence/coherence-overlap-upstream.re.stderr
index dea948ff8abbb..6c3484c2d8c4d 100644
--- a/src/test/ui/coherence/coherence-overlap-upstream.re.stderr
+++ b/src/test/ui/coherence/coherence-overlap-upstream.re.stderr
@@ -5,6 +5,8 @@ LL | impl<T> Foo for T where T: Remote {}
    | --------------------------------- first implementation here
 LL | impl Foo for i16 {}
    | ^^^^^^^^^^^^^^^^ conflicting implementation for `i16`
+   |
+   = note: upstream crates may add new impl of trait `coherence_lib::Remote` for type `i16` in future versions
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/coherence/coherence_copy_like_err_fundamental_struct_tuple.old.stderr b/src/test/ui/coherence/coherence_copy_like_err_fundamental_struct_tuple.old.stderr
index 0ec4f0bb8e74d..12c7a1f977c3f 100644
--- a/src/test/ui/coherence/coherence_copy_like_err_fundamental_struct_tuple.old.stderr
+++ b/src/test/ui/coherence/coherence_copy_like_err_fundamental_struct_tuple.old.stderr
@@ -6,6 +6,8 @@ LL | impl<T: lib::MyCopy> MyTrait for T { }
 ...
 LL | impl MyTrait for lib::MyFundamentalStruct<(MyType,)> { }
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `lib::MyFundamentalStruct<(MyType,)>`
+   |
+   = note: upstream crates may add new impl of trait `lib::MyCopy` for type `lib::MyFundamentalStruct<(MyType,)>` in future versions
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/coherence/coherence_copy_like_err_fundamental_struct_tuple.re.stderr b/src/test/ui/coherence/coherence_copy_like_err_fundamental_struct_tuple.re.stderr
index 0ec4f0bb8e74d..12c7a1f977c3f 100644
--- a/src/test/ui/coherence/coherence_copy_like_err_fundamental_struct_tuple.re.stderr
+++ b/src/test/ui/coherence/coherence_copy_like_err_fundamental_struct_tuple.re.stderr
@@ -6,6 +6,8 @@ LL | impl<T: lib::MyCopy> MyTrait for T { }
 ...
 LL | impl MyTrait for lib::MyFundamentalStruct<(MyType,)> { }
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `lib::MyFundamentalStruct<(MyType,)>`
+   |
+   = note: upstream crates may add new impl of trait `lib::MyCopy` for type `lib::MyFundamentalStruct<(MyType,)>` in future versions
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/coherence/coherence_copy_like_err_struct.old.stderr b/src/test/ui/coherence/coherence_copy_like_err_struct.old.stderr
index e5862fdda7c58..1b6c62e9bf3a8 100644
--- a/src/test/ui/coherence/coherence_copy_like_err_struct.old.stderr
+++ b/src/test/ui/coherence/coherence_copy_like_err_struct.old.stderr
@@ -6,6 +6,8 @@ LL | impl<T: lib::MyCopy> MyTrait for T { }
 ...
 LL | impl MyTrait for lib::MyStruct<MyType> { }
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `lib::MyStruct<MyType>`
+   |
+   = note: upstream crates may add new impl of trait `lib::MyCopy` for type `lib::MyStruct<MyType>` in future versions
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/coherence/coherence_copy_like_err_struct.re.stderr b/src/test/ui/coherence/coherence_copy_like_err_struct.re.stderr
index e5862fdda7c58..1b6c62e9bf3a8 100644
--- a/src/test/ui/coherence/coherence_copy_like_err_struct.re.stderr
+++ b/src/test/ui/coherence/coherence_copy_like_err_struct.re.stderr
@@ -6,6 +6,8 @@ LL | impl<T: lib::MyCopy> MyTrait for T { }
 ...
 LL | impl MyTrait for lib::MyStruct<MyType> { }
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `lib::MyStruct<MyType>`
+   |
+   = note: upstream crates may add new impl of trait `lib::MyCopy` for type `lib::MyStruct<MyType>` in future versions
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/coherence/coherence_copy_like_err_tuple.old.stderr b/src/test/ui/coherence/coherence_copy_like_err_tuple.old.stderr
index a3c4ef8e105a2..11bd788c76153 100644
--- a/src/test/ui/coherence/coherence_copy_like_err_tuple.old.stderr
+++ b/src/test/ui/coherence/coherence_copy_like_err_tuple.old.stderr
@@ -6,6 +6,8 @@ LL | impl<T: lib::MyCopy> MyTrait for T { }
 ...
 LL | impl MyTrait for (MyType,) { }
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(MyType,)`
+   |
+   = note: upstream crates may add new impl of trait `lib::MyCopy` for type `(MyType,)` in future versions
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/coherence/coherence_copy_like_err_tuple.re.stderr b/src/test/ui/coherence/coherence_copy_like_err_tuple.re.stderr
index a3c4ef8e105a2..11bd788c76153 100644
--- a/src/test/ui/coherence/coherence_copy_like_err_tuple.re.stderr
+++ b/src/test/ui/coherence/coherence_copy_like_err_tuple.re.stderr
@@ -6,6 +6,8 @@ LL | impl<T: lib::MyCopy> MyTrait for T { }
 ...
 LL | impl MyTrait for (MyType,) { }
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(MyType,)`
+   |
+   = note: upstream crates may add new impl of trait `lib::MyCopy` for type `(MyType,)` in future versions
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/consts/const_let_refutable.nll.stderr b/src/test/ui/consts/const_let_refutable.nll.stderr
deleted file mode 100644
index a61c9b0c9fef9..0000000000000
--- a/src/test/ui/consts/const_let_refutable.nll.stderr
+++ /dev/null
@@ -1,31 +0,0 @@
-error[E0005]: refutable pattern in function argument: `&[]` not covered
-  --> $DIR/const_let_refutable.rs:3:16
-   |
-LL | const fn slice([a, b]: &[i32]) -> i32 {
-   |                ^^^^^^ pattern `&[]` not covered
-
-error[E0723]: can only call other `const fn` within a `const fn`, but `const <&i32 as std::ops::Add>::add` is not stable as `const fn`
-  --> $DIR/const_let_refutable.rs:4:5
-   |
-LL |     a + b
-   |     ^^^^^
-   |
-   = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563
-   = help: add `#![feature(const_fn)]` to the crate attributes to enable
-
-error[E0381]: use of possibly uninitialized variable: `a`
-  --> $DIR/const_let_refutable.rs:4:5
-   |
-LL |     a + b
-   |     ^ use of possibly uninitialized `a`
-
-error[E0381]: use of possibly uninitialized variable: `b`
-  --> $DIR/const_let_refutable.rs:4:9
-   |
-LL |     a + b
-   |         ^ use of possibly uninitialized `b`
-
-error: aborting due to 4 previous errors
-
-Some errors have detailed explanations: E0005, E0381, E0723.
-For more information about an error, try `rustc --explain E0005`.
diff --git a/src/test/ui/consts/const_let_refutable.rs b/src/test/ui/consts/const_let_refutable.rs
index 322048c7fbf3f..7b3a591223025 100644
--- a/src/test/ui/consts/const_let_refutable.rs
+++ b/src/test/ui/consts/const_let_refutable.rs
@@ -2,10 +2,6 @@ fn main() {}
 
 const fn slice([a, b]: &[i32]) -> i32 { //~ ERROR refutable pattern in function argument
     a + b //~ ERROR can only call other `const fn` within a `const fn`
-    //~^ WARN use of possibly uninitialized variable: `a`
-    //~| WARN this error has been downgraded to a warning for backwards compatibility
-    //~| WARN this represents potential undefined behavior in your code and this warning will
-    //~| WARN use of possibly uninitialized variable: `b`
-    //~| WARN this error has been downgraded to a warning for backwards compatibility
-    //~| WARN this represents potential undefined behavior in your code and this warning will
+    //~^ ERROR use of possibly uninitialized variable: `a`
+    //~| ERROR use of possibly uninitialized variable: `b`
 }
diff --git a/src/test/ui/consts/const_let_refutable.stderr b/src/test/ui/consts/const_let_refutable.stderr
index a848b20ed98f5..a61c9b0c9fef9 100644
--- a/src/test/ui/consts/const_let_refutable.stderr
+++ b/src/test/ui/consts/const_let_refutable.stderr
@@ -13,27 +13,19 @@ LL |     a + b
    = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563
    = help: add `#![feature(const_fn)]` to the crate attributes to enable
 
-warning[E0381]: use of possibly uninitialized variable: `a`
+error[E0381]: use of possibly uninitialized variable: `a`
   --> $DIR/const_let_refutable.rs:4:5
    |
 LL |     a + b
    |     ^ use of possibly uninitialized `a`
-   |
-   = warning: this error has been downgraded to a warning for backwards compatibility with previous releases
-   = warning: this represents potential undefined behavior in your code and this warning will become a hard error in the future
-   = note: for more information, try `rustc --explain E0729`
 
-warning[E0381]: use of possibly uninitialized variable: `b`
+error[E0381]: use of possibly uninitialized variable: `b`
   --> $DIR/const_let_refutable.rs:4:9
    |
 LL |     a + b
    |         ^ use of possibly uninitialized `b`
-   |
-   = warning: this error has been downgraded to a warning for backwards compatibility with previous releases
-   = warning: this represents potential undefined behavior in your code and this warning will become a hard error in the future
-   = note: for more information, try `rustc --explain E0729`
 
-error: aborting due to 2 previous errors
+error: aborting due to 4 previous errors
 
 Some errors have detailed explanations: E0005, E0381, E0723.
 For more information about an error, try `rustc --explain E0005`.
diff --git a/src/test/ui/empty/empty-never-array.nll.stderr b/src/test/ui/empty/empty-never-array.nll.stderr
deleted file mode 100644
index 01ee1c3a4d7fa..0000000000000
--- a/src/test/ui/empty/empty-never-array.nll.stderr
+++ /dev/null
@@ -1,23 +0,0 @@
-error[E0005]: refutable pattern in local binding: `T(_, _)` not covered
-  --> $DIR/empty-never-array.rs:10:9
-   |
-LL | / enum Helper<T, U> {
-LL | |     T(T, [!; 0]),
-LL | |     #[allow(dead_code)]
-LL | |     U(U),
-LL | | }
-   | |_- `Helper<T, U>` defined here
-...
-LL |       let Helper::U(u) = Helper::T(t, []);
-   |           ^^^^^^^^^^^^ pattern `T(_, _)` not covered
-
-error[E0381]: use of possibly uninitialized variable: `u`
-  --> $DIR/empty-never-array.rs:12:5
-   |
-LL |     u
-   |     ^ use of possibly uninitialized `u`
-
-error: aborting due to 2 previous errors
-
-Some errors have detailed explanations: E0005, E0381.
-For more information about an error, try `rustc --explain E0005`.
diff --git a/src/test/ui/empty/empty-never-array.rs b/src/test/ui/empty/empty-never-array.rs
index ce781da7d47e1..ffd2545b291e2 100644
--- a/src/test/ui/empty/empty-never-array.rs
+++ b/src/test/ui/empty/empty-never-array.rs
@@ -10,9 +10,7 @@ fn transmute<T, U>(t: T) -> U {
     let Helper::U(u) = Helper::T(t, []);
     //~^ ERROR refutable pattern in local binding: `T(_, _)` not covered
     u
-    //~^ WARN use of possibly uninitialized variable: `u`
-    //~| WARN this error has been downgraded to a warning for backwards compatibility
-    //~| WARN this represents potential undefined behavior in your code and this warning will
+    //~^ ERROR use of possibly uninitialized variable: `u`
 }
 
 fn main() {
diff --git a/src/test/ui/empty/empty-never-array.stderr b/src/test/ui/empty/empty-never-array.stderr
index 9911dd4683b66..01ee1c3a4d7fa 100644
--- a/src/test/ui/empty/empty-never-array.stderr
+++ b/src/test/ui/empty/empty-never-array.stderr
@@ -11,17 +11,13 @@ LL | | }
 LL |       let Helper::U(u) = Helper::T(t, []);
    |           ^^^^^^^^^^^^ pattern `T(_, _)` not covered
 
-warning[E0381]: use of possibly uninitialized variable: `u`
+error[E0381]: use of possibly uninitialized variable: `u`
   --> $DIR/empty-never-array.rs:12:5
    |
 LL |     u
    |     ^ use of possibly uninitialized `u`
-   |
-   = warning: this error has been downgraded to a warning for backwards compatibility with previous releases
-   = warning: this represents potential undefined behavior in your code and this warning will become a hard error in the future
-   = note: for more information, try `rustc --explain E0729`
 
-error: aborting due to previous error
+error: aborting due to 2 previous errors
 
 Some errors have detailed explanations: E0005, E0381.
 For more information about an error, try `rustc --explain E0005`.
diff --git a/src/test/ui/generator/partial-initialization-across-yield.rs b/src/test/ui/generator/partial-initialization-across-yield.rs
new file mode 100644
index 0000000000000..1e4593002cb9a
--- /dev/null
+++ b/src/test/ui/generator/partial-initialization-across-yield.rs
@@ -0,0 +1,46 @@
+// Test that we don't allow yielding from a generator while a local is partially
+// initialized.
+
+#![feature(generators)]
+
+struct S { x: i32, y: i32 }
+struct T(i32, i32);
+
+fn test_tuple() {
+    let _ = || {
+        let mut t: (i32, i32);
+        t.0 = 42;
+        //~^ ERROR assign to part of possibly uninitialized variable: `t` [E0381]
+        yield;
+        t.1 = 88;
+        let _ = t;
+    };
+}
+
+fn test_tuple_struct() {
+    let _ = || {
+        let mut t: T;
+        t.0 = 42;
+        //~^ ERROR assign to part of possibly uninitialized variable: `t` [E0381]
+        yield;
+        t.1 = 88;
+        let _ = t;
+    };
+}
+
+fn test_struct() {
+    let _ = || {
+        let mut t: S;
+        t.x = 42;
+        //~^ ERROR assign to part of possibly uninitialized variable: `t` [E0381]
+        yield;
+        t.y = 88;
+        let _ = t;
+    };
+}
+
+fn main() {
+    test_tuple();
+    test_tuple_struct();
+    test_struct();
+}
diff --git a/src/test/ui/generator/partial-initialization-across-yield.stderr b/src/test/ui/generator/partial-initialization-across-yield.stderr
new file mode 100644
index 0000000000000..8bf0037e07009
--- /dev/null
+++ b/src/test/ui/generator/partial-initialization-across-yield.stderr
@@ -0,0 +1,21 @@
+error[E0381]: assign to part of possibly uninitialized variable: `t`
+  --> $DIR/partial-initialization-across-yield.rs:12:9
+   |
+LL |         t.0 = 42;
+   |         ^^^^^^^^ use of possibly uninitialized `t`
+
+error[E0381]: assign to part of possibly uninitialized variable: `t`
+  --> $DIR/partial-initialization-across-yield.rs:23:9
+   |
+LL |         t.0 = 42;
+   |         ^^^^^^^^ use of possibly uninitialized `t`
+
+error[E0381]: assign to part of possibly uninitialized variable: `t`
+  --> $DIR/partial-initialization-across-yield.rs:34:9
+   |
+LL |         t.x = 42;
+   |         ^^^^^^^^ use of possibly uninitialized `t`
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0381`.
diff --git a/src/test/ui/issues/issue-15381.nll.stderr b/src/test/ui/issues/issue-15381.nll.stderr
deleted file mode 100644
index a8495846b3610..0000000000000
--- a/src/test/ui/issues/issue-15381.nll.stderr
+++ /dev/null
@@ -1,16 +0,0 @@
-error[E0005]: refutable pattern in `for` loop binding: `&[]` not covered
-  --> $DIR/issue-15381.rs:4:9
-   |
-LL |     for &[x,y,z] in values.chunks(3).filter(|&xs| xs.len() == 3) {
-   |         ^^^^^^^^ pattern `&[]` not covered
-
-error[E0381]: borrow of possibly uninitialized variable: `y`
-  --> $DIR/issue-15381.rs:6:26
-   |
-LL |         println!("y={}", y);
-   |                          ^ use of possibly uninitialized `y`
-
-error: aborting due to 2 previous errors
-
-Some errors have detailed explanations: E0005, E0381.
-For more information about an error, try `rustc --explain E0005`.
diff --git a/src/test/ui/issues/issue-15381.rs b/src/test/ui/issues/issue-15381.rs
index 3dbd4e717a0db..d21c321b09399 100644
--- a/src/test/ui/issues/issue-15381.rs
+++ b/src/test/ui/issues/issue-15381.rs
@@ -4,8 +4,6 @@ fn main() {
     for &[x,y,z] in values.chunks(3).filter(|&xs| xs.len() == 3) {
         //~^ ERROR refutable pattern in `for` loop binding: `&[]` not covered
         println!("y={}", y);
-        //~^ WARN borrow of possibly uninitialized variable: `y`
-        //~| WARN this error has been downgraded to a warning for backwards compatibility
-        //~| WARN this represents potential undefined behavior in your code and this warning will
+        //~^ ERROR borrow of possibly uninitialized variable: `y`
     }
 }
diff --git a/src/test/ui/issues/issue-15381.stderr b/src/test/ui/issues/issue-15381.stderr
index 7b11d85ead874..a8495846b3610 100644
--- a/src/test/ui/issues/issue-15381.stderr
+++ b/src/test/ui/issues/issue-15381.stderr
@@ -4,17 +4,13 @@ error[E0005]: refutable pattern in `for` loop binding: `&[]` not covered
 LL |     for &[x,y,z] in values.chunks(3).filter(|&xs| xs.len() == 3) {
    |         ^^^^^^^^ pattern `&[]` not covered
 
-warning[E0381]: borrow of possibly uninitialized variable: `y`
+error[E0381]: borrow of possibly uninitialized variable: `y`
   --> $DIR/issue-15381.rs:6:26
    |
 LL |         println!("y={}", y);
    |                          ^ use of possibly uninitialized `y`
-   |
-   = warning: this error has been downgraded to a warning for backwards compatibility with previous releases
-   = warning: this represents potential undefined behavior in your code and this warning will become a hard error in the future
-   = note: for more information, try `rustc --explain E0729`
 
-error: aborting due to previous error
+error: aborting due to 2 previous errors
 
 Some errors have detailed explanations: E0005, E0381.
 For more information about an error, try `rustc --explain E0005`.
diff --git a/src/test/ui/issues/issue-48728.stderr b/src/test/ui/issues/issue-48728.stderr
index 777e1fc9c27ea..99a9bf9903e25 100644
--- a/src/test/ui/issues/issue-48728.stderr
+++ b/src/test/ui/issues/issue-48728.stderr
@@ -6,6 +6,8 @@ LL | #[derive(Clone)]
 ...
 LL | impl<T: Clone + ?Sized> Clone for Node<[T]> {
    | ------------------------------------------- first implementation here
+   |
+   = note: upstream crates may add new impl of trait `std::clone::Clone` for type `[_]` in future versions
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/lex-bad-token.rs b/src/test/ui/parser/lex-bad-token.rs
index feb670c3d3dd0..9e4824611128d 100644
--- a/src/test/ui/parser/lex-bad-token.rs
+++ b/src/test/ui/parser/lex-bad-token.rs
@@ -1 +1,3 @@
 ● //~ ERROR: unknown start of token
+
+fn main() {}
diff --git a/src/test/ui/parser/lex-stray-backslash.rs b/src/test/ui/parser/lex-stray-backslash.rs
index 90d359231a6e7..bb27f44c279f7 100644
--- a/src/test/ui/parser/lex-stray-backslash.rs
+++ b/src/test/ui/parser/lex-stray-backslash.rs
@@ -1 +1,3 @@
 \ //~ ERROR: unknown start of token: \
+
+fn main() {}
diff --git a/src/test/ui/parser/unicode-quote-chars.rs b/src/test/ui/parser/unicode-quote-chars.rs
index 69644211b8a11..1812dad81afc3 100644
--- a/src/test/ui/parser/unicode-quote-chars.rs
+++ b/src/test/ui/parser/unicode-quote-chars.rs
@@ -4,4 +4,7 @@ fn main() {
     println!(“hello world”);
     //~^ ERROR unknown start of token: \u{201c}
     //~^^ HELP Unicode characters '“' (Left Double Quotation Mark) and '”' (Right Double Quotation Mark) look like '"' (Quotation Mark), but are not
+    //~^^^ ERROR unknown start of token: \u{201d}
+    //~^^^^ HELP Unicode character '”' (Right Double Quotation Mark) looks like '"' (Quotation Mark), but it is not
+    //~^^^^^ ERROR expected token: `,`
 }
diff --git a/src/test/ui/parser/unicode-quote-chars.stderr b/src/test/ui/parser/unicode-quote-chars.stderr
index 4a09ed75605e4..84e45ecd873a4 100644
--- a/src/test/ui/parser/unicode-quote-chars.stderr
+++ b/src/test/ui/parser/unicode-quote-chars.stderr
@@ -8,5 +8,21 @@ help: Unicode characters '“' (Left Double Quotation Mark) and '”' (Right Dou
 LL |     println!("hello world");
    |              ^^^^^^^^^^^^^
 
-error: aborting due to previous error
+error: unknown start of token: \u{201d}
+  --> $DIR/unicode-quote-chars.rs:4:26
+   |
+LL |     println!(“hello world”);
+   |                          ^
+help: Unicode character '”' (Right Double Quotation Mark) looks like '"' (Quotation Mark), but it is not
+   |
+LL |     println!(“hello world");
+   |                          ^
+
+error: expected token: `,`
+  --> $DIR/unicode-quote-chars.rs:4:21
+   |
+LL |     println!(“hello world”);
+   |                     ^^^^^ expected `,`
+
+error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/recursion/recursive-types-are-not-uninhabited.nll.stderr b/src/test/ui/recursion/recursive-types-are-not-uninhabited.nll.stderr
deleted file mode 100644
index eee331d95b9bc..0000000000000
--- a/src/test/ui/recursion/recursive-types-are-not-uninhabited.nll.stderr
+++ /dev/null
@@ -1,16 +0,0 @@
-error[E0005]: refutable pattern in local binding: `Err(_)` not covered
-  --> $DIR/recursive-types-are-not-uninhabited.rs:6:9
-   |
-LL |     let Ok(x) = res;
-   |         ^^^^^ pattern `Err(_)` not covered
-
-error[E0381]: use of possibly uninitialized variable: `x`
-  --> $DIR/recursive-types-are-not-uninhabited.rs:8:5
-   |
-LL |     x
-   |     ^ use of possibly uninitialized `x`
-
-error: aborting due to 2 previous errors
-
-Some errors have detailed explanations: E0005, E0381.
-For more information about an error, try `rustc --explain E0005`.
diff --git a/src/test/ui/recursion/recursive-types-are-not-uninhabited.rs b/src/test/ui/recursion/recursive-types-are-not-uninhabited.rs
index a618aba9413f0..45910c3c3a8c6 100644
--- a/src/test/ui/recursion/recursive-types-are-not-uninhabited.rs
+++ b/src/test/ui/recursion/recursive-types-are-not-uninhabited.rs
@@ -6,9 +6,7 @@ fn foo(res: Result<u32, &R>) -> u32 {
     let Ok(x) = res;
     //~^ ERROR refutable pattern
     x
-    //~^ WARN use of possibly uninitialized variable: `x`
-    //~| WARN this error has been downgraded to a warning for backwards compatibility
-    //~| WARN this represents potential undefined behavior in your code and this warning will
+    //~^ ERROR use of possibly uninitialized variable: `x`
 }
 
 fn main() {
diff --git a/src/test/ui/recursion/recursive-types-are-not-uninhabited.stderr b/src/test/ui/recursion/recursive-types-are-not-uninhabited.stderr
index 9203f893fdbf7..eee331d95b9bc 100644
--- a/src/test/ui/recursion/recursive-types-are-not-uninhabited.stderr
+++ b/src/test/ui/recursion/recursive-types-are-not-uninhabited.stderr
@@ -4,17 +4,13 @@ error[E0005]: refutable pattern in local binding: `Err(_)` not covered
 LL |     let Ok(x) = res;
    |         ^^^^^ pattern `Err(_)` not covered
 
-warning[E0381]: use of possibly uninitialized variable: `x`
+error[E0381]: use of possibly uninitialized variable: `x`
   --> $DIR/recursive-types-are-not-uninhabited.rs:8:5
    |
 LL |     x
    |     ^ use of possibly uninitialized `x`
-   |
-   = warning: this error has been downgraded to a warning for backwards compatibility with previous releases
-   = warning: this represents potential undefined behavior in your code and this warning will become a hard error in the future
-   = note: for more information, try `rustc --explain E0729`
 
-error: aborting due to previous error
+error: aborting due to 2 previous errors
 
 Some errors have detailed explanations: E0005, E0381.
 For more information about an error, try `rustc --explain E0005`.
diff --git a/src/test/ui/specialization/issue-52050.stderr b/src/test/ui/specialization/issue-52050.stderr
index 583c580d341ba..dcb34f3ad4836 100644
--- a/src/test/ui/specialization/issue-52050.stderr
+++ b/src/test/ui/specialization/issue-52050.stderr
@@ -10,6 +10,8 @@ LL | | }
 LL | 
 LL |   impl IntoPyDictPointer for ()
    |   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `()`
+   |
+   = note: upstream crates may add new impl of trait `std::iter::Iterator` for type `()` in future versions
 
 error: aborting due to previous error