about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_ast/src/ast.rs7
-rw-r--r--compiler/rustc_ast/src/node_id.rs5
-rw-r--r--compiler/rustc_borrowck/src/constraints/mod.rs10
-rw-r--r--compiler/rustc_borrowck/src/dataflow.rs5
-rw-r--r--compiler/rustc_borrowck/src/location.rs5
-rw-r--r--compiler/rustc_borrowck/src/member_constraints.rs5
-rw-r--r--compiler/rustc_borrowck/src/region_infer/values.rs6
-rw-r--r--compiler/rustc_borrowck/src/type_check/liveness/local_use_map.rs2
-rw-r--r--compiler/rustc_data_structures/src/graph/dominators/mod.rs2
-rw-r--r--compiler/rustc_error_codes/src/error_codes.rs3
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0377.md29
-rw-r--r--compiler/rustc_hir/src/hir_id.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs6
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/arg_matrix.rs10
-rw-r--r--compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/mod.rs10
-rw-r--r--compiler/rustc_index/src/vec/tests.rs5
-rw-r--r--compiler/rustc_infer/src/infer/region_constraints/leak_check.rs10
-rw-r--r--compiler/rustc_lint/src/levels.rs4
-rw-r--r--compiler/rustc_macros/src/newtype.rs155
-rw-r--r--compiler/rustc_middle/src/middle/region.rs5
-rw-r--r--compiler/rustc_middle/src/mir/coverage.rs42
-rw-r--r--compiler/rustc_middle/src/mir/mod.rs32
-rw-r--r--compiler/rustc_middle/src/mir/query.rs7
-rw-r--r--compiler/rustc_middle/src/thir.rs5
-rw-r--r--compiler/rustc_middle/src/ty/structural_impls.rs6
-rw-r--r--compiler/rustc_middle/src/ty/sty.rs7
-rw-r--r--compiler/rustc_middle/src/ty/typeck_results.rs6
-rw-r--r--compiler/rustc_mir_build/src/build/mod.rs2
-rw-r--r--compiler/rustc_mir_build/src/build/scope.rs2
-rw-r--r--compiler/rustc_mir_dataflow/src/move_paths/mod.rs15
-rw-r--r--compiler/rustc_mir_transform/src/cleanup_post_borrowck.rs65
-rw-r--r--compiler/rustc_mir_transform/src/coverage/graph.rs4
-rw-r--r--compiler/rustc_mir_transform/src/lib.rs5
-rw-r--r--compiler/rustc_mir_transform/src/normalize_array_len.rs3
-rw-r--r--compiler/rustc_mir_transform/src/remove_false_edges.rs29
-rw-r--r--compiler/rustc_passes/src/liveness.rs10
-rw-r--r--compiler/rustc_query_system/src/dep_graph/graph.rs4
-rw-r--r--compiler/rustc_query_system/src/dep_graph/serialized.rs5
-rw-r--r--compiler/rustc_span/src/def_id.rs14
-rw-r--r--compiler/rustc_span/src/hygiene.rs14
-rw-r--r--compiler/rustc_span/src/symbol.rs2
-rw-r--r--compiler/rustc_target/src/abi/mod.rs5
-rw-r--r--compiler/rustc_type_ir/src/lib.rs14
-rw-r--r--library/alloc/src/boxed.rs2
-rw-r--r--library/alloc/src/rc.rs4
-rw-r--r--library/alloc/src/sync.rs4
-rw-r--r--library/core/src/cell.rs12
-rw-r--r--library/core/src/marker.rs2
-rw-r--r--library/core/src/ops/mod.rs2
-rw-r--r--library/core/src/ops/unsize.rs20
-rw-r--r--library/core/src/ptr/non_null.rs2
-rw-r--r--src/bootstrap/install.rs12
-rw-r--r--src/librustdoc/clean/cfg.rs2
-rw-r--r--src/librustdoc/html/static/css/rustdoc.css11
-rw-r--r--src/test/mir-opt/const_prop/slice_len.main.ConstProp.32bit.diff7
-rw-r--r--src/test/mir-opt/const_prop/slice_len.main.ConstProp.64bit.diff7
-rw-r--r--src/test/mir-opt/issue_76432.test.SimplifyComparisonIntegral.diff12
-rw-r--r--src/test/mir-opt/lower_array_len_e2e.rs2
-rw-r--r--src/test/mir-opt/remove_fake_borrows.match_guard.CleanupPostBorrowck.diff (renamed from src/test/mir-opt/remove_fake_borrows.match_guard.CleanupNonCodegenStatements.diff)14
-rw-r--r--src/test/mir-opt/remove_fake_borrows.rs2
-rw-r--r--src/test/rustdoc-gui/codeblock-sub.goml5
-rw-r--r--src/test/rustdoc-gui/src/test_docs/lib.rs19
-rw-r--r--src/test/rustdoc-gui/struct-fields.goml2
-rw-r--r--src/test/ui/error-codes/E0377.rs14
-rw-r--r--src/test/ui/error-codes/E0377.stderr9
-rw-r--r--src/tools/tidy/src/error_codes_check.rs4
66 files changed, 344 insertions, 410 deletions
diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs
index f933b9b161c..31596a1e9bf 100644
--- a/compiler/rustc_ast/src/ast.rs
+++ b/compiler/rustc_ast/src/ast.rs
@@ -2554,10 +2554,9 @@ pub enum AttrStyle {
 }
 
 rustc_index::newtype_index! {
-    pub struct AttrId {
-        ENCODABLE = custom
-        DEBUG_FORMAT = "AttrId({})"
-    }
+    #[custom_encodable]
+    #[debug_format = "AttrId({})]"]
+    pub struct AttrId {}
 }
 
 impl<S: Encoder> Encodable<S> for AttrId {
diff --git a/compiler/rustc_ast/src/node_id.rs b/compiler/rustc_ast/src/node_id.rs
index 7b5acc3f485..daa82996b3d 100644
--- a/compiler/rustc_ast/src/node_id.rs
+++ b/compiler/rustc_ast/src/node_id.rs
@@ -8,9 +8,8 @@ rustc_index::newtype_index! {
     /// This is later turned into [`DefId`] and `HirId` for the HIR.
     ///
     /// [`DefId`]: rustc_span::def_id::DefId
-    pub struct NodeId {
-        DEBUG_FORMAT = "NodeId({})"
-    }
+    #[debug_format = "NodeId({})"]
+    pub struct NodeId {}
 }
 
 rustc_data_structures::define_id_collections!(NodeMap, NodeSet, NodeMapEntry, NodeId);
diff --git a/compiler/rustc_borrowck/src/constraints/mod.rs b/compiler/rustc_borrowck/src/constraints/mod.rs
index 84a93e5f72e..1f0b8adeaf1 100644
--- a/compiler/rustc_borrowck/src/constraints/mod.rs
+++ b/compiler/rustc_borrowck/src/constraints/mod.rs
@@ -115,13 +115,11 @@ impl<'tcx> fmt::Debug for OutlivesConstraint<'tcx> {
 }
 
 rustc_index::newtype_index! {
-    pub struct OutlivesConstraintIndex {
-        DEBUG_FORMAT = "OutlivesConstraintIndex({})"
-    }
+    #[debug_format = "OutlivesConstraintIndex({})"]
+    pub struct OutlivesConstraintIndex {}
 }
 
 rustc_index::newtype_index! {
-    pub struct ConstraintSccIndex {
-        DEBUG_FORMAT = "ConstraintSccIndex({})"
-    }
+    #[debug_format = "ConstraintSccIndex({})"]
+    pub struct ConstraintSccIndex {}
 }
diff --git a/compiler/rustc_borrowck/src/dataflow.rs b/compiler/rustc_borrowck/src/dataflow.rs
index f825b1d8f70..8c4885770ad 100644
--- a/compiler/rustc_borrowck/src/dataflow.rs
+++ b/compiler/rustc_borrowck/src/dataflow.rs
@@ -108,9 +108,8 @@ impl_visitable! {
 }
 
 rustc_index::newtype_index! {
-    pub struct BorrowIndex {
-        DEBUG_FORMAT = "bw{}"
-    }
+    #[debug_format = "bw{}"]
+    pub struct BorrowIndex {}
 }
 
 /// `Borrows` stores the data used in the analyses that track the flow
diff --git a/compiler/rustc_borrowck/src/location.rs b/compiler/rustc_borrowck/src/location.rs
index 9fa7e218b1b..288b7d85be2 100644
--- a/compiler/rustc_borrowck/src/location.rs
+++ b/compiler/rustc_borrowck/src/location.rs
@@ -20,9 +20,8 @@ pub struct LocationTable {
 }
 
 rustc_index::newtype_index! {
-    pub struct LocationIndex {
-        DEBUG_FORMAT = "LocationIndex({})"
-    }
+    #[debug_format = "LocationIndex({})"]
+    pub struct LocationIndex {}
 }
 
 #[derive(Copy, Clone, Debug)]
diff --git a/compiler/rustc_borrowck/src/member_constraints.rs b/compiler/rustc_borrowck/src/member_constraints.rs
index b5e00f471d2..b63e286676f 100644
--- a/compiler/rustc_borrowck/src/member_constraints.rs
+++ b/compiler/rustc_borrowck/src/member_constraints.rs
@@ -55,9 +55,8 @@ pub(crate) struct NllMemberConstraint<'tcx> {
 }
 
 rustc_index::newtype_index! {
-    pub(crate) struct NllMemberConstraintIndex {
-        DEBUG_FORMAT = "MemberConstraintIndex({})"
-    }
+    #[debug_format = "MemberConstraintIndex({})"]
+    pub(crate) struct NllMemberConstraintIndex {}
 }
 
 impl Default for MemberConstraintSet<'_, ty::RegionVid> {
