about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2018-12-24 07:26:19 +0000
committerbors <bors@rust-lang.org>2018-12-24 07:26:19 +0000
commit94bf2c15eb3d072e92855a605783a29920df9e46 (patch)
treec54866741b6c39b4ddce1f30ae136075ec936bc5 /src
parente16928082aa2d66a4498132572b69156b94b25f1 (diff)
parentdff3e41914905eae0326c00de0dd9befc9d9ae83 (diff)
downloadrust-94bf2c15eb3d072e92855a605783a29920df9e46.tar.gz
rust-94bf2c15eb3d072e92855a605783a29920df9e46.zip
Auto merge of #57087 - Centril:rollup, r=Centril
Rollup of 14 pull requests

Successful merges:

 - #56188 (enum type instead of variant suggestion unification )
 - #56342 (Improve docs for collecting into `Option`s)
 - #56916 (Fix mutable references in `static mut`)
 - #56917 (Simplify MIR generation for logical operations)
 - #56939 (Pin stabilization)
 - #56953 (Mark tuple structs as live if their constructors are used)
 - #56964 (Remove `TokenStream::JointTree`.)
 - #56966 (Correct strings for raw pointer deref and array access suggestions)
 - #57020 (Point to cause of `fn` expected return type)
 - #57032 (fix deprecation warnings in liballoc benches)
 - #57053 (Fix alignment for array indexing)
 - #57062 (Fix a comment)
 - #57067 (Stabilize min_const_unsafe_fn in 1.33)
 - #57078 (Ignore two tests on s390x)

Failed merges:

r? @ghost
Diffstat (limited to 'src')
-rw-r--r--src/liballoc/Cargo.toml1
-rw-r--r--src/liballoc/benches/btree/map.rs4
-rw-r--r--src/liballoc/benches/lib.rs1
-rw-r--r--src/liballoc/benches/slice.rs3
-rw-r--r--src/liballoc/benches/str.rs8
-rw-r--r--src/liballoc/boxed.rs10
-rw-r--r--src/liballoc/lib.rs1
-rw-r--r--src/liballoc/rc.rs8
-rw-r--r--src/liballoc/sync.rs8
-rw-r--r--src/libcore/future/future.rs2
-rw-r--r--src/libcore/marker.rs11
-rw-r--r--src/libcore/option.rs46
-rw-r--r--src/libcore/pin.rs81
-rw-r--r--src/libcore/prelude/v1.rs2
-rw-r--r--src/librustc/hir/mod.rs11
-rw-r--r--src/librustc/ich/impls_mir.rs1
-rw-r--r--src/librustc/middle/dead.rs80
-rw-r--r--src/librustc/mir/mod.rs3
-rw-r--r--src/librustc_codegen_ssa/mir/place.rs13
-rw-r--r--src/librustc_codegen_ssa/mir/rvalue.rs3
-rw-r--r--src/librustc_mir/build/expr/into.rs53
-rw-r--r--src/librustc_mir/monomorphize/collector.rs2
-rw-r--r--src/librustc_mir/transform/check_unsafety.rs29
-rw-r--r--src/librustc_mir/transform/qualify_consts.rs2
-rw-r--r--src/librustc_resolve/lib.rs56
-rw-r--r--src/librustc_typeck/check/coercion.rs14
-rw-r--r--src/librustc_typeck/check/demand.rs1
-rw-r--r--src/librustc_typeck/check/mod.rs35
-rw-r--r--src/libstd/future.rs2
-rw-r--r--src/libstd/lib.rs4
-rw-r--r--src/libsyntax/feature_gate.rs5
-rw-r--r--src/libsyntax/parse/lexer/tokentrees.rs5
-rw-r--r--src/libsyntax/tokenstream.rs93
-rw-r--r--src/libsyntax_ext/proc_macro_server.rs8
-rw-r--r--src/libsyntax_pos/lib.rs7
-rw-r--r--src/test/codegen/issue-56927.rs44
-rw-r--r--src/test/codegen/packed.rs36
-rw-r--r--src/test/codegen/x86_mmx.rs1
-rw-r--r--src/test/compile-fail/must_use-in-stdlib-traits.rs2
-rw-r--r--src/test/run-pass-fulldeps/newtype_index.rs2
-rw-r--r--src/test/run-pass/arbitrary_self_types_stdlib_pointers.rs2
-rw-r--r--src/test/run-pass/async-await.rs4
-rw-r--r--src/test/run-pass/futures-api.rs2
-rw-r--r--src/test/rustdoc/const-display.rs1
-rw-r--r--src/test/ui/consts/min_const_fn/min_const_fn_unsafe.rs51
-rw-r--r--src/test/ui/consts/min_const_fn/min_const_fn_unsafe.stderr49
-rw-r--r--src/test/ui/consts/min_const_fn/min_const_fn_unsafe_feature_gate.rs61
-rw-r--r--src/test/ui/consts/min_const_fn/min_const_fn_unsafe_feature_gate.stderr44
-rw-r--r--src/test/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability.rs1
-rw-r--r--src/test/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability.stderr8
-rw-r--r--src/test/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability2.rs1
-rw-r--r--src/test/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability2.stderr6
-rw-r--r--src/test/ui/consts/static_mut_containing_mut_ref.rs7
-rw-r--r--src/test/ui/consts/static_mut_containing_mut_ref2.rs9
-rw-r--r--src/test/ui/consts/static_mut_containing_mut_ref2.stderr16
-rw-r--r--src/test/ui/consts/static_mut_containing_mut_ref3.rs8
-rw-r--r--src/test/ui/consts/static_mut_containing_mut_ref3.stderr9
-rw-r--r--src/test/ui/dead-code-tuple-struct-field.rs12
-rw-r--r--src/test/ui/did_you_mean/issue-56028-there-is-an-enum-variant.rs15
-rw-r--r--src/test/ui/did_you_mean/issue-56028-there-is-an-enum-variant.stderr38
-rw-r--r--src/test/ui/enum/enum-variant-type-2.stderr2
-rw-r--r--src/test/ui/error-codes/E0069.stderr4
-rw-r--r--src/test/ui/impl-trait/equality.stderr3
-rw-r--r--src/test/ui/issues/issue-11004.stderr8
-rw-r--r--src/test/ui/issues/issue-17546.stderr4
-rw-r--r--src/test/ui/issues/issue-30535.stderr7
-rw-r--r--src/test/ui/issues/issue-35075.stderr18
-rw-r--r--src/test/ui/issues/issue-35675.stderr34
-rw-r--r--src/test/ui/parenthesised-deref-suggestion.rs11
-rw-r--r--src/test/ui/parenthesised-deref-suggestion.stderr21
-rw-r--r--src/test/ui/ret-non-nil.stderr4
-rw-r--r--src/test/ui/return/return-unit-from-diverging.stderr4
-rw-r--r--src/test/ui/target-feature-gate.rs1
-rw-r--r--src/test/ui/target-feature-gate.stderr2
-rw-r--r--src/test/ui/unsafe/unsafe-fn-autoderef.stderr4
-rw-r--r--src/test/ui/variants/variant-used-as-type.stderr16
-rw-r--r--src/test/ui/write-to-static-mut-in-static.rs4
-rw-r--r--src/test/ui/write-to-static-mut-in-static.stderr20
78 files changed, 720 insertions, 489 deletions
diff --git a/src/liballoc/Cargo.toml b/src/liballoc/Cargo.toml
index b2eb3566c04..861c7cecb88 100644
--- a/src/liballoc/Cargo.toml
+++ b/src/liballoc/Cargo.toml
@@ -15,6 +15,7 @@ compiler_builtins = { version = "0.1.0", features = ['rustc-dep-of-std'] }
 
 [dev-dependencies]
 rand = "0.6"
+rand_xorshift = "0.1"
 
 [[test]]
 name = "collectionstests"
diff --git a/src/liballoc/benches/btree/map.rs b/src/liballoc/benches/btree/map.rs
index 20b9091a07b..6e2b5e06b7a 100644
--- a/src/liballoc/benches/btree/map.rs
+++ b/src/liballoc/benches/btree/map.rs
@@ -12,7 +12,7 @@
 use std::iter::Iterator;
 use std::vec::Vec;
 use std::collections::BTreeMap;
