diff --git a/compiler/rustc_data_structures/src/graph/mod.rs b/compiler/rustc_data_structures/src/graph/mod.rs
index e0903e4324124..dff22855629a8 100644
--- a/compiler/rustc_data_structures/src/graph/mod.rs
+++ b/compiler/rustc_data_structures/src/graph/mod.rs
@@ -60,18 +60,13 @@ pub trait WithStartNode: DirectedGraph {
 }
 
 pub trait ControlFlowGraph:
-    DirectedGraph + WithStartNode + WithPredecessors + WithStartNode + WithSuccessors + WithNumNodes
+    DirectedGraph + WithStartNode + WithPredecessors + WithSuccessors + WithNumNodes
 {
     // convenient trait
 }
 
 impl<T> ControlFlowGraph for T where
-    T: DirectedGraph
-        + WithStartNode
-        + WithPredecessors
-        + WithStartNode
-        + WithSuccessors
-        + WithNumNodes
+    T: DirectedGraph + WithStartNode + WithPredecessors + WithSuccessors + WithNumNodes
 {
 }
 
diff --git a/compiler/rustc_error_codes/src/error_codes/E0530.md b/compiler/rustc_error_codes/src/error_codes/E0530.md
index 502f674fc1d21..60fa711cbed36 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0530.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0530.md
@@ -1,32 +1,57 @@
 A binding shadowed something it shouldn't.
 
-Erroneous code example:
+A match arm or a variable has a name that is already used by
+something else, e.g.
+
+* struct name
+* enum variant
+* static
+* associated constant
+
+This error may also happen when an enum variant *with fields* is used
+in a pattern, but without its fields.
+
+```compile_fail
+enum Enum {
+    WithField(i32)
+}
+
+use Enum::*;
+match WithField(1) {
+    WithField => {} // error: missing (_)
+}
+```
+
+Match bindings cannot shadow statics:
 
 ```compile_fail,E0530
 static TEST: i32 = 0;
 
-let r: (i32, i32) = (0, 0);
+let r = 123;
 match r {
-    TEST => {} // error: match bindings cannot shadow statics
+    TEST => {} // error: name of a static
 }
 ```
 
-To fix this error, just change the binding's name in order to avoid shadowing
-one of the following:
+Fixed examples:
 
-* struct name
-* struct/enum variant
-* static
-* const
-* associated const
+```
+static TEST: i32 = 0;
 
-Fixed example:
+let r = 123;
+match r {
+    some_value => {} // ok!
+}
+```
+
+or
 
 ```
-static TEST: i32 = 0;
+const TEST: i32 = 0; // const, not static
 
-let r: (i32, i32) = (0, 0);
+let r = 123;
 match r {
-    something => {} // ok!
+    TEST => {} // const is ok!
+    other_values => {}
 }
 ```
