about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2021-12-15 09:31:59 +0000
committerbors <bors@rust-lang.org>2021-12-15 09:31:59 +0000
commit3ee016ae4d4c6ee4a34faa2eb7fdae2ffa7c9b46 (patch)
treefeda053596eb3645cbba8cb313676bdcd7024fee
parentdf89fd2063aaa060c72c81254db0b930ff379e9a (diff)
parent6c6cfa87c08a7bfb6b27bb01b9337aa3178716a5 (diff)
downloadrust-3ee016ae4d4c6ee4a34faa2eb7fdae2ffa7c9b46.tar.gz
rust-3ee016ae4d4c6ee4a34faa2eb7fdae2ffa7c9b46.zip
Auto merge of #91959 - matthiaskrgr:rollup-rhajuvw, r=matthiaskrgr
Rollup of 7 pull requests

Successful merges:

 - #90521 (Stabilize `destructuring_assignment`)
 - #91479 (Add `[T]::as_simd(_mut)`)
 - #91584 (Improve code for rustdoc-gui tester)
 - #91886 (core: minor `Option` doc correction)
 - #91888 (Handle unordered const/ty generics for object lifetime defaults)
 - #91905 (Fix source code page sidebar on mobile)
 - #91906 (Removed `in_band_lifetimes` from `library\proc_macro`)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
-rw-r--r--compiler/rustc_ast_lowering/src/expr.rs19
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs3
-rw-r--r--compiler/rustc_ast_passes/src/feature_gate.rs5
-rw-r--r--compiler/rustc_expand/src/lib.rs2
-rw-r--r--compiler/rustc_feature/src/accepted.rs2
-rw-r--r--compiler/rustc_feature/src/active.rs2
-rw-r--r--compiler/rustc_hir/src/hir.rs14
-rw-r--r--compiler/rustc_parse/src/parser/expr.rs2
-rw-r--r--compiler/rustc_resolve/src/late/lifetimes.rs9
-rw-r--r--compiler/rustc_typeck/src/check/expr.rs5
-rw-r--r--library/alloc/src/lib.rs2
-rw-r--r--library/core/src/option.rs4
-rw-r--r--library/core/src/slice/mod.rs119
-rw-r--r--library/proc_macro/src/bridge/client.rs4
-rw-r--r--library/proc_macro/src/bridge/mod.rs8
-rw-r--r--library/proc_macro/src/bridge/rpc.rs8
-rw-r--r--library/proc_macro/src/lib.rs1
-rw-r--r--src/librustdoc/html/static/css/rustdoc.css12
-rw-r--r--src/test/rustdoc-gui/sidebar-source-code.goml32
-rw-r--r--src/test/ui/associated-types/associated-type-destructuring-assignment.rs1
-rw-r--r--src/test/ui/const-generics/defaults/auxiliary/trait_object_lt_defaults_lib.rs1
-rw-r--r--src/test/ui/const-generics/defaults/trait_object_lt_defaults.rs24
-rw-r--r--src/test/ui/cross/cross-file-errors/main.rs1
-rw-r--r--src/test/ui/cross/cross-file-errors/main.stderr18
-rw-r--r--src/test/ui/destructuring-assignment/bad-expr-lhs.rs7
-rw-r--r--src/test/ui/destructuring-assignment/bad-expr-lhs.stderr28
-rw-r--r--src/test/ui/destructuring-assignment/default-match-bindings-forbidden.rs2
-rw-r--r--src/test/ui/destructuring-assignment/default-match-bindings-forbidden.stderr2
-rw-r--r--src/test/ui/destructuring-assignment/drop-order.rs1
-rw-r--r--src/test/ui/destructuring-assignment/nested_destructure.rs2
-rw-r--r--src/test/ui/destructuring-assignment/note-unsupported.rs11
-rw-r--r--src/test/ui/destructuring-assignment/note-unsupported.stderr59
-rw-r--r--src/test/ui/destructuring-assignment/slice_destructure.rs2
-rw-r--r--src/test/ui/destructuring-assignment/slice_destructure_fail.rs2
-rw-r--r--src/test/ui/destructuring-assignment/slice_destructure_fail.stderr6
-rw-r--r--src/test/ui/destructuring-assignment/struct_destructure.rs1
-rw-r--r--src/test/ui/destructuring-assignment/struct_destructure_fail.rs1
-rw-r--r--src/test/ui/destructuring-assignment/struct_destructure_fail.stderr10
-rw-r--r--src/test/ui/destructuring-assignment/tuple_destructure.rs2
-rw-r--r--src/test/ui/destructuring-assignment/tuple_destructure_fail.rs2
-rw-r--r--src/test/ui/destructuring-assignment/tuple_destructure_fail.stderr8
-rw-r--r--src/test/ui/destructuring-assignment/tuple_struct_destructure.rs2
-rw-r--r--src/test/ui/destructuring-assignment/tuple_struct_destructure_fail.rs2
-rw-r--r--src/test/ui/destructuring-assignment/tuple_struct_destructure_fail.stderr18
-rw-r--r--src/test/ui/destructuring-assignment/underscore-range-expr-gating.rs10
-rw-r--r--src/test/ui/destructuring-assignment/underscore-range-expr-gating.stderr21
-rw-r--r--src/test/ui/destructuring-assignment/warn-unused-duplication.rs2
-rw-r--r--src/test/ui/destructuring-assignment/warn-unused-duplication.stderr4
-rw-r--r--src/test/ui/feature-gates/feature-gate-destructuring_assignment.rs4
-rw-r--r--src/test/ui/feature-gates/feature-gate-destructuring_assignment.stderr14
-rw-r--r--src/test/ui/issues/issue-77218/issue-77218-2.fixed1
-rw-r--r--src/test/ui/issues/issue-77218/issue-77218-2.rs1
-rw-r--r--src/test/ui/issues/issue-77218/issue-77218-2.stderr2
-rw-r--r--src/test/ui/issues/issue-77218/issue-77218.fixed3
-rw-r--r--src/test/ui/issues/issue-77218/issue-77218.rs3
-rw-r--r--src/test/ui/issues/issue-77218/issue-77218.stderr16
-rw-r--r--src/test/ui/suggestions/fn-or-tuple-struct-with-underscore-args.rs6
-rw-r--r--src/test/ui/suggestions/fn-or-tuple-struct-with-underscore-args.stderr65
-rw-r--r--src/test/ui/suggestions/if-let-typo.rs5
-rw-r--r--src/test/ui/suggestions/if-let-typo.stderr47
-rw-r--r--src/test/ui/weird-exprs.rs1
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-6250.stderr15
-rw-r--r--src/tools/rustdoc-gui/tester.js10
63 files changed, 272 insertions, 424 deletions
diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs
index 75a45a437e7..be67fe72127 100644
--- a/compiler/rustc_ast_lowering/src/expr.rs
+++ b/compiler/rustc_ast_lowering/src/expr.rs
@@ -9,7 +9,6 @@ use rustc_errors::struct_span_err;
 use rustc_hir as hir;
 use rustc_hir::def::Res;
 use rustc_hir::definitions::DefPathData;
-use rustc_session::parse::feature_err;
 use rustc_span::hygiene::ExpnId;
 use rustc_span::source_map::{respan, DesugaringKind, Span, Spanned};
 use rustc_span::symbol::{sym, Ident, Symbol};
@@ -962,24 +961,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
                 self.lower_span(eq_sign_span),
             );
         }
-        if !self.sess.features_untracked().destructuring_assignment {
-            let mut err = feature_err(
-                &self.sess.parse_sess,
-                sym::destructuring_assignment,
-                eq_sign_span,
-                "destructuring assignments are unstable",
-            );
-            err.span_label(lhs.span, "cannot assign to this expression");
-            if self.is_in_loop_condition {
-                err.span_suggestion_verbose(
-                    lhs.span.shrink_to_lo(),
-                    "you might have meant to use pattern destructuring",
-                    "let ".to_string(),
-                    rustc_errors::Applicability::MachineApplicable,
-                );
-            }
-            err.emit();
-        }
 
         let mut assignments = vec![];
 
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index fee2e7636ea..0077dec889d 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -52,7 +52,7 @@ use rustc_hir::def::{DefKind, Namespace, PartialRes, PerNS, Res};
 use rustc_hir::def_id::{DefId, DefPathHash, LocalDefId, CRATE_DEF_ID};
 use rustc_hir::definitions::{DefKey, DefPathData, Definitions};
 use rustc_hir::intravisit;
-use rustc_hir::{ConstArg, GenericArg, InferKind, ParamName};
+use rustc_hir::{ConstArg, GenericArg, ParamName};
 use rustc_index::vec::{Idx, IndexVec};
 use rustc_query_system::ich::StableHashingContext;
 use rustc_session::lint::builtin::BARE_TRAIT_OBJECTS;
@@ -1113,7 +1113,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                         return GenericArg::Infer(hir::InferArg {
                             hir_id: self.lower_node_id(ty.id),
                             span: self.lower_span(ty.span),
-                            kind: InferKind::Type,
                         });
                     }
                     // We parse const arguments as path types as we cannot distinguish them during
diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs
index 1d1539152be..975874b6b2c 100644
--- a/compiler/rustc_ast_passes/src/feature_gate.rs
+++ b/compiler/rustc_ast_passes/src/feature_gate.rs
@@ -724,11 +724,6 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session) {
     gate_all!(half_open_range_patterns, "half-open range patterns are unstable");
     gate_all!(inline_const, "inline-const is experimental");
     gate_all!(inline_const_pat, "inline-const in pattern position is experimental");
-    if sess.parse_sess.span_diagnostic.err_count() == 0 {
-        // Errors for `destructuring_assignment` can get quite noisy, especially where `_` is
-        // involved, so we only emit errors where there are no other parsing errors.
-        gate_all!(destructuring_assignment, "destructuring assignments are unstable");
-    }
 
     // All uses of `gate_all!` below this point were added in #65742,
     // and subsequently disabled (with the non-early gating readded).
diff --git a/compiler/rustc_expand/src/lib.rs b/compiler/rustc_expand/src/lib.rs
index 60a62ac204c..47a64b457d0 100644
--- a/compiler/rustc_expand/src/lib.rs
+++ b/compiler/rustc_expand/src/lib.rs
@@ -1,6 +1,6 @@
 #![feature(crate_visibility_modifier)]
 #![feature(decl_macro)]
-#![feature(destructuring_assignment)]
+#![cfg_attr(bootstrap, feature(destructuring_assignment))]
 #![feature(if_let_guard)]
 #![feature(let_else)]
 #![feature(proc_macro_diagnostic)]
diff --git a/compiler/rustc_feature/src/accepted.rs b/compiler/rustc_feature/src/accepted.rs
index 87b08dc5264..32a9d081ed8 100644
--- a/compiler/rustc_feature/src/accepted.rs
+++ b/compiler/rustc_feature/src/accepted.rs
@@ -114,6 +114,8 @@ declare_features! (
     (accepted, default_type_params, "1.0.0", None, None),
     /// Allows `#[deprecated]` attribute.
     (accepted, deprecated, "1.9.0", Some(29935), None),
+    /// Allows the use of destructuring assignments.
+    (accepted, destructuring_assignment, "1.59.0", Some(71126), None),
     /// Allows `#[doc(alias = "...")]`.
     (accepted, doc_alias, "1.48.0", Some(50146), None),
     /// Allows `..` in tuple (struct) patterns.
diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs
index 22f6559d15f..ebd12d6ab4e 100644
--- a/compiler/rustc_feature/src/active.rs
+++ b/compiler/rustc_feature/src/active.rs
@@ -356,8 +356,6 @@ declare_features! (
     (active, default_type_parameter_fallback, "1.3.0", Some(27336), None),
     /// Allows `#[derive(Default)]` and `#[default]` on enums.
     (active, derive_default_enum, "1.56.0", Some(86985), None),
-    /// Allows the use of destructuring assignments.
-    (active, destructuring_assignment, "1.49.0", Some(71126), None),
     /// Tells rustdoc to automatically generate `#[doc(cfg(...))]`.
     (active, doc_auto_cfg, "1.58.0", Some(43781), None),
     /// Allows `#[doc(cfg(...))]`.
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index f044c187f39..e2358aac1e7 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -255,23 +255,9 @@ pub struct ConstArg {
     pub span: Span,
 }
 
-#[derive(Copy, Clone, Encodable, Debug, HashStable_Generic)]
-pub enum InferKind {
-    Const,
-    Type,
-}
-
-impl InferKind {
-    #[inline]
-    pub fn is_type(self) -> bool {
-        matches!(self, InferKind::Type)
-    }
-}
-
 #[derive(Encodable, Debug, HashStable_Generic)]
 pub struct InferArg {
     pub hir_id: HirId,
-    pub kind: InferKind,
     pub span: Span,
 }
 
diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs
index c62ebb271f4..ddb4f2dc25d 100644
--- a/compiler/rustc_parse/src/parser/expr.rs
+++ b/compiler/rustc_parse/src/parser/expr.rs
@@ -1297,7 +1297,6 @@ impl<'a> Parser<'a> {
         } else if self.eat_keyword(kw::Let) {
             self.parse_let_expr(attrs)
         } else if self.eat_keyword(kw::Underscore) {
-            self.sess.gated_spans.gate(sym::destructuring_assignment, self.prev_token.span);
             Ok(self.mk_expr(self.prev_token.span, ExprKind::Underscore, attrs))
         } else if !self.unclosed_delims.is_empty() && self.check(&token::Semi) {
             // Don't complain about bare semicolons after unclosed braces
@@ -2620,7 +2619,6 @@ impl<'a> Parser<'a> {
                 let exp_span = self.prev_token.span;
                 // We permit `.. }` on the left-hand side of a destructuring assignment.
                 if self.check(&token::CloseDelim(close_delim)) {
-                    self.sess.gated_spans.gate(sym::destructuring_assignment, self.prev_token.span);
                     base = ast::StructRest::Rest(self.prev_token.span.shrink_to_hi());
                     break;
                 }
diff --git a/compiler/rustc_resolve/src/late/lifetimes.rs b/compiler/rustc_resolve/src/late/lifetimes.rs
index c94c56df75b..05098defead 100644
--- a/compiler/rustc_resolve/src/late/lifetimes.rs
+++ b/compiler/rustc_resolve/src/late/lifetimes.rs
@@ -2541,8 +2541,8 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
                                 GenericParamDefKind::Type { object_lifetime_default, .. } => {
                                     Some(object_lifetime_default)
                                 }
-                                GenericParamDefKind::Lifetime
-                                | GenericParamDefKind::Const { .. } => None,
+                                GenericParamDefKind::Const { .. } => Some(Set1::Empty),
+                                GenericParamDefKind::Lifetime => None,
                             })
                             .collect()
                     })
@@ -2569,12 +2569,11 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
                 }
                 GenericArg::Const(ct) => {
                     self.visit_anon_const(&ct.value);
+                    i += 1;
                 }
                 GenericArg::Infer(inf) => {
                     self.visit_id(inf.hir_id);
-                    if inf.kind.is_type() {
-                        i += 1;
-                    }
+                    i += 1;
                 }
             }
         }
diff --git a/compiler/rustc_typeck/src/check/expr.rs b/compiler/rustc_typeck/src/check/expr.rs
index bc6ad3c9686..6a63feb09a1 100644
--- a/compiler/rustc_typeck/src/check/expr.rs
+++ b/compiler/rustc_typeck/src/check/expr.rs
@@ -878,11 +878,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         "let ".to_string(),
                         Applicability::MachineApplicable,
                     );
-                    if !self.sess().features_untracked().destructuring_assignment {
-                        // We already emit an E0658 with a suggestion for `while let`, this is
-                        // redundant output.
-                        err.delay_as_bug();
-                    }
                     break;
                 }
                 hir::Node::Item(_)
diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs
index e8a932835f6..600862c4224 100644
--- a/library/alloc/src/lib.rs
+++ b/library/alloc/src/lib.rs
@@ -136,7 +136,7 @@
 #![feature(cfg_target_has_atomic)]
 #![feature(const_fn_trait_bound)]
 #![feature(const_trait_impl)]
-#![feature(destructuring_assignment)]
+#![cfg_attr(bootstrap, feature(destructuring_assignment))]
 #![feature(dropck_eyepatch)]
 #![feature(exclusive_range_pattern)]
 #![feature(fundamental)]
diff --git a/library/core/src/option.rs b/library/core/src/option.rs
index 381e2d6eed3..015366ed490 100644
--- a/library/core/src/option.rs
+++ b/library/core/src/option.rs
@@ -512,11 +512,11 @@ use crate::{
 #[rustc_diagnostic_item = "Option"]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub enum Option<T> {
-    /// No value
+    /// No value.
     #[lang = "None"]
     #[stable(feature = "rust1", since = "1.0.0")]
     None,
-    /// Some value `T`
+    /// Some value of type `T`.
     #[lang = "Some"]
     #[stable(feature = "rust1", since = "1.0.0")]
     Some(#[stable(feature = "rust1", since = "1.0.0")] T),
diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs
index 7d5d70f1720..49dce89a494 100644
--- a/library/core/src/slice/mod.rs
+++ b/library/core/src/slice/mod.rs
@@ -16,6 +16,8 @@ use crate::option::Option::{None, Some};
 use crate::ptr;
 use crate::result::Result;
 use crate::result::Result::{Err, Ok};
+#[cfg(not(miri))] // Miri does not support all SIMD intrinsics
+use crate::simd::{self, Simd};
 use crate::slice;
 
 #[unstable(
@@ -3512,6 +3514,123 @@ impl<T> [T] {
         }
     }
 
+    /// Split a slice into a prefix, a middle of aligned SIMD types, and a suffix.
+    ///
+    /// This is a safe wrapper around [`slice::align_to`], so has the same weak
+    /// postconditions as that method.  You're only assured that
+    /// `self.len() == prefix.len() + middle.len() * LANES + suffix.len()`.
+    ///
+    /// Notably, all of the following are possible:
+    /// - `prefix.len() >= LANES`.
+    /// - `middle.is_empty()` despite `self.len() >= 3 * LANES`.
+    /// - `suffix.len() >= LANES`.
+    ///
+    /// That said, this is a safe method, so if you're only writing safe code,
+    /// then this can at most cause incorrect logic, not unsoundness.
+    ///
+    /// # Panics
+    ///
+    /// This will panic if the size of the SIMD type is different from
+    /// `LANES` times that of the scalar.
+    ///
+    /// At the time of writing, the trait restrictions on `Simd<T, LANES>` keeps
+    /// that from ever happening, as only power-of-two numbers of lanes are
+    /// supported.  It's possible that, in the future, those restrictions might
+    /// be lifted in a way that would make it possible to see panics from this
+    /// method for something like `LANES == 3`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(portable_simd)]
+    ///
+    /// let short = &[1, 2, 3];
+    /// let (prefix, middle, suffix) = short.as_simd::<4>();
+    /// assert_eq!(middle, []); // Not enough elements for anything in the middle
+    ///
+    /// // They might be split in any possible way between prefix and suffix
+    /// let it = prefix.iter().chain(suffix).copied();
+    /// assert_eq!(it.collect::<Vec<_>>(), vec![1, 2, 3]);
+    ///
+    /// fn basic_simd_sum(x: &[f32]) -> f32 {
+    ///     use std::ops::Add;
+    ///     use std::simd::f32x4;
+    ///     let (prefix, middle, suffix) = x.as_simd();
+    ///     let sums = f32x4::from_array([
+    ///         prefix.iter().copied().sum(),
+    ///         0.0,
+    ///         0.0,
+    ///         suffix.iter().copied().sum(),
+    ///     ]);
+    ///     let sums = middle.iter().copied().fold(sums, f32x4::add);
+    ///     sums.horizontal_sum()
+    /// }
+    ///
+    /// let numbers: Vec<f32> = (1..101).map(|x| x as _).collect();
+    /// assert_eq!(basic_simd_sum(&numbers[1..99]), 4949.0);
+    /// ```
+    #[unstable(feature = "portable_simd", issue = "86656")]
+    #[cfg(not(miri))] // Miri does not support all SIMD intrinsics
+    pub fn as_simd<const LANES: usize>(&self) -> (&[T], &[Simd<T, LANES>], &[T])
+    where
+        Simd<T, LANES>: AsRef<[T; LANES]>,
+        T: simd::SimdElement,
+        simd::LaneCount<LANES>: simd::SupportedLaneCount,
+    {
+        // These are expected to always match, as vector types are laid out like
+        // arrays per <https://llvm.org/docs/LangRef.html#vector-type>, but we
+        // might as well double-check since it'll optimize away anyhow.
+        assert_eq!(mem::size_of::<Simd<T, LANES>>(), mem::size_of::<[T; LANES]>());
+
+        // SAFETY: The simd types have the same layout as arrays, just with
+        // potentially-higher alignment, so the de-facto transmutes are sound.
+        unsafe { self.align_to() }
+    }
+
+    /// Split a slice into a prefix, a middle of aligned SIMD types, and a suffix.
+    ///
+    /// This is a safe wrapper around [`slice::align_to_mut`], so has the same weak
+    /// postconditions as that method.  You're only assured that
+    /// `self.len() == prefix.len() + middle.len() * LANES + suffix.len()`.
+    ///
+    /// Notably, all of the following are possible:
+    /// - `prefix.len() >= LANES`.
+    /// - `middle.is_empty()` despite `self.len() >= 3 * LANES`.
+    /// - `suffix.len() >= LANES`.
+    ///
+    /// That said, this is a safe method, so if you're only writing safe code,
+    /// then this can at most cause incorrect logic, not unsoundness.
+    ///
+    /// This is the mutable version of [`slice::as_simd`]; see that for examples.
+    ///
+    /// # Panics
+    ///
+    /// This will panic if the size of the SIMD type is different from
+    /// `LANES` times that of the scalar.
+    ///
+    /// At the time of writing, the trait restrictions on `Simd<T, LANES>` keeps
+    /// that from ever happening, as only power-of-two numbers of lanes are
+    /// supported.  It's possible that, in the future, those restrictions might
+    /// be lifted in a way that would make it possible to see panics from this
+    /// method for something like `LANES == 3`.
+    #[unstable(feature = "portable_simd", issue = "86656")]
+    #[cfg(not(miri))] // Miri does not support all SIMD intrinsics
+    pub fn as_simd_mut<const LANES: usize>(&mut self) -> (&mut [T], &mut [Simd<T, LANES>], &mut [T])
+    where
+        Simd<T, LANES>: AsMut<[T; LANES]>,
+        T: simd::SimdElement,
+        simd::LaneCount<LANES>: simd::SupportedLaneCount,
+    {
+        // These are expected to always match, as vector types are laid out like
+        // arrays per <https://llvm.org/docs/LangRef.html#vector-type>, but we
+        // might as well double-check since it'll optimize away anyhow.
+        assert_eq!(mem::size_of::<Simd<T, LANES>>(), mem::size_of::<[T; LANES]>());
+
+        // SAFETY: The simd types have the same layout as arrays, just with
+        // potentially-higher alignment, so the de-facto transmutes are sound.
+        unsafe { self.align_to_mut() }
+    }
+
     /// Checks if the elements of this slice are sorted.
     ///
     /// That is, for each element `a` and its following element `b`, `a <= b` must hold. If the
diff --git a/library/proc_macro/src/bridge/client.rs b/library/proc_macro/src/bridge/client.rs
index 8ae7b6de1a6..83a2ac6f0d4 100644
--- a/library/proc_macro/src/bridge/client.rs
+++ b/library/proc_macro/src/bridge/client.rs
@@ -78,7 +78,7 @@ macro_rules! define_handles {
                 }
             }
 