-use rand::{Rng, thread_rng};
+use rand::{Rng, seq::SliceRandom, thread_rng};
 use test::{Bencher, black_box};
 
 macro_rules! map_insert_rand_bench {
@@ -78,7 +78,7 @@ macro_rules! map_find_rand_bench {
                 map.insert(k, k);
             }
 
-            rng.shuffle(&mut keys);
+            keys.shuffle(&mut rng);
 
             // measure
             let mut i = 0;
diff --git a/src/liballoc/benches/lib.rs b/src/liballoc/benches/lib.rs
index b4f4fd74f3a..9502a7dc3c0 100644
--- a/src/liballoc/benches/lib.rs
+++ b/src/liballoc/benches/lib.rs
@@ -13,6 +13,7 @@
 #![feature(test)]
 
 extern crate rand;
+extern crate rand_xorshift;
 extern crate test;
 
 mod btree;
diff --git a/src/liballoc/benches/slice.rs b/src/liballoc/benches/slice.rs
index 490320f57cb..fc588994063 100644
--- a/src/liballoc/benches/slice.rs
+++ b/src/liballoc/benches/slice.rs
@@ -12,8 +12,9 @@ use rand::{thread_rng};
 use std::mem;
 use std::ptr;
 
-use rand::{Rng, SeedableRng, XorShiftRng};
+use rand::{Rng, SeedableRng};
 use rand::distributions::{Standard, Alphanumeric};
+use rand_xorshift::XorShiftRng;
 use test::{Bencher, black_box};
 
 #[bench]
diff --git a/src/liballoc/benches/str.rs b/src/liballoc/benches/str.rs
index 38c94d4d8b5..c5e1576d24e 100644
--- a/src/liballoc/benches/str.rs
+++ b/src/liballoc/benches/str.rs
@@ -274,11 +274,11 @@ make_test!(split_a_str, s, s.split("a").count());
 make_test!(trim_ascii_char, s, {
     s.trim_matches(|c: char| c.is_ascii())
 });
-make_test!(trim_left_ascii_char, s, {
-    s.trim_left_matches(|c: char| c.is_ascii())
+make_test!(trim_start_ascii_char, s, {
+    s.trim_start_matches(|c: char| c.is_ascii())
 });
-make_test!(trim_right_ascii_char, s, {
-    s.trim_right_matches(|c: char| c.is_ascii())
+make_test!(trim_end_ascii_char, s, {
+    s.trim_end_matches(|c: char| c.is_ascii())
 });
 
 make_test!(find_underscore_char, s, s.find('_'));
diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs
index f1581310b48..7438f3e6c9d 100644
--- a/src/liballoc/boxed.rs
+++ b/src/liballoc/boxed.rs
@@ -111,9 +111,11 @@ impl<T> Box<T> {
         box x
     }
 
-    #[unstable(feature = "pin", issue = "49150")]
+    /// Constructs a new `Pin<Box<T>>`. If `T` does not implement `Unpin`, then
+    /// `x` will be pinned in memory and unable to be moved.
+    #[stable(feature = "pin", since = "1.33.0")]
     #[inline(always)]
-    pub fn pinned(x: T) -> Pin<Box<T>> {
+    pub fn pin(x: T) -> Pin<Box<T>> {
         (box x).into()
     }
 }
@@ -446,7 +448,7 @@ impl<T> From<T> for Box<T> {
     }
 }
 
-#[unstable(feature = "pin", issue = "49150")]
+#[stable(feature = "pin", since = "1.33.0")]
 impl<T> From<Box<T>> for Pin<Box<T>> {
     fn from(boxed: Box<T>) -> Self {
         // It's not possible to move or replace the insides of a `Pin<Box<T>>`
@@ -813,7 +815,7 @@ impl<T: ?Sized> AsMut<T> for Box<T> {
  *  implementation of `Unpin` (where `T: Unpin`) would be valid/safe, and
  *  could have a method to project a Pin<T> from it.
  */
-#[unstable(feature = "pin", issue = "49150")]
+#[stable(feature = "pin", since = "1.33.0")]
 impl<T: ?Sized> Unpin for Box<T> { }
 
 #[unstable(feature = "generator_trait", issue = "43122")]
diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs
index afa7a6f919d..8a66cafc001 100644
--- a/src/liballoc/lib.rs
+++ b/src/liballoc/lib.rs
@@ -102,7 +102,6 @@
 #![feature(nll)]
 #![feature(optin_builtin_traits)]
 #![feature(pattern)]
-#![feature(pin)]
 #![feature(ptr_internals)]
 #![feature(ptr_offset_from)]
 #![feature(rustc_attrs)]
diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs
index 65a610b9d1e..af316b0b61b 100644
--- a/src/liballoc/rc.rs
+++ b/src/liballoc/rc.rs
@@ -325,8 +325,10 @@ impl<T> Rc<T> {
         }
     }
 
-    #[unstable(feature = "pin", issue = "49150")]
-    pub fn pinned(value: T) -> Pin<Rc<T>> {
+    /// Constructs a new `Pin<Rc<T>>`. If `T` does not implement `Unpin`, then
+    /// `value` will be pinned in memory and unable to be moved.
+    #[stable(feature = "pin", since = "1.33.0")]
+    pub fn pin(value: T) -> Pin<Rc<T>> {
         unsafe { Pin::new_unchecked(Rc::new(value)) }
     }
 
@@ -1934,5 +1936,5 @@ impl<T: ?Sized> AsRef<T> for Rc<T> {
     }
 }
 
-#[unstable(feature = "pin", issue = "49150")]
+#[stable(feature = "pin", since = "1.33.0")]
 impl<T: ?Sized> Unpin for Rc<T> { }
diff --git a/src/liballoc/sync.rs b/src/liballoc/sync.rs
index 948c36117a3..7b8afb1943c 100644
--- a/src/liballoc/sync.rs
+++ b/src/liballoc/sync.rs
@@ -303,8 +303,10 @@ impl<T> Arc<T> {
         Arc { ptr: Box::into_raw_non_null(x), phantom: PhantomData }
     }
 
-    #[unstable(feature = "pin", issue = "49150")]
-    pub fn pinned(data: T) -> Pin<Arc<T>> {
+    /// Constructs a new `Pin<Arc<T>>`. If `T` does not implement `Unpin`, then
+    /// `data` will be pinned in memory and unable to be moved.
+    #[stable(feature = "pin", since = "1.33.0")]
+    pub fn pin(data: T) -> Pin<Arc<T>> {
         unsafe { Pin::new_unchecked(Arc::new(data)) }
     }
 
@@ -2050,5 +2052,5 @@ impl<T: ?Sized> AsRef<T> for Arc<T> {
     }
 }
 
-#[unstable(feature = "pin", issue = "49150")]
+#[stable(feature = "pin", since = "1.33.0")]
 impl<T: ?Sized> Unpin for Arc<T> { }
diff --git a/src/libcore/future/future.rs b/src/libcore/future/future.rs
index 5dee1d6dd3a..da3aa8449ba 100644
--- a/src/libcore/future/future.rs
+++ b/src/libcore/future/future.rs
@@ -120,7 +120,7 @@ impl<'a, F: ?Sized + Future + Unpin> Future for &'a mut F {
 
 impl<P> Future for Pin<P>
 where
-    P: ops::DerefMut,
+    P: Unpin + ops::DerefMut,
     P::Target: Future,
 {
     type Output = <<P as ops::Deref>::Target as Future>::Output;
diff --git a/src/libcore/marker.rs b/src/libcore/marker.rs
index d3d16127ed5..74055a4f8a9 100644
--- a/src/libcore/marker.rs
+++ b/src/libcore/marker.rs
@@ -621,7 +621,6 @@ unsafe impl<T: ?Sized> Freeze for &mut T {}
 /// So this, for example, can only be done on types implementing `Unpin`:
 ///
 /// ```rust
-/// #![feature(pin)]
 /// use std::mem::replace;
 /// use std::pin::Pin;
 ///
@@ -637,23 +636,23 @@ unsafe impl<T: ?Sized> Freeze for &mut T {}
 /// [`replace`]: ../../std/mem/fn.replace.html
 /// [`Pin`]: ../pin/struct.Pin.html
 /// [`pin module`]: ../../std/pin/index.html
-#[unstable(feature = "pin", issue = "49150")]
+#[stable(feature = "pin", since = "1.33.0")]
 pub auto trait Unpin {}
 
 /// A marker type which does not implement `Unpin`.
 ///
 /// If a type contains a `PhantomPinned`, it will not implement `Unpin` by default.
-#[unstable(feature = "pin", issue = "49150")]
+#[stable(feature = "pin", since = "1.33.0")]
 #[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
 pub struct PhantomPinned;
 
-#[unstable(feature = "pin", issue = "49150")]
+#[stable(feature = "pin", since = "1.33.0")]
 impl !Unpin for PhantomPinned {}
 
-#[unstable(feature = "pin", issue = "49150")]
+#[stable(feature = "pin", since = "1.33.0")]
 impl<'a, T: ?Sized + 'a> Unpin for &'a T {}
 
-#[unstable(feature = "pin", issue = "49150")]
+#[stable(feature = "pin", since = "1.33.0")]
 impl<'a, T: ?Sized + 'a> Unpin for &'a mut T {}
 
 /// Implementations of `Copy` for primitive types.
diff --git a/src/libcore/option.rs b/src/libcore/option.rs
index 44d632ece05..2b01da0de52 100644
--- a/src/libcore/option.rs
+++ b/src/libcore/option.rs
@@ -273,7 +273,7 @@ impl<T> Option<T> {
 
     /// Converts from `Pin<&Option<T>>` to `Option<Pin<&T>>`
     #[inline]
-    #[unstable(feature = "pin", issue = "49150")]
+    #[stable(feature = "pin", since = "1.33.0")]
     pub fn as_pin_ref<'a>(self: Pin<&'a Option<T>>) -> Option<Pin<&'a T>> {
         unsafe {
             Pin::get_ref(self).as_ref().map(|x| Pin::new_unchecked(x))
@@ -282,10 +282,10 @@ impl<T> Option<T> {
 
     /// Converts from `Pin<&mut Option<T>>` to `Option<Pin<&mut T>>`
     #[inline]
-    #[unstable(feature = "pin", issue = "49150")]
+    #[stable(feature = "pin", since = "1.33.0")]
     pub fn as_pin_mut<'a>(self: Pin<&'a mut Option<T>>) -> Option<Pin<&'a mut T>> {
         unsafe {
-            Pin::get_mut_unchecked(self).as_mut().map(|x| Pin::new_unchecked(x))
+            Pin::get_unchecked_mut(self).as_mut().map(|x| Pin::new_unchecked(x))
         }
     }
 
@@ -1253,20 +1253,42 @@ impl<A, V: FromIterator<A>> FromIterator<Option<A>> for Option<V> {
     /// returned. Should no [`None`][Option::None] occur, a container with the
     /// values of each [`Option`] is returned.
     ///
-    /// Here is an example which increments every integer in a vector,
-    /// checking for overflow:
+    /// # Examples
+    ///
+    /// Here is an example which increments every integer in a vector.
+    /// `We use the checked variant of `add` that returns `None` when the
+    /// calculation would result in an overflow.
     ///
     /// ```
-    /// use std::u16;
+    /// let items = vec![0_u16, 1, 2];
+    ///
+    /// let res: Option<Vec<u16>> = items
+    ///     .iter()
+    ///     .map(|x| x.checked_add(1))
+    ///     .collect();
     ///
-    /// let v = vec![1, 2];
-    /// let res: Option<Vec<u16>> = v.iter().map(|&x: &u16|
-    ///     if x == u16::MAX { None }
-    ///     else { Some(x + 1) }
-    /// ).collect();
-    /// assert!(res == Some(vec![2, 3]));
+    /// assert_eq!(res, Some(vec![1, 2, 3]));
     /// ```
     ///
+    /// As you can see, this will return the expected, valid items.
+    ///
+    /// Here is another example that tries to subtract one from another list
+    /// of integers, this time checking for underflow:
+    ///
+    /// ```
+    /// let items = vec![2_u16, 1, 0];
+    ///
+    /// let res: Option<Vec<u16>> = items
+    ///     .iter()
+    ///     .map(|x| x.checked_sub(1))
+    ///     .collect();
+    ///
+    /// assert_eq!(res, None);
+    /// ```
+    ///
+    /// Since the last element is zero, it would underflow. Thus, the resulting
+    /// value is `None`.
+    ///
     /// [`Iterator`]: ../iter/trait.Iterator.html
     #[inline]
     fn from_iter<I: IntoIterator<Item=Option<A>>>(iter: I) -> Option<V> {
diff --git a/src/libcore/pin.rs b/src/libcore/pin.rs
index 521ce9b5f6b..d8508631bf9 100644
--- a/src/libcore/pin.rs
+++ b/src/libcore/pin.rs
@@ -36,15 +36,13 @@
 //! are always freely movable, even if the data they point to isn't.
 //!
 //! [`Pin`]: struct.Pin.html
-//! [`Unpin`]: trait.Unpin.html
+//! [`Unpin`]: ../../std/marker/trait.Unpin.html
 //! [`swap`]: ../../std/mem/fn.swap.html
 //! [`Box`]: ../../std/boxed/struct.Box.html
 //!
 //! # Examples
 //!
 //! ```rust
-//! #![feature(pin)]
-//!
 //! use std::pin::Pin;
 //! use std::marker::PhantomPinned;
 //! use std::ptr::NonNull;
@@ -72,13 +70,13 @@
 //!             slice: NonNull::dangling(),
 //!             _pin: PhantomPinned,
 //!         };
-//!         let mut boxed = Box::pinned(res);
+//!         let mut boxed = Box::pin(res);
 //!
 //!         let slice = NonNull::from(&boxed.data);
 //!         // we know this is safe because modifying a field doesn't move the whole struct
 //!         unsafe {
 //!             let mut_ref: Pin<&mut Self> = Pin::as_mut(&mut boxed);
-//!             Pin::get_mut_unchecked(mut_ref).slice = slice;
+//!             Pin::get_unchecked_mut(mut_ref).slice = slice;
 //!         }
 //!         boxed
 //!     }
@@ -97,15 +95,12 @@
 //! // std::mem::swap(&mut *still_unmoved, &mut *new_unmoved);
 //! ```
 
-#![unstable(feature = "pin", issue = "49150")]
+#![stable(feature = "pin", since = "1.33.0")]
 
 use fmt;
-use marker::Sized;
+use marker::{Sized, Unpin};
 use ops::{Deref, DerefMut, Receiver, CoerceUnsized, DispatchFromDyn};
 
-#[doc(inline)]
-pub use marker::Unpin;
-
 /// A pinned pointer.
 ///
 /// This is a wrapper around a kind of pointer which makes that pointer "pin" its
@@ -119,8 +114,9 @@ pub use marker::Unpin;
 //
 // Note: the derives below are allowed because they all only use `&P`, so they
 // cannot move the value behind `pointer`.
-#[unstable(feature = "pin", issue = "49150")]
+#[stable(feature = "pin", since = "1.33.0")]
 #[fundamental]
+#[repr(transparent)]
 #[derive(Copy, Clone, Hash, Eq, PartialEq, Ord, PartialOrd)]
 pub struct Pin<P> {
     pointer: P,
@@ -132,7 +128,7 @@ where
 {
     /// Construct a new `Pin` around a pointer to some data of a type that
     /// implements `Unpin`.
-    #[unstable(feature = "pin", issue = "49150")]
+    #[stable(feature = "pin", since = "1.33.0")]
     #[inline(always)]
     pub fn new(pointer: P) -> Pin<P> {
         // Safety: the value pointed to is `Unpin`, and so has no requirements
@@ -154,14 +150,14 @@ impl<P: Deref> Pin<P> {
     ///
     /// If `pointer` dereferences to an `Unpin` type, `Pin::new` should be used
     /// instead.
-    #[unstable(feature = "pin", issue = "49150")]
+    #[stable(feature = "pin", since = "1.33.0")]
     #[inline(always)]
     pub unsafe fn new_unchecked(pointer: P) -> Pin<P> {
         Pin { pointer }
     }
 
     /// Get a pinned shared reference from this pinned pointer.
-    #[unstable(feature = "pin", issue = "49150")]
+    #[stable(feature = "pin", since = "1.33.0")]
     #[inline(always)]
     pub fn as_ref(self: &Pin<P>) -> Pin<&P::Target> {
         unsafe { Pin::new_unchecked(&*self.pointer) }
@@ -170,14 +166,14 @@ impl<P: Deref> Pin<P> {
 
 impl<P: DerefMut> Pin<P> {
     /// Get a pinned mutable reference from this pinned pointer.
-    #[unstable(feature = "pin", issue = "49150")]
+    #[stable(feature = "pin", since = "1.33.0")]
     #[inline(always)]
     pub fn as_mut(self: &mut Pin<P>) -> Pin<&mut P::Target> {
         unsafe { Pin::new_unchecked(&mut *self.pointer) }
     }
 
     /// Assign a new value to the memory behind the pinned reference.
-    #[unstable(feature = "pin", issue = "49150")]
+    #[stable(feature = "pin", since = "1.33.0")]
     #[inline(always)]
     pub fn set(mut self: Pin<P>, value: P::Target)
     where
@@ -199,11 +195,11 @@ impl<'a, T: ?Sized> Pin<&'a T> {
     /// will not move so long as the argument value does not move (for example,
     /// because it is one of the fields of that value), and also that you do
     /// not move out of the argument you receive to the interior function.
-    #[unstable(feature = "pin", issue = "49150")]
-    pub unsafe fn map_unchecked<U, F>(this: Pin<&'a T>, func: F) -> Pin<&'a U> where
+    #[stable(feature = "pin", since = "1.33.0")]
+    pub unsafe fn map_unchecked<U, F>(self: Pin<&'a T>, func: F) -> Pin<&'a U> where
         F: FnOnce(&T) -> &U,
     {
-        let pointer = &*this.pointer;
+        let pointer = &*self.pointer;
         let new_pointer = func(pointer);
         Pin::new_unchecked(new_pointer)
     }
@@ -215,19 +211,19 @@ impl<'a, T: ?Sized> Pin<&'a T> {
     /// that lives for as long as the borrow of the `Pin`, not the lifetime of
     /// the `Pin` itself. This method allows turning the `Pin` into a reference
     /// with the same lifetime as the original `Pin`.
-    #[unstable(feature = "pin", issue = "49150")]
+    #[stable(feature = "pin", since = "1.33.0")]
     #[inline(always)]
-    pub fn get_ref(this: Pin<&'a T>) -> &'a T {
-        this.pointer
+    pub fn get_ref(self: Pin<&'a T>) -> &'a T {
+        self.pointer
     }
 }
 
 impl<'a, T: ?Sized> Pin<&'a mut T> {
     /// Convert this `Pin<&mut T>` into a `Pin<&T>` with the same lifetime.
-    #[unstable(feature = "pin", issue = "49150")]
+    #[stable(feature = "pin", since = "1.33.0")]
     #[inline(always)]
-    pub fn into_ref(this: Pin<&'a mut T>) -> Pin<&'a T> {
-        Pin { pointer: this.pointer }
+    pub fn into_ref(self: Pin<&'a mut T>) -> Pin<&'a T> {
+        Pin { pointer: self.pointer }
     }
 
     /// Get a mutable reference to the data inside of this `Pin`.
@@ -239,12 +235,12 @@ impl<'a, T: ?Sized> Pin<&'a mut T> {
     /// that lives for as long as the borrow of the `Pin`, not the lifetime of
     /// the `Pin` itself. This method allows turning the `Pin` into a reference
     /// with the same lifetime as the original `Pin`.
-    #[unstable(feature = "pin", issue = "49150")]
+    #[stable(feature = "pin", since = "1.33.0")]
     #[inline(always)]
-    pub fn get_mut(this: Pin<&'a mut T>) -> &'a mut T
+    pub fn get_mut(self: Pin<&'a mut T>) -> &'a mut T
         where T: Unpin,
     {
-        this.pointer
+        self.pointer
     }
 
     /// Get a mutable reference to the data inside of this `Pin`.
@@ -257,10 +253,10 @@ impl<'a, T: ?Sized> Pin<&'a mut T> {
     ///
     /// If the underlying data is `Unpin`, `Pin::get_mut` should be used
     /// instead.
-    #[unstable(feature = "pin", issue = "49150")]
+    #[stable(feature = "pin", since = "1.33.0")]
     #[inline(always)]
-    pub unsafe fn get_mut_unchecked(this: Pin<&'a mut T>) -> &'a mut T {
-        this.pointer
+    pub unsafe fn get_unchecked_mut(self: Pin<&'a mut T>) -> &'a mut T {
+        self.pointer
     }
 
     /// Construct a new pin by mapping the interior value.
@@ -274,17 +270,17 @@ impl<'a, T: ?Sized> Pin<&'a mut T> {
     /// will not move so long as the argument value does not move (for example,
     /// because it is one of the fields of that value), and also that you do
     /// not move out of the argument you receive to the interior function.
-    #[unstable(feature = "pin", issue = "49150")]
-    pub unsafe fn map_unchecked_mut<U, F>(this: Pin<&'a mut T>, func: F) -> Pin<&'a mut U> where
+    #[stable(feature = "pin", since = "1.33.0")]
+    pub unsafe fn map_unchecked_mut<U, F>(self: Pin<&'a mut T>, func: F) -> Pin<&'a mut U> where
         F: FnOnce(&mut T) -> &mut U,
     {
-        let pointer = Pin::get_mut_unchecked(this);
+        let pointer = Pin::get_unchecked_mut(self);
         let new_pointer = func(pointer);
         Pin::new_unchecked(new_pointer)
     }
 }
 
-#[unstable(feature = "pin", issue = "49150")]
+#[stable(feature = "pin", since = "1.33.0")]
 impl<P: Deref> Deref for Pin<P> {
     type Target = P::Target;
     fn deref(&self) -> &P::Target {
@@ -292,7 +288,7 @@ impl<P: Deref> Deref for Pin<P> {
     }
 }
 
-#[unstable(feature = "pin", issue = "49150")]
+#[stable(feature = "pin", since = "1.33.0")]
 impl<P: DerefMut> DerefMut for Pin<P>
 where
     P::Target: Unpin
@@ -305,21 +301,21 @@ where
 #[unstable(feature = "receiver_trait", issue = "0")]
 impl<P: Receiver> Receiver for Pin<P> {}
 
-#[unstable(feature = "pin", issue = "49150")]
+#[stable(feature = "pin", since = "1.33.0")]
 impl<P: fmt::Debug> fmt::Debug for Pin<P> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         fmt::Debug::fmt(&self.pointer, f)
     }
 }
 
-#[unstable(feature = "pin", issue = "49150")]
+#[stable(feature = "pin", since = "1.33.0")]
 impl<P: fmt::Display> fmt::Display for Pin<P> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         fmt::Display::fmt(&self.pointer, f)
     }
 }
 
-#[unstable(feature = "pin", issue = "49150")]
+#[stable(feature = "pin", since = "1.33.0")]
 impl<P: fmt::Pointer> fmt::Pointer for Pin<P> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         fmt::Pointer::fmt(&self.pointer, f)
@@ -331,17 +327,14 @@ impl<P: fmt::Pointer> fmt::Pointer for Pin<P> {
 // `Deref<Target=Unpin>` is unsound. Any such impl would probably be unsound
 // for other reasons, though, so we just need to take care not to allow such
 // impls to land in std.
-#[unstable(feature = "pin", issue = "49150")]
+#[stable(feature = "pin", since = "1.33.0")]
 impl<P, U> CoerceUnsized<Pin<U>> for Pin<P>
 where
     P: CoerceUnsized<U>,
 {}
 
-#[unstable(feature = "pin", issue = "49150")]
+#[stable(feature = "pin", since = "1.33.0")]
 impl<'a, P, U> DispatchFromDyn<Pin<U>> for Pin<P>
 where
     P: DispatchFromDyn<U>,
 {}
-
-#[unstable(feature = "pin", issue = "49150")]
-impl<P> Unpin for Pin<P> {}
diff --git a/src/libcore/prelude/v1.rs b/src/libcore/prelude/v1.rs
index 45f629a6442..a1e6034b208 100644
--- a/src/libcore/prelude/v1.rs
+++ b/src/libcore/prelude/v1.rs
@@ -19,7 +19,7 @@
 // Re-exported core operators
 #[stable(feature = "core_prelude", since = "1.4.0")]
 #[doc(no_inline)]
-pub use marker::{Copy, Send, Sized, Sync};
+pub use marker::{Copy, Send, Sized, Sync, Unpin};
 #[stable(feature = "core_prelude", since = "1.4.0")]
 #[doc(no_inline)]
 pub use ops::{Drop, Fn, FnMut, FnOnce};
diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs
index 156d55b9e2f..0fd5963c99d 100644
--- a/src/librustc/hir/mod.rs
+++ b/src/librustc/hir/mod.rs
@@ -1979,6 +1979,15 @@ pub enum FunctionRetTy {
     Return(P<Ty>),
 }
 
+impl fmt::Display for FunctionRetTy {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        match self {
+            Return(ref ty) => print::to_string(print::NO_ANN, |s| s.print_type(ty)).fmt(f),
+            DefaultReturn(_) => "()".fmt(f),
+        }
+    }
+}
+
 impl FunctionRetTy {
     pub fn span(&self) -> Span {
         match *self {
@@ -2119,7 +2128,7 @@ impl StructField {
 /// Id of the whole enum lives in `Item`.
 ///
 /// For structs: `NodeId` represents an Id of the structure's constructor, so it is not actually
-/// used for `Struct`-structs (but still presents). Structures don't have an analogue of "Id of
+/// used for `Struct`-structs (but still present). Structures don't have an analogue of "Id of
 /// the variant itself" from enum variants.
 /// Id of the whole struct lives in `Item`.
 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
diff --git a/src/librustc/ich/impls_mir.rs b/src/librustc/ich/impls_mir.rs
index d82020f59a1..6852e2c6961 100644
--- a/src/librustc/ich/impls_mir.rs
+++ b/src/librustc/ich/impls_mir.rs
@@ -47,7 +47,6 @@ impl_stable_hash_for!(enum mir::BorrowKind {
 impl_stable_hash_for!(enum mir::UnsafetyViolationKind {
     General,
     GeneralAndConstFn,
-    GatedConstFnCall,
     ExternStatic(lint_node_id),
     BorrowPacked(lint_node_id),
 });
diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs
index 934d7c12be5..d2175c28309 100644
--- a/src/librustc/middle/dead.rs
+++ b/src/librustc/middle/dead.rs
@@ -25,6 +25,8 @@ use middle::privacy;
 use ty::{self, TyCtxt};
 use util::nodemap::FxHashSet;
 
+use rustc_data_structures::fx::FxHashMap;
+
 use syntax::{ast, source_map};
 use syntax::attr;
 use syntax_pos;
@@ -55,12 +57,15 @@ struct MarkSymbolVisitor<'a, 'tcx: 'a> {
     in_pat: bool,
     inherited_pub_visibility: bool,
     ignore_variant_stack: Vec<DefId>,
+    // maps from tuple struct constructors to tuple struct items
+    struct_constructors: FxHashMap<ast::NodeId, ast::NodeId>,
 }
 
 impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
     fn check_def_id(&mut self, def_id: DefId) {
         if let Some(node_id) = self.tcx.hir().as_local_node_id(def_id) {
-            if should_explore(self.tcx, node_id) {
+            if should_explore(self.tcx, node_id) ||
+               self.struct_constructors.contains_key(&node_id) {
                 self.worklist.push(node_id);
             }
             self.live_symbols.insert(node_id);
@@ -137,19 +142,23 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
                 continue
             }
 
-            if let Some(ref node) = self.tcx.hir().find(id) {
+            // in the case of tuple struct constructors we want to check the item, not the generated
+            // tuple struct constructor function
+            let id = self.struct_constructors.get(&id).cloned().unwrap_or(id);
+
+            if let Some(node) = self.tcx.hir().find(id) {
                 self.live_symbols.insert(id);
                 self.visit_node(node);
             }
         }
     }
 
-    fn visit_node(&mut self, node: &Node<'tcx>) {
+    fn visit_node(&mut self, node: Node<'tcx>) {
         let had_repr_c = self.repr_has_repr_c;
         self.repr_has_repr_c = false;
         let had_inherited_pub_visibility = self.inherited_pub_visibility;
         self.inherited_pub_visibility = false;
-        match *node {
+        match node {
             Node::Item(item) => {
                 match item.node {
                     hir::ItemKind::Struct(..) | hir::ItemKind::Union(..) => {
@@ -337,6 +346,8 @@ struct LifeSeeder<'k, 'tcx: 'k> {
     worklist: Vec<ast::NodeId>,
     krate: &'k hir::Crate,
     tcx: TyCtxt<'k, 'tcx, 'tcx>,
+    // see `MarkSymbolVisitor::struct_constructors`
+    struct_constructors: FxHashMap<ast::NodeId, ast::NodeId>,
 }
 
 impl<'v, 'k, 'tcx> ItemLikeVisitor<'v> for LifeSeeder<'k, 'tcx> {
@@ -379,6 +390,9 @@ impl<'v, 'k, 'tcx> ItemLikeVisitor<'v> for LifeSeeder<'k, 'tcx> {
                     }
                 }
             }
+            hir::ItemKind::Struct(ref variant_data, _) => {
+                self.struct_constructors.insert(variant_data.id(), item.id);
+            }
             _ => ()
         }
     }
@@ -392,11 +406,11 @@ impl<'v, 'k, 'tcx> ItemLikeVisitor<'v> for LifeSeeder<'k, 'tcx> {
     }
 }
 
-fn create_and_seed_worklist<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                                      access_levels: &privacy::AccessLevels,
-                                      krate: &hir::Crate)
-                                      -> Vec<ast::NodeId>
-{
+fn create_and_seed_worklist<'a, 'tcx>(
+    tcx: TyCtxt<'a, 'tcx, 'tcx>,
+    access_levels: &privacy::AccessLevels,
+    krate: &hir::Crate,
+) -> (Vec<ast::NodeId>, FxHashMap<ast::NodeId, ast::NodeId>) {
     let worklist = access_levels.map.iter().filter_map(|(&id, level)| {
         if level >= &privacy::AccessLevel::Reachable {
             Some(id)
@@ -413,17 +427,18 @@ fn create_and_seed_worklist<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
         worklist,
         krate,
         tcx,
+        struct_constructors: Default::default(),
     };
     krate.visit_all_item_likes(&mut life_seeder);
 
-    return life_seeder.worklist;
+    (life_seeder.worklist, life_seeder.struct_constructors)
 }
 
 fn find_live<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                        access_levels: &privacy::AccessLevels,
                        krate: &hir::Crate)
                        -> FxHashSet<ast::NodeId> {
-    let worklist = create_and_seed_worklist(tcx, access_levels, krate);
+    let (worklist, struct_constructors) = create_and_seed_worklist(tcx, access_levels, krate);
     let mut symbol_visitor = MarkSymbolVisitor {
         worklist,
         tcx,
@@ -433,20 +448,12 @@ fn find_live<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
         in_pat: false,
         inherited_pub_visibility: false,
         ignore_variant_stack: vec![],
+        struct_constructors,
     };
     symbol_visitor.mark_live_symbols();
     symbol_visitor.live_symbols
 }
 
-fn get_struct_ctor_id(item: &hir::Item) -> Option<ast::NodeId> {
-    match item.node {
-        hir::ItemKind::Struct(ref struct_def, _) if !struct_def.is_struct() => {
-            Some(struct_def.id())
-        }
-        _ => None
-    }
-}
-
 struct DeadVisitor<'a, 'tcx: 'a> {
     tcx: TyCtxt<'a, 'tcx, 'tcx>,
     live_symbols: FxHashSet<ast::NodeId>,
@@ -464,46 +471,35 @@ impl<'a, 'tcx> DeadVisitor<'a, 'tcx> {
             | hir::ItemKind::Union(..) => true,
             _ => false
         };
-        let ctor_id = get_struct_ctor_id(item);
-        should_warn && !self.symbol_is_live(item.id, ctor_id)
+        should_warn && !self.symbol_is_live(item.id)
     }
 
     fn should_warn_about_field(&mut self, field: &hir::StructField) -> bool {
         let field_type = self.tcx.type_of(self.tcx.hir().local_def_id(field.id));
         !field.is_positional()
-            && !self.symbol_is_live(field.id, None)
+            && !self.symbol_is_live(field.id)
             && !field_type.is_phantom_data()
             && !has_allow_dead_code_or_lang_attr(self.tcx, field.id, &field.attrs)
     }
 
     fn should_warn_about_variant(&mut self, variant: &hir::VariantKind) -> bool {
-        !self.symbol_is_live(variant.data.id(), None)
+        !self.symbol_is_live(variant.data.id())
             && !has_allow_dead_code_or_lang_attr(self.tcx,
                                                  variant.data.id(),
                                                  &variant.attrs)
     }
 
     fn should_warn_about_foreign_item(&mut self, fi: &hir::ForeignItem) -> bool {
-        !self.symbol_is_live(fi.id, None)
+        !self.symbol_is_live(fi.id)
             && !has_allow_dead_code_or_lang_attr(self.tcx, fi.id, &fi.attrs)
     }
 
     // id := node id of an item's definition.
-    // ctor_id := `Some` if the item is a struct_ctor (tuple struct),
-    //            `None` otherwise.
-    // If the item is a struct_ctor, then either its `id` or
-    // `ctor_id` (unwrapped) is in the live_symbols set. More specifically,
-    // DefMap maps the ExprKind::Path of a struct_ctor to the node referred by
-    // `ctor_id`. On the other hand, in a statement like
-    // `type <ident> <generics> = <ty>;` where <ty> refers to a struct_ctor,
-    // DefMap maps <ty> to `id` instead.
-    fn symbol_is_live(&mut self,
-                      id: ast::NodeId,
-                      ctor_id: Option<ast::NodeId>)
-                      -> bool {
-        if self.live_symbols.contains(&id)
-           || ctor_id.map_or(false, |ctor| self.live_symbols.contains(&ctor))
-        {
+    fn symbol_is_live(
+        &mut self,
+        id: ast::NodeId,
+    ) -> bool {
+        if self.live_symbols.contains(&id) {
             return true;
         }
         // If it's a type whose items are live, then it's live, too.
@@ -611,7 +607,7 @@ impl<'a, 'tcx> Visitor<'tcx> for DeadVisitor<'a, 'tcx> {
     fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem) {
         match impl_item.node {
             hir::ImplItemKind::Const(_, body_id) => {
-                if !self.symbol_is_live(impl_item.id, None) {
+                if !self.symbol_is_live(impl_item.id) {
                     self.warn_dead_code(impl_item.id,
                                         impl_item.span,
                                         impl_item.ident.name,
@@ -621,7 +617,7 @@ impl<'a, 'tcx> Visitor<'tcx> for DeadVisitor<'a, 'tcx> {
                 self.visit_nested_body(body_id)
             }
             hir::ImplItemKind::Method(_, body_id) => {
-                if !self.symbol_is_live(impl_item.id, None) {
+                if !self.symbol_is_live(impl_item.id) {
                     let span = self.tcx.sess.source_map().def_span(impl_item.span);
                     self.warn_dead_code(impl_item.id, span, impl_item.ident.name, "method", "used");
                 }
diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs
index dc14450e8d2..120350a573b 100644
--- a/src/librustc/mir/mod.rs
+++ b/src/librustc/mir/mod.rs
@@ -2792,9 +2792,6 @@ impl Location {
 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
 pub enum UnsafetyViolationKind {
     General,
-    /// Right now function calls to `const unsafe fn` are only permitted behind a feature gate
-    /// Also, even `const unsafe fn` need an `unsafe` block to do the allowed operations.
-    GatedConstFnCall,
     /// Permitted in const fn and regular fns
     GeneralAndConstFn,
     ExternStatic(ast::NodeId),
diff --git a/src/librustc_codegen_ssa/mir/place.rs b/src/librustc_codegen_ssa/mir/place.rs
index 90aa9f6cbc7..5fad4a24b26 100644
--- a/src/librustc_codegen_ssa/mir/place.rs
+++ b/src/librustc_codegen_ssa/mir/place.rs
@@ -335,11 +335,20 @@ impl<'a, 'tcx: 'a, V: CodegenObject> PlaceRef<'tcx, V> {
         bx: &mut Bx,
         llindex: V
     ) -> Self {
+        // Statically compute the offset if we can, otherwise just use the element size,
+        // as this will yield the lowest alignment.
+        let layout = self.layout.field(bx, 0);
+        let offset = if bx.is_const_integral(llindex) {
+            layout.size.checked_mul(bx.const_to_uint(llindex), bx).unwrap_or(layout.size)
+        } else {
+            layout.size
+        };
+
         PlaceRef {
             llval: bx.inbounds_gep(self.llval, &[bx.cx().const_usize(0), llindex]),
             llextra: None,
-            layout: self.layout.field(bx.cx(), 0),
-            align: self.align
+            layout,
+            align: self.align.restrict_for_offset(offset),
         }
     }
 
diff --git a/src/librustc_codegen_ssa/mir/rvalue.rs b/src/librustc_codegen_ssa/mir/rvalue.rs
index c932ffd1c1b..052342dd759 100644
--- a/src/librustc_codegen_ssa/mir/rvalue.rs
+++ b/src/librustc_codegen_ssa/mir/rvalue.rs
@@ -131,8 +131,9 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                 let keep_going = header_bx.icmp(IntPredicate::IntNE, current, end);
                 header_bx.cond_br(keep_going, body_bx.llbb(), next_bx.llbb());
 
+                let align = dest.align.restrict_for_offset(dest.layout.field(bx.cx(), 0).size);
                 cg_elem.val.store(&mut body_bx,
-                    PlaceRef::new_sized(current, cg_elem.layout, dest.align));
+                    PlaceRef::new_sized(current, cg_elem.layout, align));
 
                 let next = body_bx.inbounds_gep(current, &[bx.cx().const_usize(1)]);
                 body_bx.br(header_bx.llbb());
diff --git a/src/librustc_mir/build/expr/into.rs b/src/librustc_mir/build/expr/into.rs
index 146bf538306..64defaf78a4 100644
--- a/src/librustc_mir/build/expr/into.rs
+++ b/src/librustc_mir/build/expr/into.rs
@@ -126,18 +126,17 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
             ExprKind::LogicalOp { op, lhs, rhs } => {
                 // And:
                 //
-                // [block: If(lhs)] -true-> [else_block: If(rhs)] -true-> [true_block]
-                //        |                          | (false)
-                //        +----------false-----------+------------------> [false_block]
+                // [block: If(lhs)] -true-> [else_block: dest = (rhs)]
+                //        | (false)
+                //  [shortcurcuit_block: dest = false]
                 //
                 // Or:
                 //
-                // [block: If(lhs)] -false-> [else_block: If(rhs)] -true-> [true_block]
-                //        | (true)                   | (false)
-                //  [true_block]               [false_block]
+                // [block: If(lhs)] -false-> [else_block: dest = (rhs)]
+                //        | (true)
+                //  [shortcurcuit_block: dest = true]
 
-                let (true_block, false_block, mut else_block, join_block) = (
-                    this.cfg.start_new_block(),
+                let (shortcircuit_block, mut else_block, join_block) = (
                     this.cfg.start_new_block(),
                     this.cfg.start_new_block(),
                     this.cfg.start_new_block(),
@@ -145,47 +144,41 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
 
                 let lhs = unpack!(block = this.as_local_operand(block, lhs));
                 let blocks = match op {
-                    LogicalOp::And => (else_block, false_block),
-                    LogicalOp::Or => (true_block, else_block),
+                    LogicalOp::And => (else_block, shortcircuit_block),
+                    LogicalOp::Or => (shortcircuit_block, else_block),
                 };
                 let term = TerminatorKind::if_(this.hir.tcx(), lhs, blocks.0, blocks.1);
                 this.cfg.terminate(block, source_info, term);
 
-                let rhs = unpack!(else_block = this.as_local_operand(else_block, rhs));
-                let term = TerminatorKind::if_(this.hir.tcx(), rhs, true_block, false_block);
-                this.cfg.terminate(else_block, source_info, term);
-
                 this.cfg.push_assign_constant(
-                    true_block,
+                    shortcircuit_block,
                     source_info,
                     destination,
                     Constant {
                         span: expr_span,
                         ty: this.hir.bool_ty(),
                         user_ty: None,
-                        literal: this.hir.true_literal(),
+                        literal: match op {
+                            LogicalOp::And => this.hir.false_literal(),
+                            LogicalOp::Or => this.hir.true_literal(),
+                        },
                     },
                 );
-
-                this.cfg.push_assign_constant(
-                    false_block,
+                this.cfg.terminate(
+                    shortcircuit_block,
                     source_info,
-                    destination,
-                    Constant {
-                        span: expr_span,
-                        ty: this.hir.bool_ty(),
-                        user_ty: None,
-                        literal: this.hir.false_literal(),
-                    },
+                    TerminatorKind::Goto { target: join_block },
                 );
 
-                this.cfg.terminate(
-                    true_block,
+                let rhs = unpack!(else_block = this.as_local_operand(else_block, rhs));
+                this.cfg.push_assign(
+                    else_block,
                     source_info,
-                    TerminatorKind::Goto { target: join_block },
+                    destination,
+                    Rvalue::Use(rhs),
                 );
                 this.cfg.terminate(
-                    false_block,
+                    else_block,
                     source_info,
                     TerminatorKind::Goto { target: join_block },
                 );
diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs
index a6239a8115a..8ab9cb42b82 100644
--- a/src/librustc_mir/monomorphize/collector.rs
+++ b/src/librustc_mir/monomorphize/collector.rs
@@ -139,7 +139,7 @@
 //!
 //! #### Boxes
 //! Since `Box` expression have special compiler support, no explicit calls to
-//! `exchange_malloc()` and `exchange_free()` may show up in MIR, even if the
+//! `exchange_malloc()` and `box_free()` may show up in MIR, even if the
 //! compiler will generate them. We have to observe `Rvalue::Box` expressions
 //! and Box-typed drop-statements for that purpose.
 //!
diff --git a/src/librustc_mir/transform/check_unsafety.rs b/src/librustc_mir/transform/check_unsafety.rs
index f6b7f817aad..89d9c03f74e 100644
--- a/src/librustc_mir/transform/check_unsafety.rs
+++ b/src/librustc_mir/transform/check_unsafety.rs
@@ -23,7 +23,6 @@ use rustc::mir::visit::{PlaceContext, Visitor, MutatingUseContext};
 
 use syntax::ast;
 use syntax::symbol::Symbol;
-use syntax::feature_gate::{emit_feature_err, GateIssue};
 
 use std::ops::Bound;
 
@@ -97,7 +96,7 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> {
                 if let hir::Unsafety::Unsafe = sig.unsafety() {
                     self.require_unsafe("call to unsafe function",
                         "consult the function's documentation for information on how to avoid \
-                         undefined behavior", UnsafetyViolationKind::GatedConstFnCall)
+                         undefined behavior", UnsafetyViolationKind::GeneralAndConstFn)
                 }
             }
         }
@@ -325,11 +324,6 @@ impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> {
                             // compat lint
                             violation.kind = UnsafetyViolationKind::General;
                         },
-                        UnsafetyViolationKind::GatedConstFnCall => {
-                            // safe code can't call unsafe const fns, this `UnsafetyViolationKind`
-                            // is only relevant for `Safety::ExplicitUnsafe` in `unsafe const fn`s
-                            violation.kind = UnsafetyViolationKind::General;
-                        }
                     }
                     if !self.violations.contains(&violation) {
                         self.violations.push(violation)
@@ -346,19 +340,8 @@ impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> {
                 }
                 // only some unsafety is allowed in const fn
                 if self.min_const_fn {
-                    let min_const_unsafe_fn = self.tcx.features().min_const_unsafe_fn;
                     for violation in violations {
                         match violation.kind {
-                            UnsafetyViolationKind::GatedConstFnCall if min_const_unsafe_fn => {
-                                // these function calls to unsafe functions are allowed
-                                // if `#![feature(min_const_unsafe_fn)]` is active
-                            },
-                            UnsafetyViolationKind::GatedConstFnCall => {
-                                // without the feature gate, we report errors
-                                if !self.violations.contains(&violation) {
-                                    self.violations.push(violation.clone())
-                                }
-                            }
                             // these unsafe things are stable in const fn
                             UnsafetyViolationKind::GeneralAndConstFn => {},
                             // these things are forbidden in const fns
@@ -620,16 +603,6 @@ pub fn check_unsafety<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) {
                     .note(&details.as_str()[..])
                     .emit();
             }
-            UnsafetyViolationKind::GatedConstFnCall => {
-                emit_feature_err(
-                    &tcx.sess.parse_sess,
-                    "min_const_unsafe_fn",
-                    source_info.span,
-                    GateIssue::Language,
-                    "calls to `const unsafe fn` in const fns are unstable",
-                );
-
-            }
             UnsafetyViolationKind::ExternStatic(lint_node_id) => {
                 tcx.lint_node_note(SAFE_EXTERN_STATICS,
                               lint_node_id,
diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs
index b854f029e51..646a671d4a2 100644
--- a/src/librustc_mir/transform/qualify_consts.rs
+++ b/src/librustc_mir/transform/qualify_consts.rs
@@ -518,7 +518,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
 
                 // Only allow statics (not consts) to refer to other statics.
                 if self.mode == Mode::Static || self.mode == Mode::StaticMut {
-                    if context.is_mutating_use() {
+                    if self.mode == Mode::Static && context.is_mutating_use() {
                         // this is not strictly necessary as miri will also bail out
                         // For interior mutability we can't really catch this statically as that
                         // goes through raw pointers and intermediate temporaries, so miri has
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index 794e5741d62..e543677ef06 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -3213,23 +3213,43 @@ impl<'a> Resolver<'a> {
                 let enum_candidates =
                     this.lookup_import_candidates(ident, ns, is_enum_variant);
                 let mut enum_candidates = enum_candidates.iter()
-                    .map(|suggestion| import_candidate_to_paths(&suggestion)).collect::<Vec<_>>();
+                    .map(|suggestion| {
+                        import_candidate_to_enum_paths(&suggestion)
+                    }).collect::<Vec<_>>();
                 enum_candidates.sort();
-                for (sp, variant_path, enum_path) in enum_candidates {
-                    if sp.is_dummy() {
-                        let msg = format!("there is an enum variant `{}`, \
-                                           try using `{}`?",
-                                          variant_path,
-                                          enum_path);
-                        err.help(&msg);
+
+                if !enum_candidates.is_empty() {
+                    // contextualize for E0412 "cannot find type", but don't belabor the point
+                    // (that it's a variant) for E0573 "expected type, found variant"
+                    let preamble = if def.is_none() {
+                        let others = match enum_candidates.len() {
+                            1 => String::new(),
+                            2 => " and 1 other".to_owned(),
+                            n => format!(" and {} others", n)
+                        };
+                        format!("there is an enum variant `{}`{}; ",
+                                enum_candidates[0].0, others)
                     } else {
-                        err.span_suggestion_with_applicability(
-                            span,
-                            "you can try using the variant's enum",
-                            enum_path,
-                            Applicability::MachineApplicable,
-                        );
-                    }
+                        String::new()
+                    };
+                    let msg = format!("{}try using the variant's enum", preamble);
+
+                    err.span_suggestions_with_applicability(
+                        span,
+                        &msg,
+                        enum_candidates.into_iter()
+                            .map(|(_variant_path, enum_ty_path)| enum_ty_path)
+                            // variants reëxported in prelude doesn't mean `prelude::v1` is the
+                            // type name! FIXME: is there a more principled way to do this that
+                            // would work for other reëxports?
+                            .filter(|enum_ty_path| enum_ty_path != "std::prelude::v1")
+                            // also say `Option` rather than `std::prelude::v1::Option`
+                            .map(|enum_ty_path| {
+                                // FIXME #56861: DRYer prelude filtering
+                                enum_ty_path.trim_start_matches("std::prelude::v1::").to_owned()
+                            }),
+                        Applicability::MachineApplicable,
+                    );
                 }
             }
             if path.len() == 1 && this.self_type_is_available(span) {
@@ -5128,8 +5148,8 @@ fn path_names_to_string(path: &Path) -> String {
                         .collect::<Vec<_>>())
 }
 
-/// Get the path for an enum and the variant from an `ImportSuggestion` for an enum variant.
-fn import_candidate_to_paths(suggestion: &ImportSuggestion) -> (Span, String, String) {
+/// Get the stringified path for an enum from an `ImportSuggestion` for an enum variant.
+fn import_candidate_to_enum_paths(suggestion: &ImportSuggestion) -> (String, String) {
     let variant_path = &suggestion.path;
     let variant_path_string = path_names_to_string(variant_path);
 
@@ -5140,7 +5160,7 @@ fn import_candidate_to_paths(suggestion: &ImportSuggestion) -> (Span, String, St
     };
     let enum_path_string = path_names_to_string(&enum_path);
 
-    (suggestion.path.span, variant_path_string, enum_path_string)
+    (variant_path_string, enum_path_string)
 }
 
 
diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs
index 9a1f9784192..8b2be849423 100644
--- a/src/librustc_typeck/check/coercion.rs
+++ b/src/librustc_typeck/check/coercion.rs
@@ -1169,7 +1169,6 @@ impl<'gcx, 'tcx, 'exprs, E> CoerceMany<'gcx, 'tcx, 'exprs, E>
             // `expression_ty` will be unit).
             //
             // Another example is `break` with no argument expression.
-            assert!(expression_ty.is_unit());
             assert!(expression_ty.is_unit(), "if let hack without unit type");
             fcx.at(cause, fcx.param_env)
                .eq_exp(label_expression_as_expected, expression_ty, self.merged_ty())
@@ -1210,13 +1209,14 @@ impl<'gcx, 'tcx, 'exprs, E> CoerceMany<'gcx, 'tcx, 'exprs, E>
                     (self.final_ty.unwrap_or(self.expected_ty), expression_ty)
                 };
 
+                let reason_label = "expected because of this statement";
                 let mut db;
                 match cause.code {
                     ObligationCauseCode::ReturnNoExpression => {
                         db = struct_span_err!(
                             fcx.tcx.sess, cause.span, E0069,
                             "`return;` in a function whose return type is not `()`");
-                        db.span_label(cause.span, "return type is not ()");
+                        db.span_label(cause.span, "return type is not `()`");
                     }
                     ObligationCauseCode::BlockTailExpression(blk_id) => {
                         db = fcx.report_mismatched_types(cause, expected, found, err);
@@ -1234,9 +1234,19 @@ impl<'gcx, 'tcx, 'exprs, E> CoerceMany<'gcx, 'tcx, 'exprs, E>
                             cause.span,
                             blk_id,
                         );
+                        if let Some(sp) = fcx.ret_coercion_span.borrow().as_ref() {
+                            if !sp.overlaps(cause.span) {
+                                db.span_label(*sp, reason_label);
+                            }
+                        }
                     }
                     _ => {
                         db = fcx.report_mismatched_types(cause, expected, found, err);
+                        if let Some(sp) = fcx.ret_coercion_span.borrow().as_ref() {
+                            if !sp.overlaps(cause.span) {
+                                db.span_label(*sp, reason_label);
+                            }
+                        }
                     }
                 }
 
diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs
index db4b68611c5..996b57f558c 100644
--- a/src/librustc_typeck/check/demand.rs
+++ b/src/librustc_typeck/check/demand.rs
@@ -123,6 +123,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                         let sole_field_ty = sole_field.ty(self.tcx, substs);
                         if self.can_coerce(expr_ty, sole_field_ty) {
                             let variant_path = self.tcx.item_path_str(variant.did);
+                            // FIXME #56861: DRYer prelude filtering
                             Some(variant_path.trim_start_matches("std::prelude::v1::").to_string())
                         } else {
                             None
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index d45f8fd6de8..0665452e30a 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -538,6 +538,7 @@ pub struct FnCtxt<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
     err_count_on_creation: usize,
 
     ret_coercion: Option<RefCell<DynamicCoerceMany<'gcx, 'tcx>>>,
+    ret_coercion_span: RefCell<Option<Span>>,
 
     yield_ty: Option<Ty<'tcx>>,
 
@@ -1987,6 +1988,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
             param_env,
             err_count_on_creation: inh.tcx.sess.err_count(),
             ret_coercion: None,
+            ret_coercion_span: RefCell::new(None),
             yield_ty: None,
             ps: RefCell::new(UnsafetyState::function(hir::Unsafety::Normal,
                                                      ast::CRATE_NODE_ID)),
@@ -3440,7 +3442,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                             len.assert_usize(self.tcx),
                             field.as_str().parse::<u64>()
                         ) {
-                            let base = self.tcx.hir().node_to_pretty_string(base.id);
+                            let base = self.tcx.sess.source_map()
+                                .span_to_snippet(base.span)
+                                .unwrap_or_else(|_| self.tcx.hir().node_to_pretty_string(base.id));
                             let help = "instead of using tuple indexing, use array indexing";
                             let suggestion = format!("{}[{}]", base, field);
                             let applicability = if len < user_index {
@@ -3454,11 +3458,13 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                         }
                     }
                     ty::RawPtr(..) => {
-                        let base = self.tcx.hir().node_to_pretty_string(base.id);
-                        let msg = format!("`{}` is a native pointer; try dereferencing it", base);
+                        let base = self.tcx.sess.source_map()
+                            .span_to_snippet(base.span)
+                            .unwrap_or_else(|_| self.tcx.hir().node_to_pretty_string(base.id));
+                        let msg = format!("`{}` is a raw pointer; try dereferencing it", base);
                         let suggestion = format!("(*{}).{}", base, field);
                         err.span_suggestion_with_applicability(
-                            field.span,
+                            expr.span,
                             &msg,
                             suggestion,
                             Applicability::MaybeIncorrect,
@@ -4168,11 +4174,30 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                     struct_span_err!(self.tcx.sess, expr.span, E0572,
                                      "return statement outside of function body").emit();
                 } else if let Some(ref e) = *expr_opt {
+                    *self.ret_coercion_span.borrow_mut() = Some(e.span);
                     self.check_return_expr(e);
                 } else {
                     let mut coercion = self.ret_coercion.as_ref().unwrap().borrow_mut();
+                    *self.ret_coercion_span.borrow_mut() = Some(expr.span);
                     let cause = self.cause(expr.span, ObligationCauseCode::ReturnNoExpression);
-                    coercion.coerce_forced_unit(self, &cause, &mut |_| (), true);
+                    if let Some((fn_decl, _)) = self.get_fn_decl(expr.id) {
+                        coercion.coerce_forced_unit(
+                            self,
+                            &cause,
+                            &mut |db| {
+                                db.span_label(
+                                    fn_decl.output.span(),
+                                    format!(
+                                        "expected `{}` because of this return type",
+                                        fn_decl.output,
+                                    ),
+                                );
+                            },
+                            true,
+                        );
+                    } else {
+                        coercion.coerce_forced_unit(self, &cause, &mut |_| (), true);
+                    }
                 }
                 tcx.types.never
             }
diff --git a/src/libstd/future.rs b/src/libstd/future.rs
index d5e6cab948b..3379be79186 100644
--- a/src/libstd/future.rs
+++ b/src/libstd/future.rs
@@ -43,7 +43,7 @@ impl<T: Generator<Yield = ()>> !Unpin for GenFuture<T> {}
 impl<T: Generator<Yield = ()>> Future for GenFuture<T> {
     type Output = T::Return;
     fn poll(self: Pin<&mut Self>, lw: &LocalWaker) -> Poll<Self::Output> {
-        set_task_waker(lw, || match unsafe { Pin::get_mut_unchecked(self).0.resume() } {
+        set_task_waker(lw, || match unsafe { Pin::get_unchecked_mut(self).0.resume() } {
             GeneratorState::Yielded(()) => Poll::Pending,
             GeneratorState::Complete(x) => Poll::Ready(x),
         })
diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs
index 0d3de34fe64..5bede9eafc1 100644
--- a/src/libstd/lib.rs
+++ b/src/libstd/lib.rs
@@ -273,7 +273,6 @@
 #![feature(libc)]
 #![feature(link_args)]
 #![feature(linkage)]
-#![cfg_attr(not(stage0), feature(min_const_unsafe_fn))]
 #![feature(needs_panic_runtime)]
 #![feature(never_type)]
 #![feature(nll)]
@@ -282,7 +281,6 @@
 #![feature(optin_builtin_traits)]
 #![feature(panic_internals)]
 #![feature(panic_unwind)]
-#![feature(pin)]
 #![feature(prelude_import)]
 #![feature(ptr_internals)]
 #![feature(raw)]
@@ -434,7 +432,7 @@ pub use alloc_crate::borrow;
 pub use alloc_crate::fmt;
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use alloc_crate::format;
-#[unstable(feature = "pin", issue = "49150")]
+#[stable(feature = "pin", since = "1.33.0")]
 pub use core::pin;
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use alloc_crate::slice;
diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs
index 941a3a288da..2238e429a58 100644
--- a/src/libsyntax/feature_gate.rs
+++ b/src/libsyntax/feature_gate.rs
@@ -486,9 +486,6 @@ declare_features! (
 
     // `extern crate self as foo;` puts local crate root into extern prelude under name `foo`.
     (active, extern_crate_self, "1.31.0", Some(56409), None),
-
-    // Allows calling `const unsafe fn` inside `unsafe` blocks in `const fn` functions.
-    (active, min_const_unsafe_fn, "1.31.0", Some(55607), None),
 );
 
 declare_features! (
@@ -694,6 +691,8 @@ declare_features! (
     (accepted, underscore_imports, "1.33.0", Some(48216), None),
     // Allows `#[repr(packed(N))]` attribute on structs.
     (accepted, repr_packed, "1.33.0", Some(33158), None),
+    // Allows calling `const unsafe fn` inside `unsafe` blocks in `const fn` functions.
+    (accepted, min_const_unsafe_fn, "1.33.0", Some(55607), None),
 );
 
 // If you change this, please modify `src/doc/unstable-book` as well. You must
diff --git a/src/libsyntax/parse/lexer/tokentrees.rs b/src/libsyntax/parse/lexer/tokentrees.rs
index 6f9dc247a78..265ff5f57e4 100644
--- a/src/libsyntax/parse/lexer/tokentrees.rs
+++ b/src/libsyntax/parse/lexer/tokentrees.rs
@@ -11,7 +11,7 @@
 use print::pprust::token_to_string;
 use parse::lexer::StringReader;
 use parse::{token, PResult};
-use tokenstream::{DelimSpan, TokenStream, TokenTree};
+use tokenstream::{DelimSpan, IsJoint::*, TokenStream, TokenTree};
 
 impl<'a> StringReader<'a> {
     // Parse a stream of tokens into a list of `TokenTree`s, up to an `Eof`.
@@ -186,8 +186,7 @@ impl<'a> StringReader<'a> {
                 let raw = self.span_src_raw;
                 self.real_token();
                 let is_joint = raw.hi() == self.span_src_raw.lo() && token::is_op(&self.token);
-
-                Ok(if is_joint { tt.joint() } else { tt.into() })
+                Ok(TokenStream::Tree(tt, if is_joint { Joint } else { NonJoint }))
             }
         }
     }
diff --git a/src/libsyntax/tokenstream.rs b/src/libsyntax/tokenstream.rs
index 013ecd3d343..b04495d751a 100644
--- a/src/libsyntax/tokenstream.rs
+++ b/src/libsyntax/tokenstream.rs
@@ -123,7 +123,7 @@ impl TokenTree {
     }
 
     pub fn joint(self) -> TokenStream {
-        TokenStream::JointTree(self)
+        TokenStream::Tree(self, Joint)
     }
 
     /// Returns the opening delimiter as a token tree.
@@ -156,8 +156,7 @@ impl TokenTree {
 #[derive(Clone, Debug)]
 pub enum TokenStream {
     Empty,
-    Tree(TokenTree),
-    JointTree(TokenTree),
+    Tree(TokenTree, IsJoint),
     Stream(Lrc<Vec<TokenStream>>),
 }
 
@@ -165,6 +164,14 @@ pub enum TokenStream {
 #[cfg(target_arch = "x86_64")]
 static_assert!(MEM_SIZE_OF_TOKEN_STREAM: mem::size_of::<TokenStream>() == 32);
 
+#[derive(Clone, Copy, Debug, PartialEq)]
+pub enum IsJoint {
+    Joint,
+    NonJoint
+}
+
+use self::IsJoint::*;
+
 impl TokenStream {
     /// Given a `TokenStream` with a `Stream` of only two arguments, return a new `TokenStream`
     /// separating the two arguments with a comma for diagnostic suggestions.
@@ -176,16 +183,16 @@ impl TokenStream {
             while let Some((pos, ts)) = iter.next() {
                 if let Some((_, next)) = iter.peek() {
                     let sp = match (&ts, &next) {
-                        (TokenStream::Tree(TokenTree::Token(_, token::Token::Comma)), _) |
-                        (_, TokenStream::Tree(TokenTree::Token(_, token::Token::Comma))) => {
-                            continue;
-                        }
-                        (TokenStream::Tree(TokenTree::Token(sp, _)), _) => *sp,
-                        (TokenStream::Tree(TokenTree::Delimited(sp, ..)), _) => sp.entire(),
+                        (TokenStream::Tree(TokenTree::Token(_, token::Token::Comma), NonJoint), _) |
+                        (_, TokenStream::Tree(TokenTree::Token(_, token::Token::Comma), NonJoint))
+                          => continue,
+                        (TokenStream::Tree(TokenTree::Token(sp, _), NonJoint), _) => *sp,
+                        (TokenStream::Tree(TokenTree::Delimited(sp, ..), NonJoint), _) =>
+                            sp.entire(),
                         _ => continue,
                     };
                     let sp = sp.shrink_to_hi();
-                    let comma = TokenStream::Tree(TokenTree::Token(sp, token::Comma));
+                    let comma = TokenStream::Tree(TokenTree::Token(sp, token::Comma), NonJoint);
                     suggestion = Some((pos, comma, sp));
                 }
             }
@@ -204,7 +211,7 @@ impl TokenStream {
 
 impl From<TokenTree> for TokenStream {
     fn from(tt: TokenTree) -> TokenStream {
-        TokenStream::Tree(tt)
+        TokenStream::Tree(tt, NonJoint)
     }
 }
 
@@ -232,7 +239,7 @@ impl Extend<TokenStream> for TokenStream {
                 vec.reserve(iter.size_hint().0);
                 vec
             }
-            TokenStream::Tree(_) | TokenStream::JointTree(_) => {
+            TokenStream::Tree(..) => {
                 let mut vec = Vec::new();
                 vec.reserve(1 + iter.size_hint().0);
                 vec.push(this);
@@ -369,8 +376,7 @@ impl TokenStream {
     /// Returns true if the token tree is a joint operation w.r.t. `proc_macro::TokenNode`.
     pub fn as_tree(self) -> (TokenTree, bool /* joint? */) {
         match self {
-            TokenStream::Tree(tree) => (tree, false),
-            TokenStream::JointTree(tree) => (tree, true),
+            TokenStream::Tree(tree, is_joint) => (tree, is_joint == Joint),
             _ => unreachable!(),
         }
     }
@@ -381,8 +387,7 @@ impl TokenStream {
         let mut i = 0;
         while let Some(stream) = trees.next_as_stream() {
             result.push(match stream {
-                TokenStream::Tree(tree) => f(i, tree).into(),
-                TokenStream::JointTree(tree) => f(i, tree).joint(),
+                TokenStream::Tree(tree, is_joint) => TokenStream::Tree(f(i, tree), is_joint),
                 _ => unreachable!()
             });
             i += 1;
@@ -395,27 +400,25 @@ impl TokenStream {
         let mut result = Vec::new();
         while let Some(stream) = trees.next_as_stream() {
             result.push(match stream {
-                TokenStream::Tree(tree) => f(tree).into(),
-                TokenStream::JointTree(tree) => f(tree).joint(),
+                TokenStream::Tree(tree, is_joint) => TokenStream::Tree(f(tree), is_joint),
                 _ => unreachable!()
             });
         }
         TokenStream::new(result)
     }
 
-    fn first_tree_and_joint(&self) -> Option<(TokenTree, bool)> {
+    fn first_tree_and_joint(&self) -> Option<(TokenTree, IsJoint)> {
         match self {
             TokenStream::Empty => None,
-            TokenStream::Tree(ref tree) => Some((tree.clone(), false)),
-            TokenStream::JointTree(ref tree) => Some((tree.clone(), true)),
+            TokenStream::Tree(ref tree, is_joint) => Some((tree.clone(), *is_joint)),
             TokenStream::Stream(ref stream) => stream.first().unwrap().first_tree_and_joint(),
         }
     }
 
     fn last_tree_if_joint(&self) -> Option<TokenTree> {
         match self {
-            TokenStream::Empty | TokenStream::Tree(..) => None,
-            TokenStream::JointTree(ref tree) => Some(tree.clone()),
+            TokenStream::Empty | TokenStream::Tree(_, NonJoint) => None,
+            TokenStream::Tree(ref tree, Joint) => Some(tree.clone()),
             TokenStream::Stream(ref stream) => stream.last().unwrap().last_tree_if_joint(),
         }
     }
@@ -439,11 +442,7 @@ impl TokenStreamBuilder {
                     self.push_all_but_last_tree(&last_stream);
                     let glued_span = last_span.to(span);
                     let glued_tt = TokenTree::Token(glued_span, glued_tok);
-                    let glued_tokenstream = if is_joint {
-                        glued_tt.joint()
-                    } else {
-                        glued_tt.into()
-                    };
+                    let glued_tokenstream = TokenStream::Tree(glued_tt, is_joint);
                     self.0.push(glued_tokenstream);
                     self.push_all_but_first_tree(&stream);
                     return
@@ -493,8 +492,7 @@ pub struct Cursor(CursorKind);
 #[derive(Clone)]
 enum CursorKind {
     Empty,
-    Tree(TokenTree, bool /* consumed? */),
-    JointTree(TokenTree, bool /* consumed? */),
+    Tree(TokenTree, IsJoint, bool /* consumed? */),
     Stream(StreamCursor),
 }
 
@@ -516,9 +514,9 @@ impl StreamCursor {
                 self.index += 1;
                 let next = self.stream[self.index - 1].clone();
                 match next {
-                    TokenStream::Tree(..) | TokenStream::JointTree(..) => return Some(next),
-                    TokenStream::Stream(stream) => self.insert(stream),
                     TokenStream::Empty => {}
+                    TokenStream::Tree(..) => return Some(next),
+                    TokenStream::Stream(stream) => self.insert(stream),
                 }
             } else if let Some((stream, index)) = self.stack.pop() {
                 self.stream = stream;
@@ -540,7 +538,7 @@ impl Iterator for Cursor {
 
     fn next(&mut self) -> Option<TokenTree> {
         self.next_as_stream().map(|stream| match stream {
-            TokenStream::Tree(tree) | TokenStream::JointTree(tree) => tree,
+            TokenStream::Tree(tree, _) => tree,
             _ => unreachable!()
         })
     }
@@ -550,18 +548,15 @@ impl Cursor {
     fn new(stream: TokenStream) -> Self {
         Cursor(match stream {
             TokenStream::Empty => CursorKind::Empty,
-            TokenStream::Tree(tree) => CursorKind::Tree(tree, false),
-            TokenStream::JointTree(tree) => CursorKind::JointTree(tree, false),
+            TokenStream::Tree(tree, is_joint) => CursorKind::Tree(tree, is_joint, false),
             TokenStream::Stream(stream) => CursorKind::Stream(StreamCursor::new(stream)),
         })
     }
 
     pub fn next_as_stream(&mut self) -> Option<TokenStream> {
         let (stream, consumed) = match self.0 {
-            CursorKind::Tree(ref tree, ref mut consumed @ false) =>
-                (tree.clone().into(), consumed),
-            CursorKind::JointTree(ref tree, ref mut consumed @ false) =>
-                (tree.clone().joint(), consumed),
+            CursorKind::Tree(ref tree, ref is_joint, ref mut consumed @ false) =>
+                (TokenStream::Tree(tree.clone(), *is_joint), consumed),
             CursorKind::Stream(ref mut cursor) => return cursor.next_as_stream(),
             _ => return None,
         };
@@ -574,7 +569,7 @@ impl Cursor {
         match self.0 {
             _ if stream.is_empty() => return,
             CursorKind::Empty => *self = stream.trees(),
-            CursorKind::Tree(_, consumed) | CursorKind::JointTree(_, consumed) => {
+            CursorKind::Tree(_, _, consumed) => {
                 *self = TokenStream::new(vec![self.original_stream(), stream]).trees();
                 if consumed {
                     self.next();
@@ -589,8 +584,8 @@ impl Cursor {
     pub fn original_stream(&self) -> TokenStream {
         match self.0 {
             CursorKind::Empty => TokenStream::empty(),
-            CursorKind::Tree(ref tree, _) => tree.clone().into(),
-            CursorKind::JointTree(ref tree, _) => tree.clone().joint(),
+            CursorKind::Tree(ref tree, ref is_joint, _) =>
+                TokenStream::Tree(tree.clone(), *is_joint),
             CursorKind::Stream(ref cursor) => TokenStream::Stream(
                 cursor.stack.get(0).cloned().map(|(stream, _)| stream)
                     .unwrap_or_else(|| cursor.stream.clone())
@@ -602,9 +597,8 @@ impl Cursor {
         fn look_ahead(streams: &[TokenStream], mut n: usize) -> Result<TokenTree, usize> {
             for stream in streams {
                 n = match stream {
-                    TokenStream::Tree(ref tree) | TokenStream::JointTree(ref tree)
-                        if n == 0 => return Ok(tree.clone()),
-                    TokenStream::Tree(..) | TokenStream::JointTree(..) => n - 1,
+                    TokenStream::Tree(ref tree, _) if n == 0 => return Ok(tree.clone()),
+                    TokenStream::Tree(..) => n - 1,
                     TokenStream::Stream(ref stream) => match look_ahead(stream, n) {
                         Ok(tree) => return Ok(tree),
                         Err(n) => n,
@@ -617,10 +611,8 @@ impl Cursor {
 
         match self.0 {
             CursorKind::Empty |
-            CursorKind::Tree(_, true) |
-            CursorKind::JointTree(_, true) => Err(n),
-            CursorKind::Tree(ref tree, false) |
-            CursorKind::JointTree(ref tree, false) => look_ahead(&[tree.clone().into()], n),
+            CursorKind::Tree(_, _, true) => Err(n),
+            CursorKind::Tree(ref tree, _, false) => look_ahead(&[tree.clone().into()], n),
             CursorKind::Stream(ref cursor) => {
                 look_ahead(&cursor.stream[cursor.index ..], n).or_else(|mut n| {
                     for &(ref stream, index) in cursor.stack.iter().rev() {
@@ -653,8 +645,7 @@ impl From<TokenStream> for ThinTokenStream {
     fn from(stream: TokenStream) -> ThinTokenStream {
         ThinTokenStream(match stream {
             TokenStream::Empty => None,
-            TokenStream::Tree(tree) => Some(Lrc::new(vec![tree.into()])),
-            TokenStream::JointTree(tree) => Some(Lrc::new(vec![tree.joint()])),
+            TokenStream::Tree(..) => Some(Lrc::new(vec![stream])),
             TokenStream::Stream(stream) => Some(stream),
         })
     }
diff --git a/src/libsyntax_ext/proc_macro_server.rs b/src/libsyntax_ext/proc_macro_server.rs
index ca960cbe41b..507ceb53432 100644
--- a/src/libsyntax_ext/proc_macro_server.rs
+++ b/src/libsyntax_ext/proc_macro_server.rs
@@ -21,7 +21,7 @@ use syntax::ast;
 use syntax::ext::base::ExtCtxt;
 use syntax::parse::lexer::comments;
 use syntax::parse::{self, token, ParseSess};
-use syntax::tokenstream::{self, DelimSpan, TokenStream};
+use syntax::tokenstream::{self, DelimSpan, IsJoint::*, TokenStream};
 use syntax_pos::hygiene::{SyntaxContext, Transparency};
 use syntax_pos::symbol::{keywords, Symbol};
 use syntax_pos::{BytePos, FileName, MultiSpan, Pos, SourceFile, Span};
@@ -278,11 +278,7 @@ impl ToInternal<TokenStream> for TokenTree<Group, Punct, Ident, Literal> {
         };
 
         let tree = tokenstream::TokenTree::Token(span, token);
-        if joint {
-            tree.joint()
-        } else {
-            tree.into()
-        }
+        TokenStream::Tree(tree, if joint { Joint } else { NonJoint })
     }
 }
 
diff --git a/src/libsyntax_pos/lib.rs b/src/libsyntax_pos/lib.rs
index 9aafb9fc549..ae2259d5258 100644
--- a/src/libsyntax_pos/lib.rs
+++ b/src/libsyntax_pos/lib.rs
@@ -334,6 +334,13 @@ impl Span {
         span.lo <= other.lo && other.hi <= span.hi
     }
 
+    /// Return `true` if `self` touches `other`.
+    pub fn overlaps(self, other: Span) -> bool {
+        let span = self.data();
+        let other = other.data();
+        span.lo < other.hi && other.lo < span.hi
+    }
+
     /// Return true if the spans are equal with regards to the source text.
     ///
     /// Use this instead of `==` when either span could be generated code,
diff --git a/src/test/codegen/issue-56927.rs b/src/test/codegen/issue-56927.rs
new file mode 100644
index 00000000000..0544ff86aac
--- /dev/null
+++ b/src/test/codegen/issue-56927.rs
@@ -0,0 +1,44 @@
+// compile-flags: -C no-prepopulate-passes
+
+#![crate_type="rlib"]
+use std::usize;
+
+#[repr(align(16))]
+pub struct S {
+    arr: [u32; 4],
+}
+
+// CHECK-LABEL: @test1
+// CHECK: store i32 0, i32* %{{.+}}, align 16
+// CHECK: store i32 1, i32* %{{.+}}, align 4
+// CHECK: store i32 2, i32* %{{.+}}, align 8
+// CHECK: store i32 3, i32* %{{.+}}, align 4
+#[no_mangle]
+pub fn test1(s: &mut S) {
+    s.arr[0] = 0;
+    s.arr[1] = 1;
+    s.arr[2] = 2;
+    s.arr[3] = 3;
+}
+
+// CHECK-LABEL: @test2
+// CHECK: store i32 4, i32* %{{.+}}, align 4
+#[allow(const_err)]
+#[no_mangle]
+pub fn test2(s: &mut S) {
+    s.arr[usize::MAX / 4 + 1] = 4;
+}
+
+// CHECK-LABEL: @test3
+// CHECK: store i32 5, i32* %{{.+}}, align 4
+#[no_mangle]
+pub fn test3(s: &mut S, i: usize) {
+    s.arr[i] = 5;
+}
+
+// CHECK-LABEL: @test4
+// CHECK: store i32 6, i32* %{{.+}}, align 4
+#[no_mangle]
+pub fn test4(s: &mut S) {
+    s.arr = [6; 4];
+}
diff --git a/src/test/codegen/packed.rs b/src/test/codegen/packed.rs
index fb6507fd22a..3b4e89f12e0 100644
--- a/src/test/codegen/packed.rs
+++ b/src/test/codegen/packed.rs
@@ -83,6 +83,42 @@ pub fn call_pkd2(f: fn() -> Array) -> BigPacked2 {
     BigPacked2 { dealign: 0, data: f() }
 }
 
+// CHECK-LABEL: @write_packed_array1
+// CHECK: store i32 0, i32* %{{.+}}, align 1
+// CHECK: store i32 1, i32* %{{.+}}, align 1
+// CHECK: store i32 2, i32* %{{.+}}, align 1
+#[no_mangle]
+pub fn write_packed_array1(p: &mut BigPacked1) {
+    p.data.0[0] = 0;
+    p.data.0[1] = 1;
+    p.data.0[2] = 2;
+}
+
+// CHECK-LABEL: @write_packed_array2
+// CHECK: store i32 0, i32* %{{.+}}, align 2
+// CHECK: store i32 1, i32* %{{.+}}, align 2
+// CHECK: store i32 2, i32* %{{.+}}, align 2
+#[no_mangle]
+pub fn write_packed_array2(p: &mut BigPacked2) {
+    p.data.0[0] = 0;
+    p.data.0[1] = 1;
+    p.data.0[2] = 2;
+}
+
+// CHECK-LABEL: @repeat_packed_array1
+// CHECK: store i32 42, i32* %{{.+}}, align 1
+#[no_mangle]
+pub fn repeat_packed_array1(p: &mut BigPacked1) {
+    p.data.0 = [42; 8];
+}
+
+// CHECK-LABEL: @repeat_packed_array2
+// CHECK: store i32 42, i32* %{{.+}}, align 2
+#[no_mangle]
+pub fn repeat_packed_array2(p: &mut BigPacked2) {
+    p.data.0 = [42; 8];
+}
+
 #[repr(packed)]
 #[derive(Copy, Clone)]
 pub struct Packed1Pair(u8, u32);
diff --git a/src/test/codegen/x86_mmx.rs b/src/test/codegen/x86_mmx.rs
index 4424c30e0f8..0fd3d542438 100644
--- a/src/test/codegen/x86_mmx.rs
+++ b/src/test/codegen/x86_mmx.rs
@@ -18,6 +18,7 @@
 // ignore-powerpc64le
 // ignore-sparc
 // ignore-sparc64
+// ignore-s390x
 // compile-flags: -O
 
 #![feature(repr_simd)]
diff --git a/src/test/compile-fail/must_use-in-stdlib-traits.rs b/src/test/compile-fail/must_use-in-stdlib-traits.rs
index 4bb5c59722a..7e446fdaeaf 100644
--- a/src/test/compile-fail/must_use-in-stdlib-traits.rs
+++ b/src/test/compile-fail/must_use-in-stdlib-traits.rs
@@ -1,5 +1,5 @@
 #![deny(unused_must_use)]
-#![feature(futures_api, pin, arbitrary_self_types)]
+#![feature(arbitrary_self_types, futures_api)]
 
 use std::iter::Iterator;
 use std::future::Future;
diff --git a/src/test/run-pass-fulldeps/newtype_index.rs b/src/test/run-pass-fulldeps/newtype_index.rs
index 0fd7ccd55fb..3cd622a33b1 100644
--- a/src/test/run-pass-fulldeps/newtype_index.rs
+++ b/src/test/run-pass-fulldeps/newtype_index.rs
@@ -1,4 +1,4 @@
-#![feature(rustc_attrs, rustc_private, step_trait, min_const_unsafe_fn)]
+#![feature(rustc_attrs, rustc_private, step_trait)]
 
 #[macro_use] extern crate rustc_data_structures;
 extern crate rustc_serialize;
diff --git a/src/test/run-pass/arbitrary_self_types_stdlib_pointers.rs b/src/test/run-pass/arbitrary_self_types_stdlib_pointers.rs
index 6ec70bb8c09..e5ee2233b76 100644
--- a/src/test/run-pass/arbitrary_self_types_stdlib_pointers.rs
+++ b/src/test/run-pass/arbitrary_self_types_stdlib_pointers.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(pin)]
+#![feature(arbitrary_self_types)]
 #![feature(rustc_attrs)]
 
 use std::{
diff --git a/src/test/run-pass/async-await.rs b/src/test/run-pass/async-await.rs
index 59da7580354..d9eb801a206 100644
--- a/src/test/run-pass/async-await.rs
+++ b/src/test/run-pass/async-await.rs
@@ -10,7 +10,7 @@
 
 // edition:2018
 
-#![feature(arbitrary_self_types, async_await, await_macro, futures_api, pin)]
+#![feature(arbitrary_self_types, async_await, await_macro, futures_api)]
 
 use std::pin::Pin;
 use std::future::Future;
@@ -138,7 +138,7 @@ where
     F: FnOnce(u8) -> Fut,
     Fut: Future<Output = u8>,
 {
-    let mut fut = Box::pinned(f(9));
+    let mut fut = Box::pin(f(9));
     let counter = Arc::new(Counter { wakes: AtomicUsize::new(0) });
     let waker = local_waker_from_nonlocal(counter.clone());
     assert_eq!(0, counter.wakes.load(atomic::Ordering::SeqCst));
diff --git a/src/test/run-pass/futures-api.rs b/src/test/run-pass/futures-api.rs
index 18865e4a076..ac674889249 100644
--- a/src/test/run-pass/futures-api.rs
+++ b/src/test/run-pass/futures-api.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(arbitrary_self_types, futures_api, pin)]
+#![feature(arbitrary_self_types, futures_api)]
 #![allow(unused)]
 
 use std::future::Future;
diff --git a/src/test/rustdoc/const-display.rs b/src/test/rustdoc/const-display.rs
index 8ac0d07ceef..f38fab91de7 100644
--- a/src/test/rustdoc/const-display.rs
+++ b/src/test/rustdoc/const-display.rs
@@ -15,7 +15,6 @@
             issue = "0")]
 
 #![feature(rustc_const_unstable, const_fn, foo, foo2)]
-#![feature(min_const_unsafe_fn)]
 #![feature(staged_api)]
 
 // @has 'foo/fn.foo.html' '//pre' 'pub unsafe fn foo() -> u32'
diff --git a/src/test/ui/consts/min_const_fn/min_const_fn_unsafe.rs b/src/test/ui/consts/min_const_fn/min_const_fn_unsafe.rs
index 92e99c6228a..da875fe7a6b 100644
--- a/src/test/ui/consts/min_const_fn/min_const_fn_unsafe.rs
+++ b/src/test/ui/consts/min_const_fn/min_const_fn_unsafe.rs
@@ -8,27 +8,62 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// gate-test-min_const_unsafe_fn
+//------------------------------------------------------------------------------
+// OK
+//------------------------------------------------------------------------------
 
-// ok
 const unsafe fn ret_i32_no_unsafe() -> i32 { 42 }
 const unsafe fn ret_null_ptr_no_unsafe<T>() -> *const T { 0 as *const T }
 const unsafe fn ret_null_mut_ptr_no_unsafe<T>() -> *mut T { 0 as *mut T }
 const fn no_unsafe() { unsafe {} }
 
-// not ok
 const fn call_unsafe_const_fn() -> i32 {
-    unsafe { ret_i32_no_unsafe() } //~ ERROR calls to `const unsafe fn` in const fns are unstable
+    unsafe { ret_i32_no_unsafe() }
 }
 const fn call_unsafe_generic_const_fn() -> *const String {
     unsafe { ret_null_ptr_no_unsafe::<String>() }
-    //~^ ERROR calls to `const unsafe fn` in const fns are unstable
 }
-const fn call_unsafe_generic_cell_const_fn() -> *const Vec<std::cell::Cell<u32>> {
+const fn call_unsafe_generic_cell_const_fn()
+    -> *const Vec<std::cell::Cell<u32>>
+{
     unsafe { ret_null_mut_ptr_no_unsafe::<Vec<std::cell::Cell<u32>>>() }
-    //~^ ERROR calls to `const unsafe fn` in const fns
 }
-const unsafe fn deref_forbidden(x: *mut usize) -> usize { *x }
+
+const unsafe fn call_unsafe_const_unsafe_fn() -> i32 {
+    unsafe { ret_i32_no_unsafe() }
+}
+const unsafe fn call_unsafe_generic_const_unsafe_fn() -> *const String {
+    unsafe { ret_null_ptr_no_unsafe::<String>() }
+}
+const unsafe fn call_unsafe_generic_cell_const_unsafe_fn()
+    -> *const Vec<std::cell::Cell<u32>>
+{
+    unsafe { ret_null_mut_ptr_no_unsafe::<Vec<std::cell::Cell<u32>>>() }
+}
+
+const unsafe fn call_unsafe_const_unsafe_fn_immediate() -> i32 {
+    ret_i32_no_unsafe()
+}
+const unsafe fn call_unsafe_generic_const_unsafe_fn_immediate() -> *const String {
+    ret_null_ptr_no_unsafe::<String>()
+}
+const unsafe fn call_unsafe_generic_cell_const_unsafe_fn_immediate()
+    -> *const Vec<std::cell::Cell<u32>>
+{
+    ret_null_mut_ptr_no_unsafe::<Vec<std::cell::Cell<u32>>>()
+}
+
+//------------------------------------------------------------------------------
+// NOT OK
+//------------------------------------------------------------------------------
+
+const fn bad_const_fn_deref_raw(x: *mut usize) -> &'static usize { unsafe { &*x } } //~ is unsafe
+//~^ dereferencing raw pointers in constant functions
+
+const unsafe fn bad_const_unsafe_deref_raw(x: *mut usize) -> usize { *x }
+//~^ dereferencing raw pointers in constant functions
+
+const unsafe fn bad_const_unsafe_deref_raw_ref(x: *mut usize) -> &'static usize { &*x }
 //~^ dereferencing raw pointers in constant functions
 
 fn main() {}
diff --git a/src/test/ui/consts/min_const_fn/min_const_fn_unsafe.stderr b/src/test/ui/consts/min_const_fn/min_const_fn_unsafe.stderr
index fafc89d1493..68b782bf0e7 100644
--- a/src/test/ui/consts/min_const_fn/min_const_fn_unsafe.stderr
+++ b/src/test/ui/consts/min_const_fn/min_const_fn_unsafe.stderr
@@ -1,43 +1,44 @@
 error[E0658]: dereferencing raw pointers in constant functions is unstable (see issue #51911)
-  --> $DIR/min_const_fn_unsafe.rs:31:59
+  --> $DIR/min_const_fn_unsafe.rs:60:77
    |
-LL | const unsafe fn deref_forbidden(x: *mut usize) -> usize { *x }
-   |                                                           ^^
+LL | const fn bad_const_fn_deref_raw(x: *mut usize) -> &'static usize { unsafe { &*x } } //~ is unsafe
+   |                                                                             ^^^
    |
    = help: add #![feature(const_raw_ptr_deref)] to the crate attributes to enable
 
-error[E0658]: unions in const fn are unstable (see issue #51909)
-  --> $DIR/min_const_fn_unsafe.rs:38:5
+error[E0658]: dereferencing raw pointers in constant functions is unstable (see issue #51911)
+  --> $DIR/min_const_fn_unsafe.rs:63:70
    |
-LL |     Foo { x: () }.y
-   |     ^^^^^^^^^^^^^^^
+LL | const unsafe fn bad_const_unsafe_deref_raw(x: *mut usize) -> usize { *x }
+   |                                                                      ^^
    |
-   = help: add #![feature(const_fn_union)] to the crate attributes to enable
+   = help: add #![feature(const_raw_ptr_deref)] to the crate attributes to enable
 
-error[E0658]: calls to `const unsafe fn` in const fns are unstable (see issue #55607)
-  --> $DIR/min_const_fn_unsafe.rs:21:14
+error[E0658]: dereferencing raw pointers in constant functions is unstable (see issue #51911)
+  --> $DIR/min_const_fn_unsafe.rs:66:83
    |
-LL |     unsafe { ret_i32_no_unsafe() } //~ ERROR calls to `const unsafe fn` in const fns are unstable
-   |              ^^^^^^^^^^^^^^^^^^^
+LL | const unsafe fn bad_const_unsafe_deref_raw_ref(x: *mut usize) -> &'static usize { &*x }
+   |                                                                                   ^^^
    |
-   = help: add #![feature(min_const_unsafe_fn)] to the crate attributes to enable
+   = help: add #![feature(const_raw_ptr_deref)] to the crate attributes to enable
 
-error[E0658]: calls to `const unsafe fn` in const fns are unstable (see issue #55607)
-  --> $DIR/min_const_fn_unsafe.rs:24:14
+error[E0658]: unions in const fn are unstable (see issue #51909)
+  --> $DIR/min_const_fn_unsafe.rs:73:5
    |
-LL |     unsafe { ret_null_ptr_no_unsafe::<String>() }
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     Foo { x: () }.y
+   |     ^^^^^^^^^^^^^^^
    |
-   = help: add #![feature(min_const_unsafe_fn)] to the crate attributes to enable
+   = help: add #![feature(const_fn_union)] to the crate attributes to enable
 
-error[E0658]: calls to `const unsafe fn` in const fns are unstable (see issue #55607)
-  --> $DIR/min_const_fn_unsafe.rs:28:14
+error[E0133]: dereference of raw pointer is unsafe and requires unsafe function or block
+  --> $DIR/min_const_fn_unsafe.rs:60:77
    |
-LL |     unsafe { ret_null_mut_ptr_no_unsafe::<Vec<std::cell::Cell<u32>>>() }
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | const fn bad_const_fn_deref_raw(x: *mut usize) -> &'static usize { unsafe { &*x } } //~ is unsafe
+   |                                                                             ^^^ dereference of raw pointer
    |
-   = help: add #![feature(min_const_unsafe_fn)] to the crate attributes to enable
+   = note: raw pointers may be NULL, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior
 
 error: aborting due to 5 previous errors
 
-For more information about this error, try `rustc --explain E0658`.
+Some errors occurred: E0133, E0658.
+For more information about an error, try `rustc --explain E0133`.
diff --git a/src/test/ui/consts/min_const_fn/min_const_fn_unsafe_feature_gate.rs b/src/test/ui/consts/min_const_fn/min_const_fn_unsafe_feature_gate.rs
deleted file mode 100644
index 67a48206126..00000000000
--- a/src/test/ui/consts/min_const_fn/min_const_fn_unsafe_feature_gate.rs
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#![feature(min_const_unsafe_fn)]
-
-// ok
-const unsafe fn foo4() -> i32 { 42 }
-const unsafe fn foo5<T>() -> *const T { 0 as *const T }
-const unsafe fn foo6<T>() -> *mut T { 0 as *mut T }
-const fn no_unsafe() { unsafe {} }
-
-const fn foo8() -> i32 {
-    unsafe { foo4() }
-}
-const fn foo9() -> *const String {
-    unsafe { foo5::<String>() }
-}
-const fn foo10() -> *const Vec<std::cell::Cell<u32>> {
-    unsafe { foo6::<Vec<std::cell::Cell<u32>>>() }
-}
-const unsafe fn foo8_3() -> i32 {
-    unsafe { foo4() }
-}
-const unsafe fn foo9_3() -> *const String {
-    unsafe { foo5::<String>() }
-}
-const unsafe fn foo10_3() -> *const Vec<std::cell::Cell<u32>> {
-    unsafe { foo6::<Vec<std::cell::Cell<u32>>>() }
-}
-const unsafe fn foo8_2() -> i32 {
-    foo4()
-}
-const unsafe fn foo9_2() -> *const String {
-    foo5::<String>()
-}
-const unsafe fn foo10_2() -> *const Vec<std::cell::Cell<u32>> {
-    foo6::<Vec<std::cell::Cell<u32>>>()
-}
-const unsafe fn foo30_3(x: *mut usize) -> usize { *x }
-//~^ dereferencing raw pointers in constant functions
-
-const unsafe fn foo30_4(x: *mut usize) -> &'static usize { &*x }
-//~^ dereferencing raw pointers in constant functions
-
-const fn foo30_5(x: *mut usize) -> &'static usize { unsafe { &*x } } //~ is unsafe
-//~^ dereferencing raw pointers in constant functions
-
-fn main() {}
-
-const unsafe fn no_union() {
-    union Foo { x: (), y: () }
-    Foo { x: () }.y
-    //~^ unions in const fn
-}
diff --git a/src/test/ui/consts/min_const_fn/min_const_fn_unsafe_feature_gate.stderr b/src/test/ui/consts/min_const_fn/min_const_fn_unsafe_feature_gate.stderr
deleted file mode 100644
index 63bf9a53e50..00000000000
--- a/src/test/ui/consts/min_const_fn/min_const_fn_unsafe_feature_gate.stderr
+++ /dev/null
@@ -1,44 +0,0 @@
-error[E0658]: dereferencing raw pointers in constant functions is unstable (see issue #51911)
-  --> $DIR/min_const_fn_unsafe_feature_gate.rs:46:51
-   |
-LL | const unsafe fn foo30_3(x: *mut usize) -> usize { *x }
-   |                                                   ^^
-   |
-   = help: add #![feature(const_raw_ptr_deref)] to the crate attributes to enable
-
-error[E0658]: dereferencing raw pointers in constant functions is unstable (see issue #51911)
-  --> $DIR/min_const_fn_unsafe_feature_gate.rs:49:60
-   |
-LL | const unsafe fn foo30_4(x: *mut usize) -> &'static usize { &*x }
-   |                                                            ^^^
-   |
-   = help: add #![feature(const_raw_ptr_deref)] to the crate attributes to enable
-
-error[E0658]: dereferencing raw pointers in constant functions is unstable (see issue #51911)
-  --> $DIR/min_const_fn_unsafe_feature_gate.rs:52:62
-   |
-LL | const fn foo30_5(x: *mut usize) -> &'static usize { unsafe { &*x } } //~ is unsafe
-   |                                                              ^^^
-   |
-   = help: add #![feature(const_raw_ptr_deref)] to the crate attributes to enable
-
-error[E0658]: unions in const fn are unstable (see issue #51909)
-  --> $DIR/min_const_fn_unsafe_feature_gate.rs:59:5
-   |
-LL |     Foo { x: () }.y
-   |     ^^^^^^^^^^^^^^^
-   |
-   = help: add #![feature(const_fn_union)] to the crate attributes to enable
-
-error[E0133]: dereference of raw pointer is unsafe and requires unsafe function or block
-  --> $DIR/min_const_fn_unsafe_feature_gate.rs:52:62
-   |
-LL | const fn foo30_5(x: *mut usize) -> &'static usize { unsafe { &*x } } //~ is unsafe
-   |                                                              ^^^ dereference of raw pointer
-   |
-   = note: raw pointers may be NULL, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior
-
-error: aborting due to 5 previous errors
-
-Some errors occurred: E0133, E0658.
-For more information about an error, try `rustc --explain E0133`.
diff --git a/src/test/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability.rs b/src/test/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability.rs
index f559c23ff0f..33fcea98189 100644
--- a/src/test/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability.rs
+++ b/src/test/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability.rs
@@ -14,7 +14,6 @@
             issue = "0")]
 
 #![feature(rustc_const_unstable, const_fn, foo, foo2)]
-#![feature(min_const_unsafe_fn)]
 #![feature(staged_api)]
 
 #[stable(feature = "rust1", since = "1.0.0")]
diff --git a/src/test/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability.stderr b/src/test/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability.stderr
index 37be2889173..2a0ef0e6b96 100644
--- a/src/test/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability.stderr
+++ b/src/test/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability.stderr
@@ -1,23 +1,23 @@
 error: can only call other `min_const_fn` within a `min_const_fn`
-  --> $DIR/min_const_unsafe_fn_libstd_stability.rs:26:41
+  --> $DIR/min_const_unsafe_fn_libstd_stability.rs:25:41
    |
 LL | const unsafe fn bar() -> u32 { unsafe { foo() } } //~ ERROR can only call other `min_const_fn`
    |                                         ^^^^^
 
 error: can only call other `min_const_fn` within a `min_const_fn`
-  --> $DIR/min_const_unsafe_fn_libstd_stability.rs:33:42
+  --> $DIR/min_const_unsafe_fn_libstd_stability.rs:32:42
    |
 LL | const unsafe fn bar2() -> u32 { unsafe { foo2() } } //~ ERROR can only call other `min_const_fn`
    |                                          ^^^^^^
 
 error: only int, `bool` and `char` operations are stable in const fn
-  --> $DIR/min_const_unsafe_fn_libstd_stability.rs:37:33
+  --> $DIR/min_const_unsafe_fn_libstd_stability.rs:36:33
    |
 LL | const unsafe fn bar3() -> u32 { (5f32 + 6f32) as u32 } //~ ERROR only int, `bool` and `char` op
    |                                 ^^^^^^^^^^^^^
 
 error: can only call other `min_const_fn` within a `min_const_fn`
-  --> $DIR/min_const_unsafe_fn_libstd_stability.rs:45:48
+  --> $DIR/min_const_unsafe_fn_libstd_stability.rs:44:48
    |
 LL | const unsafe fn bar2_gated() -> u32 { unsafe { foo2_gated() } } //~ ERROR can only call other
    |                                                ^^^^^^^^^^^^
diff --git a/src/test/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability2.rs b/src/test/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability2.rs
index 131bc97c85a..68205edd63b 100644
--- a/src/test/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability2.rs
+++ b/src/test/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability2.rs
@@ -14,7 +14,6 @@
             issue = "0")]
 
 #![feature(rustc_const_unstable, const_fn, foo, foo2)]
-#![feature(min_const_unsafe_fn)]
 #![feature(staged_api)]
 
 #[stable(feature = "rust1", since = "1.0.0")]
diff --git a/src/test/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability2.stderr b/src/test/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability2.stderr
index 0b58dc1294b..61533015185 100644
--- a/src/test/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability2.stderr
+++ b/src/test/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability2.stderr
@@ -1,17 +1,17 @@
 error: can only call other `min_const_fn` within a `min_const_fn`
-  --> $DIR/min_const_unsafe_fn_libstd_stability2.rs:26:32
+  --> $DIR/min_const_unsafe_fn_libstd_stability2.rs:25:32
    |
 LL | const unsafe fn bar() -> u32 { foo() } //~ ERROR can only call other `min_const_fn`
    |                                ^^^^^
 
 error: can only call other `min_const_fn` within a `min_const_fn`
-  --> $DIR/min_const_unsafe_fn_libstd_stability2.rs:33:33
+  --> $DIR/min_const_unsafe_fn_libstd_stability2.rs:32:33
    |
 LL | const unsafe fn bar2() -> u32 { foo2() } //~ ERROR can only call other `min_const_fn`
    |                                 ^^^^^^
 
 error: can only call other `min_const_fn` within a `min_const_fn`
-  --> $DIR/min_const_unsafe_fn_libstd_stability2.rs:41:39
+  --> $DIR/min_const_unsafe_fn_libstd_stability2.rs:40:39
    |
 LL | const unsafe fn bar2_gated() -> u32 { foo2_gated() } //~ ERROR can only call other `min_const_fn`
    |                                       ^^^^^^^^^^^^
diff --git a/src/test/ui/consts/static_mut_containing_mut_ref.rs b/src/test/ui/consts/static_mut_containing_mut_ref.rs
new file mode 100644
index 00000000000..27e1a111163
--- /dev/null
+++ b/src/test/ui/consts/static_mut_containing_mut_ref.rs
@@ -0,0 +1,7 @@
+// compile-pass
+
+static mut STDERR_BUFFER_SPACE: [u8; 42] = [0u8; 42];
+
+pub static mut STDERR_BUFFER: *mut [u8] = unsafe { &mut STDERR_BUFFER_SPACE };
+
+fn main() {}
diff --git a/src/test/ui/consts/static_mut_containing_mut_ref2.rs b/src/test/ui/consts/static_mut_containing_mut_ref2.rs
new file mode 100644
index 00000000000..4180b1e295a
--- /dev/null
+++ b/src/test/ui/consts/static_mut_containing_mut_ref2.rs
@@ -0,0 +1,9 @@
+#![feature(const_let)]
+
+static mut STDERR_BUFFER_SPACE: u8 = 0;
+
+pub static mut STDERR_BUFFER: () = unsafe { *(&mut STDERR_BUFFER_SPACE) = 42; };
+//~^ ERROR references in statics may only refer to immutable values
+//~| ERROR static contains unimplemented expression type
+
+fn main() {}
diff --git a/src/test/ui/consts/static_mut_containing_mut_ref2.stderr b/src/test/ui/consts/static_mut_containing_mut_ref2.stderr
new file mode 100644
index 00000000000..f0ae1545056
--- /dev/null
+++ b/src/test/ui/consts/static_mut_containing_mut_ref2.stderr
@@ -0,0 +1,16 @@
+error[E0017]: references in statics may only refer to immutable values
+  --> $DIR/static_mut_containing_mut_ref2.rs:5:46
+   |
+LL | pub static mut STDERR_BUFFER: () = unsafe { *(&mut STDERR_BUFFER_SPACE) = 42; };
+   |                                              ^^^^^^^^^^^^^^^^^^^^^^^^^^ statics require immutable values
+
+error[E0019]: static contains unimplemented expression type
+  --> $DIR/static_mut_containing_mut_ref2.rs:5:45
+   |
+LL | pub static mut STDERR_BUFFER: () = unsafe { *(&mut STDERR_BUFFER_SPACE) = 42; };
+   |                                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
+Some errors occurred: E0017, E0019.
+For more information about an error, try `rustc --explain E0017`.
diff --git a/src/test/ui/consts/static_mut_containing_mut_ref3.rs b/src/test/ui/consts/static_mut_containing_mut_ref3.rs
new file mode 100644
index 00000000000..0bc7faa9afd
--- /dev/null
+++ b/src/test/ui/consts/static_mut_containing_mut_ref3.rs
@@ -0,0 +1,8 @@
+#![feature(const_let)]
+
+static mut FOO: (u8, u8) = (42, 43);
+
+static mut BAR: () = unsafe { FOO.0 = 99; };
+//~^ ERROR could not evaluate static initializer
+
+fn main() {}
diff --git a/src/test/ui/consts/static_mut_containing_mut_ref3.stderr b/src/test/ui/consts/static_mut_containing_mut_ref3.stderr
new file mode 100644
index 00000000000..cae53c6fee9
--- /dev/null
+++ b/src/test/ui/consts/static_mut_containing_mut_ref3.stderr
@@ -0,0 +1,9 @@
+error[E0080]: could not evaluate static initializer
+  --> $DIR/static_mut_containing_mut_ref3.rs:5:31
+   |
+LL | static mut BAR: () = unsafe { FOO.0 = 99; };
+   |                               ^^^^^^^^^^ tried to modify a static's initial value from another static's initializer
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/src/test/ui/dead-code-tuple-struct-field.rs b/src/test/ui/dead-code-tuple-struct-field.rs
new file mode 100644
index 00000000000..496ce4fb378
--- /dev/null
+++ b/src/test/ui/dead-code-tuple-struct-field.rs
@@ -0,0 +1,12 @@
+// compile-pass
+
+#![deny(dead_code)]
+
+const LEN: usize = 4;
+
+#[derive(Debug)]
+struct Wrapper([u8; LEN]);
+
+fn main() {
+    println!("{:?}", Wrapper([0, 1, 2, 3]));
+}
diff --git a/src/test/ui/did_you_mean/issue-56028-there-is-an-enum-variant.rs b/src/test/ui/did_you_mean/issue-56028-there-is-an-enum-variant.rs
new file mode 100644
index 00000000000..264cfa44994
--- /dev/null
+++ b/src/test/ui/did_you_mean/issue-56028-there-is-an-enum-variant.rs
@@ -0,0 +1,15 @@
+enum PutDown { Set }
+enum AffixHeart { Set }
+enum CauseToBe { Set }
+enum Determine { Set }
+enum TableDishesAction { Set }
+enum Solidify { Set }
+enum UnorderedCollection { Set }
+
+fn setup() -> Set { Set }
+//~^ ERROR cannot find type `Set` in this scope
+//~| ERROR cannot find value `Set` in this scope
+
+fn main() {
+    setup();
+}
diff --git a/src/test/ui/did_you_mean/issue-56028-there-is-an-enum-variant.stderr b/src/test/ui/did_you_mean/issue-56028-there-is-an-enum-variant.stderr
new file mode 100644
index 00000000000..6107ca32a5d
--- /dev/null
+++ b/src/test/ui/did_you_mean/issue-56028-there-is-an-enum-variant.stderr
@@ -0,0 +1,38 @@
+error[E0412]: cannot find type `Set` in this scope
+  --> $DIR/issue-56028-there-is-an-enum-variant.rs:9:15
+   |
+LL | fn setup() -> Set { Set }
+   |               ^^^ not found in this scope
+help: there is an enum variant `AffixHeart::Set` and 7 others; try using the variant's enum
+   |
+LL | fn setup() -> AffixHeart { Set }
+   |               ^^^^^^^^^^
+LL | fn setup() -> CauseToBe { Set }
+   |               ^^^^^^^^^
+LL | fn setup() -> Determine { Set }
+   |               ^^^^^^^^^
+LL | fn setup() -> PutDown { Set }
+   |               ^^^^^^^
+and 3 other candidates
+
+error[E0425]: cannot find value `Set` in this scope
+  --> $DIR/issue-56028-there-is-an-enum-variant.rs:9:21
+   |
+LL | fn setup() -> Set { Set }
+   |                     ^^^ not found in this scope
+help: possible candidates are found in other modules, you can import them into scope
+   |
+LL | use AffixHeart::Set;
+   |
+LL | use CauseToBe::Set;
+   |
+LL | use Determine::Set;
+   |
+LL | use PutDown::Set;
+   |
+and 3 other candidates
+
+error: aborting due to 2 previous errors
+
+Some errors occurred: E0412, E0425.
+For more information about an error, try `rustc --explain E0412`.
diff --git a/src/test/ui/enum/enum-variant-type-2.stderr b/src/test/ui/enum/enum-variant-type-2.stderr
index 7a786af71bb..eb869f5539f 100644
--- a/src/test/ui/enum/enum-variant-type-2.stderr
+++ b/src/test/ui/enum/enum-variant-type-2.stderr
@@ -5,7 +5,7 @@ LL | fn foo(x: Foo::Bar) {} //~ ERROR expected type, found variant `Foo::Bar`
    |           ^^^^^^^^
    |           |
    |           not a type
-   |           help: you can try using the variant's enum: `Foo`
+   |           help: try using the variant's enum: `Foo`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/error-codes/E0069.stderr b/src/test/ui/error-codes/E0069.stderr
index 0ba1ed45663..12b778f42e2 100644
--- a/src/test/ui/error-codes/E0069.stderr
+++ b/src/test/ui/error-codes/E0069.stderr
@@ -1,8 +1,10 @@
 error[E0069]: `return;` in a function whose return type is not `()`
   --> $DIR/E0069.rs:12:5
    |
+LL | fn foo() -> u8 {
+   |             -- expected `u8` because of this return type
 LL |     return;
-   |     ^^^^^^ return type is not ()
+   |     ^^^^^^ return type is not `()`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/impl-trait/equality.stderr b/src/test/ui/impl-trait/equality.stderr
index e277d4e28cb..f1d2071bbdb 100644
--- a/src/test/ui/impl-trait/equality.stderr
+++ b/src/test/ui/impl-trait/equality.stderr
@@ -1,6 +1,9 @@
 error[E0308]: mismatched types
   --> $DIR/equality.rs:25:5
    |
+LL |         return 1_i32;
+   |                ----- expected because of this statement
+LL |     }
 LL |     0_u32
    |     ^^^^^ expected i32, found u32
    |
diff --git a/src/test/ui/issues/issue-11004.stderr b/src/test/ui/issues/issue-11004.stderr
index 215120c9c25..eb5b568b347 100644
--- a/src/test/ui/issues/issue-11004.stderr
+++ b/src/test/ui/issues/issue-11004.stderr
@@ -2,13 +2,17 @@ error[E0609]: no field `x` on type `*mut A`
   --> $DIR/issue-11004.rs:17:21
    |
 LL |     let x : i32 = n.x; //~ no field `x` on type `*mut A`
-   |                     ^ help: `n` is a native pointer; try dereferencing it: `(*n).x`
+   |                   --^
+   |                   |
+   |                   help: `n` is a raw pointer; try dereferencing it: `(*n).x`
 
 error[E0609]: no field `y` on type `*mut A`
   --> $DIR/issue-11004.rs:18:21
    |
 LL |     let y : f64 = n.y; //~ no field `y` on type `*mut A`
-   |                     ^ help: `n` is a native pointer; try dereferencing it: `(*n).y`
+   |                   --^
+   |                   |
+   |                   help: `n` is a raw pointer; try dereferencing it: `(*n).y`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/issues/issue-17546.stderr b/src/test/ui/issues/issue-17546.stderr
index 39f7d5fcc04..a8ab5e8eb77 100644
--- a/src/test/ui/issues/issue-17546.stderr
+++ b/src/test/ui/issues/issue-17546.stderr
@@ -5,7 +5,7 @@ LL |     fn new() -> NoResult<MyEnum, String> {
    |                 --------^^^^^^^^^^^^^^^^
    |                 |
    |                 did you mean `Result`?
-   |                 help: you can try using the variant's enum: `foo::MyEnum`
+   |                 help: try using the variant's enum: `foo::MyEnum`
 
 error[E0573]: expected type, found variant `Result`
   --> $DIR/issue-17546.rs:32:17
@@ -48,7 +48,7 @@ LL | fn newer() -> NoResult<foo::MyEnum, String> {
    |               --------^^^^^^^^^^^^^^^^^^^^^
    |               |
    |               did you mean `Result`?
-   |               help: you can try using the variant's enum: `foo::MyEnum`
+   |               help: try using the variant's enum: `foo::MyEnum`
 
 error: aborting due to 4 previous errors
 
diff --git a/src/test/ui/issues/issue-30535.stderr b/src/test/ui/issues/issue-30535.stderr
index c3838fdb9cf..35ef227acfc 100644
--- a/src/test/ui/issues/issue-30535.stderr
+++ b/src/test/ui/issues/issue-30535.stderr
@@ -2,9 +2,10 @@ error[E0573]: expected type, found variant `foo::Foo::FooV`
   --> $DIR/issue-30535.rs:16:8
    |
 LL |     _: foo::Foo::FooV //~ ERROR expected type, found variant `foo::Foo::FooV`
-   |        ^^^^^^^^^^^^^^ not a type
-   |
-   = help: there is an enum variant `foo::Foo::FooV`, try using `foo::Foo`?
+   |        ^^^^^^^^^^^^^^
+   |        |
+   |        not a type
+   |        help: try using the variant's enum: `foo::Foo`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-35075.stderr b/src/test/ui/issues/issue-35075.stderr
index 9b2f17f038b..ead07a5f0c8 100644
--- a/src/test/ui/issues/issue-35075.stderr
+++ b/src/test/ui/issues/issue-35075.stderr
@@ -2,19 +2,21 @@ error[E0412]: cannot find type `Foo` in this scope
   --> $DIR/issue-35075.rs:12:12
    |
 LL |     inner: Foo<T> //~ ERROR cannot find type `Foo` in this scope
-   |            ^^^---
-   |            |
-   |            not found in this scope
-   |            help: you can try using the variant's enum: `Baz`
+   |            ^^^ not found in this scope
+help: there is an enum variant `Baz::Foo`; try using the variant's enum
+   |
+LL |     inner: Baz //~ ERROR cannot find type `Foo` in this scope
+   |            ^^^
 
 error[E0412]: cannot find type `Foo` in this scope
   --> $DIR/issue-35075.rs:16:9
    |
 LL |     Foo(Foo<T>) //~ ERROR cannot find type `Foo` in this scope
-   |         ^^^---
-   |         |
-   |         not found in this scope
-   |         help: you can try using the variant's enum: `Baz`
+   |         ^^^ not found in this scope
+help: there is an enum variant `Baz::Foo`; try using the variant's enum
+   |
+LL |     Foo(Baz) //~ ERROR cannot find type `Foo` in this scope
+   |         ^^^
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/issues/issue-35675.stderr b/src/test/ui/issues/issue-35675.stderr
index fef8de3a28d..652e1695a85 100644
--- a/src/test/ui/issues/issue-35675.stderr
+++ b/src/test/ui/issues/issue-35675.stderr
@@ -2,10 +2,11 @@ error[E0412]: cannot find type `Apple` in this scope
   --> $DIR/issue-35675.rs:17:29
    |
 LL | fn should_return_fruit() -> Apple {
+   |                             ^^^^^ not found in this scope
+help: there is an enum variant `Fruit::Apple`; try using the variant's enum
+   |
+LL | fn should_return_fruit() -> Fruit {
    |                             ^^^^^
-   |                             |
-   |                             not found in this scope
-   |                             help: you can try using the variant's enum: `Fruit`
 
 error[E0425]: cannot find function `Apple` in this scope
   --> $DIR/issue-35675.rs:19:5
@@ -24,7 +25,7 @@ LL | fn should_return_fruit_too() -> Fruit::Apple {
    |                                 ^^^^^^^^^^^^
    |                                 |
    |                                 not a type
-   |                                 help: you can try using the variant's enum: `Fruit`
+   |                                 help: try using the variant's enum: `Fruit`
 
 error[E0425]: cannot find function `Apple` in this scope
   --> $DIR/issue-35675.rs:25:5
@@ -40,28 +41,29 @@ error[E0573]: expected type, found variant `Ok`
   --> $DIR/issue-35675.rs:29:13
    |
 LL | fn foo() -> Ok {
-   |             ^^ not a type
-   |
-   = help: there is an enum variant `std::prelude::v1::Ok`, try using `std::prelude::v1`?
-   = help: there is an enum variant `std::result::Result::Ok`, try using `std::result::Result`?
+   |             ^^
+   |             |
+   |             not a type
+   |             help: try using the variant's enum: `std::result::Result`
 
 error[E0412]: cannot find type `Variant3` in this scope
   --> $DIR/issue-35675.rs:34:13
    |
 LL | fn bar() -> Variant3 {
-   |             ^^^^^^^^
-   |             |
-   |             not found in this scope
-   |             help: you can try using the variant's enum: `x::Enum`
+   |             ^^^^^^^^ not found in this scope
+help: there is an enum variant `x::Enum::Variant3`; try using the variant's enum
+   |
+LL | fn bar() -> x::Enum {
+   |             ^^^^^^^
 
 error[E0573]: expected type, found variant `Some`
   --> $DIR/issue-35675.rs:38:13
    |
 LL | fn qux() -> Some {
-   |             ^^^^ not a type
-   |
-   = help: there is an enum variant `std::prelude::v1::Option::Some`, try using `std::prelude::v1::Option`?
-   = help: there is an enum variant `std::prelude::v1::Some`, try using `std::prelude::v1`?
+   |             ^^^^
+   |             |
+   |             not a type
+   |             help: try using the variant's enum: `Option`
 
 error: aborting due to 7 previous errors
 
diff --git a/src/test/ui/parenthesised-deref-suggestion.rs b/src/test/ui/parenthesised-deref-suggestion.rs
new file mode 100644
index 00000000000..0b4ccdd5a56
--- /dev/null
+++ b/src/test/ui/parenthesised-deref-suggestion.rs
@@ -0,0 +1,11 @@
+struct Session {
+    opts: u8,
+}
+
+fn main() {
+    let sess: &Session = &Session { opts: 0 };
+    (sess as *const Session).opts; //~ ERROR no field `opts` on type `*const Session`
+
+    let x = [0u32];
+    (x as [u32; 1]).0; //~ ERROR no field `0` on type `[u32; 1]`
+}
diff --git a/src/test/ui/parenthesised-deref-suggestion.stderr b/src/test/ui/parenthesised-deref-suggestion.stderr
new file mode 100644
index 00000000000..71a2bf67f06
--- /dev/null
+++ b/src/test/ui/parenthesised-deref-suggestion.stderr
@@ -0,0 +1,21 @@
+error[E0609]: no field `opts` on type `*const Session`
+  --> $DIR/parenthesised-deref-suggestion.rs:7:30
+   |
+LL |     (sess as *const Session).opts; //~ ERROR no field `opts` on type `*const Session`
+   |                              ^^^^
+help: `(sess as *const Session)` is a raw pointer; try dereferencing it
+   |
+LL |     (*(sess as *const Session)).opts; //~ ERROR no field `opts` on type `*const Session`
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0609]: no field `0` on type `[u32; 1]`
+  --> $DIR/parenthesised-deref-suggestion.rs:10:21
+   |
+LL |     (x as [u32; 1]).0; //~ ERROR no field `0` on type `[u32; 1]`
+   |     ----------------^
+   |     |
+   |     help: instead of using tuple indexing, use array indexing: `(x as [u32; 1])[0]`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0609`.
diff --git a/src/test/ui/ret-non-nil.stderr b/src/test/ui/ret-non-nil.stderr
index 01f126bd11e..e0fdc8c67ed 100644
--- a/src/test/ui/ret-non-nil.stderr
+++ b/src/test/ui/ret-non-nil.stderr
@@ -2,7 +2,9 @@ error[E0069]: `return;` in a function whose return type is not `()`
   --> $DIR/ret-non-nil.rs:15:19
    |
 LL | fn g() -> isize { return; }
-   |                   ^^^^^^ return type is not ()
+   |           -----   ^^^^^^ return type is not `()`
+   |           |
+   |           expected `isize` because of this return type
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/return/return-unit-from-diverging.stderr b/src/test/ui/return/return-unit-from-diverging.stderr
index 38d4ca37366..5a9f0877cc6 100644
--- a/src/test/ui/return/return-unit-from-diverging.stderr
+++ b/src/test/ui/return/return-unit-from-diverging.stderr
@@ -1,8 +1,10 @@
 error[E0069]: `return;` in a function whose return type is not `()`
   --> $DIR/return-unit-from-diverging.rs:15:5
    |
+LL | fn fail() -> ! {
+   |              - expected `!` because of this return type
 LL |     return; //~ ERROR in a function whose return type is not
-   |     ^^^^^^ return type is not ()
+   |     ^^^^^^ return type is not `()`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/target-feature-gate.rs b/src/test/ui/target-feature-gate.rs
index cb0938b861c..9f3a7b5e924 100644
--- a/src/test/ui/target-feature-gate.rs
+++ b/src/test/ui/target-feature-gate.rs
@@ -19,6 +19,7 @@
 // ignore-powerpc64le
 // ignore-sparc
 // ignore-sparc64
+// ignore-s390x
 // gate-test-sse4a_target_feature
 // gate-test-powerpc_target_feature
 // gate-test-avx512_target_feature
diff --git a/src/test/ui/target-feature-gate.stderr b/src/test/ui/target-feature-gate.stderr
index d7154324d12..73da67a9b8f 100644
--- a/src/test/ui/target-feature-gate.stderr
+++ b/src/test/ui/target-feature-gate.stderr
@@ -1,5 +1,5 @@
 error[E0658]: the target feature `avx512bw` is currently unstable (see issue #44839)
-  --> $DIR/target-feature-gate.rs:36:18
+  --> $DIR/target-feature-gate.rs:37:18
    |
 LL | #[target_feature(enable = "avx512bw")]
    |                  ^^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/unsafe/unsafe-fn-autoderef.stderr b/src/test/ui/unsafe/unsafe-fn-autoderef.stderr
index 13fcbb347c9..7525f670515 100644
--- a/src/test/ui/unsafe/unsafe-fn-autoderef.stderr
+++ b/src/test/ui/unsafe/unsafe-fn-autoderef.stderr
@@ -2,7 +2,9 @@ error[E0609]: no field `f` on type `*const Rec`
   --> $DIR/unsafe-fn-autoderef.rs:29:14
    |
 LL |     return p.f; //~ ERROR no field `f` on type `*const Rec`
-   |              ^ help: `p` is a native pointer; try dereferencing it: `(*p).f`
+   |            --^
+   |            |
+   |            help: `p` is a raw pointer; try dereferencing it: `(*p).f`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/variants/variant-used-as-type.stderr b/src/test/ui/variants/variant-used-as-type.stderr
index 972fe8a8a61..c72729923ef 100644
--- a/src/test/ui/variants/variant-used-as-type.stderr
+++ b/src/test/ui/variants/variant-used-as-type.stderr
@@ -3,28 +3,24 @@ error[E0573]: expected type, found variant `Ty::A`
    |
 LL |     B(Ty::A),
    |       ^^^^^ not a type
-help: you can try using the variant's enum
-   |
-LL |     B(Ty),
-   |       ^^
-help: you can try using the variant's enum
+help: try using the variant's enum
    |
 LL |     B(E),
    |       ^
+LL |     B(Ty),
+   |       ^^
 
 error[E0573]: expected type, found variant `E::A`
   --> $DIR/variant-used-as-type.rs:27:6
    |
 LL | impl E::A {}
    |      ^^^^ not a type
-help: you can try using the variant's enum
-   |
-LL | impl Ty {}
-   |      ^^
-help: you can try using the variant's enum
+help: try using the variant's enum
    |
 LL | impl E {}
    |      ^
+LL | impl Ty {}
+   |      ^^
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/write-to-static-mut-in-static.rs b/src/test/ui/write-to-static-mut-in-static.rs
index 191f09b54ee..983b5d48e60 100644
--- a/src/test/ui/write-to-static-mut-in-static.rs
+++ b/src/test/ui/write-to-static-mut-in-static.rs
@@ -12,10 +12,10 @@
 
 pub static mut A: u32 = 0;
 pub static mut B: () = unsafe { A = 1; };
-//~^ ERROR cannot mutate statics in the initializer of another static
+//~^ ERROR could not evaluate static initializer
 
 pub static mut C: u32 = unsafe { C = 1; 0 };
-//~^ ERROR cannot mutate statics in the initializer of another static
+//~^ ERROR cycle detected
 
 pub static D: u32 = D;
 
diff --git a/src/test/ui/write-to-static-mut-in-static.stderr b/src/test/ui/write-to-static-mut-in-static.stderr
index 673a71b4642..335f849fb24 100644
--- a/src/test/ui/write-to-static-mut-in-static.stderr
+++ b/src/test/ui/write-to-static-mut-in-static.stderr
@@ -1,14 +1,28 @@
-error: cannot mutate statics in the initializer of another static
+error[E0080]: could not evaluate static initializer
   --> $DIR/write-to-static-mut-in-static.rs:14:33
    |
 LL | pub static mut B: () = unsafe { A = 1; };
-   |                                 ^^^^^
+   |                                 ^^^^^ tried to modify a static's initial value from another static's initializer
 
-error: cannot mutate statics in the initializer of another static
+error[E0391]: cycle detected when const-evaluating `C`
   --> $DIR/write-to-static-mut-in-static.rs:17:34
    |
 LL | pub static mut C: u32 = unsafe { C = 1; 0 };
    |                                  ^^^^^
+   |
+note: ...which requires const-evaluating `C`...
+  --> $DIR/write-to-static-mut-in-static.rs:17:1
+   |
+LL | pub static mut C: u32 = unsafe { C = 1; 0 };
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: ...which again requires const-evaluating `C`, completing the cycle
+note: cycle used when const-evaluating + checking `C`
+  --> $DIR/write-to-static-mut-in-static.rs:17:1
+   |
+LL | pub static mut C: u32 = unsafe { C = 1; 0 };
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 2 previous errors
 
+Some errors occurred: E0080, E0391.
+For more information about an error, try `rustc --explain E0080`.