diff --git a/compiler/rustc_symbol_mangling/src/legacy.rs b/compiler/rustc_symbol_mangling/src/legacy.rs
index 0c64fe6ea60a9..1b4e6b4e38177 100644
--- a/compiler/rustc_symbol_mangling/src/legacy.rs
+++ b/compiler/rustc_symbol_mangling/src/legacy.rs
@@ -55,7 +55,8 @@ pub(super) fn mangle(
 
     let hash = get_symbol_hash(tcx, instance, instance_ty, instantiating_crate);
 
-    let mut printer = SymbolPrinter { tcx, path: SymbolPath::new(), keep_within_component: false }
+    let mut printer = SymbolPrinter { tcx, path: SymbolPath::new(), keep_within_component: false };
+    printer
         .print_def_path(
             def_id,
             if let ty::InstanceDef::DropGlue(_, _) = instance.def {
@@ -198,7 +199,7 @@ struct SymbolPrinter<'tcx> {
 // `PrettyPrinter` aka pretty printing of e.g. types in paths,
 // symbol names should have their own printing machinery.
 
-impl Printer<'tcx> for SymbolPrinter<'tcx> {
+impl Printer<'tcx> for &mut SymbolPrinter<'tcx> {
     type Error = fmt::Error;
 
     type Path = Self;
@@ -242,7 +243,7 @@ impl Printer<'tcx> for SymbolPrinter<'tcx> {
         Ok(self)
     }
 
-    fn print_const(mut self, ct: &'tcx ty::Const<'tcx>) -> Result<Self::Const, Self::Error> {
+    fn print_const(self, ct: &'tcx ty::Const<'tcx>) -> Result<Self::Const, Self::Error> {
         // only print integers
         if let ty::ConstKind::Value(ConstValue::Scalar(Scalar::Int { .. })) = ct.val {
             if ct.ty.is_integral() {
@@ -253,7 +254,7 @@ impl Printer<'tcx> for SymbolPrinter<'tcx> {
         Ok(self)
     }
 
-    fn path_crate(mut self, cnum: CrateNum) -> Result<Self::Path, Self::Error> {
+    fn path_crate(self, cnum: CrateNum) -> Result<Self::Path, Self::Error> {
         self.write_str(&self.tcx.crate_name(cnum).as_str())?;
         Ok(self)
     }
@@ -344,7 +345,7 @@ impl Printer<'tcx> for SymbolPrinter<'tcx> {
     }
 }
 
-impl PrettyPrinter<'tcx> for SymbolPrinter<'tcx> {
+impl PrettyPrinter<'tcx> for &mut SymbolPrinter<'tcx> {
     fn region_should_not_be_omitted(&self, _region: ty::Region<'_>) -> bool {
         false
     }
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
index 3f713ce3c3914..ac07cc1f03439 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
@@ -245,9 +245,10 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
                 if let ObligationCauseCode::WellFormed(Some(wf_loc)) =
                     root_obligation.cause.code.peel_derives()
                 {
-                    if let Some(cause) =
-                        self.tcx.diagnostic_hir_wf_check((obligation.predicate, wf_loc.clone()))
-                    {
+                    if let Some(cause) = self.tcx.diagnostic_hir_wf_check((
+                        tcx.erase_regions(obligation.predicate),
+                        wf_loc.clone(),
+                    )) {
                         obligation.cause = cause;
                         span = obligation.cause.span;
                     }
diff --git a/compiler/rustc_typeck/src/check/expr.rs b/compiler/rustc_typeck/src/check/expr.rs
index 831b573e1568a..a536285651102 100644
--- a/compiler/rustc_typeck/src/check/expr.rs
+++ b/compiler/rustc_typeck/src/check/expr.rs
@@ -1313,15 +1313,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 .emit();
             }
         } else if check_completeness && !error_happened && !remaining_fields.is_empty() {
-            let no_accessible_remaining_fields = remaining_fields
-                .iter()
-                .find(|(_, (_, field))| {
-                    field.vis.is_accessible_from(tcx.parent_module(expr_id).to_def_id(), tcx)
-                })
-                .is_none();
+            let inaccessible_remaining_fields = remaining_fields.iter().any(|(_, (_, field))| {
+                !field.vis.is_accessible_from(tcx.parent_module(expr_id).to_def_id(), tcx)
+            });
 
-            if no_accessible_remaining_fields {
-                self.report_no_accessible_fields(adt_ty, span);
+            if inaccessible_remaining_fields {
+                self.report_inaccessible_fields(adt_ty, span);
             } else {
                 self.report_missing_fields(adt_ty, span, remaining_fields);
             }
@@ -1398,7 +1395,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         .emit();
     }
 
-    /// Report an error for a struct field expression when there are no visible fields.
+    /// Report an error for a struct field expression when there are invisible fields.
     ///
     /// ```text
     /// error: cannot construct `Foo` with struct literal syntax due to inaccessible fields
@@ -1409,7 +1406,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     ///
     /// error: aborting due to previous error
     /// ```
-    fn report_no_accessible_fields(&self, adt_ty: Ty<'tcx>, span: Span) {
+    fn report_inaccessible_fields(&self, adt_ty: Ty<'tcx>, span: Span) {
         self.tcx.sess.span_err(
             span,
             &format!(
diff --git a/compiler/rustc_typeck/src/check/method/suggest.rs b/compiler/rustc_typeck/src/check/method/suggest.rs
index 77586ce48529c..c7a7462668aa5 100644
--- a/compiler/rustc_typeck/src/check/method/suggest.rs
+++ b/compiler/rustc_typeck/src/check/method/suggest.rs
@@ -1695,8 +1695,8 @@ fn print_disambiguation_help(
     source_map: &source_map::SourceMap,
 ) {
     let mut applicability = Applicability::MachineApplicable;
-    let sugg_args = if let (ty::AssocKind::Fn, Some(args)) = (kind, args) {
-        format!(
+    let (span, sugg) = if let (ty::AssocKind::Fn, Some(args)) = (kind, args) {
+        let args = format!(
             "({}{})",
             if rcvr_ty.is_region_ptr() {
                 if rcvr_ty.is_mutable_ptr() { "&mut " } else { "&" }
@@ -1710,12 +1710,12 @@ fn print_disambiguation_help(
                 }))
                 .collect::<Vec<_>>()
                 .join(", "),
-        )
+        );
+        (span, format!("{}::{}{}", trait_name, item_name, args))
     } else {
-        String::new()
+        (span.with_hi(item_name.span.lo()), format!("{}::", trait_name))
     };
-    let sugg = format!("{}::{}{}", trait_name, item_name, sugg_args);
-    err.span_suggestion(
+    err.span_suggestion_verbose(
         span,
         &format!(
             "disambiguate the {} for {}",
diff --git a/compiler/rustc_typeck/src/check/pat.rs b/compiler/rustc_typeck/src/check/pat.rs
index db77d155a2bae..dae574bb7bf0f 100644
--- a/compiler/rustc_typeck/src/check/pat.rs
+++ b/compiler/rustc_typeck/src/check/pat.rs
@@ -1250,15 +1250,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 tcx.sess.struct_span_err(pat.span, "`..` cannot be used in union patterns").emit();
             }
         } else if !etc && !unmentioned_fields.is_empty() {
-            let no_accessible_unmentioned_fields = !unmentioned_fields.iter().any(|(field, _)| {
-                field.vis.is_accessible_from(tcx.parent_module(pat.hir_id).to_def_id(), tcx)
-            });
+            let accessible_unmentioned_fields: Vec<_> = unmentioned_fields
+                .iter()
+                .copied()
+                .filter(|(field, _)| {
+                    field.vis.is_accessible_from(tcx.parent_module(pat.hir_id).to_def_id(), tcx)
+                })
+                .collect();
 
-            if no_accessible_unmentioned_fields {
+            if accessible_unmentioned_fields.is_empty() {
                 unmentioned_err = Some(self.error_no_accessible_fields(pat, &fields));
             } else {
-                unmentioned_err =
-                    Some(self.error_unmentioned_fields(pat, &unmentioned_fields, &fields));
+                unmentioned_err = Some(self.error_unmentioned_fields(
+                    pat,
+                    &accessible_unmentioned_fields,
+                    accessible_unmentioned_fields.len() != unmentioned_fields.len(),
+                    &fields,
+                ));
             }
         }
         match (inexistent_fields_err, unmentioned_err) {
@@ -1583,17 +1591,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         &self,
         pat: &Pat<'_>,
         unmentioned_fields: &[(&ty::FieldDef, Ident)],
+        have_inaccessible_fields: bool,
         fields: &'tcx [hir::PatField<'tcx>],
     ) -> DiagnosticBuilder<'tcx> {
+        let inaccessible = if have_inaccessible_fields { " and inaccessible fields" } else { "" };
         let field_names = if unmentioned_fields.len() == 1 {
-            format!("field `{}`", unmentioned_fields[0].1)
+            format!("field `{}`{}", unmentioned_fields[0].1, inaccessible)
         } else {
             let fields = unmentioned_fields
                 .iter()
                 .map(|(_, name)| format!("`{}`", name))
                 .collect::<Vec<String>>()
                 .join(", ");
-            format!("fields {}", fields)
+            format!("fields {}{}", fields, inaccessible)
         };
         let mut err = struct_span_err!(
             self.tcx.sess,
@@ -1624,17 +1634,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         err.span_suggestion(
             sp,
             &format!(
-                "include the missing field{} in the pattern",
+                "include the missing field{} in the pattern{}",
                 if len == 1 { "" } else { "s" },
+                if have_inaccessible_fields { " and ignore the inaccessible fields" } else { "" }
             ),
             format!(
-                "{}{}{}",
+                "{}{}{}{}",
                 prefix,
                 unmentioned_fields
                     .iter()
                     .map(|(_, name)| name.to_string())
                     .collect::<Vec<_>>()
                     .join(", "),
+                if have_inaccessible_fields { ", .." } else { "" },
                 postfix,
             ),
             Applicability::MachineApplicable,
diff --git a/compiler/rustc_typeck/src/collect/type_of.rs b/compiler/rustc_typeck/src/collect/type_of.rs
index 96b3fa9aa0143..b9483d6f98760 100644
--- a/compiler/rustc_typeck/src/collect/type_of.rs
+++ b/compiler/rustc_typeck/src/collect/type_of.rs
@@ -190,8 +190,12 @@ pub(super) fn opt_const_param_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<
                 // Try to use the segment resolution if it is valid, otherwise we
                 // default to the path resolution.
                 let res = segment.res.filter(|&r| r != Res::Err).unwrap_or(path.res);
+                use def::CtorOf;
                 let generics = match res {
-                    Res::Def(DefKind::Ctor(..), def_id) => {
+                    Res::Def(DefKind::Ctor(CtorOf::Variant, _), def_id) => tcx.generics_of(
+                        tcx.parent(def_id).and_then(|def_id| tcx.parent(def_id)).unwrap(),
+                    ),
+                    Res::Def(DefKind::Variant | DefKind::Ctor(CtorOf::Struct, _), def_id) => {
                         tcx.generics_of(tcx.parent(def_id).unwrap())
                     }
                     // Other `DefKind`s don't have generics and would ICE when calling
@@ -200,7 +204,6 @@ pub(super) fn opt_const_param_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<
                         DefKind::Struct
                         | DefKind::Union
                         | DefKind::Enum
-                        | DefKind::Variant
                         | DefKind::Trait
                         | DefKind::OpaqueTy
                         | DefKind::TyAlias
diff --git a/library/core/src/convert/num.rs b/library/core/src/convert/num.rs
index 1d3a12962145e..75ef873abc965 100644
--- a/library/core/src/convert/num.rs
+++ b/library/core/src/convert/num.rs
@@ -45,7 +45,8 @@ impl_float_to_int!(f64 => u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize);
 macro_rules! impl_from {
     ($Small: ty, $Large: ty, #[$attr:meta], $doc: expr) => {
         #[$attr]
-        impl From<$Small> for $Large {
+        #[rustc_const_unstable(feature = "const_num_from_num", issue = "87852")]
+        impl const From<$Small> for $Large {
             // Rustdocs on the impl block show a "[+] show undocumented items" toggle.
             // Rustdocs on functions do not.
             #[doc = $doc]
@@ -172,7 +173,8 @@ impl_from! { f32, f64, #[stable(feature = "lossless_float_conv", since = "1.6.0"
 macro_rules! try_from_unbounded {
     ($source:ty, $($target:ty),*) => {$(
         #[stable(feature = "try_from", since = "1.34.0")]
-        impl TryFrom<$source> for $target {
+        #[rustc_const_unstable(feature = "const_num_from_num", issue = "87852")]
+        impl const TryFrom<$source> for $target {
             type Error = TryFromIntError;
 
             /// Try to create the target number type from a source
@@ -190,7 +192,8 @@ macro_rules! try_from_unbounded {
 macro_rules! try_from_lower_bounded {
     ($source:ty, $($target:ty),*) => {$(
         #[stable(feature = "try_from", since = "1.34.0")]
-        impl TryFrom<$source> for $target {
+        #[rustc_const_unstable(feature = "const_num_from_num", issue = "87852")]
+        impl const TryFrom<$source> for $target {
             type Error = TryFromIntError;
 
             /// Try to create the target number type from a source
@@ -212,7 +215,8 @@ macro_rules! try_from_lower_bounded {
 macro_rules! try_from_upper_bounded {
     ($source:ty, $($target:ty),*) => {$(
         #[stable(feature = "try_from", since = "1.34.0")]
-        impl TryFrom<$source> for $target {
+        #[rustc_const_unstable(feature = "const_num_from_num", issue = "87852")]
+        impl const TryFrom<$source> for $target {
             type Error = TryFromIntError;
 
             /// Try to create the target number type from a source
@@ -234,7 +238,8 @@ macro_rules! try_from_upper_bounded {
 macro_rules! try_from_both_bounded {
     ($source:ty, $($target:ty),*) => {$(
         #[stable(feature = "try_from", since = "1.34.0")]
-        impl TryFrom<$source> for $target {
+        #[rustc_const_unstable(feature = "const_num_from_num", issue = "87852")]
+        impl const TryFrom<$source> for $target {
             type Error = TryFromIntError;
 
             /// Try to create the target number type from a source
diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs
index 222ef34b6aa8a..37c3f8d4c16ab 100644
--- a/library/core/src/lib.rs
+++ b/library/core/src/lib.rs
@@ -99,6 +99,7 @@
 #![feature(const_slice_from_raw_parts)]
 #![feature(const_slice_ptr_len)]
 #![feature(const_swap)]
+#![feature(const_trait_impl)]
 #![feature(const_type_id)]
 #![feature(const_type_name)]
 #![feature(const_unreachable_unchecked)]
diff --git a/library/core/src/option.rs b/library/core/src/option.rs
index d4e9c384f9302..3f9f04606b36a 100644
--- a/library/core/src/option.rs
+++ b/library/core/src/option.rs
@@ -1399,6 +1399,33 @@ impl<T> Option<T> {
     }
 }
 
+impl<T, U> Option<(T, U)> {
+    /// Unzips an option containing a tuple of two options
+    ///
+    /// If `self` is `Some((a, b))` this method returns `(Some(a), Some(b))`.
+    /// Otherwise, `(None, None)` is returned.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(unzip_option)]
+    ///
+    /// let x = Some((1, "hi"));
+    /// let y = None::<(u8, u32)>;
+    ///
+    /// assert_eq!(x.unzip(), (Some(1), Some("hi")));
+    /// assert_eq!(y.unzip(), (None, None));
+    /// ```
+    #[inline]
+    #[unstable(feature = "unzip_option", issue = "87800", reason = "recently added")]
+    pub const fn unzip(self) -> (Option<T>, Option<U>) {
+        match self {
+            Some((a, b)) => (Some(a), Some(b)),
+            None => (None, None),
+        }
+    }
+}
+
 impl<T: Copy> Option<&T> {
     /// Maps an `Option<&T>` to an `Option<T>` by copying the contents of the
     /// option.
diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs
index c7756a503c3e9..13f483f19b770 100644
--- a/library/core/tests/lib.rs
+++ b/library/core/tests/lib.rs
@@ -13,6 +13,8 @@
 #![feature(const_ptr_read)]
 #![feature(const_ptr_write)]
 #![feature(const_ptr_offset)]
+#![feature(const_trait_impl)]
+#![feature(const_num_from_num)]
 #![feature(core_intrinsics)]
 #![feature(core_private_bignum)]
 #![feature(core_private_diy_float)]
@@ -66,6 +68,7 @@
 #![feature(slice_group_by)]
 #![feature(trusted_random_access)]
 #![feature(unsize)]
+#![feature(unzip_option)]
 #![deny(unsafe_op_in_unsafe_fn)]
 
 extern crate test;
diff --git a/library/core/tests/num/const_from.rs b/library/core/tests/num/const_from.rs
new file mode 100644
index 0000000000000..aca18ef39de1a
--- /dev/null
+++ b/library/core/tests/num/const_from.rs
@@ -0,0 +1,25 @@
+#[test]
+fn from() {
+    use core::convert::TryFrom;
+    use core::num::TryFromIntError;
+
+    // From
+    const FROM: i64 = i64::from(1i32);
+    assert_eq!(FROM, 1i64);
+
+    // From int to float
+    const FROM_F64: f64 = f64::from(42u8);
+    assert_eq!(FROM_F64, 42f64);
+
+    // Upper bounded
+    const U8_FROM_U16: Result<u8, TryFromIntError> = u8::try_from(1u16);
+    assert_eq!(U8_FROM_U16, Ok(1u8));
+
+    // Both bounded
+    const I8_FROM_I16: Result<i8, TryFromIntError> = i8::try_from(1i16);
+    assert_eq!(I8_FROM_I16, Ok(1i8));
+
+    // Lower bounded
+    const I16_FROM_U16: Result<i16, TryFromIntError> = i16::try_from(1u16);
+    assert_eq!(I16_FROM_U16, Ok(1i16));
+}
diff --git a/library/core/tests/num/mod.rs b/library/core/tests/num/mod.rs
index 76e838cf6bfbd..37b5e9127d5b0 100644
--- a/library/core/tests/num/mod.rs
+++ b/library/core/tests/num/mod.rs
@@ -27,6 +27,8 @@ mod u64;
 mod u8;
 
 mod bignum;
+
+mod const_from;
 mod dec2flt;
 mod flt2dec;
 mod int_log;
diff --git a/library/core/tests/option.rs b/library/core/tests/option.rs
index 88ea15a3b33fa..cd8fdebe36a05 100644
--- a/library/core/tests/option.rs
+++ b/library/core/tests/option.rs
@@ -399,7 +399,7 @@ fn test_unwrap_drop() {
 }
 
 #[test]
-pub fn option_ext() {
+fn option_ext() {
     let thing = "{{ f }}";
     let f = thing.find("{{");
 
@@ -407,3 +407,35 @@ pub fn option_ext() {
         println!("None!");
     }
 }
+
+#[test]
+fn zip_options() {
+    let x = Some(10);
+    let y = Some("foo");
+    let z: Option<usize> = None;
+
+    assert_eq!(x.zip(y), Some((10, "foo")));
+    assert_eq!(x.zip(z), None);
+    assert_eq!(z.zip(x), None);
+}
+
+#[test]
+fn unzip_options() {
+    let x = Some((10, "foo"));
+    let y = None::<(bool, i32)>;
+
+    assert_eq!(x.unzip(), (Some(10), Some("foo")));
+    assert_eq!(y.unzip(), (None, None));
+}
+
+#[test]
+fn zip_unzip_roundtrip() {
+    let x = Some(10);
+    let y = Some("foo");
+
+    let z = x.zip(y);
+    assert_eq!(z, Some((10, "foo")));
+
+    let a = z.unzip();
+    assert_eq!(a, (x, y));
+}
diff --git a/library/core/tests/slice.rs b/library/core/tests/slice.rs
index 240b894057c3e..43e2af3eb18d2 100644
--- a/library/core/tests/slice.rs
+++ b/library/core/tests/slice.rs
@@ -739,6 +739,10 @@ fn test_array_windows_count() {
     let v3: &[i32] = &[];
     let c3 = v3.array_windows::<2>();
     assert_eq!(c3.count(), 0);
+
+    let v4: &[()] = &[(); usize::MAX];
+    let c4 = v4.array_windows::<1>();
+    assert_eq!(c4.count(), usize::MAX);
 }
 
 #[test]
@@ -1050,6 +1054,10 @@ fn test_windows_count() {
     let v3: &[i32] = &[];
     let c3 = v3.windows(2);
     assert_eq!(c3.count(), 0);
+
+    let v4 = &[(); usize::MAX];
+    let c4 = v4.windows(1);
+    assert_eq!(c4.count(), usize::MAX);
 }
 
 #[test]
diff --git a/library/std/src/thread/mod.rs b/library/std/src/thread/mod.rs
index 36e1d502019b7..f44df845bf4dd 100644
--- a/library/std/src/thread/mod.rs
+++ b/library/std/src/thread/mod.rs
@@ -28,7 +28,7 @@
 //! When the main thread of a Rust program terminates, the entire program shuts
 //! down, even if other threads are still running. However, this module provides
 //! convenient facilities for automatically waiting for the termination of a
-//! child thread (i.e., join).
+//! thread (i.e., join).
 //!
 //! ## Spawning a thread
 //!
@@ -42,38 +42,43 @@
 //! });
 //! ```
 //!
-//! In this example, the spawned thread is "detached" from the current
-//! thread. This means that it can outlive its parent (the thread that spawned
-//! it), unless this parent is the main thread.
+//! In this example, the spawned thread is "detached," which means that there is
+//! no way for the program to learn when the spawned thread completes or otherwise
+//! terminates.
 //!
-//! The parent thread can also wait on the completion of the child
-//! thread; a call to [`spawn`] produces a [`JoinHandle`], which provides
-//! a `join` method for waiting:
+//! To learn when a thread completes, it is necessary to capture the [`JoinHandle`]
+//! object that is returned by the call to [`spawn`], which provides
+//! a `join` method that allows the caller to wait for the completion of the
+//! spawned thread:
 //!
 //! ```rust
 //! use std::thread;
 //!
-//! let child = thread::spawn(move || {
+//! let thread_join_handle = thread::spawn(move || {
 //!     // some work here
 //! });
 //! // some work here
-//! let res = child.join();
+//! let res = thread_join_handle.join();
 //! ```
 //!
 //! The [`join`] method returns a [`thread::Result`] containing [`Ok`] of the final
-//! value produced by the child thread, or [`Err`] of the value given to
-//! a call to [`panic!`] if the child panicked.
+//! value produced by the spawned thread, or [`Err`] of the value given to
+//! a call to [`panic!`] if the thread panicked.
+//!
+//! Note that there is no parent/child relationship between a thread that spawns a
+//! new thread and the thread being spawned.  In particular, the spawned thread may or
+//! may not outlive the spawning thread, unless the spawning thread is the main thread.
 //!
 //! ## Configuring threads
 //!
 //! A new thread can be configured before it is spawned via the [`Builder`] type,
-//! which currently allows you to set the name and stack size for the child thread:
+//! which currently allows you to set the name and stack size for the thread:
 //!
 //! ```rust
 //! # #![allow(unused_must_use)]
 //! use std::thread;
 //!
-//! thread::Builder::new().name("child1".to_string()).spawn(move || {
+//! thread::Builder::new().name("thread1".to_string()).spawn(move || {
 //!     println!("Hello, world!");
 //! });
 //! ```
@@ -344,7 +349,7 @@ impl Builder {
     /// The spawned thread may outlive the caller (unless the caller thread
     /// is the main thread; the whole process is terminated when the main
     /// thread finishes). The join handle can be used to block on
-    /// termination of the child thread, including recovering its panics.
+    /// termination of the spawned thread, including recovering its panics.
     ///
     /// For a more complete documentation see [`thread::spawn`][`spawn`].
     ///
@@ -389,7 +394,7 @@ impl Builder {
     /// The spawned thread may outlive the caller (unless the caller thread
     /// is the main thread; the whole process is terminated when the main
     /// thread finishes). The join handle can be used to block on
-    /// termination of the child thread, including recovering its panics.
+    /// termination of the spawned thread, including recovering its panics.
     ///
     /// This method is identical to [`thread::Builder::spawn`][`Builder::spawn`],
     /// except for the relaxed lifetime bounds, which render it unsafe.
@@ -516,15 +521,16 @@ impl Builder {
 
 /// Spawns a new thread, returning a [`JoinHandle`] for it.
 ///
-/// The join handle will implicitly *detach* the child thread upon being
-/// dropped. In this case, the child thread may outlive the parent (unless
-/// the parent thread is the main thread; the whole process is terminated when
-/// the main thread finishes). Additionally, the join handle provides a [`join`]
-/// method that can be used to join the child thread. If the child thread
-/// panics, [`join`] will return an [`Err`] containing the argument given to
-/// [`panic!`].
+/// The join handle provides a [`join`] method that can be used to join the spawned
+/// thread. If the spawned thread panics, [`join`] will return an [`Err`] containing
+/// the argument given to [`panic!`].
+///
+/// If the join handle is dropped, the spawned thread will implicitly be *detached*.
+/// In this case, the spawned thread may no longer be joined.
+/// (It is the responsibility of the program to either eventually join threads it
+/// creates or detach them; otherwise, a resource leak will result.)
 ///
-/// This will create a thread using default parameters of [`Builder`], if you
+/// This call will create a thread using default parameters of [`Builder`], if you
 /// want to specify the stack size or the name of the thread, use this API
 /// instead.
 ///
@@ -533,8 +539,8 @@ impl Builder {
 ///
 /// - The `'static` constraint means that the closure and its return value
 ///   must have a lifetime of the whole program execution. The reason for this
-///   is that threads can `detach` and outlive the lifetime they have been
-///   created in.
+///   is that threads can outlive the lifetime they have been created in.
+///
 ///   Indeed if the thread, and by extension its return value, can outlive their
 ///   caller, we need to make sure that they will be valid afterwards, and since
 ///   we *can't* know when it will return we need to have them valid as long as
@@ -1236,10 +1242,10 @@ impl fmt::Debug for Thread {
 #[stable(feature = "rust1", since = "1.0.0")]
 pub type Result<T> = crate::result::Result<T, Box<dyn Any + Send + 'static>>;
 
-// This packet is used to communicate the return value between the child thread
-// and the parent thread. Memory is shared through the `Arc` within and there's
+// This packet is used to communicate the return value between the spawned thread
+// and the rest of the program. Memory is shared through the `Arc` within and there's
 // no need for a mutex here because synchronization happens with `join()` (the
-// parent thread never reads this packet until the child has exited).
+// caller will never read this packet until the thread has exited).
 //
 // This packet itself is then stored into a `JoinInner` which in turns is placed
 // in `JoinHandle` and `JoinGuard`. Due to the usage of `UnsafeCell` we need to
@@ -1303,7 +1309,7 @@ impl<T> JoinInner<T> {
 /// }).unwrap();
 /// ```
 ///
-/// Child being detached and outliving its parent:
+/// A thread being detached and outliving the thread that spawned it:
 ///
 /// ```no_run
 /// use std::thread;
@@ -1361,12 +1367,15 @@ impl<T> JoinHandle<T> {
 
     /// Waits for the associated thread to finish.
     ///
+    /// This function will return immediately if the associated thread has already finished.
+    ///
     /// In terms of [atomic memory orderings],  the completion of the associated
     /// thread synchronizes with this function returning. In other words, all
-    /// operations performed by that thread are ordered before all
+    /// operations performed by that thread [happen
+    /// before](https://doc.rust-lang.org/nomicon/atomics.html#data-accesses) all
     /// operations that happen after `join` returns.
     ///
-    /// If the child thread panics, [`Err`] is returned with the parameter given
+    /// If the associated thread panics, [`Err`] is returned with the parameter given
     /// to [`panic!`].
     ///
     /// [`Err`]: crate::result::Result::Err
diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md
index b5d20a6a4cd81..5718a18393f9c 100644
--- a/src/doc/rustc/src/platform-support.md
+++ b/src/doc/rustc/src/platform-support.md
@@ -115,6 +115,7 @@ The `std` column in the table below has the following meanings:
 target | std | notes
 -------|:---:|-------
 `aarch64-apple-ios` | ✓ | ARM64 iOS
+[`aarch64-apple-ios-sim`](platform-support/aarch64-apple-ios-sim.md) | ✓ | Apple iOS Simulator on ARM64
 `aarch64-fuchsia` | ✓ | ARM64 Fuchsia
 `aarch64-linux-android` | ✓ | ARM64 Android
 `aarch64-unknown-none-softfloat` | * | Bare ARM64, softfloat
@@ -165,7 +166,6 @@ target | std | notes
 `wasm32-unknown-unknown` | ✓ | WebAssembly
 `wasm32-wasi` | ✓ | WebAssembly with WASI
 `x86_64-apple-ios` | ✓ | 64-bit x86 iOS
-[`aarch64-apple-ios-sim`](platform-support/aarch64-apple-ios-sim.md) | ✓ |  | Apple iOS Simulator on ARM64
 `x86_64-fortanix-unknown-sgx` | ✓ | [Fortanix ABI] for 64-bit Intel SGX
 `x86_64-fuchsia` | ✓ | 64-bit Fuchsia
 `x86_64-linux-android` | ✓ | 64-bit x86 Android
diff --git a/src/doc/rustdoc/src/documentation-tests.md b/src/doc/rustdoc/src/documentation-tests.md
index cb7b85655b5a8..70900a0bab942 100644
--- a/src/doc/rustdoc/src/documentation-tests.md
+++ b/src/doc/rustdoc/src/documentation-tests.md
@@ -297,9 +297,14 @@ we can add the `#[macro_use]` attribute. Second, we’ll need to add our own
 
 ## Attributes
 
-There are a few annotations that are useful to help `rustdoc` do the right
+Code blocks can be annotated with attributes that help `rustdoc` do the right
 thing when testing your code:
 
+The `ignore` attribute tells Rust to ignore your code. This is almost never
+what you want as it's the most generic. Instead, consider annotating it
+with `text` if it's not code or using `#`s to get a working example that
+only shows the part you care about.
+
 ```rust
 /// ```ignore
 /// fn foo() {
@@ -307,10 +312,8 @@ thing when testing your code:
 # fn foo() {}
 ```
 
-The `ignore` directive tells Rust to ignore your code. This is almost never
-what you want, as it's the most generic. Instead, consider annotating it
-with `text` if it's not code, or using `#`s to get a working example that
-only shows the part you care about.
+`should_panic` tells `rustdoc` that the code should compile correctly but
+panic during execution. If the code doesn't panic, the test will fail.
 
 ```rust
 /// ```should_panic
@@ -319,8 +322,10 @@ only shows the part you care about.
 # fn foo() {}
 ```
 
-`should_panic` tells `rustdoc` that the code should compile correctly, but
-not actually pass as a test.
+The `no_run` attribute will compile your code but not run it. This is
+important for examples such as "Here's how to retrieve a web page,"
+which you would want to ensure compiles, but might be run in a test
+environment that has no network access.
 
 ```rust
 /// ```no_run
@@ -331,24 +336,24 @@ not actually pass as a test.
 # fn foo() {}
 ```
 
-The `no_run` attribute will compile your code, but not run it. This is
-important for examples such as "Here's how to retrieve a web page,"
-which you would want to ensure compiles, but might be run in a test
-environment that has no network access.
+`compile_fail` tells `rustdoc` that the compilation should fail. If it
+compiles, then the test will fail. However, please note that code failing
+with the current Rust release may work in a future release, as new features
+are added.
 
-```text
+```rust
 /// ```compile_fail
 /// let x = 5;
 /// x += 2; // shouldn't compile!
 /// ```
+# fn foo() {}
 ```
 
-`compile_fail` tells `rustdoc` that the compilation should fail. If it
-compiles, then the test will fail. However please note that code failing
-with the current Rust release may work in a future release, as new features
-are added.
+`edition2018` tells `rustdoc` that the code sample should be compiled using
+the 2018 edition of Rust. Similarly, you can specify `edition2015` to compile
+the code with the 2015 edition.
 
-```text
+```rust
 /// Only runs on the 2018 edition.
 ///
 /// ```edition2018
@@ -358,12 +363,9 @@ are added.
 ///         + "3".parse::<i32>()?
 /// };
 /// ```
+# fn foo() {}
 ```
 
-`edition2018` tells `rustdoc` that the code sample should be compiled using
-the 2018 edition of Rust. Similarly, you can specify `edition2015` to compile
-the code with the 2015 edition.
-
 ## Syntax reference
 
 The *exact* syntax for code blocks, including the edge cases, can be found
@@ -385,7 +387,7 @@ section.
 
 However, it's preferable to use fenced code blocks over indented code blocks.
 Not only are fenced code blocks considered more idiomatic for Rust code,
-but there is no way to use directives such as `ignore` or `should_panic` with
+but there is no way to use attributes such as `ignore` or `should_panic` with
 indented code blocks.
 
 ### Include items only when collecting doctests
diff --git a/src/librustdoc/html/static/css/themes/ayu.css b/src/librustdoc/html/static/css/themes/ayu.css
index 849924ea5501e..8dd7b2b3edc40 100644
--- a/src/librustdoc/html/static/css/themes/ayu.css
+++ b/src/librustdoc/html/static/css/themes/ayu.css
@@ -37,7 +37,7 @@ h4 {
 .docblock code {
 	color: #ffb454;
 }
-h3 > code, h4 > code, h5 > code {
+.code-header {
 	color: #e6e1cf;
 }
 pre > code {
diff --git a/src/test/ui/associated-consts/associated-const-ambiguity-report.stderr b/src/test/ui/associated-consts/associated-const-ambiguity-report.stderr
index c5e32afbbce40..fc94ef2ff8872 100644
--- a/src/test/ui/associated-consts/associated-const-ambiguity-report.stderr
+++ b/src/test/ui/associated-consts/associated-const-ambiguity-report.stderr
@@ -17,11 +17,11 @@ LL |     const ID: i32 = 3;
 help: disambiguate the associated constant for candidate #1
    |
 LL | const X: i32 = Foo::ID;
-   |                ^^^^^^^
+   |                ^^^^^
 help: disambiguate the associated constant for candidate #2
    |
 LL | const X: i32 = Bar::ID;
-   |                ^^^^^^^
+   |                ^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/const-generics/enum-variants.rs b/src/test/ui/const-generics/enum-variants.rs
new file mode 100644
index 0000000000000..5c6c4a8efac15
--- /dev/null
+++ b/src/test/ui/const-generics/enum-variants.rs
@@ -0,0 +1,24 @@
+// check-pass
+enum Foo<const N: usize> {
+    Variant,
+    Variant2(),
+    Variant3{},
+}
+
+struct Bar<const N: usize>;
+struct Bar2<const N: usize>();
+struct Bar3<const N: usize> {}
+
+fn main() {
+    let _ = Foo::Variant::<1>;
+    let _ = Foo::Variant2::<1>();
+    let _ = Foo::Variant3::<1>{};
+
+    let _ = Foo::<1>::Variant;
+    let _ = Foo::<1>::Variant2();
+    let _ = Foo::<1>::Variant3{};
+
+    let _ = Bar::<1>;
+    let _ = Bar2::<1>();
+    let _ = Bar3::<1>{};
+}
diff --git a/src/test/ui/error-codes/E0034.stderr b/src/test/ui/error-codes/E0034.stderr
index 471512ca8f72c..55119857d8f83 100644
--- a/src/test/ui/error-codes/E0034.stderr
+++ b/src/test/ui/error-codes/E0034.stderr
@@ -17,11 +17,11 @@ LL |     fn foo() {}
 help: disambiguate the associated function for candidate #1
    |
 LL |     Trait1::foo()
-   |     ^^^^^^^^^^^
+   |     ^^^^^^^^
 help: disambiguate the associated function for candidate #2
    |
 LL |     Trait2::foo()
-   |     ^^^^^^^^^^^
+   |     ^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-18446.stderr b/src/test/ui/issues/issue-18446.stderr
index 11c8cfdcf66a5..33cf76d777bb6 100644
--- a/src/test/ui/issues/issue-18446.stderr
+++ b/src/test/ui/issues/issue-18446.stderr
@@ -2,10 +2,7 @@ error[E0034]: multiple applicable items in scope
   --> $DIR/issue-18446.rs:18:7
    |
 LL |     x.foo();
-   |     --^^^--
-   |     | |
-   |     | multiple `foo` found
-   |     help: disambiguate the associated function for candidate #2: `T::foo(&x)`
+   |       ^^^ multiple `foo` found
    |
 note: candidate #1 is defined in an impl for the type `(dyn T + 'a)`
   --> $DIR/issue-18446.rs:9:5
@@ -17,6 +14,10 @@ note: candidate #2 is defined in the trait `T`
    |
 LL |     fn foo(&self);
    |     ^^^^^^^^^^^^^^
+help: disambiguate the associated function for candidate #2
+   |
+LL |     T::foo(&x);
+   |     ^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/methods/method-ambig-two-traits-from-impls2.stderr b/src/test/ui/methods/method-ambig-two-traits-from-impls2.stderr
index 85b3964788590..7bfb8baa0c643 100644
--- a/src/test/ui/methods/method-ambig-two-traits-from-impls2.stderr
+++ b/src/test/ui/methods/method-ambig-two-traits-from-impls2.stderr
@@ -17,11 +17,11 @@ LL |     fn foo() {}
 help: disambiguate the associated function for candidate #1
    |
 LL |     A::foo();
-   |     ^^^^^^
+   |     ^^^
 help: disambiguate the associated function for candidate #2
    |
 LL |     B::foo();
-   |     ^^^^^^
+   |     ^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/span/issue-7575.stderr b/src/test/ui/span/issue-7575.stderr
index 16a1ac6d71814..f789441378fe4 100644
--- a/src/test/ui/span/issue-7575.stderr
+++ b/src/test/ui/span/issue-7575.stderr
@@ -61,10 +61,7 @@ error[E0599]: no method named `is_str` found for type parameter `T` in the curre
   --> $DIR/issue-7575.rs:70:7
    |
 LL |     t.is_str()
-   |     --^^^^^^--
-   |     | |
-   |     | this is an associated function, not a method
-   |     help: disambiguate the associated function for the candidate: `ManyImplTrait::is_str(t)`
+   |       ^^^^^^ this is an associated function, not a method
    |
    = note: found the following associated functions; to be used as methods, functions must have a `self` parameter
 note: the candidate is defined in the trait `ManyImplTrait`
@@ -73,6 +70,10 @@ note: the candidate is defined in the trait `ManyImplTrait`
 LL |     fn is_str() -> bool {
    |     ^^^^^^^^^^^^^^^^^^^
    = help: items from traits can only be used if the type parameter is bounded by the trait
+help: disambiguate the associated function for the candidate
+   |
+LL |     ManyImplTrait::is_str(t)
+   |
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/typeck/issue-87872-missing-inaccessible-field-literal.rs b/src/test/ui/typeck/issue-87872-missing-inaccessible-field-literal.rs
new file mode 100644
index 0000000000000..3176144133760
--- /dev/null
+++ b/src/test/ui/typeck/issue-87872-missing-inaccessible-field-literal.rs
@@ -0,0 +1,11 @@
+pub mod foo {
+    pub struct Foo {
+        pub you_can_use_this_field: bool,
+        you_cant_use_this_field: bool,
+    }
+}
+
+fn main() {
+    foo::Foo {};
+    //~^ ERROR cannot construct `Foo` with struct literal syntax due to inaccessible fields
+}
diff --git a/src/test/ui/typeck/issue-87872-missing-inaccessible-field-literal.stderr b/src/test/ui/typeck/issue-87872-missing-inaccessible-field-literal.stderr
new file mode 100644
index 0000000000000..81b73c00e8600
--- /dev/null
+++ b/src/test/ui/typeck/issue-87872-missing-inaccessible-field-literal.stderr
@@ -0,0 +1,8 @@
+error: cannot construct `Foo` with struct literal syntax due to inaccessible fields
+  --> $DIR/issue-87872-missing-inaccessible-field-literal.rs:9:5
+   |
+LL |     foo::Foo {};
+   |     ^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/typeck/issue-87872-missing-inaccessible-field-pattern.rs b/src/test/ui/typeck/issue-87872-missing-inaccessible-field-pattern.rs
new file mode 100644
index 0000000000000..d28e17559d879
--- /dev/null
+++ b/src/test/ui/typeck/issue-87872-missing-inaccessible-field-pattern.rs
@@ -0,0 +1,11 @@
+#![allow(dead_code, unused_variables)]
+
+pub mod foo {
+    #[derive(Default)]
+    pub struct Foo { pub visible: bool, invisible: bool, }
+}
+
+fn main() {
+    let foo::Foo {} = foo::Foo::default();
+    //~^ ERROR pattern does not mention field `visible` and inaccessible fields
+}
diff --git a/src/test/ui/typeck/issue-87872-missing-inaccessible-field-pattern.stderr b/src/test/ui/typeck/issue-87872-missing-inaccessible-field-pattern.stderr
new file mode 100644
index 0000000000000..51b8e39b101a3
--- /dev/null
+++ b/src/test/ui/typeck/issue-87872-missing-inaccessible-field-pattern.stderr
@@ -0,0 +1,18 @@
+error[E0027]: pattern does not mention field `visible` and inaccessible fields
+  --> $DIR/issue-87872-missing-inaccessible-field-pattern.rs:9:9
+   |
+LL |     let foo::Foo {} = foo::Foo::default();
+   |         ^^^^^^^^^^^ missing field `visible` and inaccessible fields
+   |
+help: include the missing field in the pattern and ignore the inaccessible fields
+   |
+LL |     let foo::Foo { visible, .. } = foo::Foo::default();
+   |                  ^^^^^^^^^^^^^^^
+help: if you don't care about this missing field, you can explicitly ignore it
+   |
+LL |     let foo::Foo { .. } = foo::Foo::default();
+   |                  ^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0027`.
diff --git a/src/test/ui/wf/hir-wf-check-erase-regions.rs b/src/test/ui/wf/hir-wf-check-erase-regions.rs
new file mode 100644
index 0000000000000..bb398e5698a80
--- /dev/null
+++ b/src/test/ui/wf/hir-wf-check-erase-regions.rs
@@ -0,0 +1,14 @@
+// Regression test for #87549.
+// compile-flags: -C incremental=tmp/wf/hir-wf-check-erase-regions
+
+pub struct Table<T, const N: usize>([Option<T>; N]);
+
+impl<'a, T, const N: usize> IntoIterator for &'a Table<T, N> {
+    type IntoIter = std::iter::Flatten<std::slice::Iter<'a, T>>; //~ ERROR `&T` is not an iterator
+    type Item = &'a T;
+
+    fn into_iter(self) -> Self::IntoIter { //~ ERROR `&T` is not an iterator
+        unimplemented!()
+    }
+}
+fn main() {}
diff --git a/src/test/ui/wf/hir-wf-check-erase-regions.stderr b/src/test/ui/wf/hir-wf-check-erase-regions.stderr
new file mode 100644
index 0000000000000..a704754e82a92
--- /dev/null
+++ b/src/test/ui/wf/hir-wf-check-erase-regions.stderr
@@ -0,0 +1,31 @@
+error[E0277]: `&T` is not an iterator
+  --> $DIR/hir-wf-check-erase-regions.rs:7:5
+   |
+LL |     type IntoIter = std::iter::Flatten<std::slice::Iter<'a, T>>;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `&T` is not an iterator
+   |
+  ::: $SRC_DIR/core/src/iter/adapters/flatten.rs:LL:COL
+   |
+LL | pub struct Flatten<I: Iterator<Item: IntoIterator>> {
+   |                                      ------------ required by this bound in `Flatten`
+   |
+   = help: the trait `Iterator` is not implemented for `&T`
+   = note: required because of the requirements on the impl of `IntoIterator` for `&T`
+
+error[E0277]: `&T` is not an iterator
+  --> $DIR/hir-wf-check-erase-regions.rs:10:27
+   |
+LL |     fn into_iter(self) -> Self::IntoIter {
+   |                           ^^^^^^^^^^^^^^ `&T` is not an iterator
+   |
+  ::: $SRC_DIR/core/src/iter/adapters/flatten.rs:LL:COL
+   |
+LL | pub struct Flatten<I: Iterator<Item: IntoIterator>> {
+   |                                      ------------ required by this bound in `Flatten`
+   |
+   = help: the trait `Iterator` is not implemented for `&T`
+   = note: required because of the requirements on the impl of `IntoIterator` for `&T`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0277`.