diff --git a/compiler/rustc_borrowck/src/region_infer/values.rs b/compiler/rustc_borrowck/src/region_infer/values.rs
index 7498ddccf19..c3dfeedc205 100644
--- a/compiler/rustc_borrowck/src/region_infer/values.rs
+++ b/compiler/rustc_borrowck/src/region_infer/values.rs
@@ -90,12 +90,14 @@ impl RegionValueElements {
 rustc_index::newtype_index! {
     /// A single integer representing a `Location` in the MIR control-flow
     /// graph. Constructed efficiently from `RegionValueElements`.
-    pub struct PointIndex { DEBUG_FORMAT = "PointIndex({})" }
+    #[debug_format = "PointIndex({})"]
+    pub struct PointIndex {}
 }
 
 rustc_index::newtype_index! {
     /// A single integer representing a `ty::Placeholder`.
-    pub struct PlaceholderIndex { DEBUG_FORMAT = "PlaceholderIndex({})" }
+    #[debug_format = "PlaceholderIndex({})"]
+    pub struct PlaceholderIndex {}
 }
 
 /// An individual element in a region value -- the value of a
diff --git a/compiler/rustc_borrowck/src/type_check/liveness/local_use_map.rs b/compiler/rustc_borrowck/src/type_check/liveness/local_use_map.rs
index fda2cee43fb..8023ef60d20 100644
--- a/compiler/rustc_borrowck/src/type_check/liveness/local_use_map.rs
+++ b/compiler/rustc_borrowck/src/type_check/liveness/local_use_map.rs
@@ -46,7 +46,7 @@ struct Appearance {
 }
 
 rustc_index::newtype_index! {
-    pub struct AppearanceIndex { .. }
+    pub struct AppearanceIndex {}
 }
 
 impl vll::LinkElem for Appearance {
diff --git a/compiler/rustc_data_structures/src/graph/dominators/mod.rs b/compiler/rustc_data_structures/src/graph/dominators/mod.rs
index 00913a483db..94a8c1fc051 100644
--- a/compiler/rustc_data_structures/src/graph/dominators/mod.rs
+++ b/compiler/rustc_data_structures/src/graph/dominators/mod.rs
@@ -22,7 +22,7 @@ struct PreOrderFrame<Iter> {
 }
 
 rustc_index::newtype_index! {
-    struct PreorderIndex { .. }
+    struct PreorderIndex {}
 }
 
 pub fn dominators<G: ControlFlowGraph>(graph: G) -> Dominators<G::Node> {
diff --git a/compiler/rustc_error_codes/src/error_codes.rs b/compiler/rustc_error_codes/src/error_codes.rs
index 883a4bbe8e8..4e149fc2b99 100644
--- a/compiler/rustc_error_codes/src/error_codes.rs
+++ b/compiler/rustc_error_codes/src/error_codes.rs
@@ -184,6 +184,7 @@ E0373: include_str!("./error_codes/E0373.md"),
 E0374: include_str!("./error_codes/E0374.md"),
 E0375: include_str!("./error_codes/E0375.md"),
 E0376: include_str!("./error_codes/E0376.md"),
+E0377: include_str!("./error_codes/E0377.md"),
 E0378: include_str!("./error_codes/E0378.md"),
 E0379: include_str!("./error_codes/E0379.md"),
 E0380: include_str!("./error_codes/E0380.md"),
@@ -579,8 +580,6 @@ E0791: include_str!("./error_codes/E0791.md"),
 //  E0315, // cannot invoke closure outside of its lifetime
 //  E0319, // trait impls for defaulted traits allowed just for structs/enums
 //  E0372, // coherence not object safe
-    E0377, // the trait `CoerceUnsized` may only be implemented for a coercion
-           // between structures with the same definition
 //  E0385, // {} in an aliasable location
 //  E0402, // cannot use an outer type parameter in this context
 //  E0406, // merged into 420
diff --git a/compiler/rustc_error_codes/src/error_codes/E0377.md b/compiler/rustc_error_codes/src/error_codes/E0377.md
new file mode 100644
index 00000000000..b1d36406332
--- /dev/null
+++ b/compiler/rustc_error_codes/src/error_codes/E0377.md
@@ -0,0 +1,29 @@
+The trait `CoerceUnsized` may only be implemented for a coercion between
+structures with the same definition.
+
+Example of erroneous code:
+
+```compile_fail,E0377
+#![feature(coerce_unsized)]
+use std::ops::CoerceUnsized;
+
+pub struct Foo<T: ?Sized> {
+    field_with_unsized_type: T,
+}
+
+pub struct Bar<T: ?Sized> {
+    field_with_unsized_type: T,
+}
+
+// error: the trait `CoerceUnsized` may only be implemented for a coercion
+//        between structures with the same definition
+impl<T, U> CoerceUnsized<Bar<U>> for Foo<T> where T: CoerceUnsized<U> {}
+```
+
+When attempting to implement `CoerceUnsized`, the `impl` signature must look
+like: `impl CoerceUnsized<Type<U>> for Type<T> where T: CoerceUnsized<U>`;
+the *implementer* and *`CoerceUnsized` type parameter* must be the same
+type. In this example, `Bar` and `Foo` (even though structurally identical)
+are *not* the same type and are rejected. Learn more about the `CoerceUnsized`
+trait and DST coercion in
+[the `CoerceUnsized` docs](../std/ops/trait.CoerceUnsized.html).
diff --git a/compiler/rustc_hir/src/hir_id.rs b/compiler/rustc_hir/src/hir_id.rs
index 060f40919f5..03bcaa69468 100644
--- a/compiler/rustc_hir/src/hir_id.rs
+++ b/compiler/rustc_hir/src/hir_id.rs
@@ -138,7 +138,7 @@ rustc_index::newtype_index! {
     /// an "item-like" to something else can be implemented by a `Vec` instead of a
     /// tree or hash map.
     #[derive(HashStable_Generic)]
-    pub struct ItemLocalId { .. }
+    pub struct ItemLocalId {}
 }
 
 impl ItemLocalId {
diff --git a/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs b/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs
index 972769eb197..a9331af4eab 100644
--- a/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs
+++ b/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs
@@ -198,10 +198,10 @@ impl<'tcx> InherentOverlapChecker<'tcx> {
             // entire graph when there are many connected regions.
 
             rustc_index::newtype_index! {
-                pub struct RegionId {
-                    ENCODABLE = custom
-                }
+                #[custom_encodable]
+                pub struct RegionId {}
             }
+
             struct ConnectedRegion {
                 idents: SmallVec<[Symbol; 8]>,
                 impl_blocks: FxHashSet<usize>,
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/arg_matrix.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/arg_matrix.rs
index fc83994caf5..6f26afcaf16 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/arg_matrix.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/arg_matrix.rs
@@ -4,15 +4,13 @@ use rustc_index::vec::IndexVec;
 use rustc_middle::ty::error::TypeError;
 
 rustc_index::newtype_index! {
-    pub(crate) struct ExpectedIdx {
-        DEBUG_FORMAT = "ExpectedIdx({})",
-    }
+    #[debug_format = "ExpectedIdx({})"]
+    pub(crate) struct ExpectedIdx {}
 }
 
 rustc_index::newtype_index! {
-    pub(crate) struct ProvidedIdx {
-        DEBUG_FORMAT = "ProvidedIdx({})",
-    }
+    #[debug_format = "ProvidedIdx({})"]
+    pub(crate) struct ProvidedIdx {}
 }
 
 impl ExpectedIdx {
diff --git a/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/mod.rs b/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/mod.rs
index 2abcadcc9ce..2f55ea939fc 100644
--- a/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/mod.rs
+++ b/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/mod.rs
@@ -96,15 +96,13 @@ fn for_each_consumable<'tcx>(hir: Map<'tcx>, place: TrackedValue, mut f: impl Fn
 }
 
 rustc_index::newtype_index! {
-    pub struct PostOrderId {
-        DEBUG_FORMAT = "id({})",
-    }
+    #[debug_format = "id({})"]
+    pub struct PostOrderId {}
 }
 
 rustc_index::newtype_index! {
-    pub struct TrackedValueIndex {
-        DEBUG_FORMAT = "hidx({})",
-    }
+    #[debug_format = "hidx({})"]
+    pub struct TrackedValueIndex {}
 }
 
 /// Identifies a value whose drop state we need to track.
diff --git a/compiler/rustc_index/src/vec/tests.rs b/compiler/rustc_index/src/vec/tests.rs
index 915d2e8bcb3..cb0f0db220d 100644
--- a/compiler/rustc_index/src/vec/tests.rs
+++ b/compiler/rustc_index/src/vec/tests.rs
@@ -3,7 +3,10 @@
 // Allows the macro invocation below to work
 use crate as rustc_index;
 
-rustc_macros::newtype_index!(struct MyIdx { MAX = 0xFFFF_FFFA });
+rustc_macros::newtype_index! {
+    #[max = 0xFFFF_FFFA]
+    struct MyIdx {}
+}
 
 #[test]
 fn index_size_is_optimized() {
diff --git a/compiler/rustc_infer/src/infer/region_constraints/leak_check.rs b/compiler/rustc_infer/src/infer/region_constraints/leak_check.rs
index 22b4bbb17d4..c46edc33ff4 100644
--- a/compiler/rustc_infer/src/infer/region_constraints/leak_check.rs
+++ b/compiler/rustc_infer/src/infer/region_constraints/leak_check.rs
@@ -357,15 +357,13 @@ impl<'tcx> SccUniverse<'tcx> {
 }
 
 rustc_index::newtype_index! {
-    struct LeakCheckNode {
-        DEBUG_FORMAT = "LeakCheckNode({})"
-    }
+    #[debug_format = "LeakCheckNode({})"]
+    struct LeakCheckNode {}
 }
 
 rustc_index::newtype_index! {
-    struct LeakCheckScc {
-        DEBUG_FORMAT = "LeakCheckScc({})"
-    }
+    #[debug_format = "LeakCheckScc({})"]
+    struct LeakCheckScc {}
 }
 
 /// Represents the graph of constraints. For each `R1: R2` constraint we create
diff --git a/compiler/rustc_lint/src/levels.rs b/compiler/rustc_lint/src/levels.rs
index 847c356b83c..e9d3d44a3f9 100644
--- a/compiler/rustc_lint/src/levels.rs
+++ b/compiler/rustc_lint/src/levels.rs
@@ -39,9 +39,9 @@ struct LintLevelSets {
 }
 
 rustc_index::newtype_index! {
+    #[custom_encodable] // we don't need encoding
     struct LintStackIndex {
-        ENCODABLE = custom, // we don't need encoding
-        const COMMAND_LINE = 0,
+        const COMMAND_LINE = 0;
     }
 }
 
diff --git a/compiler/rustc_macros/src/newtype.rs b/compiler/rustc_macros/src/newtype.rs
index fd3f5225155..153473de624 100644
--- a/compiler/rustc_macros/src/newtype.rs
+++ b/compiler/rustc_macros/src/newtype.rs
@@ -1,35 +1,15 @@
 use proc_macro2::{Span, TokenStream};
 use quote::quote;
 use syn::parse::*;
-use syn::punctuated::Punctuated;
 use syn::*;
 
-mod kw {
-    syn::custom_keyword!(derive);
-    syn::custom_keyword!(DEBUG_FORMAT);
-    syn::custom_keyword!(MAX);
-    syn::custom_keyword!(ENCODABLE);
-    syn::custom_keyword!(custom);
-    syn::custom_keyword!(ORD_IMPL);
-}
-
-#[derive(Debug)]
-enum DebugFormat {
-    // The user will provide a custom `Debug` impl, so we shouldn't generate
-    // one
-    Custom,
-    // Use the specified format string in the generated `Debug` impl
-    // By default, this is "{}"
-    Format(String),
-}
-
 // We parse the input and emit the output in a single step.
 // This field stores the final macro output
 struct Newtype(TokenStream);
 
 impl Parse for Newtype {
     fn parse(input: ParseStream<'_>) -> Result<Self> {
-        let attrs = input.call(Attribute::parse_outer)?;
+        let mut attrs = input.call(Attribute::parse_outer)?;
         let vis: Visibility = input.parse()?;
         input.parse::<Token![struct]>()?;
         let name: Ident = input.parse()?;
@@ -39,93 +19,68 @@ impl Parse for Newtype {
 
         // Any additional `#[derive]` macro paths to apply
         let mut derive_paths: Vec<Path> = Vec::new();
-        let mut debug_format: Option<DebugFormat> = None;
+        let mut debug_format: Option<Lit> = None;
         let mut max = None;
         let mut consts = Vec::new();
         let mut encodable = true;
         let mut ord = true;
 
-        // Parse an optional trailing comma
-        let try_comma = || -> Result<()> {
-            if body.lookahead1().peek(Token![,]) {
-                body.parse::<Token![,]>()?;
-            }
-            Ok(())
-        };
-
-        if body.lookahead1().peek(Token![..]) {
-            body.parse::<Token![..]>()?;
-        } else {
-            loop {
-                if body.lookahead1().peek(kw::derive) {
-                    body.parse::<kw::derive>()?;
-                    let derives;
-                    bracketed!(derives in body);
-                    let derives: Punctuated<Path, Token![,]> =
-                        derives.parse_terminated(Path::parse)?;
-                    try_comma()?;
-                    derive_paths.extend(derives);
-                    continue;
-                }
-                if body.lookahead1().peek(kw::DEBUG_FORMAT) {
-                    body.parse::<kw::DEBUG_FORMAT>()?;
-                    body.parse::<Token![=]>()?;
-                    let new_debug_format = if body.lookahead1().peek(kw::custom) {
-                        body.parse::<kw::custom>()?;
-                        DebugFormat::Custom
-                    } else {
-                        let format_str: LitStr = body.parse()?;
-                        DebugFormat::Format(format_str.value())
-                    };
-                    try_comma()?;
-                    if let Some(old) = debug_format.replace(new_debug_format) {
-                        panic!("Specified multiple debug format options: {:?}", old);
-                    }
-                    continue;
-                }
-                if body.lookahead1().peek(kw::MAX) {
-                    body.parse::<kw::MAX>()?;
-                    body.parse::<Token![=]>()?;
-                    let val: Lit = body.parse()?;
-                    try_comma()?;
-                    if let Some(old) = max.replace(val) {
-                        panic!("Specified multiple MAX: {:?}", old);
-                    }
-                    continue;
-                }
-                if body.lookahead1().peek(kw::ENCODABLE) {
-                    body.parse::<kw::ENCODABLE>()?;
-                    body.parse::<Token![=]>()?;
-                    body.parse::<kw::custom>()?;
-                    try_comma()?;
+        attrs.retain(|attr| match attr.path.get_ident() {
+            Some(ident) => match &*ident.to_string() {
+                "custom_encodable" => {
                     encodable = false;
-                    continue;
+                    false
                 }
-                if body.lookahead1().peek(kw::ORD_IMPL) {
-                    body.parse::<kw::ORD_IMPL>()?;
-                    body.parse::<Token![=]>()?;
-                    body.parse::<kw::custom>()?;
+                "no_ord_impl" => {
                     ord = false;
-                    continue;
+                    false
                 }
+                "max" => {
+                    let Ok(Meta::NameValue(literal) )= attr.parse_meta() else {
+                        panic!("#[max = NUMBER] attribute requires max value");
+                    };
+
+                    if let Some(old) = max.replace(literal.lit) {
+                        panic!("Specified multiple max: {:?}", old);
+                    }
 
-                // We've parsed everything that the user provided, so we're done
-                if body.is_empty() {
-                    break;
+                    false
                 }
+                "debug_format" => {
+                    let Ok(Meta::NameValue(literal) )= attr.parse_meta() else {
+                        panic!("#[debug_format = FMT] attribute requires a format");
+                    };
+
+                    if let Some(old) = debug_format.replace(literal.lit) {
+                        panic!("Specified multiple debug format options: {:?}", old);
+                    }
 
-                // Otherwise, we are parsing a user-defined constant
-                let const_attrs = body.call(Attribute::parse_outer)?;
-                body.parse::<Token![const]>()?;
-                let const_name: Ident = body.parse()?;
-                body.parse::<Token![=]>()?;
-                let const_val: Expr = body.parse()?;
-                try_comma()?;
-                consts.push(quote! { #(#const_attrs)* #vis const #const_name: #name = #name::from_u32(#const_val); });
+                    false
+                }
+                _ => true,
+            },
+            _ => true,
+        });
+
+        loop {
+            // We've parsed everything that the user provided, so we're done
+            if body.is_empty() {
+                break;
             }
+
+            // Otherwise, we are parsing a user-defined constant
+            let const_attrs = body.call(Attribute::parse_outer)?;
+            body.parse::<Token![const]>()?;
+            let const_name: Ident = body.parse()?;
+            body.parse::<Token![=]>()?;
+            let const_val: Expr = body.parse()?;
+            body.parse::<Token![;]>()?;
+            consts.push(quote! { #(#const_attrs)* #vis const #const_name: #name = #name::from_u32(#const_val); });
         }
 
-        let debug_format = debug_format.unwrap_or(DebugFormat::Format("{}".to_string()));
+        let debug_format =
+            debug_format.unwrap_or_else(|| Lit::Str(LitStr::new("{}", Span::call_site())));
+
         // shave off 256 indices at the end to allow space for packing these indices into enums
         let max = max.unwrap_or_else(|| Lit::Int(LitInt::new("0xFFFF_FF00", Span::call_site())));
 
@@ -180,18 +135,14 @@ impl Parse for Newtype {
             quote! {}
         };
 
-        let debug_impl = match debug_format {
-            DebugFormat::Custom => quote! {},
-            DebugFormat::Format(format) => {
-                quote! {
-                    impl ::std::fmt::Debug for #name {
-                        fn fmt(&self, fmt: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
-                            write!(fmt, #format, self.as_u32())
-                        }
-                    }
+        let debug_impl = quote! {
+            impl ::std::fmt::Debug for #name {
+                fn fmt(&self, fmt: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
+                    write!(fmt, #debug_format, self.as_u32())
                 }
             }
         };
+
         let spec_partial_eq_impl = if let Lit::Int(max) = &max {
             if let Ok(max_val) = max.base10_parse::<u32>() {
                 quote! {
diff --git a/compiler/rustc_middle/src/middle/region.rs b/compiler/rustc_middle/src/middle/region.rs
index c886175c6ea..94ca38c0e75 100644
--- a/compiler/rustc_middle/src/middle/region.rs
+++ b/compiler/rustc_middle/src/middle/region.rs
@@ -147,9 +147,8 @@ rustc_index::newtype_index! {
     ///
     /// * The subscope with `first_statement_index == 1` is scope of `c`,
     ///   and thus does not include EXPR_2, but covers the `...`.
-    pub struct FirstStatementIndex {
-        derive [HashStable]
-    }
+    #[derive(HashStable)]
+    pub struct FirstStatementIndex {}
 }
 
 // compilation error if size of `ScopeData` is not the same as a `u32`
diff --git a/compiler/rustc_middle/src/mir/coverage.rs b/compiler/rustc_middle/src/mir/coverage.rs
index 0b55757eb03..e7bb3ab0bc3 100644
--- a/compiler/rustc_middle/src/mir/coverage.rs
+++ b/compiler/rustc_middle/src/mir/coverage.rs
@@ -10,10 +10,10 @@ rustc_index::newtype_index! {
     /// CounterValueReference.as_u32() (which ascend from 1) or an ExpressionOperandId.as_u32()
     /// (which _*descend*_ from u32::MAX). Id value `0` (zero) represents a virtual counter with a
     /// constant value of `0`.
+    #[derive(HashStable)]
+    #[max = 0xFFFF_FFFF]
+    #[debug_format = "ExpressionOperandId({})"]
     pub struct ExpressionOperandId {
-        derive [HashStable]
-        DEBUG_FORMAT = "ExpressionOperandId({})",
-        MAX = 0xFFFF_FFFF,
     }
 }
 
@@ -32,11 +32,10 @@ impl ExpressionOperandId {
 }
 
 rustc_index::newtype_index! {
-    pub struct CounterValueReference {
-        derive [HashStable]
-        DEBUG_FORMAT = "CounterValueReference({})",
-        MAX = 0xFFFF_FFFF,
-    }
+    #[derive(HashStable)]
+    #[max = 0xFFFF_FFFF]
+    #[debug_format = "CounterValueReference({})"]
+    pub struct CounterValueReference {}
 }
 
 impl CounterValueReference {
@@ -56,33 +55,30 @@ rustc_index::newtype_index! {
     /// InjectedExpressionId.as_u32() converts to ExpressionOperandId.as_u32()
     ///
     /// Values descend from u32::MAX.
-    pub struct InjectedExpressionId {
-        derive [HashStable]
-        DEBUG_FORMAT = "InjectedExpressionId({})",
-        MAX = 0xFFFF_FFFF,
-    }
+    #[derive(HashStable)]
+    #[max = 0xFFFF_FFFF]
+    #[debug_format = "InjectedExpressionId({})"]
+    pub struct InjectedExpressionId {}
 }
 
 rustc_index::newtype_index! {
     /// InjectedExpressionIndex.as_u32() translates to u32::MAX - ExpressionOperandId.as_u32()
     ///
     /// Values ascend from 0.
-    pub struct InjectedExpressionIndex {
-        derive [HashStable]
-        DEBUG_FORMAT = "InjectedExpressionIndex({})",
-        MAX = 0xFFFF_FFFF,
-    }
+    #[derive(HashStable)]
+    #[max = 0xFFFF_FFFF]
+    #[debug_format = "InjectedExpressionIndex({})"]
+    pub struct InjectedExpressionIndex {}
 }
 
 rustc_index::newtype_index! {
     /// MappedExpressionIndex values ascend from zero, and are recalculated indexes based on their
     /// array position in the LLVM coverage map "Expressions" array, which is assembled during the
     /// "mapgen" process. They cannot be computed algorithmically, from the other `newtype_index`s.
-    pub struct MappedExpressionIndex {
-        derive [HashStable]
-        DEBUG_FORMAT = "MappedExpressionIndex({})",
-        MAX = 0xFFFF_FFFF,
-    }
+    #[derive(HashStable)]
+    #[max = 0xFFFF_FFFF]
+    #[debug_format = "MappedExpressionIndex({})"]
+    pub struct MappedExpressionIndex {}
 }
 
 impl From<CounterValueReference> for ExpressionOperandId {
diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs
index bdaa586c698..ffdf61d4244 100644
--- a/compiler/rustc_middle/src/mir/mod.rs
+++ b/compiler/rustc_middle/src/mir/mod.rs
@@ -654,10 +654,10 @@ impl SourceInfo {
 // Variables and temps
 
 rustc_index::newtype_index! {
+    #[derive(HashStable)]
+    #[debug_format = "_{}"]
     pub struct Local {
-        derive [HashStable]
-        DEBUG_FORMAT = "_{}",
-        const RETURN_PLACE = 0,
+        const RETURN_PLACE = 0;
     }
 }
 
@@ -1146,10 +1146,10 @@ rustc_index::newtype_index! {
     ///     https://rustc-dev-guide.rust-lang.org/appendix/background.html#what-is-a-dataflow-analysis
     /// [`CriticalCallEdges`]: ../../rustc_const_eval/transform/add_call_guards/enum.AddCallGuards.html#variant.CriticalCallEdges
     /// [guide-mir]: https://rustc-dev-guide.rust-lang.org/mir/
+    #[derive(HashStable)]
+    #[debug_format = "bb{}"]
     pub struct BasicBlock {
-        derive [HashStable]
-        DEBUG_FORMAT = "bb{}",
-        const START_BLOCK = 0,
+        const START_BLOCK = 0;
     }
 }
 
@@ -1530,10 +1530,9 @@ rustc_index::newtype_index! {
     /// [wrapper]: https://rustc-dev-guide.rust-lang.org/appendix/glossary.html#newtype
     /// [CFG]: https://rustc-dev-guide.rust-lang.org/appendix/background.html#cfg
     /// [mir-datatypes]: https://rustc-dev-guide.rust-lang.org/mir/index.html#mir-data-types
-    pub struct Field {
-        derive [HashStable]
-        DEBUG_FORMAT = "field[{}]"
-    }
+    #[derive(HashStable)]
+    #[debug_format = "field[{}]"]
+    pub struct Field {}
 }
 
 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
@@ -1757,10 +1756,10 @@ impl Debug for Place<'_> {
 // Scopes
 
 rustc_index::newtype_index! {
+    #[derive(HashStable)]
+    #[debug_format = "scope[{}]"]
     pub struct SourceScope {
-        derive [HashStable]
-        DEBUG_FORMAT = "scope[{}]",
-        const OUTERMOST_SOURCE_SCOPE = 0,
+        const OUTERMOST_SOURCE_SCOPE = 0;
     }
 }
 
@@ -2755,10 +2754,9 @@ impl<'tcx> TypeVisitable<'tcx> for UserTypeProjection {
 }
 
 rustc_index::newtype_index! {
-    pub struct Promoted {
-        derive [HashStable]
-        DEBUG_FORMAT = "promoted[{}]"
-    }
+    #[derive(HashStable)]
+    #[debug_format = "promoted[{}]"]
+    pub struct Promoted {}
 }
 
 impl<'tcx> Debug for Constant<'tcx> {
diff --git a/compiler/rustc_middle/src/mir/query.rs b/compiler/rustc_middle/src/mir/query.rs
index efd7357afc4..a8a4532223c 100644
--- a/compiler/rustc_middle/src/mir/query.rs
+++ b/compiler/rustc_middle/src/mir/query.rs
@@ -130,10 +130,9 @@ pub struct UnsafetyCheckResult {
 }
 
 rustc_index::newtype_index! {
-    pub struct GeneratorSavedLocal {
-        derive [HashStable]
-        DEBUG_FORMAT = "_{}",
-    }
+    #[derive(HashStable)]
+    #[debug_format = "_{}"]
+    pub struct GeneratorSavedLocal {}
 }
 
 /// The layout of generator state.
diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs
index 8bef9dfe099..ac903010c8d 100644
--- a/compiler/rustc_middle/src/thir.rs
+++ b/compiler/rustc_middle/src/thir.rs
@@ -35,9 +35,8 @@ macro_rules! thir_with_elements {
         $(
             newtype_index! {
                 #[derive(HashStable)]
-                pub struct $id {
-                    DEBUG_FORMAT = $format
-                }
+                #[debug_format = $format]
+                pub struct $id {}
             }
         )*
 
diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs
index 3c6800cf293..30073b541ec 100644
--- a/compiler/rustc_middle/src/ty/structural_impls.rs
+++ b/compiler/rustc_middle/src/ty/structural_impls.rs
@@ -99,12 +99,6 @@ impl<'tcx> fmt::Debug for ty::ConstVid<'tcx> {
     }
 }
 
-impl fmt::Debug for ty::RegionVid {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        write!(f, "'_#{}r", self.index())
-    }
-}
-
 impl<'tcx> fmt::Debug for ty::TraitRef<'tcx> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         with_no_trimmed_paths!(fmt::Display::fmt(self, f))
diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs
index 66aeebab88b..e13b68c83b5 100644
--- a/compiler/rustc_middle/src/ty/sty.rs
+++ b/compiler/rustc_middle/src/ty/sty.rs
@@ -1378,9 +1378,8 @@ pub struct ConstVid<'tcx> {
 rustc_index::newtype_index! {
     /// A **region** (lifetime) **v**ariable **ID**.
     #[derive(HashStable)]
-    pub struct RegionVid {
-        DEBUG_FORMAT = custom,
-    }
+    #[debug_format = "'_#{}r"]
+    pub struct RegionVid {}
 }
 
 impl Atom for RegionVid {
@@ -1391,7 +1390,7 @@ impl Atom for RegionVid {
 
 rustc_index::newtype_index! {
     #[derive(HashStable)]
-    pub struct BoundVar { .. }
+    pub struct BoundVar {}
 }
 
 #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, TyEncodable, TyDecodable)]
diff --git a/compiler/rustc_middle/src/ty/typeck_results.rs b/compiler/rustc_middle/src/ty/typeck_results.rs
index 4fe85d4366f..136a4906c58 100644
--- a/compiler/rustc_middle/src/ty/typeck_results.rs
+++ b/compiler/rustc_middle/src/ty/typeck_results.rs
@@ -608,10 +608,10 @@ impl<'a, V> LocalTableInContextMut<'a, V> {
 }
 
 rustc_index::newtype_index! {
+    #[derive(HashStable)]
+    #[debug_format = "UserType({})"]
     pub struct UserTypeAnnotationIndex {
-        derive [HashStable]
-        DEBUG_FORMAT = "UserType({})",
-        const START_INDEX = 0,
+        const START_INDEX = 0;
     }
 }
 
diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs
index 7af89dd472f..c785dfb500f 100644
--- a/compiler/rustc_mir_build/src/build/mod.rs
+++ b/compiler/rustc_mir_build/src/build/mod.rs
@@ -372,7 +372,7 @@ struct CFG<'tcx> {
 }
 
 rustc_index::newtype_index! {
-    struct ScopeId { .. }
+    struct ScopeId {}
 }
 
 #[derive(Debug)]
diff --git a/compiler/rustc_mir_build/src/build/scope.rs b/compiler/rustc_mir_build/src/build/scope.rs
index 33f49ffdaf6..c92634a609d 100644
--- a/compiler/rustc_mir_build/src/build/scope.rs
+++ b/compiler/rustc_mir_build/src/build/scope.rs
@@ -185,7 +185,7 @@ pub(crate) enum BreakableTarget {
 }
 
 rustc_index::newtype_index! {
-    struct DropIdx { .. }
+    struct DropIdx {}
 }
 
 const ROOT_NODE: DropIdx = DropIdx::from_u32(0);
diff --git a/compiler/rustc_mir_dataflow/src/move_paths/mod.rs b/compiler/rustc_mir_dataflow/src/move_paths/mod.rs
index b36e268cf8b..9b053985bed 100644
--- a/compiler/rustc_mir_dataflow/src/move_paths/mod.rs
+++ b/compiler/rustc_mir_dataflow/src/move_paths/mod.rs
@@ -14,9 +14,8 @@ use self::abs_domain::{AbstractElem, Lift};
 mod abs_domain;
 
 rustc_index::newtype_index! {
-    pub struct MovePathIndex {
-        DEBUG_FORMAT = "mp{}"
-    }
+    #[debug_format = "mp{}"]
+    pub struct MovePathIndex {}
 }
 
 impl polonius_engine::Atom for MovePathIndex {
@@ -26,15 +25,13 @@ impl polonius_engine::Atom for MovePathIndex {
 }
 
 rustc_index::newtype_index! {
-    pub struct MoveOutIndex {
-        DEBUG_FORMAT = "mo{}"
-    }
+    #[debug_format = "mo{}"]
+    pub struct MoveOutIndex {}
 }
 
 rustc_index::newtype_index! {
-    pub struct InitIndex {
-        DEBUG_FORMAT = "in{}"
-    }
+    #[debug_format = "in{}"]
+    pub struct InitIndex {}
 }
 
 impl MoveOutIndex {
diff --git a/compiler/rustc_mir_transform/src/cleanup_post_borrowck.rs b/compiler/rustc_mir_transform/src/cleanup_post_borrowck.rs
index 3378923c22c..d435d3ee69b 100644
--- a/compiler/rustc_mir_transform/src/cleanup_post_borrowck.rs
+++ b/compiler/rustc_mir_transform/src/cleanup_post_borrowck.rs
@@ -1,39 +1,44 @@
-//! This module provides a pass to replacing the following statements with
-//! [`Nop`]s
+//! This module provides a pass that removes parts of MIR that are no longer relevant after
+//! analysis phase and borrowck. In particular, it removes false edges, user type annotations and
+//! replaces following statements with [`Nop`]s:
 //!
 //!   - [`AscribeUserType`]
 //!   - [`FakeRead`]
 //!   - [`Assign`] statements with a [`Shallow`] borrow
 //!
-//! The `CleanFakeReadsAndBorrows` "pass" is actually implemented as two
-//! traversals (aka visits) of the input MIR. The first traversal,
-//! `DeleteAndRecordFakeReads`, deletes the fake reads and finds the
-//! temporaries read by [`ForMatchGuard`] reads, and `DeleteFakeBorrows`
-//! deletes the initialization of those temporaries.
-//!
 //! [`AscribeUserType`]: rustc_middle::mir::StatementKind::AscribeUserType
-//! [`Shallow`]: rustc_middle::mir::BorrowKind::Shallow
-//! [`FakeRead`]: rustc_middle::mir::StatementKind::FakeRead
 //! [`Assign`]: rustc_middle::mir::StatementKind::Assign
-//! [`ForMatchGuard`]: rustc_middle::mir::FakeReadCause::ForMatchGuard
+//! [`FakeRead`]: rustc_middle::mir::StatementKind::FakeRead
 //! [`Nop`]: rustc_middle::mir::StatementKind::Nop
+//! [`Shallow`]: rustc_middle::mir::BorrowKind::Shallow
 
 use crate::MirPass;
-use rustc_middle::mir::visit::MutVisitor;
-use rustc_middle::mir::{Body, BorrowKind, Location, Rvalue};
-use rustc_middle::mir::{Statement, StatementKind};
+use rustc_middle::mir::{Body, BorrowKind, Rvalue, StatementKind, TerminatorKind};
 use rustc_middle::ty::TyCtxt;
 
-pub struct CleanupNonCodegenStatements;
+pub struct CleanupPostBorrowck;
 
-pub struct DeleteNonCodegenStatements<'tcx> {
-    tcx: TyCtxt<'tcx>,
-}
+impl<'tcx> MirPass<'tcx> for CleanupPostBorrowck {
+    fn run_pass(&self, _tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
+        for basic_block in body.basic_blocks.as_mut() {
+            for statement in basic_block.statements.iter_mut() {
+                match statement.kind {
+                    StatementKind::AscribeUserType(..)
+                    | StatementKind::Assign(box (_, Rvalue::Ref(_, BorrowKind::Shallow, _)))
+                    | StatementKind::FakeRead(..) => statement.make_nop(),
+                    _ => (),
+                }
+            }
+            let terminator = basic_block.terminator_mut();
+            match terminator.kind {
+                TerminatorKind::FalseEdge { real_target, .. }
+                | TerminatorKind::FalseUnwind { real_target, .. } => {
+                    terminator.kind = TerminatorKind::Goto { target: real_target };
+                }
+                _ => {}
+            }
+        }
 
-impl<'tcx> MirPass<'tcx> for CleanupNonCodegenStatements {
-    fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
-        let mut delete = DeleteNonCodegenStatements { tcx };
-        delete.visit_body_preserves_cfg(body);
         body.user_type_annotations.raw.clear();
 
         for decl in &mut body.local_decls {
@@ -41,19 +46,3 @@ impl<'tcx> MirPass<'tcx> for CleanupNonCodegenStatements {
         }
     }
 }
-
-impl<'tcx> MutVisitor<'tcx> for DeleteNonCodegenStatements<'tcx> {
-    fn tcx(&self) -> TyCtxt<'tcx> {
-        self.tcx
-    }
-
-    fn visit_statement(&mut self, statement: &mut Statement<'tcx>, location: Location) {
-        match statement.kind {
-            StatementKind::AscribeUserType(..)
-            | StatementKind::Assign(box (_, Rvalue::Ref(_, BorrowKind::Shallow, _)))
-            | StatementKind::FakeRead(..) => statement.make_nop(),
-            _ => (),
-        }
-        self.super_statement(statement, location);
-    }
-}
diff --git a/compiler/rustc_mir_transform/src/coverage/graph.rs b/compiler/rustc_mir_transform/src/coverage/graph.rs
index 782129be088..78d28f1ebab 100644
--- a/compiler/rustc_mir_transform/src/coverage/graph.rs
+++ b/compiler/rustc_mir_transform/src/coverage/graph.rs
@@ -282,9 +282,9 @@ impl graph::WithPredecessors for CoverageGraph {
 
 rustc_index::newtype_index! {
     /// A node in the control-flow graph of CoverageGraph.
+    #[debug_format = "bcb{}"]
     pub(super) struct BasicCoverageBlock {
-        DEBUG_FORMAT = "bcb{}",
-        const START_BCB = 0,
+        const START_BCB = 0;
     }
 }
 
diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs
index 93200b28830..aba5a8580f1 100644
--- a/compiler/rustc_mir_transform/src/lib.rs
+++ b/compiler/rustc_mir_transform/src/lib.rs
@@ -77,8 +77,6 @@ mod match_branches;
 mod multiple_return_terminators;
 mod normalize_array_len;
 mod nrvo;
-// This pass is public to allow external drivers to perform MIR cleanup
-pub mod remove_false_edges;
 mod remove_noop_landing_pads;
 mod remove_storage_markers;
 mod remove_uninit_drops;
@@ -494,10 +492,9 @@ fn run_analysis_to_runtime_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>
 /// After this series of passes, no lifetime analysis based on borrowing can be done.
 fn run_analysis_cleanup_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
     let passes: &[&dyn MirPass<'tcx>] = &[
-        &remove_false_edges::RemoveFalseEdges,
+        &cleanup_post_borrowck::CleanupPostBorrowck,
         &simplify_branches::SimplifyConstCondition::new("initial"),
         &remove_noop_landing_pads::RemoveNoopLandingPads,
-        &cleanup_post_borrowck::CleanupNonCodegenStatements,
         &simplify::SimplifyCfg::new("early-opt"),
         &deref_separator::Derefer,
     ];
diff --git a/compiler/rustc_mir_transform/src/normalize_array_len.rs b/compiler/rustc_mir_transform/src/normalize_array_len.rs
index a159e617178..1708b287e56 100644
--- a/compiler/rustc_mir_transform/src/normalize_array_len.rs
+++ b/compiler/rustc_mir_transform/src/normalize_array_len.rs
@@ -16,7 +16,8 @@ pub struct NormalizeArrayLen;
 
 impl<'tcx> MirPass<'tcx> for NormalizeArrayLen {
     fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
-        sess.mir_opt_level() >= 4
+        // See #105929
+        sess.mir_opt_level() >= 4 && sess.opts.unstable_opts.unsound_mir_opts
     }
 
     fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
diff --git a/compiler/rustc_mir_transform/src/remove_false_edges.rs b/compiler/rustc_mir_transform/src/remove_false_edges.rs
deleted file mode 100644
index 71f5ccf7e24..00000000000
--- a/compiler/rustc_mir_transform/src/remove_false_edges.rs
+++ /dev/null
@@ -1,29 +0,0 @@
-use rustc_middle::mir::{Body, TerminatorKind};
-use rustc_middle::ty::TyCtxt;
-
-use crate::MirPass;
-
-/// Removes `FalseEdge` and `FalseUnwind` terminators from the MIR.
-///
-/// These are only needed for borrow checking, and can be removed afterwards.
-///
-/// FIXME: This should probably have its own MIR phase.
-pub struct RemoveFalseEdges;
-
-impl<'tcx> MirPass<'tcx> for RemoveFalseEdges {
-    fn run_pass(&self, _: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
-        for block in body.basic_blocks_mut() {
-            let terminator = block.terminator_mut();
-            terminator.kind = match terminator.kind {
-                TerminatorKind::FalseEdge { real_target, .. } => {
-                    TerminatorKind::Goto { target: real_target }
-                }
-                TerminatorKind::FalseUnwind { real_target, .. } => {
-                    TerminatorKind::Goto { target: real_target }
-                }
-
-                _ => continue,
-            }
-        }
-    }
-}
diff --git a/compiler/rustc_passes/src/liveness.rs b/compiler/rustc_passes/src/liveness.rs
index 1f65cc8b609..b49432b7996 100644
--- a/compiler/rustc_passes/src/liveness.rs
+++ b/compiler/rustc_passes/src/liveness.rs
@@ -108,15 +108,13 @@ use std::rc::Rc;
 mod rwu_table;
 
 rustc_index::newtype_index! {
-    pub struct Variable {
-        DEBUG_FORMAT = "v({})",
-    }
+    #[debug_format = "v({})"]
+    pub struct Variable {}
 }
 
 rustc_index::newtype_index! {
-    pub struct LiveNode {
-        DEBUG_FORMAT = "ln({})",
-    }
+    #[debug_format = "ln({})"]
+    pub struct LiveNode {}
 }
 
 #[derive(Copy, Clone, PartialEq, Debug)]
diff --git a/compiler/rustc_query_system/src/dep_graph/graph.rs b/compiler/rustc_query_system/src/dep_graph/graph.rs
index 0e7d628c1eb..52957ee0222 100644
--- a/compiler/rustc_query_system/src/dep_graph/graph.rs
+++ b/compiler/rustc_query_system/src/dep_graph/graph.rs
@@ -37,7 +37,7 @@ pub struct DepGraph<K: DepKind> {
 }
 
 rustc_index::newtype_index! {
-    pub struct DepNodeIndex { .. }
+    pub struct DepNodeIndex {}
 }
 
 impl DepNodeIndex {
@@ -974,7 +974,7 @@ pub struct WorkProduct {
 
 // Index type for `DepNodeData`'s edges.
 rustc_index::newtype_index! {
-    struct EdgeIndex { .. }
+    struct EdgeIndex {}
 }
 
 /// `CurrentDepGraph` stores the dependency graph for the current session. It
diff --git a/compiler/rustc_query_system/src/dep_graph/serialized.rs b/compiler/rustc_query_system/src/dep_graph/serialized.rs
index d292f4beef2..a918328d413 100644
--- a/compiler/rustc_query_system/src/dep_graph/serialized.rs
+++ b/compiler/rustc_query_system/src/dep_graph/serialized.rs
@@ -27,9 +27,8 @@ use smallvec::SmallVec;
 // unused so that we can store multiple index types in `CompressedHybridIndex`,
 // and use those bits to encode which index type it contains.
 rustc_index::newtype_index! {
-    pub struct SerializedDepNodeIndex {
-        MAX = 0x7FFF_FFFF
-    }
+    #[max = 0x7FFF_FFFF]
+    pub struct SerializedDepNodeIndex {}
 }
 
 /// Data for use when recompiling the **current crate**.
diff --git a/compiler/rustc_span/src/def_id.rs b/compiler/rustc_span/src/def_id.rs
index e62ce2c266a..221f65b66e6 100644
--- a/compiler/rustc_span/src/def_id.rs
+++ b/compiler/rustc_span/src/def_id.rs
@@ -10,10 +10,9 @@ use std::fmt;
 use std::hash::{Hash, Hasher};
 
 rustc_index::newtype_index! {
-    pub struct CrateNum {
-        ENCODABLE = custom
-        DEBUG_FORMAT = "crate{}"
-    }
+    #[custom_encodable]
+    #[debug_format = "crate{}"]
+    pub struct CrateNum {}
 }
 
 /// Item definitions in the currently-compiled crate would have the `CrateNum`
@@ -194,13 +193,12 @@ rustc_index::newtype_index! {
     /// A DefIndex is an index into the hir-map for a crate, identifying a
     /// particular definition. It should really be considered an interned
     /// shorthand for a particular DefPath.
+    #[custom_encodable] // (only encodable in metadata)
+    #[debug_format = "DefIndex({})"]
     pub struct DefIndex {
-        ENCODABLE = custom // (only encodable in metadata)
-
-        DEBUG_FORMAT = "DefIndex({})",
         /// The crate root is always assigned index 0 by the AST Map code,
         /// thanks to `NodeCollector::new`.
-        const CRATE_DEF_INDEX = 0,
+        const CRATE_DEF_INDEX = 0;
     }
 }
 
diff --git a/compiler/rustc_span/src/hygiene.rs b/compiler/rustc_span/src/hygiene.rs
index 038699154c7..c2d8287f243 100644
--- a/compiler/rustc_span/src/hygiene.rs
+++ b/compiler/rustc_span/src/hygiene.rs
@@ -61,9 +61,8 @@ pub struct SyntaxContextData {
 
 rustc_index::newtype_index! {
     /// A unique ID associated with a macro invocation and expansion.
-    pub struct ExpnIndex {
-        ENCODABLE = custom
-    }
+    #[custom_encodable]
+    pub struct ExpnIndex {}
 }
 
 /// A unique ID associated with a macro invocation and expansion.
@@ -82,11 +81,10 @@ impl fmt::Debug for ExpnId {
 
 rustc_index::newtype_index! {
     /// A unique ID associated with a macro invocation and expansion.
-    pub struct LocalExpnId {
-        ENCODABLE = custom
-        ORD_IMPL = custom
-        DEBUG_FORMAT = "expn{}"
-    }
+    #[custom_encodable]
+    #[no_ord_impl]
+    #[debug_format = "expn{}"]
+    pub struct LocalExpnId {}
 }
 
 // To ensure correctness of incremental compilation,
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 9de6d9dc483..f23959b6e47 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -1802,7 +1802,7 @@ impl fmt::Display for MacroRulesNormalizedIdent {
 pub struct Symbol(SymbolIndex);
 
 rustc_index::newtype_index! {
-    struct SymbolIndex { .. }
+    struct SymbolIndex {}
 }
 
 impl Symbol {
diff --git a/compiler/rustc_target/src/abi/mod.rs b/compiler/rustc_target/src/abi/mod.rs
index 53c9878ab87..88a0a1f8ecf 100644
--- a/compiler/rustc_target/src/abi/mod.rs
+++ b/compiler/rustc_target/src/abi/mod.rs
@@ -20,9 +20,8 @@ impl ToJson for Endian {
 }
 
 rustc_index::newtype_index! {
-    pub struct VariantIdx {
-        derive [HashStable_Generic]
-    }
+    #[derive(HashStable_Generic)]
+    pub struct VariantIdx {}
 }
 
 #[derive(Copy, Clone, PartialEq, Eq, Hash, HashStable_Generic)]
diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs
index c992dbccd62..dd36a5c7a21 100644
--- a/compiler/rustc_type_ir/src/lib.rs
+++ b/compiler/rustc_type_ir/src/lib.rs
@@ -301,9 +301,9 @@ rustc_index::newtype_index! {
     ///
     /// [dbi]: https://en.wikipedia.org/wiki/De_Bruijn_index
     #[derive(HashStable_Generic)]
+    #[debug_format = "DebruijnIndex({})"]
     pub struct DebruijnIndex {
-        DEBUG_FORMAT = "DebruijnIndex({})",
-        const INNERMOST = 0,
+        const INNERMOST = 0;
     }
 }
 
@@ -499,9 +499,8 @@ pub struct FloatVarValue(pub FloatTy);
 
 rustc_index::newtype_index! {
     /// A **ty**pe **v**ariable **ID**.
-    pub struct TyVid {
-        DEBUG_FORMAT = "_#{}t"
-    }
+    #[debug_format = "_#{}t"]
+    pub struct TyVid {}
 }
 
 /// An **int**egral (`u32`, `i32`, `usize`, etc.) type **v**ariable **ID**.
@@ -788,9 +787,8 @@ rustc_index::newtype_index! {
     /// type -- an idealized representative of "types in general" that we
     /// use for checking generic functions.
     #[derive(HashStable_Generic)]
-    pub struct UniverseIndex {
-        DEBUG_FORMAT = "U{}",
-    }
+    #[debug_format = "U{}"]
+    pub struct UniverseIndex {}
 }
 
 impl UniverseIndex {
diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs
index e5f6b0c0c65..b154688fb08 100644
--- a/library/alloc/src/boxed.rs
+++ b/library/alloc/src/boxed.rs
@@ -2033,7 +2033,7 @@ impl<Args: Tuple, F: Fn<Args> + ?Sized, A: Allocator> Fn<Args> for Box<F, A> {
     }
 }
 
-#[unstable(feature = "coerce_unsized", issue = "27732")]
+#[unstable(feature = "coerce_unsized", issue = "18598")]
 impl<T: ?Sized + Unsize<U>, U: ?Sized, A: Allocator> CoerceUnsized<Box<U, A>> for Box<T, A> {}
 
 #[unstable(feature = "dispatch_from_dyn", issue = "none")]
diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs
index 38e31b1802a..80a5913daa6 100644
--- a/library/alloc/src/rc.rs
+++ b/library/alloc/src/rc.rs
@@ -336,7 +336,7 @@ impl<T: RefUnwindSafe + ?Sized> UnwindSafe for Rc<T> {}
 #[stable(feature = "rc_ref_unwind_safe", since = "1.58.0")]
 impl<T: RefUnwindSafe + ?Sized> RefUnwindSafe for Rc<T> {}
 
-#[unstable(feature = "coerce_unsized", issue = "27732")]
+#[unstable(feature = "coerce_unsized", issue = "18598")]
 impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<Rc<U>> for Rc<T> {}
 
 #[unstable(feature = "dispatch_from_dyn", issue = "none")]
@@ -2190,7 +2190,7 @@ impl<T: ?Sized> !marker::Send for Weak<T> {}
 #[stable(feature = "rc_weak", since = "1.4.0")]
 impl<T: ?Sized> !marker::Sync for Weak<T> {}
 
-#[unstable(feature = "coerce_unsized", issue = "27732")]
+#[unstable(feature = "coerce_unsized", issue = "18598")]
 impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<Weak<U>> for Weak<T> {}
 
 #[unstable(feature = "dispatch_from_dyn", issue = "none")]
diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs
index f7dc4d1094c..ddcd863aa3e 100644
--- a/library/alloc/src/sync.rs
+++ b/library/alloc/src/sync.rs
@@ -254,7 +254,7 @@ unsafe impl<T: ?Sized + Sync + Send> Sync for Arc<T> {}
 #[stable(feature = "catch_unwind", since = "1.9.0")]
 impl<T: RefUnwindSafe + ?Sized> UnwindSafe for Arc<T> {}
 
-#[unstable(feature = "coerce_unsized", issue = "27732")]
+#[unstable(feature = "coerce_unsized", issue = "18598")]
 impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<Arc<U>> for Arc<T> {}
 
 #[unstable(feature = "dispatch_from_dyn", issue = "none")]
@@ -306,7 +306,7 @@ unsafe impl<T: ?Sized + Sync + Send> Send for Weak<T> {}
 #[stable(feature = "arc_weak", since = "1.4.0")]
 unsafe impl<T: ?Sized + Sync + Send> Sync for Weak<T> {}
 
-#[unstable(feature = "coerce_unsized", issue = "27732")]
+#[unstable(feature = "coerce_unsized", issue = "18598")]
 impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<Weak<U>> for Weak<T> {}
 #[unstable(feature = "dispatch_from_dyn", issue = "none")]
 impl<T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<Weak<U>> for Weak<T> {}
diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs
index 47cce2aa39b..b4e173ce03d 100644
--- a/library/core/src/cell.rs
+++ b/library/core/src/cell.rs
@@ -568,7 +568,7 @@ impl<T: Default> Cell<T> {
     }
 }
 
-#[unstable(feature = "coerce_unsized", issue = "27732")]
+#[unstable(feature = "coerce_unsized", issue = "18598")]
 impl<T: CoerceUnsized<U>, U> CoerceUnsized<Cell<U>> for Cell<T> {}
 
 impl<T> Cell<[T]> {
@@ -1266,7 +1266,7 @@ impl<T> const From<T> for RefCell<T> {
     }
 }
 
-#[unstable(feature = "coerce_unsized", issue = "27732")]
+#[unstable(feature = "coerce_unsized", issue = "18598")]
 impl<T: CoerceUnsized<U>, U> CoerceUnsized<RefCell<U>> for RefCell<T> {}
 
 struct BorrowRef<'b> {
@@ -1492,7 +1492,7 @@ impl<'b, T: ?Sized> Ref<'b, T> {
     }
 }
 
-#[unstable(feature = "coerce_unsized", issue = "27732")]
+#[unstable(feature = "coerce_unsized", issue = "18598")]
 impl<'b, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<Ref<'b, U>> for Ref<'b, T> {}
 
 #[stable(feature = "std_guard_impls", since = "1.20.0")]
@@ -1738,7 +1738,7 @@ impl<T: ?Sized> DerefMut for RefMut<'_, T> {
     }
 }
 
-#[unstable(feature = "coerce_unsized", issue = "27732")]
+#[unstable(feature = "coerce_unsized", issue = "18598")]
 impl<'b, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<RefMut<'b, U>> for RefMut<'b, T> {}
 
 #[stable(feature = "std_guard_impls", since = "1.20.0")]
@@ -2074,7 +2074,7 @@ impl<T> const From<T> for UnsafeCell<T> {
     }
 }
 
-#[unstable(feature = "coerce_unsized", issue = "27732")]
+#[unstable(feature = "coerce_unsized", issue = "18598")]
 impl<T: CoerceUnsized<U>, U> CoerceUnsized<UnsafeCell<U>> for UnsafeCell<T> {}
 
 /// [`UnsafeCell`], but [`Sync`].
@@ -2164,7 +2164,7 @@ impl<T> const From<T> for SyncUnsafeCell<T> {
     }
 }
 
-#[unstable(feature = "coerce_unsized", issue = "27732")]
+#[unstable(feature = "coerce_unsized", issue = "18598")]
 //#[unstable(feature = "sync_unsafe_cell", issue = "95439")]
 impl<T: CoerceUnsized<U>, U> CoerceUnsized<SyncUnsafeCell<U>> for SyncUnsafeCell<T> {}
 
diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs
index 42c34280197..4b85c1112b9 100644
--- a/library/core/src/marker.rs
+++ b/library/core/src/marker.rs
@@ -126,7 +126,7 @@ pub trait Sized {
 /// [`Rc`]: ../../std/rc/struct.Rc.html
 /// [RFC982]: https://github.com/rust-lang/rfcs/blob/master/text/0982-dst-coercion.md
 /// [nomicon-coerce]: ../../nomicon/coercions.html
-#[unstable(feature = "unsize", issue = "27732")]
+#[unstable(feature = "unsize", issue = "18598")]
 #[lang = "unsize"]
 #[cfg_attr(not(bootstrap), rustc_deny_explicit_impl)]
 pub trait Unsize<T: ?Sized> {
diff --git a/library/core/src/ops/mod.rs b/library/core/src/ops/mod.rs
index eb2a92f4644..97d9b750d92 100644
--- a/library/core/src/ops/mod.rs
+++ b/library/core/src/ops/mod.rs
@@ -201,7 +201,7 @@ pub(crate) use self::try_trait::{ChangeOutputType, NeverShortCircuit};
 #[unstable(feature = "generator_trait", issue = "43122")]
 pub use self::generator::{Generator, GeneratorState};
 
-#[unstable(feature = "coerce_unsized", issue = "27732")]
+#[unstable(feature = "coerce_unsized", issue = "18598")]
 pub use self::unsize::CoerceUnsized;
 
 #[unstable(feature = "dispatch_from_dyn", issue = "none")]
diff --git a/library/core/src/ops/unsize.rs b/library/core/src/ops/unsize.rs
index a920b9165c1..b51f12580ea 100644
--- a/library/core/src/ops/unsize.rs
+++ b/library/core/src/ops/unsize.rs
@@ -31,41 +31,41 @@ use crate::marker::Unsize;
 /// [dst-coerce]: https://github.com/rust-lang/rfcs/blob/master/text/0982-dst-coercion.md
 /// [unsize]: crate::marker::Unsize
 /// [nomicon-coerce]: ../../nomicon/coercions.html
-#[unstable(feature = "coerce_unsized", issue = "27732")]
+#[unstable(feature = "coerce_unsized", issue = "18598")]
 #[lang = "coerce_unsized"]
 pub trait CoerceUnsized<T: ?Sized> {
     // Empty.
 }
 
 // &mut T -> &mut U
-#[unstable(feature = "coerce_unsized", issue = "27732")]
+#[unstable(feature = "coerce_unsized", issue = "18598")]
 impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a mut U> for &'a mut T {}
 // &mut T -> &U
-#[unstable(feature = "coerce_unsized", issue = "27732")]
+#[unstable(feature = "coerce_unsized", issue = "18598")]
 impl<'a, 'b: 'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b mut T {}
 // &mut T -> *mut U
-#[unstable(feature = "coerce_unsized", issue = "27732")]
+#[unstable(feature = "coerce_unsized", issue = "18598")]
 impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*mut U> for &'a mut T {}
 // &mut T -> *const U
-#[unstable(feature = "coerce_unsized", issue = "27732")]
+#[unstable(feature = "coerce_unsized", issue = "18598")]
 impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for &'a mut T {}
 
 // &T -> &U
-#[unstable(feature = "coerce_unsized", issue = "27732")]
+#[unstable(feature = "coerce_unsized", issue = "18598")]
 impl<'a, 'b: 'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b T {}
 // &T -> *const U
-#[unstable(feature = "coerce_unsized", issue = "27732")]
+#[unstable(feature = "coerce_unsized", issue = "18598")]
 impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for &'a T {}
 
 // *mut T -> *mut U
-#[unstable(feature = "coerce_unsized", issue = "27732")]
+#[unstable(feature = "coerce_unsized", issue = "18598")]
 impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*mut U> for *mut T {}
 // *mut T -> *const U
-#[unstable(feature = "coerce_unsized", issue = "27732")]
+#[unstable(feature = "coerce_unsized", issue = "18598")]
 impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for *mut T {}
 
 // *const T -> *const U
-#[unstable(feature = "coerce_unsized", issue = "27732")]
+#[unstable(feature = "coerce_unsized", issue = "18598")]
 impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for *const T {}
 
 /// `DispatchFromDyn` is used in the implementation of object safety checks (specifically allowing
diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs
index c4348169c78..af79d4bbd83 100644
--- a/library/core/src/ptr/non_null.rs
+++ b/library/core/src/ptr/non_null.rs
@@ -712,7 +712,7 @@ impl<T: ?Sized> const Clone for NonNull<T> {
 #[stable(feature = "nonnull", since = "1.25.0")]
 impl<T: ?Sized> Copy for NonNull<T> {}
 
-#[unstable(feature = "coerce_unsized", issue = "27732")]
+#[unstable(feature = "coerce_unsized", issue = "18598")]
 impl<T: ?Sized, U: ?Sized> CoerceUnsized<NonNull<U>> for NonNull<T> where T: Unsize<U> {}
 
 #[unstable(feature = "dispatch_from_dyn", issue = "none")]
diff --git a/src/bootstrap/install.rs b/src/bootstrap/install.rs
index c53d0d7e4cb..1815a097307 100644
--- a/src/bootstrap/install.rs
+++ b/src/bootstrap/install.rs
@@ -200,10 +200,14 @@ install!((self, builder, _config),
         install_sh(builder, "clippy", self.compiler.stage, Some(self.target), &tarball);
     };
     Miri, alias = "miri", Self::should_build(_config), only_hosts: true, {
-        let tarball = builder
-            .ensure(dist::Miri { compiler: self.compiler, target: self.target })
-            .expect("missing miri");
-        install_sh(builder, "miri", self.compiler.stage, Some(self.target), &tarball);
+        if let Some(tarball) = builder.ensure(dist::Miri { compiler: self.compiler, target: self.target }) {
+            install_sh(builder, "miri", self.compiler.stage, Some(self.target), &tarball);
+        } else {
+            // Miri is only available on nightly
+            builder.info(
+                &format!("skipping Install miri stage{} ({})", self.compiler.stage, self.target),
+            );
+        }
     };
     LlvmTools, alias = "llvm-tools", Self::should_build(_config), only_hosts: true, {
         let tarball = builder
diff --git a/src/librustdoc/clean/cfg.rs b/src/librustdoc/clean/cfg.rs
index 1843a21205c..f1853f3697d 100644
--- a/src/librustdoc/clean/cfg.rs
+++ b/src/librustdoc/clean/cfg.rs
@@ -507,7 +507,9 @@ impl<'a> fmt::Display for Display<'a> {
                         "openbsd" => "OpenBSD",
                         "redox" => "Redox",
                         "solaris" => "Solaris",
+                        "tvos" => "tvOS",
                         "wasi" => "WASI",
+                        "watchos" => "watchOS",
                         "windows" => "Windows",
                         _ => "",
                     },
diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css
index efb19467c87..11e34a3fc7d 100644
--- a/src/librustdoc/html/static/css/rustdoc.css
+++ b/src/librustdoc/html/static/css/rustdoc.css
@@ -338,6 +338,7 @@ code, pre, a.test-arrow, .code-header {
 }
 pre {
 	padding: 14px;
+	line-height: 1.5; /* https://github.com/rust-lang/rust/issues/105906 */
 }
 .item-decl pre {
 	overflow-x: auto;
@@ -1972,10 +1973,7 @@ in storage.js
 }
 
 .scraped-example .code-wrapper .example-wrap {
-	display: grid;
-	grid-template-columns: max-content auto;
 	width: 100%;
-	overflow-x: auto;
 	overflow-y: hidden;
 	margin-bottom: 0;
 }
@@ -1984,13 +1982,6 @@ in storage.js
 	overflow-x: hidden;
 }
 
-.scraped-example .code-wrapper .example-wrap pre.rust {
-	overflow-x: inherit;
-	width: inherit;
-	overflow-y: hidden;
-}
-
-
 .more-examples-toggle {
 	max-width: calc(100% + 25px);
 	margin-top: 10px;
diff --git a/src/test/mir-opt/const_prop/slice_len.main.ConstProp.32bit.diff b/src/test/mir-opt/const_prop/slice_len.main.ConstProp.32bit.diff
index 624376769b7..44445731e72 100644
--- a/src/test/mir-opt/const_prop/slice_len.main.ConstProp.32bit.diff
+++ b/src/test/mir-opt/const_prop/slice_len.main.ConstProp.32bit.diff
@@ -12,7 +12,6 @@
       let mut _7: usize;                   // in scope 0 at $DIR/slice_len.rs:+1:5: +1:33
       let mut _8: bool;                    // in scope 0 at $DIR/slice_len.rs:+1:5: +1:33
       let mut _9: &[u32; 3];               // in scope 0 at $DIR/slice_len.rs:+1:6: +1:19
-      let mut _10: &[u32; 3];              // in scope 0 at $DIR/slice_len.rs:+1:6: +1:19
   
       bb0: {
           StorageLive(_1);                 // scope 0 at $DIR/slice_len.rs:+1:5: +1:33
@@ -25,16 +24,14 @@
                                            // + literal: Const { ty: &[u32; 3], val: Unevaluated(main, [], Some(promoted[0])) }
           _4 = _9;                         // scope 0 at $DIR/slice_len.rs:+1:6: +1:19
           _3 = _4;                         // scope 0 at $DIR/slice_len.rs:+1:6: +1:19
-          StorageLive(_10);                // scope 0 at $DIR/slice_len.rs:+1:6: +1:19
-          _10 = _3;                        // scope 0 at $DIR/slice_len.rs:+1:6: +1:19
           _2 = move _3 as &[u32] (Pointer(Unsize)); // scope 0 at $DIR/slice_len.rs:+1:6: +1:19
           StorageDead(_3);                 // scope 0 at $DIR/slice_len.rs:+1:18: +1:19
           StorageLive(_6);                 // scope 0 at $DIR/slice_len.rs:+1:31: +1:32
           _6 = const 1_usize;              // scope 0 at $DIR/slice_len.rs:+1:31: +1:32
-          _7 = const 3_usize;              // scope 0 at $DIR/slice_len.rs:+1:5: +1:33
-          StorageDead(_10);                // scope 0 at $DIR/slice_len.rs:+1:5: +1:33
+-         _7 = Len((*_2));                 // scope 0 at $DIR/slice_len.rs:+1:5: +1:33
 -         _8 = Lt(_6, _7);                 // scope 0 at $DIR/slice_len.rs:+1:5: +1:33
 -         assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> bb1; // scope 0 at $DIR/slice_len.rs:+1:5: +1:33
++         _7 = const 3_usize;              // scope 0 at $DIR/slice_len.rs:+1:5: +1:33
 +         _8 = const true;                 // scope 0 at $DIR/slice_len.rs:+1:5: +1:33
 +         assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> bb1; // scope 0 at $DIR/slice_len.rs:+1:5: +1:33
       }
diff --git a/src/test/mir-opt/const_prop/slice_len.main.ConstProp.64bit.diff b/src/test/mir-opt/const_prop/slice_len.main.ConstProp.64bit.diff
index 624376769b7..44445731e72 100644
--- a/src/test/mir-opt/const_prop/slice_len.main.ConstProp.64bit.diff
+++ b/src/test/mir-opt/const_prop/slice_len.main.ConstProp.64bit.diff
@@ -12,7 +12,6 @@
       let mut _7: usize;                   // in scope 0 at $DIR/slice_len.rs:+1:5: +1:33
       let mut _8: bool;                    // in scope 0 at $DIR/slice_len.rs:+1:5: +1:33
       let mut _9: &[u32; 3];               // in scope 0 at $DIR/slice_len.rs:+1:6: +1:19
-      let mut _10: &[u32; 3];              // in scope 0 at $DIR/slice_len.rs:+1:6: +1:19
   
       bb0: {
           StorageLive(_1);                 // scope 0 at $DIR/slice_len.rs:+1:5: +1:33
@@ -25,16 +24,14 @@
                                            // + literal: Const { ty: &[u32; 3], val: Unevaluated(main, [], Some(promoted[0])) }
           _4 = _9;                         // scope 0 at $DIR/slice_len.rs:+1:6: +1:19
           _3 = _4;                         // scope 0 at $DIR/slice_len.rs:+1:6: +1:19
-          StorageLive(_10);                // scope 0 at $DIR/slice_len.rs:+1:6: +1:19
-          _10 = _3;                        // scope 0 at $DIR/slice_len.rs:+1:6: +1:19
           _2 = move _3 as &[u32] (Pointer(Unsize)); // scope 0 at $DIR/slice_len.rs:+1:6: +1:19
           StorageDead(_3);                 // scope 0 at $DIR/slice_len.rs:+1:18: +1:19
           StorageLive(_6);                 // scope 0 at $DIR/slice_len.rs:+1:31: +1:32
           _6 = const 1_usize;              // scope 0 at $DIR/slice_len.rs:+1:31: +1:32
-          _7 = const 3_usize;              // scope 0 at $DIR/slice_len.rs:+1:5: +1:33
-          StorageDead(_10);                // scope 0 at $DIR/slice_len.rs:+1:5: +1:33
+-         _7 = Len((*_2));                 // scope 0 at $DIR/slice_len.rs:+1:5: +1:33
 -         _8 = Lt(_6, _7);                 // scope 0 at $DIR/slice_len.rs:+1:5: +1:33
 -         assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> bb1; // scope 0 at $DIR/slice_len.rs:+1:5: +1:33
++         _7 = const 3_usize;              // scope 0 at $DIR/slice_len.rs:+1:5: +1:33
 +         _8 = const true;                 // scope 0 at $DIR/slice_len.rs:+1:5: +1:33
 +         assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> bb1; // scope 0 at $DIR/slice_len.rs:+1:5: +1:33
       }
diff --git a/src/test/mir-opt/issue_76432.test.SimplifyComparisonIntegral.diff b/src/test/mir-opt/issue_76432.test.SimplifyComparisonIntegral.diff
index 2368c021eda..e97b46f6ecc 100644
--- a/src/test/mir-opt/issue_76432.test.SimplifyComparisonIntegral.diff
+++ b/src/test/mir-opt/issue_76432.test.SimplifyComparisonIntegral.diff
@@ -22,7 +22,6 @@
       let mut _20: *const T;               // in scope 0 at $DIR/issue_76432.rs:+3:70: +3:84
       let mut _21: *const T;               // in scope 0 at $DIR/issue_76432.rs:+3:70: +3:84
       let mut _22: !;                      // in scope 0 at $SRC_DIR/core/src/panic.rs:LL:COL
-      let mut _23: &[T; 3];                // in scope 0 at $DIR/issue_76432.rs:+1:19: +1:29
       scope 1 {
           debug v => _2;                   // in scope 1 at $DIR/issue_76432.rs:+1:9: +1:10
           let _13: &T;                     // in scope 1 at $DIR/issue_76432.rs:+3:10: +3:16
@@ -52,17 +51,16 @@
           StorageDead(_6);                 // scope 0 at $DIR/issue_76432.rs:+1:28: +1:29
           _4 = &_5;                        // scope 0 at $DIR/issue_76432.rs:+1:19: +1:29
           _3 = _4;                         // scope 0 at $DIR/issue_76432.rs:+1:19: +1:29
-          StorageLive(_23);                // scope 0 at $DIR/issue_76432.rs:+1:19: +1:29
-          _23 = _3;                        // scope 0 at $DIR/issue_76432.rs:+1:19: +1:29
           _2 = move _3 as &[T] (Pointer(Unsize)); // scope 0 at $DIR/issue_76432.rs:+1:19: +1:29
           StorageDead(_3);                 // scope 0 at $DIR/issue_76432.rs:+1:28: +1:29
           StorageDead(_4);                 // scope 0 at $DIR/issue_76432.rs:+1:29: +1:30
           StorageLive(_9);                 // scope 1 at $DIR/issue_76432.rs:+2:5: +5:6
-          _10 = const 3_usize;             // scope 1 at $DIR/issue_76432.rs:+3:9: +3:33
-          StorageDead(_23);                // scope 1 at $DIR/issue_76432.rs:+3:9: +3:33
+          _10 = Len((*_2));                // scope 1 at $DIR/issue_76432.rs:+3:9: +3:33
           _11 = const 3_usize;             // scope 1 at $DIR/issue_76432.rs:+3:9: +3:33
-          _12 = const true;                // scope 1 at $DIR/issue_76432.rs:+3:9: +3:33
-          goto -> bb2;                     // scope 1 at $DIR/issue_76432.rs:+3:9: +3:33
+-         _12 = Eq(move _10, const 3_usize); // scope 1 at $DIR/issue_76432.rs:+3:9: +3:33
+-         switchInt(move _12) -> [0: bb1, otherwise: bb2]; // scope 1 at $DIR/issue_76432.rs:+3:9: +3:33
++         nop;                             // scope 1 at $DIR/issue_76432.rs:+3:9: +3:33
++         switchInt(move _10) -> [3: bb2, otherwise: bb1]; // scope 1 at $DIR/issue_76432.rs:+3:9: +3:33
       }
   
       bb1: {
diff --git a/src/test/mir-opt/lower_array_len_e2e.rs b/src/test/mir-opt/lower_array_len_e2e.rs
index 49b35d509f0..d8e4e521ee6 100644
--- a/src/test/mir-opt/lower_array_len_e2e.rs
+++ b/src/test/mir-opt/lower_array_len_e2e.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Z mir-opt-level=4
+// compile-flags: -Z mir-opt-level=4 -Zunsound-mir-opts
 
 // EMIT_MIR lower_array_len_e2e.array_bound.PreCodegen.after.mir
 pub fn array_bound<const N: usize>(index: usize, slice: &[u8; N]) -> u8 {
diff --git a/src/test/mir-opt/remove_fake_borrows.match_guard.CleanupNonCodegenStatements.diff b/src/test/mir-opt/remove_fake_borrows.match_guard.CleanupPostBorrowck.diff
index bb5920b28ca..0b3da98a5a1 100644
--- a/src/test/mir-opt/remove_fake_borrows.match_guard.CleanupNonCodegenStatements.diff
+++ b/src/test/mir-opt/remove_fake_borrows.match_guard.CleanupPostBorrowck.diff
@@ -1,5 +1,5 @@
-- // MIR for `match_guard` before CleanupNonCodegenStatements
-+ // MIR for `match_guard` after CleanupNonCodegenStatements
+- // MIR for `match_guard` before CleanupPostBorrowck
++ // MIR for `match_guard` after CleanupPostBorrowck
   
   fn match_guard(_1: Option<&&i32>, _2: bool) -> i32 {
       debug x => _1;                       // in scope 0 at $DIR/remove_fake_borrows.rs:+0:16: +0:17
@@ -29,7 +29,8 @@
       }
   
       bb3: {
-          goto -> bb4;                     // scope 0 at $DIR/remove_fake_borrows.rs:+2:9: +2:16
+-         falseEdge -> [real: bb4, imaginary: bb1]; // scope 0 at $DIR/remove_fake_borrows.rs:+2:9: +2:16
++         goto -> bb4;                     // scope 0 at $DIR/remove_fake_borrows.rs:+2:9: +2:16
       }
   
       bb4: {
@@ -62,15 +63,12 @@
   
       bb6: {
           StorageDead(_8);                 // scope 0 at $DIR/remove_fake_borrows.rs:+2:20: +2:21
-          goto -> bb1;                     // scope 0 at $DIR/remove_fake_borrows.rs:+2:20: +2:21
+-         falseEdge -> [real: bb1, imaginary: bb1]; // scope 0 at $DIR/remove_fake_borrows.rs:+2:20: +2:21
++         goto -> bb1;                     // scope 0 at $DIR/remove_fake_borrows.rs:+2:20: +2:21
       }
   
       bb7: {
           return;                          // scope 0 at $DIR/remove_fake_borrows.rs:+5:2: +5:2
       }
-  
-      bb8 (cleanup): {
-          resume;                          // scope 0 at $DIR/remove_fake_borrows.rs:+0:1: +5:2
-      }
   }
   
diff --git a/src/test/mir-opt/remove_fake_borrows.rs b/src/test/mir-opt/remove_fake_borrows.rs
index a980f386b69..d26c6f5d7e5 100644
--- a/src/test/mir-opt/remove_fake_borrows.rs
+++ b/src/test/mir-opt/remove_fake_borrows.rs
@@ -2,7 +2,7 @@
 
 // ignore-wasm32-bare compiled with panic=abort by default
 
-// EMIT_MIR remove_fake_borrows.match_guard.CleanupNonCodegenStatements.diff
+// EMIT_MIR remove_fake_borrows.match_guard.CleanupPostBorrowck.diff
 fn match_guard(x: Option<&&i32>, c: bool) -> i32 {
     match x {
         Some(0) if c => 0,
diff --git a/src/test/rustdoc-gui/codeblock-sub.goml b/src/test/rustdoc-gui/codeblock-sub.goml
new file mode 100644
index 00000000000..cbd314d2791
--- /dev/null
+++ b/src/test/rustdoc-gui/codeblock-sub.goml
@@ -0,0 +1,5 @@
+// Test that code blocks nested within <sub> do not have a line height of 0.
+goto: "file://" + |DOC_PATH| + "/test_docs/codeblock_sub/index.html"
+
+store-property: (codeblock_sub_1, "#codeblock-sub-1", "offsetHeight")
+assert-property-false: ("#codeblock-sub-3", { "offsetHeight": |codeblock_sub_1| })
diff --git a/src/test/rustdoc-gui/src/test_docs/lib.rs b/src/test/rustdoc-gui/src/test_docs/lib.rs
index f1b69d4dc1d..51250439694 100644
--- a/src/test/rustdoc-gui/src/test_docs/lib.rs
+++ b/src/test/rustdoc-gui/src/test_docs/lib.rs
@@ -455,3 +455,22 @@ impl TypeWithImplDoc {
     /// fn doc
     pub fn test_fn() {}
 }
+
+/// <sub id="codeblock-sub-1">
+///
+/// ```
+/// one
+/// ```
+///
+/// </sub>
+///
+/// <sub id="codeblock-sub-3">
+///
+/// ```
+/// one
+/// two
+/// three
+/// ```
+///
+/// </sub>
+pub mod codeblock_sub {}
diff --git a/src/test/rustdoc-gui/struct-fields.goml b/src/test/rustdoc-gui/struct-fields.goml
index 3ec60b58cfd..fa3e16cb81e 100644
--- a/src/test/rustdoc-gui/struct-fields.goml
+++ b/src/test/rustdoc-gui/struct-fields.goml
@@ -1,5 +1,5 @@
+// This test ensures that each field is on its own line (In other words, they have display: block).
 goto: "file://" + |DOC_PATH| + "/test_docs/struct.StructWithPublicUndocumentedFields.html"
 
-// Both fields must be on their own line. In other words, they have display: block.
 store-property: (first_top, "//*[@id='structfield.first']", "offsetTop")
 assert-property-false: ("//*[@id='structfield.second']", { "offsetTop": |first_top| })
diff --git a/src/test/ui/error-codes/E0377.rs b/src/test/ui/error-codes/E0377.rs
new file mode 100644
index 00000000000..6da2c20956a
--- /dev/null
+++ b/src/test/ui/error-codes/E0377.rs
@@ -0,0 +1,14 @@
+#![feature(coerce_unsized)]
+use std::ops::CoerceUnsized;
+
+pub struct Foo<T: ?Sized> {
+    field_with_unsized_type: T,
+}
+
+pub struct Bar<T: ?Sized> {
+    field_with_unsized_type: T,
+}
+
+impl<T, U> CoerceUnsized<Bar<U>> for Foo<T> where T: CoerceUnsized<U> {} //~ ERROR E0377
+
+fn main() {}
diff --git a/src/test/ui/error-codes/E0377.stderr b/src/test/ui/error-codes/E0377.stderr
new file mode 100644
index 00000000000..bf7d8c8d39d
--- /dev/null
+++ b/src/test/ui/error-codes/E0377.stderr
@@ -0,0 +1,9 @@
+error[E0377]: the trait `CoerceUnsized` may only be implemented for a coercion between structures with the same definition; expected `Foo`, found `Bar`
+  --> $DIR/E0377.rs:12:1
+   |
+LL | impl<T, U> CoerceUnsized<Bar<U>> for Foo<T> where T: CoerceUnsized<U> {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0377`.
diff --git a/src/tools/tidy/src/error_codes_check.rs b/src/tools/tidy/src/error_codes_check.rs
index 610e322e129..1b119e4113e 100644
--- a/src/tools/tidy/src/error_codes_check.rs
+++ b/src/tools/tidy/src/error_codes_check.rs
@@ -11,8 +11,8 @@ use regex::Regex;
 
 // A few of those error codes can't be tested but all the others can and *should* be tested!
 const EXEMPTED_FROM_TEST: &[&str] = &[
-    "E0313", "E0377", "E0461", "E0462", "E0465", "E0476", "E0490", "E0514", "E0519", "E0523",
-    "E0554", "E0640", "E0717", "E0729", "E0789",
+    "E0313", "E0461", "E0462", "E0465", "E0476", "E0490", "E0514", "E0519", "E0523", "E0554",
+    "E0640", "E0717", "E0729", "E0789",
 ];
 
 // Some error codes don't have any tests apparently...