-            impl<S: server::Types> Decode<'_, 's, HandleStore<server::MarkedTypes<S>>>
+            impl<'s, S: server::Types> Decode<'_, 's, HandleStore<server::MarkedTypes<S>>>
                 for &'s Marked<S::$oty, $oty>
             {
                 fn decode(r: &mut Reader<'_>, s: &'s HandleStore<server::MarkedTypes<S>>) -> Self {
@@ -92,7 +92,7 @@ macro_rules! define_handles {
                 }
             }
 
-            impl<S: server::Types> DecodeMut<'_, 's, HandleStore<server::MarkedTypes<S>>>
+            impl<'s, S: server::Types> DecodeMut<'_, 's, HandleStore<server::MarkedTypes<S>>>
                 for &'s mut Marked<S::$oty, $oty>
             {
                 fn decode(
diff --git a/library/proc_macro/src/bridge/mod.rs b/library/proc_macro/src/bridge/mod.rs
index 2df287f7d93..fbeb585095b 100644
--- a/library/proc_macro/src/bridge/mod.rs
+++ b/library/proc_macro/src/bridge/mod.rs
@@ -295,13 +295,13 @@ impl<T, M> Unmark for Marked<T, M> {
         self.value
     }
 }
-impl<T, M> Unmark for &'a Marked<T, M> {
+impl<'a, T, M> Unmark for &'a Marked<T, M> {
     type Unmarked = &'a T;
     fn unmark(self) -> Self::Unmarked {
         &self.value
     }
 }
-impl<T, M> Unmark for &'a mut Marked<T, M> {
+impl<'a, T, M> Unmark for &'a mut Marked<T, M> {
     type Unmarked = &'a mut T;
     fn unmark(self) -> Self::Unmarked {
         &mut self.value
@@ -356,8 +356,8 @@ mark_noop! {
     (),
     bool,
     char,
-    &'a [u8],
-    &'a str,
+    &'_ [u8],
+    &'_ str,
     String,
     usize,
     Delimiter,
diff --git a/library/proc_macro/src/bridge/rpc.rs b/library/proc_macro/src/bridge/rpc.rs
index 42432563faf..d50564d01a5 100644
--- a/library/proc_macro/src/bridge/rpc.rs
+++ b/library/proc_macro/src/bridge/rpc.rs
@@ -79,7 +79,7 @@ macro_rules! rpc_encode_decode {
             }
         }
 
-        impl<S, $($($T: for<'s> DecodeMut<'a, 's, S>),+)?> DecodeMut<'a, '_, S>
+        impl<'a, S, $($($T: for<'s> DecodeMut<'a, 's, S>),+)?> DecodeMut<'a, '_, S>
             for $name $(<$($T),+>)?
         {
             fn decode(r: &mut Reader<'a>, s: &mut S) -> Self {
@@ -176,7 +176,7 @@ impl<S, A: Encode<S>, B: Encode<S>> Encode<S> for (A, B) {
     }
 }
 
-impl<S, A: for<'s> DecodeMut<'a, 's, S>, B: for<'s> DecodeMut<'a, 's, S>> DecodeMut<'a, '_, S>
+impl<'a, S, A: for<'s> DecodeMut<'a, 's, S>, B: for<'s> DecodeMut<'a, 's, S>> DecodeMut<'a, '_, S>
     for (A, B)
 {
     fn decode(r: &mut Reader<'a>, s: &mut S) -> Self {
@@ -213,7 +213,7 @@ impl<S> Encode<S> for &[u8] {
     }
 }
 
-impl<S> DecodeMut<'a, '_, S> for &'a [u8] {
+impl<'a, S> DecodeMut<'a, '_, S> for &'a [u8] {
     fn decode(r: &mut Reader<'a>, s: &mut S) -> Self {
         let len = usize::decode(r, s);
         let xs = &r[..len];
@@ -228,7 +228,7 @@ impl<S> Encode<S> for &str {
     }
 }
 
-impl<S> DecodeMut<'a, '_, S> for &'a str {
+impl<'a, S> DecodeMut<'a, '_, S> for &'a str {
     fn decode(r: &mut Reader<'a>, s: &mut S) -> Self {
         str::from_utf8(<&[u8]>::decode(r, s)).unwrap()
     }
diff --git a/library/proc_macro/src/lib.rs b/library/proc_macro/src/lib.rs
index ef96d72a38b..69af598f91e 100644
--- a/library/proc_macro/src/lib.rs
+++ b/library/proc_macro/src/lib.rs
@@ -25,7 +25,6 @@
 #![feature(allow_internal_unstable)]
 #![feature(decl_macro)]
 #![feature(extern_types)]
-#![feature(in_band_lifetimes)]
 #![feature(negative_impls)]
 #![feature(auto_traits)]
 #![feature(restricted_std)]
diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css
index 5751ec2cc02..cbb078f2ab3 100644
--- a/src/librustdoc/html/static/css/rustdoc.css
+++ b/src/librustdoc/html/static/css/rustdoc.css
@@ -373,7 +373,6 @@ nav.sub {
 
 .source .sidebar.expanded {
 	overflow-y: auto;
-	width: 300px;
 }
 
 .source .sidebar.expanded > * {
@@ -1394,7 +1393,7 @@ pre.rust {
 	z-index: 10;
 }
 #source-sidebar {
-	width: 300px;
+	width: 100%;
 	z-index: 1;
 	overflow: auto;
 }
@@ -1711,6 +1710,10 @@ details.rustdoc-toggle[open] > summary.hideme::after {
 	.rustdoc.source .sidebar {
 		transition: width .5s;
 	}
+
+	.source .sidebar.expanded {
+		width: 300px;
+	}
 }
 
 @media (max-width: 700px) {
@@ -1999,6 +2002,11 @@ details.rustdoc-toggle[open] > summary.hideme::after {
 	.search-results div.desc, .search-results .result-description, .item-right {
 		padding-left: 2em;
 	}
+
+	.source .sidebar.expanded {
+		max-width: 100vw;
+		width: 100vw;
+	}
 }
 
 @media print {
diff --git a/src/test/rustdoc-gui/sidebar-source-code.goml b/src/test/rustdoc-gui/sidebar-source-code.goml
new file mode 100644
index 00000000000..98f4fdf4233
--- /dev/null
+++ b/src/test/rustdoc-gui/sidebar-source-code.goml
@@ -0,0 +1,32 @@
+// The goal of this test is to ensure that the sidebar is working as expected in the source
+// code pages.
+goto: file://|DOC_PATH|/src/test_docs/lib.rs.html
+// First: desktop mode.
+size: (1100, 800)
+// We check that the sidebar isn't expanded and has the expected width.
+assert-css: ("nav.sidebar", {"width": "50px"})
+// We now click on the button to expand the sidebar.
+click: (10, 10)
+// We wait for the sidebar to be expanded (there is a 0.5s animation).
+wait-for: 600
+assert-css: ("nav.sidebar.expanded", {"width": "300px"})
+// We collapse the sidebar.
+click: (10, 10)
+// We wait for the sidebar to be collapsed (there is a 0.5s animation).
+wait-for: 600
+// We ensure that the class has been removed.
+assert-false: "nav.sidebar.expanded"
+assert: "nav.sidebar"
+
+// We now switch to mobile mode.
+size: (600, 600)
+// We check that the sidebar has the expected width (0 and 1px for the border).
+assert-css: ("nav.sidebar", {"width": "1px"})
+// We expand the sidebar.
+click: "#sidebar-toggle"
+assert-css: ("nav.sidebar.expanded", {"width": "600px"})
+// We collapse the sidebar.
+click: (10, 10)
+// We ensure that the class has been removed.
+assert-false: "nav.sidebar.expanded"
+assert: "nav.sidebar"
diff --git a/src/test/ui/associated-types/associated-type-destructuring-assignment.rs b/src/test/ui/associated-types/associated-type-destructuring-assignment.rs
index fea7c7a383f..f038c9ce7ba 100644
--- a/src/test/ui/associated-types/associated-type-destructuring-assignment.rs
+++ b/src/test/ui/associated-types/associated-type-destructuring-assignment.rs
@@ -1,6 +1,5 @@
 // check-pass
 
-#![feature(destructuring_assignment)]
 #![feature(more_qualified_paths)]
 
 enum E { V() }
diff --git a/src/test/ui/const-generics/defaults/auxiliary/trait_object_lt_defaults_lib.rs b/src/test/ui/const-generics/defaults/auxiliary/trait_object_lt_defaults_lib.rs
new file mode 100644
index 00000000000..26a2c47ffb2
--- /dev/null
+++ b/src/test/ui/const-generics/defaults/auxiliary/trait_object_lt_defaults_lib.rs
@@ -0,0 +1 @@
+pub struct Foo<'a, const N: usize, T: 'a + ?Sized>(pub &'a T, [(); N]);
diff --git a/src/test/ui/const-generics/defaults/trait_object_lt_defaults.rs b/src/test/ui/const-generics/defaults/trait_object_lt_defaults.rs
new file mode 100644
index 00000000000..a1828727ecd
--- /dev/null
+++ b/src/test/ui/const-generics/defaults/trait_object_lt_defaults.rs
@@ -0,0 +1,24 @@
+// aux-build:trait_object_lt_defaults_lib.rs
+// run-pass
+#![allow(dead_code)]
+extern crate trait_object_lt_defaults_lib;
+
+// Tests that `A<'a, 3, dyn Test>` is short for `A<'a, 3, dyn Test + 'a>`
+// and `Foo<'a, 3, dyn Test>` is short for `Foo<'a, 3, dyn Test + 'a>`
+// Test is in `const-generics/defaults` because it relies on param ordering
+
+trait Test {}
+
+struct A<'a, const N: usize, T: ?Sized + 'a>(&'a T, [(); N]);
+fn blah<'a>(mut a: A<'a, 3, dyn Test>, arg: &'a (dyn Test + 'a)) {
+    a.0 = arg;
+}
+
+fn other_blah<'a>(
+    mut a: trait_object_lt_defaults_lib::Foo<'a, 3, dyn Test>,
+    arg: &'a (dyn Test + 'a),
+) {
+    a.0 = arg;
+}
+
+fn main() {}
diff --git a/src/test/ui/cross/cross-file-errors/main.rs b/src/test/ui/cross/cross-file-errors/main.rs
index 1902ab94d4c..4219f892deb 100644
--- a/src/test/ui/cross/cross-file-errors/main.rs
+++ b/src/test/ui/cross/cross-file-errors/main.rs
@@ -4,5 +4,4 @@ mod underscore;
 fn main() {
     underscore!();
     //~^ ERROR `_` can only be used on the left-hand side of an assignment
-    //~| ERROR destructuring assignments are unstable
 }
diff --git a/src/test/ui/cross/cross-file-errors/main.stderr b/src/test/ui/cross/cross-file-errors/main.stderr
index 829535f9212..293a300ed61 100644
--- a/src/test/ui/cross/cross-file-errors/main.stderr
+++ b/src/test/ui/cross/cross-file-errors/main.stderr
@@ -1,18 +1,3 @@
-error[E0658]: destructuring assignments are unstable
-  --> $DIR/underscore.rs:8:9
-   |
-LL |         _
-   |         ^
-   |
-  ::: $DIR/main.rs:5:5
-   |
-LL |     underscore!();
-   |     ------------- in this macro invocation
-   |
-   = note: see issue #71126 <https://github.com/rust-lang/rust/issues/71126> for more information
-   = help: add `#![feature(destructuring_assignment)]` to the crate attributes to enable
-   = note: this error originates in the macro `underscore` (in Nightly builds, run with -Z macro-backtrace for more info)
-
 error: in expressions, `_` can only be used on the left-hand side of an assignment
   --> $DIR/underscore.rs:8:9
    |
@@ -26,6 +11,5 @@ LL |     underscore!();
    |
    = note: this error originates in the macro `underscore` (in Nightly builds, run with -Z macro-backtrace for more info)
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/destructuring-assignment/bad-expr-lhs.rs b/src/test/ui/destructuring-assignment/bad-expr-lhs.rs
index 39536f12e3b..53794783a3c 100644
--- a/src/test/ui/destructuring-assignment/bad-expr-lhs.rs
+++ b/src/test/ui/destructuring-assignment/bad-expr-lhs.rs
@@ -1,12 +1,9 @@
 fn main() {
     1 = 2; //~ ERROR invalid left-hand side of assignment
     1 += 2; //~ ERROR invalid left-hand side of assignment
-    (1, 2) = (3, 4); //~ ERROR destructuring assignments are unstable
+    (1, 2) = (3, 4);
+    //~^ ERROR invalid left-hand side of assignment
     //~| ERROR invalid left-hand side of assignment
-    //~| ERROR invalid left-hand side of assignment
-
-    let (a, b) = (1, 2);
-    (a, b) = (3, 4); //~ ERROR destructuring assignments are unstable
 
     None = Some(3); //~ ERROR invalid left-hand side of assignment
 }
diff --git a/src/test/ui/destructuring-assignment/bad-expr-lhs.stderr b/src/test/ui/destructuring-assignment/bad-expr-lhs.stderr
index d4b2193d09f..d2986747480 100644
--- a/src/test/ui/destructuring-assignment/bad-expr-lhs.stderr
+++ b/src/test/ui/destructuring-assignment/bad-expr-lhs.stderr
@@ -1,25 +1,3 @@
-error[E0658]: destructuring assignments are unstable
-  --> $DIR/bad-expr-lhs.rs:4:12
-   |
-LL |     (1, 2) = (3, 4);
-   |     ------ ^
-   |     |
-   |     cannot assign to this expression
-   |
-   = note: see issue #71126 <https://github.com/rust-lang/rust/issues/71126> for more information
-   = help: add `#![feature(destructuring_assignment)]` to the crate attributes to enable
-
-error[E0658]: destructuring assignments are unstable
-  --> $DIR/bad-expr-lhs.rs:9:12
-   |
-LL |     (a, b) = (3, 4);
-   |     ------ ^
-   |     |
-   |     cannot assign to this expression
-   |
-   = note: see issue #71126 <https://github.com/rust-lang/rust/issues/71126> for more information
-   = help: add `#![feature(destructuring_assignment)]` to the crate attributes to enable
-
 error[E0070]: invalid left-hand side of assignment
   --> $DIR/bad-expr-lhs.rs:2:7
    |
@@ -53,14 +31,14 @@ LL |     (1, 2) = (3, 4);
    |         cannot assign to this expression
 
 error[E0070]: invalid left-hand side of assignment
-  --> $DIR/bad-expr-lhs.rs:11:10
+  --> $DIR/bad-expr-lhs.rs:8:10
    |
 LL |     None = Some(3);
    |     ---- ^
    |     |
    |     cannot assign to this expression
 
-error: aborting due to 7 previous errors
+error: aborting due to 5 previous errors
 
-Some errors have detailed explanations: E0067, E0070, E0658.
+Some errors have detailed explanations: E0067, E0070.
 For more information about an error, try `rustc --explain E0067`.
diff --git a/src/test/ui/destructuring-assignment/default-match-bindings-forbidden.rs b/src/test/ui/destructuring-assignment/default-match-bindings-forbidden.rs
index adecd0ff291..ff867c00071 100644
--- a/src/test/ui/destructuring-assignment/default-match-bindings-forbidden.rs
+++ b/src/test/ui/destructuring-assignment/default-match-bindings-forbidden.rs
@@ -1,5 +1,3 @@
-#![feature(destructuring_assignment)]
-
 fn main() {
     let mut x = &0;
     let mut y = &0;
diff --git a/src/test/ui/destructuring-assignment/default-match-bindings-forbidden.stderr b/src/test/ui/destructuring-assignment/default-match-bindings-forbidden.stderr
index e6161fdfa24..3d472bf6309 100644
--- a/src/test/ui/destructuring-assignment/default-match-bindings-forbidden.stderr
+++ b/src/test/ui/destructuring-assignment/default-match-bindings-forbidden.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/default-match-bindings-forbidden.rs:6:5
+  --> $DIR/default-match-bindings-forbidden.rs:4:5
    |
 LL |     (x, y) = &(1, 2);
    |     ^^^^^^   ------- this expression has type `&({integer}, {integer})`
diff --git a/src/test/ui/destructuring-assignment/drop-order.rs b/src/test/ui/destructuring-assignment/drop-order.rs
index d06b31c7f27..79671054ca7 100644
--- a/src/test/ui/destructuring-assignment/drop-order.rs
+++ b/src/test/ui/destructuring-assignment/drop-order.rs
@@ -2,7 +2,6 @@
 
 //! Test that let bindings and destructuring assignments have consistent drop orders
 
-#![feature(destructuring_assignment)]
 #![allow(unused_variables, unused_assignments)]
 
 use std::cell::RefCell;
diff --git a/src/test/ui/destructuring-assignment/nested_destructure.rs b/src/test/ui/destructuring-assignment/nested_destructure.rs
index 0d45ff7da72..94b3a5ff9a7 100644
--- a/src/test/ui/destructuring-assignment/nested_destructure.rs
+++ b/src/test/ui/destructuring-assignment/nested_destructure.rs
@@ -1,7 +1,5 @@
 // run-pass
 
-#![feature(destructuring_assignment)]
-
 struct Struct<S, T> {
     a: S,
     b: T,
diff --git a/src/test/ui/destructuring-assignment/note-unsupported.rs b/src/test/ui/destructuring-assignment/note-unsupported.rs
index 249fba7f920..c69edd42170 100644
--- a/src/test/ui/destructuring-assignment/note-unsupported.rs
+++ b/src/test/ui/destructuring-assignment/note-unsupported.rs
@@ -3,25 +3,20 @@ struct S { x: u8, y: u8 }
 fn main() {
     let (a, b) = (1, 2);
 
-    (a, b) = (3, 4); //~ ERROR destructuring assignments are unstable
+    (a, b) = (3, 4);
     (a, b) += (3, 4); //~ ERROR invalid left-hand side of assignment
     //~| ERROR binary assignment operation `+=` cannot be applied
 
-    [a, b] = [3, 4]; //~ ERROR destructuring assignments are unstable
+    [a, b] = [3, 4];
     [a, b] += [3, 4]; //~ ERROR invalid left-hand side of assignment
     //~| ERROR binary assignment operation `+=` cannot be applied
 
     let s = S { x: 3, y: 4 };
 
-    S { x: a, y: b } = s; //~ ERROR destructuring assignments are unstable
+    S { x: a, y: b } = s;
     S { x: a, y: b } += s; //~ ERROR invalid left-hand side of assignment
     //~| ERROR binary assignment operation `+=` cannot be applied
 
     S { x: a, ..s } = S { x: 3, y: 4 };
     //~^ ERROR functional record updates are not allowed in destructuring assignments
-    //~| ERROR destructuring assignments are unstable
-
-    let c = 3;
-
-    ((a, b), c) = ((3, 4), 5); //~ ERROR destructuring assignments are unstable
 }
diff --git a/src/test/ui/destructuring-assignment/note-unsupported.stderr b/src/test/ui/destructuring-assignment/note-unsupported.stderr
index 7b9788ca0fe..3e2282743bf 100644
--- a/src/test/ui/destructuring-assignment/note-unsupported.stderr
+++ b/src/test/ui/destructuring-assignment/note-unsupported.stderr
@@ -1,64 +1,9 @@
-error[E0658]: destructuring assignments are unstable
-  --> $DIR/note-unsupported.rs:6:12
-   |
-LL |     (a, b) = (3, 4);
-   |     ------ ^
-   |     |
-   |     cannot assign to this expression
-   |
-   = note: see issue #71126 <https://github.com/rust-lang/rust/issues/71126> for more information
-   = help: add `#![feature(destructuring_assignment)]` to the crate attributes to enable
-
-error[E0658]: destructuring assignments are unstable
-  --> $DIR/note-unsupported.rs:10:12
-   |
-LL |     [a, b] = [3, 4];
-   |     ------ ^
-   |     |
-   |     cannot assign to this expression
-   |
-   = note: see issue #71126 <https://github.com/rust-lang/rust/issues/71126> for more information
-   = help: add `#![feature(destructuring_assignment)]` to the crate attributes to enable
-
-error[E0658]: destructuring assignments are unstable
-  --> $DIR/note-unsupported.rs:16:22
-   |
-LL |     S { x: a, y: b } = s;
-   |     ---------------- ^
-   |     |
-   |     cannot assign to this expression
-   |
-   = note: see issue #71126 <https://github.com/rust-lang/rust/issues/71126> for more information
-   = help: add `#![feature(destructuring_assignment)]` to the crate attributes to enable
-
-error[E0658]: destructuring assignments are unstable
-  --> $DIR/note-unsupported.rs:20:21
-   |
-LL |     S { x: a, ..s } = S { x: 3, y: 4 };
-   |     --------------- ^
-   |     |
-   |     cannot assign to this expression
-   |
-   = note: see issue #71126 <https://github.com/rust-lang/rust/issues/71126> for more information
-   = help: add `#![feature(destructuring_assignment)]` to the crate attributes to enable
-
 error: functional record updates are not allowed in destructuring assignments
   --> $DIR/note-unsupported.rs:20:17
    |
 LL |     S { x: a, ..s } = S { x: 3, y: 4 };
    |                 ^ help: consider removing the trailing pattern
 
-error[E0658]: destructuring assignments are unstable
-  --> $DIR/note-unsupported.rs:26:17
-   |
-LL |     ((a, b), c) = ((3, 4), 5);
-   |     ----------- ^
-   |     |
-   |     cannot assign to this expression
-   |
-   = note: see issue #71126 <https://github.com/rust-lang/rust/issues/71126> for more information
-   = help: add `#![feature(destructuring_assignment)]` to the crate attributes to enable
-
 error[E0368]: binary assignment operation `+=` cannot be applied to type `({integer}, {integer})`
   --> $DIR/note-unsupported.rs:7:5
    |
@@ -124,7 +69,7 @@ LL |     S { x: a, y: b } += s;
    |     |
    |     cannot assign to this expression
 
-error: aborting due to 12 previous errors
+error: aborting due to 7 previous errors
 
-Some errors have detailed explanations: E0067, E0368, E0658.
+Some errors have detailed explanations: E0067, E0368.
 For more information about an error, try `rustc --explain E0067`.
diff --git a/src/test/ui/destructuring-assignment/slice_destructure.rs b/src/test/ui/destructuring-assignment/slice_destructure.rs
index 76cdc1260fc..762c4b5e8ea 100644
--- a/src/test/ui/destructuring-assignment/slice_destructure.rs
+++ b/src/test/ui/destructuring-assignment/slice_destructure.rs
@@ -1,7 +1,5 @@
 // run-pass
 
-#![feature(destructuring_assignment)]
-
 fn main() {
   let (mut a, mut b);
   [a, b] = [0, 1];
diff --git a/src/test/ui/destructuring-assignment/slice_destructure_fail.rs b/src/test/ui/destructuring-assignment/slice_destructure_fail.rs
index 90d93892f7f..33b09eb349d 100644
--- a/src/test/ui/destructuring-assignment/slice_destructure_fail.rs
+++ b/src/test/ui/destructuring-assignment/slice_destructure_fail.rs
@@ -1,5 +1,3 @@
-#![feature(destructuring_assignment)]
-
 fn main() {
   let (mut a, mut b);
   [a, .., b, ..] = [0, 1]; //~ ERROR `..` can only be used once per slice pattern
diff --git a/src/test/ui/destructuring-assignment/slice_destructure_fail.stderr b/src/test/ui/destructuring-assignment/slice_destructure_fail.stderr
index cc412c72df5..92c86febac4 100644
--- a/src/test/ui/destructuring-assignment/slice_destructure_fail.stderr
+++ b/src/test/ui/destructuring-assignment/slice_destructure_fail.stderr
@@ -1,5 +1,5 @@
 error: `..` can only be used once per slice pattern
-  --> $DIR/slice_destructure_fail.rs:5:14
+  --> $DIR/slice_destructure_fail.rs:3:14
    |
 LL |   [a, .., b, ..] = [0, 1];
    |       --     ^^ can only be used once per slice pattern
@@ -7,13 +7,13 @@ LL |   [a, .., b, ..] = [0, 1];
    |       previously used here
 
 error[E0527]: pattern requires 3 elements but array has 2
-  --> $DIR/slice_destructure_fail.rs:6:3
+  --> $DIR/slice_destructure_fail.rs:4:3
    |
 LL |   [a, a, b] = [1, 2];
    |   ^^^^^^^^^ expected 2 elements
 
 error[E0527]: pattern requires 1 element but array has 2
-  --> $DIR/slice_destructure_fail.rs:7:3
+  --> $DIR/slice_destructure_fail.rs:5:3
    |
 LL |   [_] = [1, 2];
    |   ^^^ expected 2 elements
diff --git a/src/test/ui/destructuring-assignment/struct_destructure.rs b/src/test/ui/destructuring-assignment/struct_destructure.rs
index 2bcbd9d0d74..8cceaadd7b9 100644
--- a/src/test/ui/destructuring-assignment/struct_destructure.rs
+++ b/src/test/ui/destructuring-assignment/struct_destructure.rs
@@ -1,6 +1,5 @@
 // run-pass
 
-#![feature(destructuring_assignment)]
 struct Struct<S, T> {
     a: S,
     b: T,
diff --git a/src/test/ui/destructuring-assignment/struct_destructure_fail.rs b/src/test/ui/destructuring-assignment/struct_destructure_fail.rs
index 4aa327b61f4..c001fccd4cb 100644
--- a/src/test/ui/destructuring-assignment/struct_destructure_fail.rs
+++ b/src/test/ui/destructuring-assignment/struct_destructure_fail.rs
@@ -1,4 +1,3 @@
-#![feature(destructuring_assignment)]
 struct Struct<S, T> {
     a: S,
     b: T,
diff --git a/src/test/ui/destructuring-assignment/struct_destructure_fail.stderr b/src/test/ui/destructuring-assignment/struct_destructure_fail.stderr
index 635bd5e7edf..ae7b3d1e5a9 100644
--- a/src/test/ui/destructuring-assignment/struct_destructure_fail.stderr
+++ b/src/test/ui/destructuring-assignment/struct_destructure_fail.stderr
@@ -1,5 +1,5 @@
 error: expected identifier, found reserved identifier `_`
-  --> $DIR/struct_destructure_fail.rs:12:17
+  --> $DIR/struct_destructure_fail.rs:11:17
    |
 LL |     Struct { a, _ } = Struct { a: 1, b: 2 };
    |     ------      ^ expected identifier, found reserved identifier
@@ -7,25 +7,25 @@ LL |     Struct { a, _ } = Struct { a: 1, b: 2 };
    |     while parsing this struct
 
 error: functional record updates are not allowed in destructuring assignments
-  --> $DIR/struct_destructure_fail.rs:14:19
+  --> $DIR/struct_destructure_fail.rs:13:19
    |
 LL |     Struct { a, ..d } = Struct { a: 1, b: 2 };
    |                   ^ help: consider removing the trailing pattern
 
 error: base expression required after `..`
-  --> $DIR/struct_destructure_fail.rs:16:19
+  --> $DIR/struct_destructure_fail.rs:15:19
    |
 LL |     Struct { a, .. };
    |                   ^ add a base expression here
 
 error[E0026]: struct `Struct` does not have a field named `c`
-  --> $DIR/struct_destructure_fail.rs:11:20
+  --> $DIR/struct_destructure_fail.rs:10:20
    |
 LL |     Struct { a, b, c } = Struct { a: 0, b: 1 };
    |                    ^ struct `Struct` does not have this field
 
 error[E0027]: pattern does not mention field `b`
-  --> $DIR/struct_destructure_fail.rs:12:5
+  --> $DIR/struct_destructure_fail.rs:11:5
    |
 LL |     Struct { a, _ } = Struct { a: 1, b: 2 };
    |     ^^^^^^^^^^^^^^^ missing field `b`
diff --git a/src/test/ui/destructuring-assignment/tuple_destructure.rs b/src/test/ui/destructuring-assignment/tuple_destructure.rs
index 2096182d421..2a8584029d0 100644
--- a/src/test/ui/destructuring-assignment/tuple_destructure.rs
+++ b/src/test/ui/destructuring-assignment/tuple_destructure.rs
@@ -1,7 +1,5 @@
 // run-pass
 
-#![feature(destructuring_assignment)]
-
 fn main() {
     let (mut a, mut b);
     (a, b) = (0, 1);
diff --git a/src/test/ui/destructuring-assignment/tuple_destructure_fail.rs b/src/test/ui/destructuring-assignment/tuple_destructure_fail.rs
index 5524e91dc40..4e3172d1973 100644
--- a/src/test/ui/destructuring-assignment/tuple_destructure_fail.rs
+++ b/src/test/ui/destructuring-assignment/tuple_destructure_fail.rs
@@ -1,5 +1,3 @@
-#![feature(destructuring_assignment)]
-
 const C: i32 = 1;
 
 fn main() {
diff --git a/src/test/ui/destructuring-assignment/tuple_destructure_fail.stderr b/src/test/ui/destructuring-assignment/tuple_destructure_fail.stderr
index 1146b88278d..55b08b74af0 100644
--- a/src/test/ui/destructuring-assignment/tuple_destructure_fail.stderr
+++ b/src/test/ui/destructuring-assignment/tuple_destructure_fail.stderr
@@ -1,5 +1,5 @@
 error: `..` can only be used once per tuple pattern
-  --> $DIR/tuple_destructure_fail.rs:7:16
+  --> $DIR/tuple_destructure_fail.rs:5:16
    |
 LL |     (a, .., b, ..) = (0, 1);
    |         --     ^^ can only be used once per tuple pattern
@@ -7,7 +7,7 @@ LL |     (a, .., b, ..) = (0, 1);
    |         previously used here
 
 error[E0308]: mismatched types
-  --> $DIR/tuple_destructure_fail.rs:8:5
+  --> $DIR/tuple_destructure_fail.rs:6:5
    |
 LL |     (a, a, b) = (1, 2);
    |     ^^^^^^^^^   ------ this expression has type `({integer}, {integer})`
@@ -18,7 +18,7 @@ LL |     (a, a, b) = (1, 2);
              found tuple `(_, _, _)`
 
 error[E0070]: invalid left-hand side of assignment
-  --> $DIR/tuple_destructure_fail.rs:9:13
+  --> $DIR/tuple_destructure_fail.rs:7:13
    |
 LL |     (C, ..) = (0,1);
    |      -      ^
@@ -26,7 +26,7 @@ LL |     (C, ..) = (0,1);
    |      cannot assign to this expression
 
 error[E0308]: mismatched types
-  --> $DIR/tuple_destructure_fail.rs:10:5
+  --> $DIR/tuple_destructure_fail.rs:8:5
    |
 LL |     (_,) = (1, 2);
    |     ^^^^   ------ this expression has type `({integer}, {integer})`
diff --git a/src/test/ui/destructuring-assignment/tuple_struct_destructure.rs b/src/test/ui/destructuring-assignment/tuple_struct_destructure.rs
index 7b5c5ad2bae..07b5f7a314e 100644
--- a/src/test/ui/destructuring-assignment/tuple_struct_destructure.rs
+++ b/src/test/ui/destructuring-assignment/tuple_struct_destructure.rs
@@ -1,7 +1,5 @@
 // run-pass
 
-#![feature(destructuring_assignment)]
-
 struct TupleStruct<S, T>(S, T);
 
 impl<S, T> TupleStruct<S, T> {
diff --git a/src/test/ui/destructuring-assignment/tuple_struct_destructure_fail.rs b/src/test/ui/destructuring-assignment/tuple_struct_destructure_fail.rs
index c39db061177..845f867d7b8 100644
--- a/src/test/ui/destructuring-assignment/tuple_struct_destructure_fail.rs
+++ b/src/test/ui/destructuring-assignment/tuple_struct_destructure_fail.rs
@@ -1,5 +1,3 @@
-#![feature(destructuring_assignment)]
-
 struct TupleStruct<S, T>(S, T);
 
 enum Enum<S, T> {
diff --git a/src/test/ui/destructuring-assignment/tuple_struct_destructure_fail.stderr b/src/test/ui/destructuring-assignment/tuple_struct_destructure_fail.stderr
index 9aae4b0a3fa..5cc7acba3f3 100644
--- a/src/test/ui/destructuring-assignment/tuple_struct_destructure_fail.stderr
+++ b/src/test/ui/destructuring-assignment/tuple_struct_destructure_fail.stderr
@@ -1,5 +1,5 @@
 error: `..` can only be used once per tuple struct or variant pattern
-  --> $DIR/tuple_struct_destructure_fail.rs:25:27
+  --> $DIR/tuple_struct_destructure_fail.rs:23:27
    |
 LL |     TupleStruct(a, .., b, ..) = TupleStruct(0, 1);
    |                    --     ^^ can only be used once per tuple struct or variant pattern
@@ -7,7 +7,7 @@ LL |     TupleStruct(a, .., b, ..) = TupleStruct(0, 1);
    |                    previously used here
 
 error: `..` can only be used once per tuple struct or variant pattern
-  --> $DIR/tuple_struct_destructure_fail.rs:27:35
+  --> $DIR/tuple_struct_destructure_fail.rs:25:35
    |
 LL |     Enum::SingleVariant(a, .., b, ..) = Enum::SingleVariant(0, 1);
    |                            --     ^^ can only be used once per tuple struct or variant pattern
@@ -15,7 +15,7 @@ LL |     Enum::SingleVariant(a, .., b, ..) = Enum::SingleVariant(0, 1);
    |                            previously used here
 
 error[E0023]: this pattern has 3 fields, but the corresponding tuple struct has 2 fields
-  --> $DIR/tuple_struct_destructure_fail.rs:30:17
+  --> $DIR/tuple_struct_destructure_fail.rs:28:17
    |
 LL | struct TupleStruct<S, T>(S, T);
    |                          -  - tuple struct has 2 fields
@@ -24,7 +24,7 @@ LL |     TupleStruct(a, a, b) = TupleStruct(1, 2);
    |                 ^  ^  ^ expected 2 fields, found 3
 
 error[E0023]: this pattern has 1 field, but the corresponding tuple struct has 2 fields
-  --> $DIR/tuple_struct_destructure_fail.rs:32:17
+  --> $DIR/tuple_struct_destructure_fail.rs:30:17
    |
 LL | struct TupleStruct<S, T>(S, T);
    |                          -  - tuple struct has 2 fields
@@ -42,7 +42,7 @@ LL |     TupleStruct(..) = TupleStruct(1, 2);
    |                 ~~
 
 error[E0023]: this pattern has 3 fields, but the corresponding tuple variant has 2 fields
-  --> $DIR/tuple_struct_destructure_fail.rs:34:25
+  --> $DIR/tuple_struct_destructure_fail.rs:32:25
    |
 LL |     SingleVariant(S, T)
    |                   -  - tuple variant has 2 fields
@@ -51,7 +51,7 @@ LL |     Enum::SingleVariant(a, a, b) = Enum::SingleVariant(1, 2);
    |                         ^  ^  ^ expected 2 fields, found 3
 
 error[E0023]: this pattern has 1 field, but the corresponding tuple variant has 2 fields
-  --> $DIR/tuple_struct_destructure_fail.rs:36:25
+  --> $DIR/tuple_struct_destructure_fail.rs:34:25
    |
 LL |     SingleVariant(S, T)
    |                   -  - tuple variant has 2 fields
@@ -69,7 +69,7 @@ LL |     Enum::SingleVariant(..) = Enum::SingleVariant(1, 2);
    |                         ~~
 
 error[E0070]: invalid left-hand side of assignment
-  --> $DIR/tuple_struct_destructure_fail.rs:40:12
+  --> $DIR/tuple_struct_destructure_fail.rs:38:12
    |
 LL |     test() = TupleStruct(0, 0);
    |     ------ ^
@@ -77,7 +77,7 @@ LL |     test() = TupleStruct(0, 0);
    |     cannot assign to this expression
 
 error[E0070]: invalid left-hand side of assignment
-  --> $DIR/tuple_struct_destructure_fail.rs:42:14
+  --> $DIR/tuple_struct_destructure_fail.rs:40:14
    |
 LL |     (test)() = TupleStruct(0, 0);
    |     -------- ^
@@ -85,7 +85,7 @@ LL |     (test)() = TupleStruct(0, 0);
    |     cannot assign to this expression
 
 error[E0070]: invalid left-hand side of assignment
-  --> $DIR/tuple_struct_destructure_fail.rs:44:38
+  --> $DIR/tuple_struct_destructure_fail.rs:42:38
    |
 LL |     <Alias::<isize> as Test>::test() = TupleStruct(0, 0);
    |     -------------------------------- ^
diff --git a/src/test/ui/destructuring-assignment/underscore-range-expr-gating.rs b/src/test/ui/destructuring-assignment/underscore-range-expr-gating.rs
deleted file mode 100644
index 4ed4f56702c..00000000000
--- a/src/test/ui/destructuring-assignment/underscore-range-expr-gating.rs
+++ /dev/null
@@ -1,10 +0,0 @@
-fn main() {}
-
-struct S { x : u32 }
-
-#[cfg(FALSE)]
-fn foo() {
-    _; //~ ERROR destructuring assignments are unstable
-
-    S { x: 5, .. }; //~ ERROR destructuring assignments are unstable
-}
diff --git a/src/test/ui/destructuring-assignment/underscore-range-expr-gating.stderr b/src/test/ui/destructuring-assignment/underscore-range-expr-gating.stderr
deleted file mode 100644
index a5ed761a01c..00000000000
--- a/src/test/ui/destructuring-assignment/underscore-range-expr-gating.stderr
+++ /dev/null
@@ -1,21 +0,0 @@
-error[E0658]: destructuring assignments are unstable
-  --> $DIR/underscore-range-expr-gating.rs:7:5
-   |
-LL |     _;
-   |     ^
-   |
-   = note: see issue #71126 <https://github.com/rust-lang/rust/issues/71126> for more information
-   = help: add `#![feature(destructuring_assignment)]` to the crate attributes to enable
-
-error[E0658]: destructuring assignments are unstable
-  --> $DIR/underscore-range-expr-gating.rs:9:15
-   |
-LL |     S { x: 5, .. };
-   |               ^^
-   |
-   = note: see issue #71126 <https://github.com/rust-lang/rust/issues/71126> for more information
-   = help: add `#![feature(destructuring_assignment)]` to the crate attributes to enable
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/destructuring-assignment/warn-unused-duplication.rs b/src/test/ui/destructuring-assignment/warn-unused-duplication.rs
index c1c5c2cd3ce..390f44b8aa5 100644
--- a/src/test/ui/destructuring-assignment/warn-unused-duplication.rs
+++ b/src/test/ui/destructuring-assignment/warn-unused-duplication.rs
@@ -1,7 +1,5 @@
 // run-pass
 
-#![feature(destructuring_assignment)]
-
 #![warn(unused_assignments)]
 
 fn main() {
diff --git a/src/test/ui/destructuring-assignment/warn-unused-duplication.stderr b/src/test/ui/destructuring-assignment/warn-unused-duplication.stderr
index b87ef6f1571..1df7a5f224f 100644
--- a/src/test/ui/destructuring-assignment/warn-unused-duplication.stderr
+++ b/src/test/ui/destructuring-assignment/warn-unused-duplication.stderr
@@ -1,11 +1,11 @@
 warning: value assigned to `a` is never read
-  --> $DIR/warn-unused-duplication.rs:11:6
+  --> $DIR/warn-unused-duplication.rs:9:6
    |
 LL |     (a, a) = (0, 1);
    |      ^
    |
 note: the lint level is defined here
-  --> $DIR/warn-unused-duplication.rs:5:9
+  --> $DIR/warn-unused-duplication.rs:3:9
    |
 LL | #![warn(unused_assignments)]
    |         ^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/feature-gates/feature-gate-destructuring_assignment.rs b/src/test/ui/feature-gates/feature-gate-destructuring_assignment.rs
deleted file mode 100644
index e7801f0e8ec..00000000000
--- a/src/test/ui/feature-gates/feature-gate-destructuring_assignment.rs
+++ /dev/null
@@ -1,4 +0,0 @@
-fn main() {
-    let (a, b) = (0, 1);
-    (a, b) = (2, 3); //~ ERROR destructuring assignments are unstable
-}
diff --git a/src/test/ui/feature-gates/feature-gate-destructuring_assignment.stderr b/src/test/ui/feature-gates/feature-gate-destructuring_assignment.stderr
deleted file mode 100644
index 62e71decb32..00000000000
--- a/src/test/ui/feature-gates/feature-gate-destructuring_assignment.stderr
+++ /dev/null
@@ -1,14 +0,0 @@
-error[E0658]: destructuring assignments are unstable
-  --> $DIR/feature-gate-destructuring_assignment.rs:3:12
-   |
-LL |     (a, b) = (2, 3);
-   |     ------ ^
-   |     |
-   |     cannot assign to this expression
-   |
-   = note: see issue #71126 <https://github.com/rust-lang/rust/issues/71126> for more information
-   = help: add `#![feature(destructuring_assignment)]` to the crate attributes to enable
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/issues/issue-77218/issue-77218-2.fixed b/src/test/ui/issues/issue-77218/issue-77218-2.fixed
index 06487fe0886..0e835d49c6d 100644
--- a/src/test/ui/issues/issue-77218/issue-77218-2.fixed
+++ b/src/test/ui/issues/issue-77218/issue-77218-2.fixed
@@ -1,5 +1,4 @@
 // run-rustfix
-#![feature(destructuring_assignment)]
 fn main() {
     let value = [7u8];
     while let Some(0) = value.get(0) { //~ ERROR invalid left-hand side of assignment
diff --git a/src/test/ui/issues/issue-77218/issue-77218-2.rs b/src/test/ui/issues/issue-77218/issue-77218-2.rs
index e19cec08e43..01dca1ae16c 100644
--- a/src/test/ui/issues/issue-77218/issue-77218-2.rs
+++ b/src/test/ui/issues/issue-77218/issue-77218-2.rs
@@ -1,5 +1,4 @@
 // run-rustfix
-#![feature(destructuring_assignment)]
 fn main() {
     let value = [7u8];
     while Some(0) = value.get(0) { //~ ERROR invalid left-hand side of assignment
diff --git a/src/test/ui/issues/issue-77218/issue-77218-2.stderr b/src/test/ui/issues/issue-77218/issue-77218-2.stderr
index 8d9eb2219d5..58c1c18f9a9 100644
--- a/src/test/ui/issues/issue-77218/issue-77218-2.stderr
+++ b/src/test/ui/issues/issue-77218/issue-77218-2.stderr
@@ -1,5 +1,5 @@
 error[E0070]: invalid left-hand side of assignment
-  --> $DIR/issue-77218-2.rs:5:19
+  --> $DIR/issue-77218-2.rs:4:19
    |
 LL |     while Some(0) = value.get(0) {
    |                -  ^
diff --git a/src/test/ui/issues/issue-77218/issue-77218.fixed b/src/test/ui/issues/issue-77218/issue-77218.fixed
index 4ea51109022..4907b43b9a9 100644
--- a/src/test/ui/issues/issue-77218/issue-77218.fixed
+++ b/src/test/ui/issues/issue-77218/issue-77218.fixed
@@ -1,6 +1,5 @@
 // run-rustfix
 fn main() {
     let value = [7u8];
-    while let Some(0) = value.get(0) { //~ ERROR destructuring assignments are unstable
-    }
+    while let Some(0) = value.get(0) {} //~ ERROR invalid left-hand side of assignment
 }
diff --git a/src/test/ui/issues/issue-77218/issue-77218.rs b/src/test/ui/issues/issue-77218/issue-77218.rs
index 0f3c12f5635..0ed154bf4d8 100644
--- a/src/test/ui/issues/issue-77218/issue-77218.rs
+++ b/src/test/ui/issues/issue-77218/issue-77218.rs
@@ -1,6 +1,5 @@
 // run-rustfix
 fn main() {
     let value = [7u8];
-    while Some(0) = value.get(0) { //~ ERROR destructuring assignments are unstable
-    }
+    while Some(0) = value.get(0) {} //~ ERROR invalid left-hand side of assignment
 }
diff --git a/src/test/ui/issues/issue-77218/issue-77218.stderr b/src/test/ui/issues/issue-77218/issue-77218.stderr
index 54f49609a44..eda635646df 100644
--- a/src/test/ui/issues/issue-77218/issue-77218.stderr
+++ b/src/test/ui/issues/issue-77218/issue-77218.stderr
@@ -1,18 +1,16 @@
-error[E0658]: destructuring assignments are unstable
+error[E0070]: invalid left-hand side of assignment
   --> $DIR/issue-77218.rs:4:19
    |
-LL |     while Some(0) = value.get(0) {
-   |           ------- ^
-   |           |
-   |           cannot assign to this expression
+LL |     while Some(0) = value.get(0) {}
+   |                -  ^
+   |                |
+   |                cannot assign to this expression
    |
-   = note: see issue #71126 <https://github.com/rust-lang/rust/issues/71126> for more information
-   = help: add `#![feature(destructuring_assignment)]` to the crate attributes to enable
 help: you might have meant to use pattern destructuring
    |
-LL |     while let Some(0) = value.get(0) {
+LL |     while let Some(0) = value.get(0) {}
    |           +++
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0658`.
+For more information about this error, try `rustc --explain E0070`.
diff --git a/src/test/ui/suggestions/fn-or-tuple-struct-with-underscore-args.rs b/src/test/ui/suggestions/fn-or-tuple-struct-with-underscore-args.rs
index 00638e04f5d..ae1dbfeea93 100644
--- a/src/test/ui/suggestions/fn-or-tuple-struct-with-underscore-args.rs
+++ b/src/test/ui/suggestions/fn-or-tuple-struct-with-underscore-args.rs
@@ -10,16 +10,10 @@ fn main() {
     let _: usize = foo(_, _);
     //~^ ERROR `_` can only be used on the left-hand side of an assignment
     //~| ERROR `_` can only be used on the left-hand side of an assignment
-    //~| ERROR destructuring assignments are unstable
-    //~| ERROR destructuring assignments are unstable
     let _: S = S(_, _);
     //~^ ERROR `_` can only be used on the left-hand side of an assignment
     //~| ERROR `_` can only be used on the left-hand side of an assignment
-    //~| ERROR destructuring assignments are unstable
-    //~| ERROR destructuring assignments are unstable
     let _: usize = T::baz(_, _);
     //~^ ERROR `_` can only be used on the left-hand side of an assignment
     //~| ERROR `_` can only be used on the left-hand side of an assignment
-    //~| ERROR destructuring assignments are unstable
-    //~| ERROR destructuring assignments are unstable
 }
diff --git a/src/test/ui/suggestions/fn-or-tuple-struct-with-underscore-args.stderr b/src/test/ui/suggestions/fn-or-tuple-struct-with-underscore-args.stderr
index 248fa6b9c9c..aa562030619 100644
--- a/src/test/ui/suggestions/fn-or-tuple-struct-with-underscore-args.stderr
+++ b/src/test/ui/suggestions/fn-or-tuple-struct-with-underscore-args.stderr
@@ -1,57 +1,3 @@
-error[E0658]: destructuring assignments are unstable
-  --> $DIR/fn-or-tuple-struct-with-underscore-args.rs:10:24
-   |
-LL |     let _: usize = foo(_, _);
-   |                        ^
-   |
-   = note: see issue #71126 <https://github.com/rust-lang/rust/issues/71126> for more information
-   = help: add `#![feature(destructuring_assignment)]` to the crate attributes to enable
-
-error[E0658]: destructuring assignments are unstable
-  --> $DIR/fn-or-tuple-struct-with-underscore-args.rs:10:27
-   |
-LL |     let _: usize = foo(_, _);
-   |                           ^
-   |
-   = note: see issue #71126 <https://github.com/rust-lang/rust/issues/71126> for more information
-   = help: add `#![feature(destructuring_assignment)]` to the crate attributes to enable
-
-error[E0658]: destructuring assignments are unstable
-  --> $DIR/fn-or-tuple-struct-with-underscore-args.rs:15:18
-   |
-LL |     let _: S = S(_, _);
-   |                  ^
-   |
-   = note: see issue #71126 <https://github.com/rust-lang/rust/issues/71126> for more information
-   = help: add `#![feature(destructuring_assignment)]` to the crate attributes to enable
-
-error[E0658]: destructuring assignments are unstable
-  --> $DIR/fn-or-tuple-struct-with-underscore-args.rs:15:21
-   |
-LL |     let _: S = S(_, _);
-   |                     ^
-   |
-   = note: see issue #71126 <https://github.com/rust-lang/rust/issues/71126> for more information
-   = help: add `#![feature(destructuring_assignment)]` to the crate attributes to enable
-
-error[E0658]: destructuring assignments are unstable
-  --> $DIR/fn-or-tuple-struct-with-underscore-args.rs:20:27
-   |
-LL |     let _: usize = T::baz(_, _);
-   |                           ^
-   |
-   = note: see issue #71126 <https://github.com/rust-lang/rust/issues/71126> for more information
-   = help: add `#![feature(destructuring_assignment)]` to the crate attributes to enable
-
-error[E0658]: destructuring assignments are unstable
-  --> $DIR/fn-or-tuple-struct-with-underscore-args.rs:20:30
-   |
-LL |     let _: usize = T::baz(_, _);
-   |                              ^
-   |
-   = note: see issue #71126 <https://github.com/rust-lang/rust/issues/71126> for more information
-   = help: add `#![feature(destructuring_assignment)]` to the crate attributes to enable
-
 error: in expressions, `_` can only be used on the left-hand side of an assignment
   --> $DIR/fn-or-tuple-struct-with-underscore-args.rs:10:24
    |
@@ -65,29 +11,28 @@ LL |     let _: usize = foo(_, _);
    |                           ^ `_` not allowed here
 
 error: in expressions, `_` can only be used on the left-hand side of an assignment
-  --> $DIR/fn-or-tuple-struct-with-underscore-args.rs:15:18
+  --> $DIR/fn-or-tuple-struct-with-underscore-args.rs:13:18
    |
 LL |     let _: S = S(_, _);
    |                  ^ `_` not allowed here
 
 error: in expressions, `_` can only be used on the left-hand side of an assignment
-  --> $DIR/fn-or-tuple-struct-with-underscore-args.rs:15:21
+  --> $DIR/fn-or-tuple-struct-with-underscore-args.rs:13:21
    |
 LL |     let _: S = S(_, _);
    |                     ^ `_` not allowed here
 
 error: in expressions, `_` can only be used on the left-hand side of an assignment
-  --> $DIR/fn-or-tuple-struct-with-underscore-args.rs:20:27
+  --> $DIR/fn-or-tuple-struct-with-underscore-args.rs:16:27
    |
 LL |     let _: usize = T::baz(_, _);
    |                           ^ `_` not allowed here
 
 error: in expressions, `_` can only be used on the left-hand side of an assignment
-  --> $DIR/fn-or-tuple-struct-with-underscore-args.rs:20:30
+  --> $DIR/fn-or-tuple-struct-with-underscore-args.rs:16:30
    |
 LL |     let _: usize = T::baz(_, _);
    |                              ^ `_` not allowed here
 
-error: aborting due to 12 previous errors
+error: aborting due to 6 previous errors
 
-For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/suggestions/if-let-typo.rs b/src/test/ui/suggestions/if-let-typo.rs
index b9714b67e58..375bd3f03c9 100644
--- a/src/test/ui/suggestions/if-let-typo.rs
+++ b/src/test/ui/suggestions/if-let-typo.rs
@@ -3,12 +3,9 @@ fn main() {
     let bar = None;
     if Some(x) = foo {} //~ ERROR cannot find value `x` in this scope
     //~^ ERROR mismatched types
-    //~^^ ERROR destructuring assignments are unstable
     if Some(foo) = bar {} //~ ERROR mismatched types
-    //~^ ERROR destructuring assignments are unstable
     if 3 = foo {} //~ ERROR mismatched types
     if Some(3) = foo {} //~ ERROR mismatched types
-    //~^ ERROR destructuring assignments are unstable
-    //~^^ ERROR invalid left-hand side of assignment
+    //~^ ERROR invalid left-hand side of assignment
     if x = 5 {}  //~ ERROR cannot find value `x` in this scope
 }
diff --git a/src/test/ui/suggestions/if-let-typo.stderr b/src/test/ui/suggestions/if-let-typo.stderr
index 058f42f2200..3d9ac40ec36 100644
--- a/src/test/ui/suggestions/if-let-typo.stderr
+++ b/src/test/ui/suggestions/if-let-typo.stderr
@@ -10,7 +10,7 @@ LL |     if let Some(x) = foo {}
    |        +++
 
 error[E0425]: cannot find value `x` in this scope
-  --> $DIR/if-let-typo.rs:13:8
+  --> $DIR/if-let-typo.rs:10:8
    |
 LL |     if x = 5 {}
    |        ^ not found in this scope
@@ -20,39 +20,6 @@ help: you might have meant to use pattern matching
 LL |     if let x = 5 {}
    |        +++
 
-error[E0658]: destructuring assignments are unstable
-  --> $DIR/if-let-typo.rs:4:16
-   |
-LL |     if Some(x) = foo {}
-   |        ------- ^
-   |        |
-   |        cannot assign to this expression
-   |
-   = note: see issue #71126 <https://github.com/rust-lang/rust/issues/71126> for more information
-   = help: add `#![feature(destructuring_assignment)]` to the crate attributes to enable
-
-error[E0658]: destructuring assignments are unstable
-  --> $DIR/if-let-typo.rs:7:18
-   |
-LL |     if Some(foo) = bar {}
-   |        --------- ^
-   |        |
-   |        cannot assign to this expression
-   |
-   = note: see issue #71126 <https://github.com/rust-lang/rust/issues/71126> for more information
-   = help: add `#![feature(destructuring_assignment)]` to the crate attributes to enable
-
-error[E0658]: destructuring assignments are unstable
-  --> $DIR/if-let-typo.rs:10:16
-   |
-LL |     if Some(3) = foo {}
-   |        ------- ^
-   |        |
-   |        cannot assign to this expression
-   |
-   = note: see issue #71126 <https://github.com/rust-lang/rust/issues/71126> for more information
-   = help: add `#![feature(destructuring_assignment)]` to the crate attributes to enable
-
 error[E0308]: mismatched types
   --> $DIR/if-let-typo.rs:4:8
    |
@@ -60,19 +27,19 @@ LL |     if Some(x) = foo {}
    |        ^^^^^^^^^^^^^ expected `bool`, found `()`
 
 error[E0308]: mismatched types
-  --> $DIR/if-let-typo.rs:7:8
+  --> $DIR/if-let-typo.rs:6:8
    |
 LL |     if Some(foo) = bar {}
    |        ^^^^^^^^^^^^^^^ expected `bool`, found `()`
 
 error[E0308]: mismatched types
-  --> $DIR/if-let-typo.rs:9:8
+  --> $DIR/if-let-typo.rs:7:8
    |
 LL |     if 3 = foo {}
    |        ^^^^^^^ expected `bool`, found `()`
 
 error[E0070]: invalid left-hand side of assignment
-  --> $DIR/if-let-typo.rs:10:16
+  --> $DIR/if-let-typo.rs:8:16
    |
 LL |     if Some(3) = foo {}
    |             -  ^
@@ -80,12 +47,12 @@ LL |     if Some(3) = foo {}
    |             cannot assign to this expression
 
 error[E0308]: mismatched types
-  --> $DIR/if-let-typo.rs:10:8
+  --> $DIR/if-let-typo.rs:8:8
    |
 LL |     if Some(3) = foo {}
    |        ^^^^^^^^^^^^^ expected `bool`, found `()`
 
-error: aborting due to 10 previous errors
+error: aborting due to 7 previous errors
 
-Some errors have detailed explanations: E0070, E0308, E0425, E0658.
+Some errors have detailed explanations: E0070, E0308, E0425.
 For more information about an error, try `rustc --explain E0070`.
diff --git a/src/test/ui/weird-exprs.rs b/src/test/ui/weird-exprs.rs
index 2d7ebbf1d5b..a02b3230689 100644
--- a/src/test/ui/weird-exprs.rs
+++ b/src/test/ui/weird-exprs.rs
@@ -1,7 +1,6 @@
 // run-pass
 
 #![feature(generators)]
-#![feature(destructuring_assignment)]
 
 #![allow(non_camel_case_types)]
 #![allow(dead_code)]
diff --git a/src/tools/clippy/tests/ui/crashes/ice-6250.stderr b/src/tools/clippy/tests/ui/crashes/ice-6250.stderr
index 0d7713aa9a2..7ffbd7a64b3 100644
--- a/src/tools/clippy/tests/ui/crashes/ice-6250.stderr
+++ b/src/tools/clippy/tests/ui/crashes/ice-6250.stderr
@@ -1,14 +1,3 @@
-error[E0658]: destructuring assignments are unstable
-  --> $DIR/ice-6250.rs:12:25
-   |
-LL |         Some(reference) = cache.data.get(key) {
-   |         --------------- ^
-   |         |
-   |         cannot assign to this expression
-   |
-   = note: see issue #71126 <https://github.com/rust-lang/rust/issues/71126> for more information
-   = help: add `#![feature(destructuring_assignment)]` to the crate attributes to enable
-
 error[E0601]: `main` function not found in crate `ice_6250`
   --> $DIR/ice-6250.rs:4:1
    |
@@ -41,7 +30,7 @@ error[E0308]: mismatched types
 LL |         Some(reference) = cache.data.get(key) {
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `bool`, found `()`
 
-error: aborting due to 4 previous errors
+error: aborting due to 3 previous errors
 
-Some errors have detailed explanations: E0308, E0601, E0658.
+Some errors have detailed explanations: E0308, E0601.
 For more information about an error, try `rustc --explain E0308`.
diff --git a/src/tools/rustdoc-gui/tester.js b/src/tools/rustdoc-gui/tester.js
index 3feb4940d87..32340ec7eec 100644
--- a/src/tools/rustdoc-gui/tester.js
+++ b/src/tools/rustdoc-gui/tester.js
@@ -133,7 +133,7 @@ async function main(argv) {
     // Print successful tests too
     let debug = false;
     // Run tests in sequentially
-    let no_headless = false;
+    let headless = true;
     const options = new Options();
     try {
         // This is more convenient that setting fields one by one.
@@ -150,7 +150,7 @@ async function main(argv) {
         }
         if (opts["no_headless"]) {
             args.push("--no-headless");
-            no_headless = true;
+            headless = false;
         }
         options.parseArguments(args);
     } catch (error) {
@@ -172,7 +172,7 @@ async function main(argv) {
     }
     files.sort();
 
-    if (no_headless) {
+    if (!headless) {
         opts["jobs"] = 1;
         console.log("`--no-headless` option is active, disabling concurrency for running tests.");
     }
@@ -181,7 +181,7 @@ async function main(argv) {
 
     if (opts["jobs"] < 1) {
         process.setMaxListeners(files.length + 1);
-    } else if (!no_headless) {
+    } else if (headless) {
         process.setMaxListeners(opts["jobs"] + 1);
     }
 
@@ -226,7 +226,7 @@ async function main(argv) {
             await Promise.race(tests_queue);
         }
     }
-    if (!no_headless && tests_queue.length > 0) {
+    if (tests_queue.length > 0) {
         await Promise.all(tests_queue);
     }
     status_bar.finish();