diff --git a/compiler/rustc_abi/src/callconv.rs b/compiler/rustc_abi/src/callconv.rs
index 9fb70b80c9efb..4529ab8058e9a 100644
--- a/compiler/rustc_abi/src/callconv.rs
+++ b/compiler/rustc_abi/src/callconv.rs
@@ -65,8 +65,6 @@ impl<'a, Ty> TyAndLayout<'a, Ty> {
         Ty: TyAbiInterface<'a, C> + Copy,
     {
         match self.backend_repr {
-            BackendRepr::Uninhabited => Err(Heterogeneous),
-
             // The primitive for this algorithm.
             BackendRepr::Scalar(scalar) => {
                 let kind = match scalar.primitive() {
diff --git a/compiler/rustc_abi/src/layout.rs b/compiler/rustc_abi/src/layout.rs
index 45cd0b517f6c7..53243266f992b 100644
--- a/compiler/rustc_abi/src/layout.rs
+++ b/compiler/rustc_abi/src/layout.rs
@@ -130,6 +130,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
             },
             backend_repr: BackendRepr::ScalarPair(a, b),
             largest_niche,
+            uninhabited: false,
             align,
             size,
             max_repr_align: None,
@@ -221,8 +222,9 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
         LayoutData {
             variants: Variants::Empty,
             fields: FieldsShape::Primitive,
-            backend_repr: BackendRepr::Uninhabited,
+            backend_repr: BackendRepr::Memory { sized: true },
             largest_niche: None,
+            uninhabited: true,
             align: dl.i8_align,
             size: Size::ZERO,
             max_repr_align: None,
@@ -400,6 +402,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
             fields: FieldsShape::Union(union_field_count),
             backend_repr: abi,
             largest_niche: None,
+            uninhabited: false,
             align,
             size: size.align_to(align.abi),
             max_repr_align,
@@ -447,7 +450,6 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
                 Scalar::Union { .. } => {}
             };
             match &mut st.backend_repr {
-                BackendRepr::Uninhabited => {}
                 BackendRepr::Scalar(scalar) => hide_niches(scalar),
                 BackendRepr::ScalarPair(a, b) => {
                     hide_niches(a);
@@ -639,9 +641,8 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
             let same_size = size == variant_layouts[largest_variant_index].size;
             let same_align = align == variant_layouts[largest_variant_index].align;
 
-            let abi = if variant_layouts.iter().all(|v| v.is_uninhabited()) {
-                BackendRepr::Uninhabited
-            } else if same_size && same_align && others_zst {
+            let uninhabited = variant_layouts.iter().all(|v| v.is_uninhabited());
+            let abi = if same_size && same_align && others_zst {
                 match variant_layouts[largest_variant_index].backend_repr {
                     // When the total alignment and size match, we can use the
                     // same ABI as the scalar variant with the reserved niche.
@@ -683,6 +684,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
                 },
                 backend_repr: abi,
                 largest_niche,
+                uninhabited,
                 size,
                 align,
                 max_repr_align,
@@ -853,9 +855,8 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
         };
         let mut abi = BackendRepr::Memory { sized: true };
 
-        if layout_variants.iter().all(|v| v.is_uninhabited()) {
-            abi = BackendRepr::Uninhabited;
-        } else if tag.size(dl) == size {
+        let uninhabited = layout_variants.iter().all(|v| v.is_uninhabited());
+        if tag.size(dl) == size {
             // Make sure we only use scalar layout when the enum is entirely its
             // own tag (i.e. it has no padding nor any non-ZST variant fields).
             abi = BackendRepr::Scalar(tag);
@@ -995,6 +996,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
                 memory_index: [0].into(),
             },
             largest_niche,
+            uninhabited,
             backend_repr: abi,
             align,
             size,
@@ -1355,9 +1357,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
                 _ => {}
             }
         }
-        if fields.iter().any(|f| f.is_uninhabited()) {
-            abi = BackendRepr::Uninhabited;
-        }
+        let uninhabited = fields.iter().any(|f| f.is_uninhabited());
 
         let unadjusted_abi_align = if repr.transparent() {
             match layout_of_single_non_zst_field {
@@ -1378,6 +1378,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
             fields: FieldsShape::Arbitrary { offsets, memory_index },
             backend_repr: abi,
             largest_niche,
+            uninhabited,
             align,
             size,
             max_repr_align,
diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs
index dbb4bed5cdd99..098638b6bcfa7 100644
--- a/compiler/rustc_abi/src/lib.rs
+++ b/compiler/rustc_abi/src/lib.rs
@@ -1404,7 +1404,6 @@ impl AddressSpace {
 #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
 #[cfg_attr(feature = "nightly", derive(HashStable_Generic))]
 pub enum BackendRepr {
-    Uninhabited,
     Scalar(Scalar),
     ScalarPair(Scalar, Scalar),
     Vector {
@@ -1423,10 +1422,9 @@ impl BackendRepr {
     #[inline]
     pub fn is_unsized(&self) -> bool {
         match *self {
-            BackendRepr::Uninhabited
-            | BackendRepr::Scalar(_)
-            | BackendRepr::ScalarPair(..)
-            | BackendRepr::Vector { .. } => false,
+            BackendRepr::Scalar(_) | BackendRepr::ScalarPair(..) | BackendRepr::Vector { .. } => {
+                false
+            }
             BackendRepr::Memory { sized } => !sized,
         }
     }
@@ -1445,12 +1443,6 @@ impl BackendRepr {
         }
     }
 
-    /// Returns `true` if this is an uninhabited type
-    #[inline]
-    pub fn is_uninhabited(&self) -> bool {
-        matches!(*self, BackendRepr::Uninhabited)
-    }
-
     /// Returns `true` if this is a scalar type
     #[inline]
     pub fn is_scalar(&self) -> bool {
@@ -1471,7 +1463,7 @@ impl BackendRepr {
             BackendRepr::Vector { element, count } => {
                 cx.data_layout().vector_align(element.size(cx) * count)
             }
-            BackendRepr::Uninhabited | BackendRepr::Memory { .. } => return None,
+            BackendRepr::Memory { .. } => return None,
         })
     }
 
@@ -1492,7 +1484,7 @@ impl BackendRepr {
                 // to make the size a multiple of align (e.g. for vectors of size 3).
                 (element.size(cx) * count).align_to(self.inherent_align(cx)?.abi)
             }
-            BackendRepr::Uninhabited | BackendRepr::Memory { .. } => return None,
+            BackendRepr::Memory { .. } => return None,
         })
     }
 
@@ -1506,9 +1498,7 @@ impl BackendRepr {
             BackendRepr::Vector { element, count } => {
                 BackendRepr::Vector { element: element.to_union(), count }
             }
-            BackendRepr::Uninhabited | BackendRepr::Memory { .. } => {
-                BackendRepr::Memory { sized: true }
-            }
+            BackendRepr::Memory { .. } => BackendRepr::Memory { sized: true },
         }
     }
 
@@ -1704,6 +1694,11 @@ pub struct LayoutData<FieldIdx: Idx, VariantIdx: Idx> {
     /// The leaf scalar with the largest number of invalid values
     /// (i.e. outside of its `valid_range`), if it exists.
     pub largest_niche: Option<Niche>,
+    /// Is this type known to be uninhabted?
+    ///
+    /// This is separate from BackendRepr because uninhabited return types can affect ABI,
+    /// especially in the case of by-pointer struct returns, which allocate stack even when unused.
+    pub uninhabited: bool,
 
     pub align: AbiAndPrefAlign,
     pub size: Size,
@@ -1735,14 +1730,14 @@ impl<FieldIdx: Idx, VariantIdx: Idx> LayoutData<FieldIdx, VariantIdx> {
     /// Returns `true` if this is an aggregate type (including a ScalarPair!)
     pub fn is_aggregate(&self) -> bool {
         match self.backend_repr {
-            BackendRepr::Uninhabited | BackendRepr::Scalar(_) | BackendRepr::Vector { .. } => false,
+            BackendRepr::Scalar(_) | BackendRepr::Vector { .. } => false,
             BackendRepr::ScalarPair(..) | BackendRepr::Memory { .. } => true,
         }
     }
 
     /// Returns `true` if this is an uninhabited type
     pub fn is_uninhabited(&self) -> bool {
-        self.backend_repr.is_uninhabited()
+        self.uninhabited
     }
 
     pub fn scalar<C: HasDataLayout>(cx: &C, scalar: Scalar) -> Self {
@@ -1778,6 +1773,7 @@ impl<FieldIdx: Idx, VariantIdx: Idx> LayoutData<FieldIdx, VariantIdx> {
             fields: FieldsShape::Primitive,
             backend_repr: BackendRepr::Scalar(scalar),
             largest_niche,
+            uninhabited: false,
             size,
             align,
             max_repr_align: None,
@@ -1802,6 +1798,7 @@ where
             backend_repr,
             fields,
             largest_niche,
+            uninhabited,
             variants,
             max_repr_align,
             unadjusted_abi_align,
@@ -1813,6 +1810,7 @@ where
             .field("abi", backend_repr)
             .field("fields", fields)
             .field("largest_niche", largest_niche)
+            .field("uninhabited", uninhabited)
             .field("variants", variants)
             .field("max_repr_align", max_repr_align)
             .field("unadjusted_abi_align", unadjusted_abi_align)
@@ -1877,7 +1875,6 @@ impl<FieldIdx: Idx, VariantIdx: Idx> LayoutData<FieldIdx, VariantIdx> {
             BackendRepr::Scalar(_) | BackendRepr::ScalarPair(..) | BackendRepr::Vector { .. } => {
                 false
             }
-            BackendRepr::Uninhabited => self.size.bytes() == 0,
             BackendRepr::Memory { sized } => sized && self.size.bytes() == 0,
         }
     }
diff --git a/compiler/rustc_codegen_cranelift/src/value_and_place.rs b/compiler/rustc_codegen_cranelift/src/value_and_place.rs
index a9b8e1bd39353..1b3f86c8405de 100644
--- a/compiler/rustc_codegen_cranelift/src/value_and_place.rs
+++ b/compiler/rustc_codegen_cranelift/src/value_and_place.rs
@@ -638,9 +638,7 @@ impl<'tcx> CPlace<'tcx> {
             }
             CPlaceInner::Addr(_, Some(_)) => bug!("Can't write value to unsized place {:?}", self),
             CPlaceInner::Addr(to_ptr, None) => {
-                if dst_layout.size == Size::ZERO
-                    || dst_layout.backend_repr == BackendRepr::Uninhabited
-                {
+                if dst_layout.size == Size::ZERO {
                     return;
                 }
 
diff --git a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs
index a1123fafe2f30..b3b7f35af8cf6 100644
--- a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs
+++ b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs
@@ -310,7 +310,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc
                 let layout = self.layout_of(tp_ty).layout;
                 let _use_integer_compare = match layout.backend_repr() {
                     Scalar(_) | ScalarPair(_, _) => true,
-                    Uninhabited | Vector { .. } => false,
+                    Vector { .. } => false,
                     Memory { .. } => {
                         // For rusty ABIs, small aggregates are actually passed
                         // as `RegKind::Integer` (see `FnAbi::adjust_for_abi`),
diff --git a/compiler/rustc_codegen_gcc/src/type_of.rs b/compiler/rustc_codegen_gcc/src/type_of.rs
index 8b8b54753e7fd..bac4fc51300a2 100644
--- a/compiler/rustc_codegen_gcc/src/type_of.rs
+++ b/compiler/rustc_codegen_gcc/src/type_of.rs
@@ -84,7 +84,7 @@ fn uncached_gcc_type<'gcc, 'tcx>(
                 false,
             );
         }
-        BackendRepr::Uninhabited | BackendRepr::Memory { .. } => {}
+        BackendRepr::Memory { .. } => {}
     }
 
     let name = match *layout.ty.kind() {
@@ -179,19 +179,16 @@ impl<'tcx> LayoutGccExt<'tcx> for TyAndLayout<'tcx> {
     fn is_gcc_immediate(&self) -> bool {
         match self.backend_repr {
             BackendRepr::Scalar(_) | BackendRepr::Vector { .. } => true,
-            BackendRepr::ScalarPair(..) | BackendRepr::Uninhabited | BackendRepr::Memory { .. } => {
-                false
-            }
+            BackendRepr::ScalarPair(..) | BackendRepr::Memory { .. } => false,
         }
     }
 
     fn is_gcc_scalar_pair(&self) -> bool {
         match self.backend_repr {
             BackendRepr::ScalarPair(..) => true,
-            BackendRepr::Uninhabited
-            | BackendRepr::Scalar(_)
-            | BackendRepr::Vector { .. }
-            | BackendRepr::Memory { .. } => false,
+            BackendRepr::Scalar(_) | BackendRepr::Vector { .. } | BackendRepr::Memory { .. } => {
+                false
+            }
         }
     }
 
diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs
index 8b97688590456..fc509704d0fde 100644
--- a/compiler/rustc_codegen_llvm/src/intrinsic.rs
+++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs
@@ -475,7 +475,7 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
                 let layout = self.layout_of(tp_ty).layout;
                 let use_integer_compare = match layout.backend_repr() {
                     Scalar(_) | ScalarPair(_, _) => true,
-                    Uninhabited | Vector { .. } => false,
+                    Vector { .. } => false,
                     Memory { .. } => {
                         // For rusty ABIs, small aggregates are actually passed
                         // as `RegKind::Integer` (see `FnAbi::adjust_for_abi`),
diff --git a/compiler/rustc_codegen_llvm/src/type_of.rs b/compiler/rustc_codegen_llvm/src/type_of.rs
index b0b6da869da68..ba01fbff38539 100644
--- a/compiler/rustc_codegen_llvm/src/type_of.rs
+++ b/compiler/rustc_codegen_llvm/src/type_of.rs
@@ -23,7 +23,7 @@ fn uncached_llvm_type<'a, 'tcx>(
             let element = layout.scalar_llvm_type_at(cx, element);
             return cx.type_vector(element, count);
         }
-        BackendRepr::Uninhabited | BackendRepr::Memory { .. } | BackendRepr::ScalarPair(..) => {}
+        BackendRepr::Memory { .. } | BackendRepr::ScalarPair(..) => {}
     }
 
     let name = match layout.ty.kind() {
@@ -172,19 +172,16 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyAndLayout<'tcx> {
     fn is_llvm_immediate(&self) -> bool {
         match self.backend_repr {
             BackendRepr::Scalar(_) | BackendRepr::Vector { .. } => true,
-            BackendRepr::ScalarPair(..) | BackendRepr::Uninhabited | BackendRepr::Memory { .. } => {
-                false
-            }
+            BackendRepr::ScalarPair(..) | BackendRepr::Memory { .. } => false,
         }
     }
 
     fn is_llvm_scalar_pair(&self) -> bool {
         match self.backend_repr {
             BackendRepr::ScalarPair(..) => true,
-            BackendRepr::Uninhabited
-            | BackendRepr::Scalar(_)
-            | BackendRepr::Vector { .. }
-            | BackendRepr::Memory { .. } => false,
+            BackendRepr::Scalar(_) | BackendRepr::Vector { .. } | BackendRepr::Memory { .. } => {
+                false
+            }
         }
     }
 
diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs
index 616d748a2995a..1b88418fcf4fc 100644
--- a/compiler/rustc_codegen_ssa/src/mir/block.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/block.rs
@@ -4,9 +4,7 @@ use rustc_abi::{BackendRepr, ExternAbi, HasDataLayout, Reg, WrappingRange};
 use rustc_ast as ast;
 use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
 use rustc_hir::lang_items::LangItem;
-use rustc_middle::mir::{
-    self, AssertKind, BasicBlock, InlineAsmMacro, SwitchTargets, UnwindTerminateReason,
-};
+use rustc_middle::mir::{self, AssertKind, InlineAsmMacro, SwitchTargets, UnwindTerminateReason};
 use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf, ValidityRequirement};
 use rustc_middle::ty::print::{with_no_trimmed_paths, with_no_visible_paths};
 use rustc_middle::ty::{self, Instance, Ty};
@@ -942,7 +940,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                     &fn_abi.ret,
                     &mut llargs,
                     Some(intrinsic),
-                    target,
                 );
                 let dest = match ret_dest {
                     _ if fn_abi.ret.is_indirect() => llargs[0],
@@ -998,19 +995,12 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
         };
 
         let mut llargs = Vec::with_capacity(arg_count);
-        let destination = target.as_ref().map(|&target| {
-            (
-                self.make_return_dest(
-                    bx,
-                    destination,
-                    &fn_abi.ret,
-                    &mut llargs,
-                    None,
-                    Some(target),
-                ),
-                target,
-            )
-        });
+
+        // We still need to call `make_return_dest` even if there's no `target`, since
+        // `fn_abi.ret` could be `PassMode::Indirect`, even if it is uninhabited,
+        // and `make_return_dest` adds the return-place indirect pointer to `llargs`.
+        let return_dest = self.make_return_dest(bx, destination, &fn_abi.ret, &mut llargs, None);
+        let destination = target.map(|target| (return_dest, target));
 
         // Split the rust-call tupled arguments off.
         let (first_args, untuple) = if abi == ExternAbi::RustCall && !args.is_empty() {
@@ -1813,11 +1803,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
         fn_ret: &ArgAbi<'tcx, Ty<'tcx>>,
         llargs: &mut Vec<Bx::Value>,
         intrinsic: Option<ty::IntrinsicDef>,
-        target: Option<BasicBlock>,
     ) -> ReturnDest<'tcx, Bx::Value> {
-        if target.is_none() {
-            return ReturnDest::Nothing;
-        }
         // If the return is ignored, we can just return a do-nothing `ReturnDest`.
         if fn_ret.is_ignore() {
             return ReturnDest::Nothing;
diff --git a/compiler/rustc_codegen_ssa/src/mir/operand.rs b/compiler/rustc_codegen_ssa/src/mir/operand.rs
index 9ca7d4f8f0047..4616533bf9932 100644
--- a/compiler/rustc_codegen_ssa/src/mir/operand.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/operand.rs
@@ -415,10 +415,7 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> {
                 bx.store(*llval, llptr, field.align.abi);
                 *llval = bx.load(llfield_ty, llptr, field.align.abi);
             }
-            (
-                OperandValue::Immediate(_),
-                BackendRepr::Uninhabited | BackendRepr::Memory { sized: false },
-            ) => {
+            (OperandValue::Immediate(_), BackendRepr::Memory { sized: false }) => {
                 bug!()
             }
             (OperandValue::Pair(..), _) => bug!(),
diff --git a/compiler/rustc_const_eval/src/interpret/operand.rs b/compiler/rustc_const_eval/src/interpret/operand.rs
index 5d905cff1f216..36da9037e43d9 100644
--- a/compiler/rustc_const_eval/src/interpret/operand.rs
+++ b/compiler/rustc_const_eval/src/interpret/operand.rs
@@ -385,7 +385,7 @@ impl<'tcx, Prov: Provenance> ImmTy<'tcx, Prov> {
             (Immediate::Uninit, _) => Immediate::Uninit,
             // If the field is uninhabited, we can forget the data (can happen in ConstProp).
             // `enum S { A(!), B, C }` is an example of an enum with Scalar layout that
-            // has an `Uninhabited` variant, which means this case is possible.
+            // has an uninhabited variant, which means this case is possible.
             _ if layout.is_uninhabited() => Immediate::Uninit,
             // the field contains no information, can be left uninit
             // (Scalar/ScalarPair can contain even aligned ZST, not just 1-ZST)
diff --git a/compiler/rustc_const_eval/src/interpret/validity.rs b/compiler/rustc_const_eval/src/interpret/validity.rs
index 0ac34f4633b57..40dec0cb39e7b 100644
--- a/compiler/rustc_const_eval/src/interpret/validity.rs
+++ b/compiler/rustc_const_eval/src/interpret/validity.rs
@@ -1264,21 +1264,20 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValueVisitor<'tcx, M> for ValidityVisitor<'rt,
             }
         }
 
-        // *After* all of this, check the ABI. We need to check the ABI to handle
-        // types like `NonNull` where the `Scalar` info is more restrictive than what
-        // the fields say (`rustc_layout_scalar_valid_range_start`).
-        // But in most cases, this will just propagate what the fields say,
-        // and then we want the error to point at the field -- so, first recurse,
-        // then check ABI.
+        // *After* all of this, check further information stored in the layout. We need to check
+        // this to handle types like `NonNull` where the `Scalar` info is more restrictive than what
+        // the fields say (`rustc_layout_scalar_valid_range_start`). But in most cases, this will
+        // just propagate what the fields say, and then we want the error to point at the field --
+        // so, we first recurse, then we do this check.
         //
         // FIXME: We could avoid some redundant checks here. For newtypes wrapping
         // scalars, we do the same check on every "level" (e.g., first we check
         // MyNewtype and then the scalar in there).
+        if val.layout.is_uninhabited() {
+            let ty = val.layout.ty;
+            throw_validation_failure!(self.path, UninhabitedVal { ty });
+        }
         match val.layout.backend_repr {
-            BackendRepr::Uninhabited => {
-                let ty = val.layout.ty;
-                throw_validation_failure!(self.path, UninhabitedVal { ty });
-            }
             BackendRepr::Scalar(scalar_layout) => {
                 if !scalar_layout.is_uninit_valid() {
                     // There is something to check here.
diff --git a/compiler/rustc_const_eval/src/util/check_validity_requirement.rs b/compiler/rustc_const_eval/src/util/check_validity_requirement.rs
index 79baf91c3ce64..6426bca2332d4 100644
--- a/compiler/rustc_const_eval/src/util/check_validity_requirement.rs
+++ b/compiler/rustc_const_eval/src/util/check_validity_requirement.rs
@@ -111,13 +111,15 @@ fn check_validity_requirement_lax<'tcx>(
     };
 
     // Check the ABI.
-    let valid = match this.backend_repr {
-        BackendRepr::Uninhabited => false, // definitely UB
-        BackendRepr::Scalar(s) => scalar_allows_raw_init(s),
-        BackendRepr::ScalarPair(s1, s2) => scalar_allows_raw_init(s1) && scalar_allows_raw_init(s2),
-        BackendRepr::Vector { element: s, count } => count == 0 || scalar_allows_raw_init(s),
-        BackendRepr::Memory { .. } => true, // Fields are checked below.
-    };
+    let valid = !this.is_uninhabited() // definitely UB if uninhabited
+        && match this.backend_repr {
+            BackendRepr::Scalar(s) => scalar_allows_raw_init(s),
+            BackendRepr::ScalarPair(s1, s2) => {
+                scalar_allows_raw_init(s1) && scalar_allows_raw_init(s2)
+            }
+            BackendRepr::Vector { element: s, count } => count == 0 || scalar_allows_raw_init(s),
+            BackendRepr::Memory { .. } => true, // Fields are checked below.
+        };
     if !valid {
         // This is definitely not okay.
         return Ok(false);
diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs
index bbb8a9fa67149..36dfca22adf18 100644
--- a/compiler/rustc_middle/src/ty/layout.rs
+++ b/compiler/rustc_middle/src/ty/layout.rs
@@ -773,8 +773,9 @@ where
                         Some(fields) => FieldsShape::Union(fields),
                         None => FieldsShape::Arbitrary { offsets: IndexVec::new(), memory_index: IndexVec::new() },
                     },
-                    backend_repr: BackendRepr::Uninhabited,
+                    backend_repr: BackendRepr::Memory { sized: true },
                     largest_niche: None,
+                    uninhabited: true,
                     align: tcx.data_layout.i8_align,
                     size: Size::ZERO,
                     max_repr_align: None,
diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs
index 77a3854ebdef3..2f8a305019999 100644
--- a/compiler/rustc_mir_transform/src/gvn.rs
+++ b/compiler/rustc_mir_transform/src/gvn.rs
@@ -1558,8 +1558,11 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
             return true;
         };
 
+        if layout.uninhabited {
+            return true;
+        }
+
         match layout.backend_repr {
-            BackendRepr::Uninhabited => true,
             BackendRepr::Scalar(a) => !a.is_always_valid(&self.ecx),
             BackendRepr::ScalarPair(a, b) => {
                 !a.is_always_valid(&self.ecx) || !b.is_always_valid(&self.ecx)
diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs
index 0962865e7f190..b37c684a0556a 100644
--- a/compiler/rustc_resolve/src/late/diagnostics.rs
+++ b/compiler/rustc_resolve/src/late/diagnostics.rs
@@ -8,7 +8,7 @@ use rustc_ast::ptr::P;
 use rustc_ast::visit::{FnCtxt, FnKind, LifetimeCtxt, Visitor, walk_ty};
 use rustc_ast::{
     self as ast, AssocItemKind, DUMMY_NODE_ID, Expr, ExprKind, GenericParam, GenericParamKind,
-    Item, ItemKind, MethodCall, NodeId, Path, Ty, TyKind,
+    Item, ItemKind, MethodCall, NodeId, Path, PathSegment, Ty, TyKind,
 };
 use rustc_ast_pretty::pprust::where_bound_predicate_to_string;
 use rustc_data_structures::fx::{FxHashSet, FxIndexSet};
@@ -1529,7 +1529,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
                     Applicability::MaybeIncorrect,
                 );
                 true
-            } else if kind == DefKind::Struct
+            } else if matches!(kind, DefKind::Struct | DefKind::TyAlias)
                 && let Some(lhs_source_span) = lhs_span.find_ancestor_inside(expr.span)
                 && let Ok(snippet) = this.r.tcx.sess.source_map().span_to_snippet(lhs_source_span)
             {
@@ -1566,7 +1566,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
             }
         };
 
-        let mut bad_struct_syntax_suggestion = |this: &mut Self, def_id: DefId| {
+        let bad_struct_syntax_suggestion = |this: &mut Self, err: &mut Diag<'_>, def_id: DefId| {
             let (followed_by_brace, closing_brace) = this.followed_by_brace(span);
 
             match source {
@@ -1740,12 +1740,10 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
                 }
             }
             (
-                Res::Def(kind @ (DefKind::Mod | DefKind::Trait), _),
+                Res::Def(kind @ (DefKind::Mod | DefKind::Trait | DefKind::TyAlias), _),
                 PathSource::Expr(Some(parent)),
-            ) => {
-                if !path_sep(self, err, parent, kind) {
-                    return false;
-                }
+            ) if path_sep(self, err, parent, kind) => {
+                return true;
             }
             (
                 Res::Def(DefKind::Enum, def_id),
@@ -1777,13 +1775,13 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
                 let (ctor_def, ctor_vis, fields) = if let Some(struct_ctor) = struct_ctor {
                     if let PathSource::Expr(Some(parent)) = source {
                         if let ExprKind::Field(..) | ExprKind::MethodCall(..) = parent.kind {
-                            bad_struct_syntax_suggestion(self, def_id);
+                            bad_struct_syntax_suggestion(self, err, def_id);
                             return true;
                         }
                     }
                     struct_ctor
                 } else {
-                    bad_struct_syntax_suggestion(self, def_id);
+                    bad_struct_syntax_suggestion(self, err, def_id);
                     return true;
                 };
 
@@ -1861,7 +1859,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
                 err.span_label(span, "constructor is not visible here due to private fields");
             }
             (Res::Def(DefKind::Union | DefKind::Variant, def_id), _) if ns == ValueNS => {
-                bad_struct_syntax_suggestion(self, def_id);
+                bad_struct_syntax_suggestion(self, err, def_id);
             }
             (Res::Def(DefKind::Ctor(_, CtorKind::Const), def_id), _) if ns == ValueNS => {
                 match source {
@@ -2471,31 +2469,73 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
         def_id: DefId,
         span: Span,
     ) {
-        let Some(variants) = self.collect_enum_ctors(def_id) else {
+        let Some(variant_ctors) = self.collect_enum_ctors(def_id) else {
             err.note("you might have meant to use one of the enum's variants");
             return;
         };
 
-        let suggest_only_tuple_variants =
-            matches!(source, PathSource::TupleStruct(..)) || source.is_call();
-        if suggest_only_tuple_variants {
+        // If the expression is a field-access or method-call, try to find a variant with the field/method name
+        // that could have been intended, and suggest replacing the `.` with `::`.
+        // Otherwise, suggest adding `::VariantName` after the enum;
+        // and if the expression is call-like, only suggest tuple variants.
+        let (suggest_path_sep_dot_span, suggest_only_tuple_variants) = match source {
+            // `Type(a, b)` in a pattern, only suggest adding a tuple variant after `Type`.
+            PathSource::TupleStruct(..) => (None, true),
+            PathSource::Expr(Some(expr)) => match &expr.kind {
+                // `Type(a, b)`, only suggest adding a tuple variant after `Type`.
+                ExprKind::Call(..) => (None, true),
+                // `Type.Foo(a, b)`, suggest replacing `.` -> `::` if variant `Foo` exists and is a tuple variant,
+                // otherwise suggest adding a variant after `Type`.
+                ExprKind::MethodCall(box MethodCall {
+                    receiver,
+                    span,
+                    seg: PathSegment { ident, .. },
+                    ..
+                }) => {
+                    let dot_span = receiver.span.between(*span);
+                    let found_tuple_variant = variant_ctors.iter().any(|(path, _, ctor_kind)| {
+                        *ctor_kind == CtorKind::Fn
+                            && path.segments.last().is_some_and(|seg| seg.ident == *ident)
+                    });
+                    (found_tuple_variant.then_some(dot_span), false)
+                }
+                // `Type.Foo`, suggest replacing `.` -> `::` if variant `Foo` exists and is a unit or tuple variant,
+                // otherwise suggest adding a variant after `Type`.
+                ExprKind::Field(base, ident) => {
+                    let dot_span = base.span.between(ident.span);
+                    let found_tuple_or_unit_variant = variant_ctors.iter().any(|(path, ..)| {
+                        path.segments.last().is_some_and(|seg| seg.ident == *ident)
+                    });
+                    (found_tuple_or_unit_variant.then_some(dot_span), false)
+                }
+                _ => (None, false),
+            },
+            _ => (None, false),
+        };
+
+        if let Some(dot_span) = suggest_path_sep_dot_span {
+            err.span_suggestion_verbose(
+                dot_span,
+                "use the path separator to refer to a variant",
+                "::",
+                Applicability::MaybeIncorrect,
+            );
+        } else if suggest_only_tuple_variants {
             // Suggest only tuple variants regardless of whether they have fields and do not
             // suggest path with added parentheses.
-            let mut suggestable_variants = variants
+            let mut suggestable_variants = variant_ctors
                 .iter()
                 .filter(|(.., kind)| *kind == CtorKind::Fn)
                 .map(|(variant, ..)| path_names_to_string(variant))
                 .collect::<Vec<_>>();
             suggestable_variants.sort();
 
-            let non_suggestable_variant_count = variants.len() - suggestable_variants.len();
+            let non_suggestable_variant_count = variant_ctors.len() - suggestable_variants.len();
 
-            let source_msg = if source.is_call() {
-                "to construct"
-            } else if matches!(source, PathSource::TupleStruct(..)) {
+            let source_msg = if matches!(source, PathSource::TupleStruct(..)) {
                 "to match against"
             } else {
-                unreachable!()
+                "to construct"
             };
 
             if !suggestable_variants.is_empty() {
@@ -2514,7 +2554,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
             }
 
             // If the enum has no tuple variants..
-            if non_suggestable_variant_count == variants.len() {
+            if non_suggestable_variant_count == variant_ctors.len() {
                 err.help(format!("the enum has no tuple variants {source_msg}"));
             }
 
@@ -2537,7 +2577,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
                 }
             };
 
-            let mut suggestable_variants = variants
+            let mut suggestable_variants = variant_ctors
                 .iter()
                 .filter(|(_, def_id, kind)| !needs_placeholder(*def_id, *kind))
                 .map(|(variant, _, kind)| (path_names_to_string(variant), kind))
@@ -2564,7 +2604,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
                 );
             }
 
-            let mut suggestable_variants_with_placeholders = variants
+            let mut suggestable_variants_with_placeholders = variant_ctors
                 .iter()
                 .filter(|(_, def_id, kind)| needs_placeholder(*def_id, *kind))
                 .map(|(variant, _, kind)| (path_names_to_string(variant), kind))
diff --git a/compiler/rustc_smir/src/rustc_smir/convert/abi.rs b/compiler/rustc_smir/src/rustc_smir/convert/abi.rs
index fb2e838cdc998..a627e0e69b62f 100644
--- a/compiler/rustc_smir/src/rustc_smir/convert/abi.rs
+++ b/compiler/rustc_smir/src/rustc_smir/convert/abi.rs
@@ -202,7 +202,6 @@ impl<'tcx> Stable<'tcx> for rustc_abi::BackendRepr {
 
     fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
         match *self {
-            rustc_abi::BackendRepr::Uninhabited => ValueAbi::Uninhabited,
             rustc_abi::BackendRepr::Scalar(scalar) => ValueAbi::Scalar(scalar.stable(tables)),
             rustc_abi::BackendRepr::ScalarPair(first, second) => {
                 ValueAbi::ScalarPair(first.stable(tables), second.stable(tables))
diff --git a/compiler/rustc_target/src/callconv/loongarch.rs b/compiler/rustc_target/src/callconv/loongarch.rs
index 47566bde6b4a4..3fa67c624a7be 100644
--- a/compiler/rustc_target/src/callconv/loongarch.rs
+++ b/compiler/rustc_target/src/callconv/loongarch.rs
@@ -80,7 +80,7 @@ where
                 }
             }
         },
-        BackendRepr::Vector { .. } | BackendRepr::Uninhabited => return Err(CannotUseFpConv),
+        BackendRepr::Vector { .. } => return Err(CannotUseFpConv),
         BackendRepr::ScalarPair(..) | BackendRepr::Memory { .. } => match arg_layout.fields {
             FieldsShape::Primitive => {
                 unreachable!("aggregates can't have `FieldsShape::Primitive`")
diff --git a/compiler/rustc_target/src/callconv/mod.rs b/compiler/rustc_target/src/callconv/mod.rs
index 2bde105562218..0ea52c1aafb76 100644
--- a/compiler/rustc_target/src/callconv/mod.rs
+++ b/compiler/rustc_target/src/callconv/mod.rs
@@ -38,7 +38,7 @@ mod xtensa;
 pub enum PassMode {
     /// Ignore the argument.
     ///
-    /// The argument is either uninhabited or a ZST.
+    /// The argument is a ZST.
     Ignore,
     /// Pass the argument directly.
     ///
@@ -350,7 +350,6 @@ impl<'a, Ty> ArgAbi<'a, Ty> {
         scalar_attrs: impl Fn(&TyAndLayout<'a, Ty>, Scalar, Size) -> ArgAttributes,
     ) -> Self {
         let mode = match layout.backend_repr {
-            BackendRepr::Uninhabited => PassMode::Ignore,
             BackendRepr::Scalar(scalar) => {
                 PassMode::Direct(scalar_attrs(&layout, scalar, Size::ZERO))
             }
diff --git a/compiler/rustc_target/src/callconv/riscv.rs b/compiler/rustc_target/src/callconv/riscv.rs
index 265ae20f9919d..785175229b031 100644
--- a/compiler/rustc_target/src/callconv/riscv.rs
+++ b/compiler/rustc_target/src/callconv/riscv.rs
@@ -86,7 +86,7 @@ where
                 }
             }
         },
-        BackendRepr::Vector { .. } | BackendRepr::Uninhabited => return Err(CannotUseFpConv),
+        BackendRepr::Vector { .. } => return Err(CannotUseFpConv),
         BackendRepr::ScalarPair(..) | BackendRepr::Memory { .. } => match arg_layout.fields {
             FieldsShape::Primitive => {
                 unreachable!("aggregates can't have `FieldsShape::Primitive`")
diff --git a/compiler/rustc_target/src/callconv/x86.rs b/compiler/rustc_target/src/callconv/x86.rs
index 5b9414536d8ca..4a9430bb80e74 100644
--- a/compiler/rustc_target/src/callconv/x86.rs
+++ b/compiler/rustc_target/src/callconv/x86.rs
@@ -108,9 +108,7 @@ where
                 Ty: TyAbiInterface<'a, C> + Copy,
             {
                 match layout.backend_repr {
-                    BackendRepr::Uninhabited
-                    | BackendRepr::Scalar(_)
-                    | BackendRepr::ScalarPair(..) => false,
+                    BackendRepr::Scalar(_) | BackendRepr::ScalarPair(..) => false,
                     BackendRepr::Vector { .. } => true,
                     BackendRepr::Memory { .. } => {
                         for i in 0..layout.fields.count() {
diff --git a/compiler/rustc_target/src/callconv/x86_64.rs b/compiler/rustc_target/src/callconv/x86_64.rs
index b15d82c26dac2..ab306e202396b 100644
--- a/compiler/rustc_target/src/callconv/x86_64.rs
+++ b/compiler/rustc_target/src/callconv/x86_64.rs
@@ -51,8 +51,6 @@ where
         }
 
         let mut c = match layout.backend_repr {
-            BackendRepr::Uninhabited => return Ok(()),
-
             BackendRepr::Scalar(scalar) => match scalar.primitive() {
                 Primitive::Int(..) | Primitive::Pointer(_) => Class::Int,
                 Primitive::Float(_) => Class::Sse,
diff --git a/compiler/rustc_target/src/callconv/x86_win64.rs b/compiler/rustc_target/src/callconv/x86_win64.rs
index 23ef2cf828409..1ee63d9200d9b 100644
--- a/compiler/rustc_target/src/callconv/x86_win64.rs
+++ b/compiler/rustc_target/src/callconv/x86_win64.rs
@@ -8,7 +8,7 @@ use crate::spec::HasTargetSpec;
 pub(crate) fn compute_abi_info<Ty>(_cx: &impl HasTargetSpec, fn_abi: &mut FnAbi<'_, Ty>) {
     let fixup = |a: &mut ArgAbi<'_, Ty>, is_ret: bool| {
         match a.layout.backend_repr {
-            BackendRepr::Uninhabited | BackendRepr::Memory { sized: false } => {}
+            BackendRepr::Memory { sized: false } => {}
             BackendRepr::ScalarPair(..) | BackendRepr::Memory { sized: true } => {
                 match a.layout.size.bits() {
                     8 => a.cast_to(Reg::i8()),
diff --git a/compiler/rustc_ty_utils/src/abi.rs b/compiler/rustc_ty_utils/src/abi.rs
index c5d2d0afbfad2..0ff82f0c256de 100644
--- a/compiler/rustc_ty_utils/src/abi.rs
+++ b/compiler/rustc_ty_utils/src/abi.rs
@@ -464,7 +464,7 @@ fn fn_abi_sanity_check<'tcx>(
 
         match &arg.mode {
             PassMode::Ignore => {
-                assert!(arg.layout.is_zst() || arg.layout.is_uninhabited());
+                assert!(arg.layout.is_zst());
             }
             PassMode::Direct(_) => {
                 // Here the Rust type is used to determine the actual ABI, so we have to be very
@@ -472,9 +472,7 @@ fn fn_abi_sanity_check<'tcx>(
                 // `layout.backend_repr` and ignore everything else. We should just reject
                 //`Aggregate` entirely here, but some targets need to be fixed first.
                 match arg.layout.backend_repr {
-                    BackendRepr::Uninhabited
-                    | BackendRepr::Scalar(_)
-                    | BackendRepr::Vector { .. } => {}
+                    BackendRepr::Scalar(_) | BackendRepr::Vector { .. } => {}
                     BackendRepr::ScalarPair(..) => {
                         panic!("`PassMode::Direct` used for ScalarPair type {}", arg.layout.ty)
                     }
diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs
index 8429e68b600da..843a84a81bd5e 100644
--- a/compiler/rustc_ty_utils/src/layout.rs
+++ b/compiler/rustc_ty_utils/src/layout.rs
@@ -364,19 +364,17 @@ fn layout_of_uncached<'tcx>(
                 .checked_mul(count, dl)
                 .ok_or_else(|| error(cx, LayoutError::SizeOverflow(ty)))?;
 
-            let abi = if count != 0 && ty.is_privately_uninhabited(tcx, cx.typing_env) {
-                BackendRepr::Uninhabited
-            } else {
-                BackendRepr::Memory { sized: true }
-            };
+            let abi = BackendRepr::Memory { sized: true };
 
             let largest_niche = if count != 0 { element.largest_niche } else { None };
+            let uninhabited = if count != 0 { element.uninhabited } else { false };
 
             tcx.mk_layout(LayoutData {
                 variants: Variants::Single { index: FIRST_VARIANT },
                 fields: FieldsShape::Array { stride: element.size, count },
                 backend_repr: abi,
                 largest_niche,
+                uninhabited,
                 align: element.align,
                 size,
                 max_repr_align: None,
@@ -391,6 +389,7 @@ fn layout_of_uncached<'tcx>(
                 fields: FieldsShape::Array { stride: element.size, count: 0 },
                 backend_repr: BackendRepr::Memory { sized: false },
                 largest_niche: None,
+                uninhabited: false,
                 align: element.align,
                 size: Size::ZERO,
                 max_repr_align: None,
@@ -406,6 +405,7 @@ fn layout_of_uncached<'tcx>(
             fields: FieldsShape::Array { stride: Size::from_bytes(1), count: 0 },
             backend_repr: BackendRepr::Memory { sized: false },
             largest_niche: None,
+            uninhabited: false,
             align: dl.i8_align,
             size: Size::ZERO,
             max_repr_align: None,
@@ -584,6 +584,7 @@ fn layout_of_uncached<'tcx>(
                 fields,
                 backend_repr: abi,
                 largest_niche: e_ly.largest_niche,
+                uninhabited: false,
                 size,
                 align,
                 max_repr_align: None,
@@ -1045,13 +1046,8 @@ fn coroutine_layout<'tcx>(
 
     size = size.align_to(align.abi);
 
-    let abi = if prefix.backend_repr.is_uninhabited()
-        || variants.iter().all(|v| v.backend_repr.is_uninhabited())
-    {
-        BackendRepr::Uninhabited
-    } else {
-        BackendRepr::Memory { sized: true }
-    };
+    let uninhabited = prefix.uninhabited || variants.iter().all(|v| v.is_uninhabited());
+    let abi = BackendRepr::Memory { sized: true };
 
     // this is similar to how ReprOptions populates its field_shuffle_seed
     let def_hash = tcx.def_path_hash(def_id).0.to_smaller_hash();
@@ -1072,6 +1068,7 @@ fn coroutine_layout<'tcx>(
         // See <https://github.com/rust-lang/rust/issues/63818>, <https://github.com/rust-lang/miri/issues/3780>.
         // FIXME: Remove when <https://github.com/rust-lang/rust/issues/125735> is implemented and aliased coroutine fields are wrapped in `UnsafePinned`.
         largest_niche: None,
+        uninhabited,
         size,
         align,
         max_repr_align: None,
diff --git a/compiler/rustc_ty_utils/src/layout/invariant.rs b/compiler/rustc_ty_utils/src/layout/invariant.rs
index 8d5403ed32468..5ea6716c5ca14 100644
--- a/compiler/rustc_ty_utils/src/layout/invariant.rs
+++ b/compiler/rustc_ty_utils/src/layout/invariant.rs
@@ -10,7 +10,11 @@ pub(super) fn layout_sanity_check<'tcx>(cx: &LayoutCx<'tcx>, layout: &TyAndLayou
 
     // Type-level uninhabitedness should always imply ABI uninhabitedness.
     if layout.ty.is_privately_uninhabited(tcx, cx.typing_env) {
-        assert!(layout.is_uninhabited());
+        assert!(
+            layout.is_uninhabited(),
+            "{:?} is type-level uninhabited but not ABI-uninhabited?",
+            layout.ty
+        );
     }
 
     if layout.size.bytes() % layout.align.abi.bytes() != 0 {
@@ -71,7 +75,7 @@ pub(super) fn layout_sanity_check<'tcx>(cx: &LayoutCx<'tcx>, layout: &TyAndLayou
         let Some((align, size)) = align.zip(size) else {
             assert_matches!(
                 layout.layout.backend_repr(),
-                BackendRepr::Uninhabited | BackendRepr::Memory { .. },
+                BackendRepr::Memory { .. },
                 "ABI unexpectedly missing alignment and/or size in {layout:#?}"
             );
             return;
@@ -235,7 +239,7 @@ pub(super) fn layout_sanity_check<'tcx>(cx: &LayoutCx<'tcx>, layout: &TyAndLayou
                 assert!(align >= element.align(cx).abi); // just sanity-checking `vector_align`.
                 // FIXME: Do some kind of check of the inner type, like for Scalar and ScalarPair.
             }
-            BackendRepr::Uninhabited | BackendRepr::Memory { .. } => {} // Nothing to check.
+            BackendRepr::Memory { .. } => {} // Nothing to check.
         }
     }
 
@@ -291,8 +295,8 @@ pub(super) fn layout_sanity_check<'tcx>(cx: &LayoutCx<'tcx>, layout: &TyAndLayou
                     || variant.is_uninhabited()
                 {
                     // These are never actually accessed anyway, so we can skip the coherence check
-                    // for them. They also fail that check, since they have
-                    // `Aggregate`/`Uninhabited` ABI even when the main type is
+                    // for them. They also fail that check, since they may have
+                    // a different ABI even when the main type is
                     // `Scalar`/`ScalarPair`. (Note that sometimes, variants with fields have size
                     // 0, and sometimes, variants without fields have non-0 size.)
                     continue;
@@ -306,7 +310,6 @@ pub(super) fn layout_sanity_check<'tcx>(cx: &LayoutCx<'tcx>, layout: &TyAndLayou
                     (BackendRepr::ScalarPair(a1, b1), BackendRepr::ScalarPair(a2, b2)) => {
                         scalar_coherent(a1, a2) && scalar_coherent(b1, b2)
                     }
-                    (BackendRepr::Uninhabited, _) => true,
                     (BackendRepr::Memory { .. }, _) => true,
                     _ => false,
                 };
diff --git a/compiler/stable_mir/src/abi.rs b/compiler/stable_mir/src/abi.rs
index 861b6692b5367..091f3e1a95e95 100644
--- a/compiler/stable_mir/src/abi.rs
+++ b/compiler/stable_mir/src/abi.rs
@@ -227,7 +227,6 @@ pub enum TagEncoding {
 /// in terms of categories of C types there are ABI rules for.
 #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize)]
 pub enum ValueAbi {
-    Uninhabited,
     Scalar(Scalar),
     ScalarPair(Scalar, Scalar),
     Vector {
@@ -244,10 +243,7 @@ impl ValueAbi {
     /// Returns `true` if the layout corresponds to an unsized type.
     pub fn is_unsized(&self) -> bool {
         match *self {
-            ValueAbi::Uninhabited
-            | ValueAbi::Scalar(_)
-            | ValueAbi::ScalarPair(..)
-            | ValueAbi::Vector { .. } => false,
+            ValueAbi::Scalar(_) | ValueAbi::ScalarPair(..) | ValueAbi::Vector { .. } => false,
             ValueAbi::Aggregate { sized } => !sized,
         }
     }
diff --git a/library/alloc/src/string.rs b/library/alloc/src/string.rs
index 154da69107884..686689868c4f2 100644
--- a/library/alloc/src/string.rs
+++ b/library/alloc/src/string.rs
@@ -3155,6 +3155,24 @@ impl From<String> for Vec<u8> {
     }
 }
 
+#[stable(feature = "try_from_vec_u8_for_string", since = "CURRENT_RUSTC_VERSION")]
+impl TryFrom<Vec<u8>> for String {
+    type Error = FromUtf8Error;
+    /// Converts the given [`Vec<u8>`] into a  [`String`] if it contains valid UTF-8 data.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let s1 = b"hello world".to_vec();
+    /// let v1 = String::try_from(s1).unwrap();
+    /// assert_eq!(v1, "hello world");
+    ///
+    /// ```
+    fn try_from(bytes: Vec<u8>) -> Result<Self, Self::Error> {
+        Self::from_utf8(bytes)
+    }
+}
+
 #[cfg(not(no_global_oom_handling))]
 #[stable(feature = "rust1", since = "1.0.0")]
 impl fmt::Write for String {
diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs
index ed45e26256e55..7b9a76e814a15 100644
--- a/library/core/src/slice/mod.rs
+++ b/library/core/src/slice/mod.rs
@@ -4796,7 +4796,7 @@ impl<T, const N: usize> [[T; N]] {
     /// assert!(empty_slice_of_arrays.as_flattened().is_empty());
     /// ```
     #[stable(feature = "slice_flatten", since = "1.80.0")]
-    #[rustc_const_unstable(feature = "const_slice_flatten", issue = "95629")]
+    #[rustc_const_stable(feature = "const_slice_flatten", since = "CURRENT_RUSTC_VERSION")]
     pub const fn as_flattened(&self) -> &[T] {
         let len = if T::IS_ZST {
             self.len().checked_mul(N).expect("slice len overflow")
@@ -4833,7 +4833,7 @@ impl<T, const N: usize> [[T; N]] {
     /// assert_eq!(array, [[6, 7, 8], [9, 10, 11], [12, 13, 14]]);
     /// ```
     #[stable(feature = "slice_flatten", since = "1.80.0")]
-    #[rustc_const_unstable(feature = "const_slice_flatten", issue = "95629")]
+    #[rustc_const_stable(feature = "const_slice_flatten", since = "CURRENT_RUSTC_VERSION")]
     pub const fn as_flattened_mut(&mut self) -> &mut [T] {
         let len = if T::IS_ZST {
             self.len().checked_mul(N).expect("slice len overflow")
diff --git a/library/std/src/sys/os_str/bytes.rs b/library/std/src/sys/os_str/bytes.rs
index 5b65d862be102..1d337694944bc 100644
--- a/library/std/src/sys/os_str/bytes.rs
+++ b/library/std/src/sys/os_str/bytes.rs
@@ -8,7 +8,7 @@ use crate::collections::TryReserveError;
 use crate::fmt::Write;
 use crate::rc::Rc;
 use crate::sync::Arc;
-use crate::sys_common::{AsInner, IntoInner};
+use crate::sys_common::{AsInner, FromInner, IntoInner};
 use crate::{fmt, mem, str};
 
 #[cfg(test)]
@@ -25,6 +25,37 @@ pub struct Slice {
     pub inner: [u8],
 }
 
+impl IntoInner<Vec<u8>> for Buf {
+    fn into_inner(self) -> Vec<u8> {
+        self.inner
+    }
+}
+
+impl FromInner<Vec<u8>> for Buf {
+    fn from_inner(inner: Vec<u8>) -> Self {
+        Buf { inner }
+    }
+}
+
+impl AsInner<[u8]> for Buf {
+    #[inline]
+    fn as_inner(&self) -> &[u8] {
+        &self.inner
+    }
+}
+
+impl fmt::Debug for Buf {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        fmt::Debug::fmt(self.as_slice(), f)
+    }
+}
+
+impl fmt::Display for Buf {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        fmt::Display::fmt(self.as_slice(), f)
+    }
+}
+
 impl fmt::Debug for Slice {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         fmt::Debug::fmt(&self.inner.utf8_chunks().debug(), f)
@@ -55,18 +86,6 @@ impl fmt::Display for Slice {
     }
 }
 
-impl fmt::Debug for Buf {
-    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
-        fmt::Debug::fmt(self.as_slice(), formatter)
-    }
-}
-
-impl fmt::Display for Buf {
-    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
-        fmt::Display::fmt(self.as_slice(), formatter)
-    }
-}
-
 impl Clone for Buf {
     #[inline]
     fn clone(&self) -> Self {
@@ -79,19 +98,6 @@ impl Clone for Buf {
     }
 }
 
-impl IntoInner<Vec<u8>> for Buf {
-    fn into_inner(self) -> Vec<u8> {
-        self.inner
-    }
-}
-
-impl AsInner<[u8]> for Buf {
-    #[inline]
-    fn as_inner(&self) -> &[u8] {
-        &self.inner
-    }
-}
-
 impl Buf {
     #[inline]
     pub fn into_encoded_bytes(self) -> Vec<u8> {
@@ -103,6 +109,12 @@ impl Buf {
         Self { inner: s }
     }
 
+    #[inline]
+    pub fn into_string(self) -> Result<String, Buf> {
+        String::from_utf8(self.inner).map_err(|p| Buf { inner: p.into_bytes() })
+    }
+
+    #[inline]
     pub fn from_string(s: String) -> Buf {
         Buf { inner: s.into_bytes() }
     }
@@ -122,6 +134,11 @@ impl Buf {
         self.inner.capacity()
     }
 
+    #[inline]
+    pub fn push_slice(&mut self, s: &Slice) {
+        self.inner.extend_from_slice(&s.inner)
+    }
+
     #[inline]
     pub fn reserve(&mut self, additional: usize) {
         self.inner.reserve(additional)
@@ -157,7 +174,7 @@ impl Buf {
         // SAFETY: Slice just wraps [u8],
         // and &*self.inner is &[u8], therefore
         // transmuting &[u8] to &Slice is safe.
-        unsafe { mem::transmute(&*self.inner) }
+        unsafe { mem::transmute(self.inner.as_slice()) }
     }
 
     #[inline]
@@ -165,15 +182,7 @@ impl Buf {
         // SAFETY: Slice just wraps [u8],
         // and &mut *self.inner is &mut [u8], therefore
         // transmuting &mut [u8] to &mut Slice is safe.
-        unsafe { mem::transmute(&mut *self.inner) }
-    }
-
-    pub fn into_string(self) -> Result<String, Buf> {
-        String::from_utf8(self.inner).map_err(|p| Buf { inner: p.into_bytes() })
-    }
-
-    pub fn push_slice(&mut self, s: &Slice) {
-        self.inner.extend_from_slice(&s.inner)
+        unsafe { mem::transmute(self.inner.as_mut_slice()) }
     }
 
     #[inline]
@@ -278,18 +287,22 @@ impl Slice {
         unsafe { Slice::from_encoded_bytes_unchecked(s.as_bytes()) }
     }
 
+    #[inline]
     pub fn to_str(&self) -> Result<&str, crate::str::Utf8Error> {
         str::from_utf8(&self.inner)
     }
 
+    #[inline]
     pub fn to_string_lossy(&self) -> Cow<'_, str> {
         String::from_utf8_lossy(&self.inner)
     }
 
+    #[inline]
     pub fn to_owned(&self) -> Buf {
         Buf { inner: self.inner.to_vec() }
     }
 
+    #[inline]
     pub fn clone_into(&self, buf: &mut Buf) {
         self.inner.clone_into(&mut buf.inner)
     }
@@ -300,6 +313,7 @@ impl Slice {
         unsafe { mem::transmute(boxed) }
     }
 
+    #[inline]
     pub fn empty_box() -> Box<Slice> {
         let boxed: Box<[u8]> = Default::default();
         unsafe { mem::transmute(boxed) }
diff --git a/library/std/src/sys/os_str/wtf8.rs b/library/std/src/sys/os_str/wtf8.rs
index a4ad5966afe57..19728d33990ac 100644
--- a/library/std/src/sys/os_str/wtf8.rs
+++ b/library/std/src/sys/os_str/wtf8.rs
@@ -10,11 +10,16 @@ use crate::sys_common::wtf8::{Wtf8, Wtf8Buf, check_utf8_boundary};
 use crate::sys_common::{AsInner, FromInner, IntoInner};
 use crate::{fmt, mem};
 
-#[derive(Clone, Hash)]
+#[derive(Hash)]
 pub struct Buf {
     pub inner: Wtf8Buf,
 }
 
+#[repr(transparent)]
+pub struct Slice {
+    pub inner: Wtf8,
+}
+
 impl IntoInner<Wtf8Buf> for Buf {
     fn into_inner(self) -> Wtf8Buf {
         self.inner
@@ -35,31 +40,38 @@ impl AsInner<Wtf8> for Buf {
 }
 
 impl fmt::Debug for Buf {
-    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
-        fmt::Debug::fmt(self.as_slice(), formatter)
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        fmt::Debug::fmt(self.as_slice(), f)
     }
 }
 
 impl fmt::Display for Buf {
-    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
-        fmt::Display::fmt(self.as_slice(), formatter)
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        fmt::Display::fmt(self.as_slice(), f)
     }
 }
 
-#[repr(transparent)]
-pub struct Slice {
-    pub inner: Wtf8,
-}
-
 impl fmt::Debug for Slice {
-    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
-        fmt::Debug::fmt(&self.inner, formatter)
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        fmt::Debug::fmt(&self.inner, f)
     }
 }
 
 impl fmt::Display for Slice {
-    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
-        fmt::Display::fmt(&self.inner, formatter)
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        fmt::Display::fmt(&self.inner, f)
+    }
+}
+
+impl Clone for Buf {
+    #[inline]
+    fn clone(&self) -> Self {
+        Buf { inner: self.inner.clone() }
+    }
+
+    #[inline]
+    fn clone_from(&mut self, source: &Self) {
+        self.inner.clone_from(&source.inner)
     }
 }
 
@@ -74,62 +86,57 @@ impl Buf {
         unsafe { Self { inner: Wtf8Buf::from_bytes_unchecked(s) } }
     }
 
-    pub fn with_capacity(capacity: usize) -> Buf {
-        Buf { inner: Wtf8Buf::with_capacity(capacity) }
-    }
-
-    pub fn clear(&mut self) {
-        self.inner.clear()
-    }
-
-    pub fn capacity(&self) -> usize {
-        self.inner.capacity()
+    #[inline]
+    pub fn into_string(self) -> Result<String, Buf> {
+        self.inner.into_string().map_err(|buf| Buf { inner: buf })
     }
 
+    #[inline]
     pub fn from_string(s: String) -> Buf {
         Buf { inner: Wtf8Buf::from_string(s) }
     }
 
-    pub fn as_slice(&self) -> &Slice {
-        // SAFETY: Slice is just a wrapper for Wtf8,
-        // and self.inner.as_slice() returns &Wtf8.
-        // Therefore, transmuting &Wtf8 to &Slice is safe.
-        unsafe { mem::transmute(self.inner.as_slice()) }
+    #[inline]
+    pub fn with_capacity(capacity: usize) -> Buf {
+        Buf { inner: Wtf8Buf::with_capacity(capacity) }
     }
 
-    pub fn as_mut_slice(&mut self) -> &mut Slice {
-        // SAFETY: Slice is just a wrapper for Wtf8,
-        // and self.inner.as_mut_slice() returns &mut Wtf8.
-        // Therefore, transmuting &mut Wtf8 to &mut Slice is safe.
-        // Additionally, care should be taken to ensure the slice
-        // is always valid Wtf8.
-        unsafe { mem::transmute(self.inner.as_mut_slice()) }
+    #[inline]
+    pub fn clear(&mut self) {
+        self.inner.clear()
     }
 
-    pub fn into_string(self) -> Result<String, Buf> {
-        self.inner.into_string().map_err(|buf| Buf { inner: buf })
+    #[inline]
+    pub fn capacity(&self) -> usize {
+        self.inner.capacity()
     }
 
+    #[inline]
     pub fn push_slice(&mut self, s: &Slice) {
         self.inner.push_wtf8(&s.inner)
     }
 
+    #[inline]
     pub fn reserve(&mut self, additional: usize) {
         self.inner.reserve(additional)
     }
 
+    #[inline]
     pub fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError> {
         self.inner.try_reserve(additional)
     }
 
+    #[inline]
     pub fn reserve_exact(&mut self, additional: usize) {
         self.inner.reserve_exact(additional)
     }
 
+    #[inline]
     pub fn try_reserve_exact(&mut self, additional: usize) -> Result<(), TryReserveError> {
         self.inner.try_reserve_exact(additional)
     }
 
+    #[inline]
     pub fn shrink_to_fit(&mut self) {
         self.inner.shrink_to_fit()
     }
@@ -139,6 +146,24 @@ impl Buf {
         self.inner.shrink_to(min_capacity)
     }
 
+    #[inline]
+    pub fn as_slice(&self) -> &Slice {
+        // SAFETY: Slice is just a wrapper for Wtf8,
+        // and self.inner.as_slice() returns &Wtf8.
+        // Therefore, transmuting &Wtf8 to &Slice is safe.
+        unsafe { mem::transmute(self.inner.as_slice()) }
+    }
+
+    #[inline]
+    pub fn as_mut_slice(&mut self) -> &mut Slice {
+        // SAFETY: Slice is just a wrapper for Wtf8,
+        // and self.inner.as_mut_slice() returns &mut Wtf8.
+        // Therefore, transmuting &mut Wtf8 to &mut Slice is safe.
+        // Additionally, care should be taken to ensure the slice
+        // is always valid Wtf8.
+        unsafe { mem::transmute(self.inner.as_mut_slice()) }
+    }
+
     #[inline]
     pub fn leak<'a>(self) -> &'a mut Slice {
         unsafe { mem::transmute(self.inner.leak()) }
@@ -194,6 +219,7 @@ impl Slice {
     }
 
     #[track_caller]
+    #[inline]
     pub fn check_public_boundary(&self, index: usize) {
         check_utf8_boundary(&self.inner, index);
     }
@@ -203,18 +229,22 @@ impl Slice {
         unsafe { mem::transmute(Wtf8::from_str(s)) }
     }
 
+    #[inline]
     pub fn to_str(&self) -> Result<&str, crate::str::Utf8Error> {
         self.inner.as_str()
     }
 
+    #[inline]
     pub fn to_string_lossy(&self) -> Cow<'_, str> {
         self.inner.to_string_lossy()
     }
 
+    #[inline]
     pub fn to_owned(&self) -> Buf {
         Buf { inner: self.inner.to_owned() }
     }
 
+    #[inline]
     pub fn clone_into(&self, buf: &mut Buf) {
         self.inner.clone_into(&mut buf.inner)
     }
@@ -224,6 +254,7 @@ impl Slice {
         unsafe { mem::transmute(self.inner.into_box()) }
     }
 
+    #[inline]
     pub fn empty_box() -> Box<Slice> {
         unsafe { mem::transmute(Wtf8::empty_box()) }
     }
diff --git a/library/std/src/sys_common/wtf8.rs b/library/std/src/sys_common/wtf8.rs
index 6c60d901ee904..f4402fc6f9865 100644
--- a/library/std/src/sys_common/wtf8.rs
+++ b/library/std/src/sys_common/wtf8.rs
@@ -156,9 +156,12 @@ impl ops::DerefMut for Wtf8Buf {
     }
 }
 
-/// Format the string with double quotes,
-/// and surrogates as `\u` followed by four hexadecimal digits.
-/// Example: `"a\u{D800}"` for a string with code points [U+0061, U+D800]
+/// Formats the string in double quotes, with characters escaped according to
+/// [`char::escape_debug`] and unpaired surrogates represented as `\u{xxxx}`,
+/// where each `x` is a hexadecimal digit.
+///
+/// For example, the code units [U+0061, U+D800, U+000A] are formatted as
+/// `"a\u{D800}\n"`.
 impl fmt::Debug for Wtf8Buf {
     #[inline]
     fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
@@ -181,7 +184,7 @@ impl Wtf8Buf {
 
     /// Creates a WTF-8 string from a WTF-8 byte vec.
     ///
-    /// Since the byte vec is not checked for valid WTF-8, this functions is
+    /// Since the byte vec is not checked for valid WTF-8, this function is
     /// marked unsafe.
     #[inline]
     pub unsafe fn from_bytes_unchecked(value: Vec<u8>) -> Wtf8Buf {
@@ -205,7 +208,7 @@ impl Wtf8Buf {
     /// Since WTF-8 is a superset of UTF-8, this always succeeds.
     #[inline]
     pub fn from_str(s: &str) -> Wtf8Buf {
-        Wtf8Buf { bytes: <[_]>::to_vec(s.as_bytes()), is_known_utf8: true }
+        Wtf8Buf { bytes: s.as_bytes().to_vec(), is_known_utf8: true }
     }
 
     pub fn clear(&mut self) {
@@ -237,8 +240,9 @@ impl Wtf8Buf {
         string
     }
 
-    /// Copied from String::push
+    /// Appends the given `char` to the end of this string.
     /// This does **not** include the WTF-8 concatenation check or `is_known_utf8` check.
+    /// Copied from String::push.
     fn push_code_point_unchecked(&mut self, code_point: CodePoint) {
         let mut bytes = [0; 4];
         let bytes = encode_utf8_raw(code_point.value, &mut bytes);
@@ -264,16 +268,16 @@ impl Wtf8Buf {
     ///
     /// # Panics
     ///
-    /// Panics if the new capacity overflows `usize`.
+    /// Panics if the new capacity exceeds `isize::MAX` bytes.
     #[inline]
     pub fn reserve(&mut self, additional: usize) {
         self.bytes.reserve(additional)
     }
 
-    /// Tries to reserve capacity for at least `additional` more length units
-    /// in the given `Wtf8Buf`. The `Wtf8Buf` may reserve more space to avoid
-    /// frequent reallocations. After calling `try_reserve`, capacity will be
-    /// greater than or equal to `self.len() + additional`. Does nothing if
+    /// Tries to reserve capacity for at least `additional` more bytes to be
+    /// inserted in the given `Wtf8Buf`. The `Wtf8Buf` may reserve more space to
+    /// avoid frequent reallocations. After calling `try_reserve`, capacity will
+    /// be greater than or equal to `self.len() + additional`. Does nothing if
     /// capacity is already sufficient. This method preserves the contents even
     /// if an error occurs.
     ///
@@ -291,8 +295,8 @@ impl Wtf8Buf {
         self.bytes.reserve_exact(additional)
     }
 
-    /// Tries to reserve the minimum capacity for exactly `additional`
-    /// length units in the given `Wtf8Buf`. After calling
+    /// Tries to reserve the minimum capacity for exactly `additional` more
+    /// bytes to be inserted in the given `Wtf8Buf`. After calling
     /// `try_reserve_exact`, capacity will be greater than or equal to
     /// `self.len() + additional` if it returns `Ok(())`.
     /// Does nothing if the capacity is already sufficient.
@@ -440,22 +444,17 @@ impl Wtf8Buf {
     ///
     /// Surrogates are replaced with `"\u{FFFD}"` (the replacement character “�”)
     pub fn into_string_lossy(mut self) -> String {
-        // Fast path: If we already have UTF-8, we can return it immediately.
-        if self.is_known_utf8 {
-            return unsafe { String::from_utf8_unchecked(self.bytes) };
-        }
-
-        let mut pos = 0;
-        loop {
-            match self.next_surrogate(pos) {
-                Some((surrogate_pos, _)) => {
-                    pos = surrogate_pos + 3;
-                    self.bytes[surrogate_pos..pos]
-                        .copy_from_slice(UTF8_REPLACEMENT_CHARACTER.as_bytes());
-                }
-                None => return unsafe { String::from_utf8_unchecked(self.bytes) },
+        if !self.is_known_utf8 {
+            let mut pos = 0;
+            while let Some((surrogate_pos, _)) = self.next_surrogate(pos) {
+                pos = surrogate_pos + 3;
+                // Surrogates and the replacement character are all 3 bytes, so
+                // they can substituted in-place.
+                self.bytes[surrogate_pos..pos]
+                    .copy_from_slice(UTF8_REPLACEMENT_CHARACTER.as_bytes());
             }
         }
+        unsafe { String::from_utf8_unchecked(self.bytes) }
     }
 
     /// Converts this `Wtf8Buf` into a boxed `Wtf8`.
@@ -535,9 +534,9 @@ impl AsInner<[u8]> for Wtf8 {
     }
 }
 
-/// Format the slice with double quotes,
-/// and surrogates as `\u` followed by four hexadecimal digits.
-/// Example: `"a\u{D800}"` for a slice with code points [U+0061, U+D800]
+/// Formats the string in double quotes, with characters escaped according to
+/// [`char::escape_debug`] and unpaired surrogates represented as `\u{xxxx}`,
+/// where each `x` is a hexadecimal digit.
 impl fmt::Debug for Wtf8 {
     fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
         fn write_str_escaped(f: &mut fmt::Formatter<'_>, s: &str) -> fmt::Result {
@@ -562,6 +561,8 @@ impl fmt::Debug for Wtf8 {
     }
 }
 
+/// Formats the string with unpaired surrogates substituted with the replacement
+/// character, U+FFFD.
 impl fmt::Display for Wtf8 {
     fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
         let wtf8_bytes = &self.bytes;
@@ -672,9 +673,8 @@ impl Wtf8 {
     ///
     /// This only copies the data if necessary (if it contains any surrogate).
     pub fn to_string_lossy(&self) -> Cow<'_, str> {
-        let surrogate_pos = match self.next_surrogate(0) {
-            None => return Cow::Borrowed(unsafe { str::from_utf8_unchecked(&self.bytes) }),
-            Some((pos, _)) => pos,
+        let Some((surrogate_pos, _)) = self.next_surrogate(0) else {
+            return Cow::Borrowed(unsafe { str::from_utf8_unchecked(&self.bytes) });
         };
         let wtf8_bytes = &self.bytes;
         let mut utf8_bytes = Vec::with_capacity(self.len());
@@ -964,7 +964,7 @@ pub struct Wtf8CodePoints<'a> {
     bytes: slice::Iter<'a, u8>,
 }
 
-impl<'a> Iterator for Wtf8CodePoints<'a> {
+impl Iterator for Wtf8CodePoints<'_> {
     type Item = CodePoint;
 
     #[inline]
@@ -990,7 +990,7 @@ pub struct EncodeWide<'a> {
 
 // Copied from libunicode/u_str.rs
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<'a> Iterator for EncodeWide<'a> {
+impl Iterator for EncodeWide<'_> {
     type Item = u16;
 
     #[inline]
diff --git a/src/bootstrap/src/core/build_steps/setup.rs b/src/bootstrap/src/core/build_steps/setup.rs
index fbd0dc3ec3021..f25dfaab0f115 100644
--- a/src/bootstrap/src/core/build_steps/setup.rs
+++ b/src/bootstrap/src/core/build_steps/setup.rs
@@ -523,19 +523,31 @@ undesirable, simply delete the `pre-push` file from .git/hooks."
 /// Handles editor-specific setup differences
 #[derive(Clone, Debug, Eq, PartialEq)]
 enum EditorKind {
-    Vscode,
-    Vim,
     Emacs,
     Helix,
+    Vim,
+    VsCode,
+    Zed,
 }
 
 impl EditorKind {
+    // Used in `./tests.rs`.
+    #[allow(dead_code)]
+    pub const ALL: &[EditorKind] = &[
+        EditorKind::Emacs,
+        EditorKind::Helix,
+        EditorKind::Vim,
+        EditorKind::VsCode,
+        EditorKind::Zed,
+    ];
+
     fn prompt_user() -> io::Result<Option<EditorKind>> {
         let prompt_str = "Available editors:
-1. vscode
-2. vim
-3. emacs
-4. helix
+1. Emacs
+2. Helix
+3. Vim
+4. VS Code
+5. Zed
 
 Select which editor you would like to set up [default: None]: ";
 
@@ -543,28 +555,41 @@ Select which editor you would like to set up [default: None]: ";
         loop {
             print!("{}", prompt_str);
             io::stdout().flush()?;
-            input.clear();
             io::stdin().read_line(&mut input)?;
-            match input.trim().to_lowercase().as_str() {
-                "1" | "vscode" => return Ok(Some(EditorKind::Vscode)),
-                "2" | "vim" => return Ok(Some(EditorKind::Vim)),
-                "3" | "emacs" => return Ok(Some(EditorKind::Emacs)),
-                "4" | "helix" => return Ok(Some(EditorKind::Helix)),
-                "" => return Ok(None),
+
+            let mut modified_input = input.to_lowercase();
+            modified_input.retain(|ch| !ch.is_whitespace());
+            match modified_input.as_str() {
+                "1" | "emacs" => return Ok(Some(EditorKind::Emacs)),
+                "2" | "helix" => return Ok(Some(EditorKind::Helix)),
+                "3" | "vim" => return Ok(Some(EditorKind::Vim)),
+                "4" | "vscode" => return Ok(Some(EditorKind::VsCode)),
+                "5" | "zed" => return Ok(Some(EditorKind::Zed)),
+                "" | "none" => return Ok(None),
                 _ => {
                     eprintln!("ERROR: unrecognized option '{}'", input.trim());
                     eprintln!("NOTE: press Ctrl+C to exit");
                 }
-            };
+            }
+
+            input.clear();
         }
     }
 
     /// A list of historical hashes of each LSP settings file
     /// New entries should be appended whenever this is updated so we can detect
     /// outdated vs. user-modified settings files.
-    fn hashes(&self) -> Vec<&str> {
+    fn hashes(&self) -> &'static [&'static str] {
         match self {
-            EditorKind::Vscode | EditorKind::Vim => vec![
+            EditorKind::Emacs => &[
+                "51068d4747a13732440d1a8b8f432603badb1864fa431d83d0fd4f8fa57039e0",
+                "d29af4d949bbe2371eac928a3c31cf9496b1701aa1c45f11cd6c759865ad5c45",
+            ],
+            EditorKind::Helix => &[
+                "2d3069b8cf1b977e5d4023965eb6199597755e6c96c185ed5f2854f98b83d233",
+                "6736d61409fbebba0933afd2e4c44ff2f97c1cb36cf0299a7f4a7819b8775040",
+            ],
+            EditorKind::Vim | EditorKind::VsCode => &[
                 "ea67e259dedf60d4429b6c349a564ffcd1563cf41c920a856d1f5b16b4701ac8",
                 "56e7bf011c71c5d81e0bf42e84938111847a810eee69d906bba494ea90b51922",
                 "af1b5efe196aed007577899db9dae15d6dbc923d6fa42fa0934e68617ba9bbe0",
@@ -576,12 +601,8 @@ Select which editor you would like to set up [default: None]: ";
                 "4eecb58a2168b252077369da446c30ed0e658301efe69691979d1ef0443928f4",
                 "c394386e6133bbf29ffd32c8af0bb3d4aac354cba9ee051f29612aa9350f8f8d",
             ],
-            EditorKind::Emacs => vec![
-                "51068d4747a13732440d1a8b8f432603badb1864fa431d83d0fd4f8fa57039e0",
-                "d29af4d949bbe2371eac928a3c31cf9496b1701aa1c45f11cd6c759865ad5c45",
-            ],
-            EditorKind::Helix => {
-                vec!["2d3069b8cf1b977e5d4023965eb6199597755e6c96c185ed5f2854f98b83d233"]
+            EditorKind::Zed => {
+                &["bbce727c269d1bd0c98afef4d612eb4ce27aea3c3a8968c5f10b31affbc40b6c"]
             }
         }
     }
@@ -592,29 +613,31 @@ Select which editor you would like to set up [default: None]: ";
 
     fn settings_short_path(&self) -> PathBuf {
         self.settings_folder().join(match self {
-            EditorKind::Vscode => "settings.json",
-            EditorKind::Vim => "coc-settings.json",
             EditorKind::Emacs => ".dir-locals.el",
             EditorKind::Helix => "languages.toml",
+            EditorKind::Vim => "coc-settings.json",
+            EditorKind::VsCode | EditorKind::Zed => "settings.json",
         })
     }
 
     fn settings_folder(&self) -> PathBuf {
         match self {
-            EditorKind::Vscode => PathBuf::from(".vscode"),
-            EditorKind::Vim => PathBuf::from(".vim"),
             EditorKind::Emacs => PathBuf::new(),
             EditorKind::Helix => PathBuf::from(".helix"),
+            EditorKind::Vim => PathBuf::from(".vim"),
+            EditorKind::VsCode => PathBuf::from(".vscode"),
+            EditorKind::Zed => PathBuf::from(".zed"),
         }
     }
 
-    fn settings_template(&self) -> &str {
+    fn settings_template(&self) -> &'static str {
         match self {
-            EditorKind::Vscode | EditorKind::Vim => {
-                include_str!("../../../../etc/rust_analyzer_settings.json")
-            }
             EditorKind::Emacs => include_str!("../../../../etc/rust_analyzer_eglot.el"),
             EditorKind::Helix => include_str!("../../../../etc/rust_analyzer_helix.toml"),
+            EditorKind::Vim | EditorKind::VsCode => {
+                include_str!("../../../../etc/rust_analyzer_settings.json")
+            }
+            EditorKind::Zed => include_str!("../../../../etc/rust_analyzer_zed.json"),
         }
     }
 
diff --git a/src/bootstrap/src/core/build_steps/setup/tests.rs b/src/bootstrap/src/core/build_steps/setup/tests.rs
index f3d4b6aa4db6e..e8f83ff75e404 100644
--- a/src/bootstrap/src/core/build_steps/setup/tests.rs
+++ b/src/bootstrap/src/core/build_steps/setup/tests.rs
@@ -5,13 +5,16 @@ use crate::utils::helpers::hex_encode;
 
 #[test]
 fn check_matching_settings_hash() {
-    let editor = EditorKind::Vscode;
-    let mut hasher = sha2::Sha256::new();
-    hasher.update(&editor.settings_template());
-    let hash = hex_encode(hasher.finalize().as_slice());
-    assert_eq!(
-        &hash,
-        editor.hashes().last().unwrap(),
-        "Update `EditorKind::hashes()` with the new hash of `src/etc/rust_analyzer_settings.json`"
-    );
+    for editor in EditorKind::ALL {
+        let mut hasher = sha2::Sha256::new();
+        hasher.update(&editor.settings_template());
+        let hash = hex_encode(hasher.finalize().as_slice());
+        assert_eq!(
+            &hash,
+            editor.hashes().last().unwrap(),
+            "Update `EditorKind::hashes()` with the new hash of `{}` for `EditorKind::{:?}`",
+            editor.settings_template(),
+            editor,
+        );
+    }
 }
diff --git a/src/doc/rustc-dev-guide/src/building/suggested.md b/src/doc/rustc-dev-guide/src/building/suggested.md
index 2c6c3fe1df84b..5c041d6cb70f9 100644
--- a/src/doc/rustc-dev-guide/src/building/suggested.md
+++ b/src/doc/rustc-dev-guide/src/building/suggested.md
@@ -154,6 +154,16 @@ You can run `./x setup editor` and select `helix`, which will prompt you to
 create `languages.toml` with the recommended configuration for Helix. The
 recommended settings live at [`src/etc/rust_analyzer_helix.toml`].
 
+### Zed
+
+Zed comes with built-in LSP and rust-analyzer support.
+It can be configured through `.zed/settings.json`, as described
+[here](https://zed.dev/docs/configuring-languages). Selecting `zed`
+in `./x setup editor` will prompt you to create a `.zed/settings.json`
+file which will configure Zed with the recommended configuration. The
+recommended `rust-analyzer` settings live
+at [`src/etc/rust_analyzer_zed.json`].
+
 ## Check, check, and check again
 
 When doing simple refactoring, it can be useful to run `./x check`
@@ -381,4 +391,5 @@ load this completion.
 [`src/etc/rust_analyzer_settings.json`]: https://github.com/rust-lang/rust/blob/master/src/etc/rust_analyzer_settings.json
 [`src/etc/rust_analyzer_eglot.el`]: https://github.com/rust-lang/rust/blob/master/src/etc/rust_analyzer_eglot.el
 [`src/etc/rust_analyzer_helix.toml`]: https://github.com/rust-lang/rust/blob/master/src/etc/rust_analyzer_helix.toml
+[`src/etc/rust_analyzer_zed.json`]: https://github.com/rust-lang/rust/blob/master/src/etc/rust_analyzer_zed.json
 [`src/etc/pre-push.sh`]: https://github.com/rust-lang/rust/blob/master/src/etc/pre-push.sh
diff --git a/src/doc/rustc-dev-guide/src/implementing_new_features.md b/src/doc/rustc-dev-guide/src/implementing_new_features.md
index 5b67ccd7f4c5e..fda38ef4fc01a 100644
--- a/src/doc/rustc-dev-guide/src/implementing_new_features.md
+++ b/src/doc/rustc-dev-guide/src/implementing_new_features.md
@@ -167,9 +167,7 @@ a new unstable feature:
 
 1. Prevent usage of the new feature unless the feature gate is set.
    You can check it in most places in the compiler using the
-   expression `tcx.features().$feature_name` (or
-   `sess.features_untracked().$feature_name` if the
-   tcx is unavailable)
+   expression `tcx.features().$feature_name()`
 
     If the feature gate is not set, you should either maintain
     the pre-feature behavior or raise an error, depending on
diff --git a/src/etc/rust_analyzer_zed.json b/src/etc/rust_analyzer_zed.json
new file mode 100644
index 0000000000000..469ea0506218f
--- /dev/null
+++ b/src/etc/rust_analyzer_zed.json
@@ -0,0 +1,52 @@
+{
+  "lsp": {
+    "rust-analyzer": {
+      "initialization_options": {
+        "cargo": {
+          "buildScripts": {
+            "enable": true,
+            "invocationLocation": "root",
+            "invocationStrategy": "once",
+            "overrideCommand": ["python3", "x.py", "check", "--json-output"]
+          },
+          "extraEnv": {
+            "RUSTC_BOOTSTRAP": "1"
+          },
+          "sysrootSrc": "./library"
+        },
+        "check": {
+          "invocationLocation": "root",
+          "invocationStrategy": "once",
+          "overrideCommand": ["python3", "x.py", "check", "--json-output"]
+        },
+        "linkedProjects": [
+          "Cargo.toml",
+          "library/Cargo.toml",
+          "src/tools/x/Cargo.toml",
+          "src/bootstrap/Cargo.toml",
+          "src/tools/rust-analyzer/Cargo.toml",
+          "compiler/rustc_codegen_cranelift/Cargo.toml",
+          "compiler/rustc_codegen_gcc/Cargo.toml"
+        ],
+        "procMacro": {
+            "enable": true,
+            "server": "${workspaceFolder}/build/host/stage0/libexec/rust-analyzer-proc-macro-srv"
+        },
+        "rustc": {
+          "source": "./Cargo.toml"
+        },
+        "rustfmt": {
+          "overrideCommand": [
+            "${workspaceFolder}/build/host/rustfmt/bin/rustfmt",
+            "--edition=2021"
+          ]
+        },
+        "server": {
+          "extraEnv": {
+            "RUSTUP_TOOLCHAIN": "nightly"
+          }
+        }
+      }
+    }
+  }
+}
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs b/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs
index b6f7c44c2aeee..f5a7b6581230f 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs
@@ -194,6 +194,7 @@ fn layout_of_simd_ty(
         fields,
         backend_repr: BackendRepr::Vector { element: e_abi, count: e_len },
         largest_niche: e_ly.largest_niche,
+        uninhabited: false,
         size,
         align,
         max_repr_align: None,
@@ -297,20 +298,17 @@ pub fn layout_of_ty_query(
                 .checked_mul(count, dl)
                 .ok_or(LayoutError::BadCalc(LayoutCalculatorError::SizeOverflow))?;
 
-            let backend_repr =
-                if count != 0 && matches!(element.backend_repr, BackendRepr::Uninhabited) {
-                    BackendRepr::Uninhabited
-                } else {
-                    BackendRepr::Memory { sized: true }
-                };
+            let backend_repr = BackendRepr::Memory { sized: true };
 
             let largest_niche = if count != 0 { element.largest_niche } else { None };
+            let uninhabited = if count != 0 { element.uninhabited } else { false };
 
             Layout {
                 variants: Variants::Single { index: struct_variant_idx() },
                 fields: FieldsShape::Array { stride: element.size, count },
                 backend_repr,
                 largest_niche,
+                uninhabited,
                 align: element.align,
                 size,
                 max_repr_align: None,
@@ -325,6 +323,7 @@ pub fn layout_of_ty_query(
                 fields: FieldsShape::Array { stride: element.size, count: 0 },
                 backend_repr: BackendRepr::Memory { sized: false },
                 largest_niche: None,
+                uninhabited: false,
                 align: element.align,
                 size: Size::ZERO,
                 max_repr_align: None,
@@ -337,6 +336,7 @@ pub fn layout_of_ty_query(
             fields: FieldsShape::Array { stride: Size::from_bytes(1), count: 0 },
             backend_repr: BackendRepr::Memory { sized: false },
             largest_niche: None,
+            uninhabited: false,
             align: dl.i8_align,
             size: Size::ZERO,
             max_repr_align: None,
diff --git a/src/tools/tidy/src/issues.txt b/src/tools/tidy/src/issues.txt
index 39c9a148e9e56..1cb47353469fa 100644
--- a/src/tools/tidy/src/issues.txt
+++ b/src/tools/tidy/src/issues.txt
@@ -3619,7 +3619,6 @@ ui/resolve/issue-21221-1.rs
 ui/resolve/issue-21221-2.rs
 ui/resolve/issue-21221-3.rs
 ui/resolve/issue-21221-4.rs
-ui/resolve/issue-22692.rs
 ui/resolve/issue-2330.rs
 ui/resolve/issue-23305.rs
 ui/resolve/issue-2356.rs
diff --git a/tests/codegen/uninhabited-transparent-return-abi.rs b/tests/codegen/uninhabited-transparent-return-abi.rs
new file mode 100644
index 0000000000000..3c0b92f61d0b4
--- /dev/null
+++ b/tests/codegen/uninhabited-transparent-return-abi.rs
@@ -0,0 +1,42 @@
+// See https://github.com/rust-lang/rust/issues/135802
+
+#![crate_type = "lib"]
+
+enum Void {}
+
+// Should be ABI-compatible with T, but wasn't prior to the PR adding this test.
+#[repr(transparent)]
+struct NoReturn<T>(T, Void);
+
+// Returned by invisible reference (in most ABIs)
+#[allow(dead_code)]
+struct Large(u64, u64, u64);
+
+extern "Rust" {
+    fn opaque() -> NoReturn<Large>;
+    fn opaque_with_arg(rsi: u32) -> NoReturn<Large>;
+}
+
+// CHECK-LABEL: @test_uninhabited_ret_by_ref
+#[no_mangle]
+pub fn test_uninhabited_ret_by_ref() {
+    // CHECK: %_1 = alloca [24 x i8], align {{8|4}}
+    // CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 24, ptr nonnull %_1)
+    // CHECK-NEXT: call void @opaque(ptr noalias nocapture noundef nonnull sret([24 x i8]) align {{8|4}} dereferenceable(24) %_1) #2
+    // CHECK-NEXT: unreachable
+    unsafe {
+        opaque();
+    }
+}
+
+// CHECK-LABEL: @test_uninhabited_ret_by_ref_with_arg
+#[no_mangle]
+pub fn test_uninhabited_ret_by_ref_with_arg(rsi: u32) {
+    // CHECK: %_2 = alloca [24 x i8], align {{8|4}}
+    // CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 24, ptr nonnull %_2)
+    // CHECK-NEXT: call void @opaque_with_arg(ptr noalias nocapture noundef nonnull sret([24 x i8]) align {{8|4}} dereferenceable(24) %_2, i32 noundef %rsi) #2
+    // CHECK-NEXT: unreachable
+    unsafe {
+        opaque_with_arg(rsi);
+    }
+}
diff --git a/tests/ui/abi/c-zst.aarch64-darwin.stderr b/tests/ui/abi/c-zst.aarch64-darwin.stderr
index c8f7d0a517c4c..57cc48aa9cf47 100644
--- a/tests/ui/abi/c-zst.aarch64-darwin.stderr
+++ b/tests/ui/abi/c-zst.aarch64-darwin.stderr
@@ -17,6 +17,7 @@ error: fn_abi_of(pass_zst) = FnAbi {
                                memory_index: [],
                            },
                            largest_niche: None,
+                           uninhabited: false,
                            variants: Single {
                                index: 0,
                            },
@@ -45,6 +46,7 @@ error: fn_abi_of(pass_zst) = FnAbi {
                            memory_index: [],
                        },
                        largest_niche: None,
+                       uninhabited: false,
                        variants: Single {
                            index: 0,
                        },
diff --git a/tests/ui/abi/c-zst.powerpc-linux.stderr b/tests/ui/abi/c-zst.powerpc-linux.stderr
index 1015f7d889880..6738017673003 100644
--- a/tests/ui/abi/c-zst.powerpc-linux.stderr
+++ b/tests/ui/abi/c-zst.powerpc-linux.stderr
@@ -17,6 +17,7 @@ error: fn_abi_of(pass_zst) = FnAbi {
                                memory_index: [],
                            },
                            largest_niche: None,
+                           uninhabited: false,
                            variants: Single {
                                index: 0,
                            },
@@ -56,6 +57,7 @@ error: fn_abi_of(pass_zst) = FnAbi {
                            memory_index: [],
                        },
                        largest_niche: None,
+                       uninhabited: false,
                        variants: Single {
                            index: 0,
                        },
diff --git a/tests/ui/abi/c-zst.s390x-linux.stderr b/tests/ui/abi/c-zst.s390x-linux.stderr
index 1015f7d889880..6738017673003 100644
--- a/tests/ui/abi/c-zst.s390x-linux.stderr
+++ b/tests/ui/abi/c-zst.s390x-linux.stderr
@@ -17,6 +17,7 @@ error: fn_abi_of(pass_zst) = FnAbi {
                                memory_index: [],
                            },
                            largest_niche: None,
+                           uninhabited: false,
                            variants: Single {
                                index: 0,
                            },
@@ -56,6 +57,7 @@ error: fn_abi_of(pass_zst) = FnAbi {
                            memory_index: [],
                        },
                        largest_niche: None,
+                       uninhabited: false,
                        variants: Single {
                            index: 0,
                        },
diff --git a/tests/ui/abi/c-zst.sparc64-linux.stderr b/tests/ui/abi/c-zst.sparc64-linux.stderr
index 1015f7d889880..6738017673003 100644
--- a/tests/ui/abi/c-zst.sparc64-linux.stderr
+++ b/tests/ui/abi/c-zst.sparc64-linux.stderr
@@ -17,6 +17,7 @@ error: fn_abi_of(pass_zst) = FnAbi {
                                memory_index: [],
                            },
                            largest_niche: None,
+                           uninhabited: false,
                            variants: Single {
                                index: 0,
                            },
@@ -56,6 +57,7 @@ error: fn_abi_of(pass_zst) = FnAbi {
                            memory_index: [],
                        },
                        largest_niche: None,
+                       uninhabited: false,
                        variants: Single {
                            index: 0,
                        },
diff --git a/tests/ui/abi/c-zst.x86_64-linux.stderr b/tests/ui/abi/c-zst.x86_64-linux.stderr
index c8f7d0a517c4c..57cc48aa9cf47 100644
--- a/tests/ui/abi/c-zst.x86_64-linux.stderr
+++ b/tests/ui/abi/c-zst.x86_64-linux.stderr
@@ -17,6 +17,7 @@ error: fn_abi_of(pass_zst) = FnAbi {
                                memory_index: [],
                            },
                            largest_niche: None,
+                           uninhabited: false,
                            variants: Single {
                                index: 0,
                            },
@@ -45,6 +46,7 @@ error: fn_abi_of(pass_zst) = FnAbi {
                            memory_index: [],
                        },
                        largest_niche: None,
+                       uninhabited: false,
                        variants: Single {
                            index: 0,
                        },
diff --git a/tests/ui/abi/c-zst.x86_64-pc-windows-gnu.stderr b/tests/ui/abi/c-zst.x86_64-pc-windows-gnu.stderr
index 1015f7d889880..6738017673003 100644
--- a/tests/ui/abi/c-zst.x86_64-pc-windows-gnu.stderr
+++ b/tests/ui/abi/c-zst.x86_64-pc-windows-gnu.stderr
@@ -17,6 +17,7 @@ error: fn_abi_of(pass_zst) = FnAbi {
                                memory_index: [],
                            },
                            largest_niche: None,
+                           uninhabited: false,
                            variants: Single {
                                index: 0,
                            },
@@ -56,6 +57,7 @@ error: fn_abi_of(pass_zst) = FnAbi {
                            memory_index: [],
                        },
                        largest_niche: None,
+                       uninhabited: false,
                        variants: Single {
                            index: 0,
                        },
diff --git a/tests/ui/abi/debug.stderr b/tests/ui/abi/debug.stderr
index e550e5bfcf3c3..5f73ff7d6bd58 100644
--- a/tests/ui/abi/debug.stderr
+++ b/tests/ui/abi/debug.stderr
@@ -20,6 +20,7 @@ error: fn_abi_of(test) = FnAbi {
                            ),
                            fields: Primitive,
                            largest_niche: None,
+                           uninhabited: false,
                            variants: Single {
                                index: 0,
                            },
@@ -67,6 +68,7 @@ error: fn_abi_of(test) = FnAbi {
                                valid_range: 0..=1,
                            },
                        ),
+                       uninhabited: false,
                        variants: Single {
                            index: 0,
                        },
@@ -125,6 +127,7 @@ error: fn_abi_of(TestFnPtr) = FnAbi {
                                    valid_range: 0..=1,
                                },
                            ),
+                           uninhabited: false,
                            variants: Single {
                                index: 0,
                            },
@@ -163,6 +166,7 @@ error: fn_abi_of(TestFnPtr) = FnAbi {
                        ),
                        fields: Primitive,
                        largest_niche: None,
+                       uninhabited: false,
                        variants: Single {
                            index: 0,
                        },
@@ -213,6 +217,7 @@ error: fn_abi_of(test_generic) = FnAbi {
                            ),
                            fields: Primitive,
                            largest_niche: None,
+                           uninhabited: false,
                            variants: Single {
                                index: 0,
                            },
@@ -248,6 +253,7 @@ error: fn_abi_of(test_generic) = FnAbi {
                            memory_index: [],
                        },
                        largest_niche: None,
+                       uninhabited: false,
                        variants: Single {
                            index: 0,
                        },
@@ -297,6 +303,7 @@ error: ABIs are not compatible
                            ),
                            fields: Primitive,
                            largest_niche: None,
+                           uninhabited: false,
                            variants: Single {
                                index: 0,
                            },
@@ -332,6 +339,7 @@ error: ABIs are not compatible
                            memory_index: [],
                        },
                        largest_niche: None,
+                       uninhabited: false,
                        variants: Single {
                            index: 0,
                        },
@@ -369,6 +377,7 @@ error: ABIs are not compatible
                            ),
                            fields: Primitive,
                            largest_niche: None,
+                           uninhabited: false,
                            variants: Single {
                                index: 0,
                            },
@@ -404,6 +413,7 @@ error: ABIs are not compatible
                            memory_index: [],
                        },
                        largest_niche: None,
+                       uninhabited: false,
                        variants: Single {
                            index: 0,
                        },
@@ -444,6 +454,7 @@ error: ABIs are not compatible
                                count: 32,
                            },
                            largest_niche: None,
+                           uninhabited: false,
                            variants: Single {
                                index: 0,
                            },
@@ -483,6 +494,7 @@ error: ABIs are not compatible
                            memory_index: [],
                        },
                        largest_niche: None,
+                       uninhabited: false,
                        variants: Single {
                            index: 0,
                        },
@@ -517,6 +529,7 @@ error: ABIs are not compatible
                                count: 32,
                            },
                            largest_niche: None,
+                           uninhabited: false,
                            variants: Single {
                                index: 0,
                            },
@@ -556,6 +569,7 @@ error: ABIs are not compatible
                            memory_index: [],
                        },
                        largest_niche: None,
+                       uninhabited: false,
                        variants: Single {
                            index: 0,
                        },
@@ -598,6 +612,7 @@ error: ABIs are not compatible
                            ),
                            fields: Primitive,
                            largest_niche: None,
+                           uninhabited: false,
                            variants: Single {
                                index: 0,
                            },
@@ -633,6 +648,7 @@ error: ABIs are not compatible
                            memory_index: [],
                        },
                        largest_niche: None,
+                       uninhabited: false,
                        variants: Single {
                            index: 0,
                        },
@@ -670,6 +686,7 @@ error: ABIs are not compatible
                            ),
                            fields: Primitive,
                            largest_niche: None,
+                           uninhabited: false,
                            variants: Single {
                                index: 0,
                            },
@@ -705,6 +722,7 @@ error: ABIs are not compatible
                            memory_index: [],
                        },
                        largest_niche: None,
+                       uninhabited: false,
                        variants: Single {
                            index: 0,
                        },
@@ -748,6 +766,7 @@ error: ABIs are not compatible
                            ),
                            fields: Primitive,
                            largest_niche: None,
+                           uninhabited: false,
                            variants: Single {
                                index: 0,
                            },
@@ -783,6 +802,7 @@ error: ABIs are not compatible
                            memory_index: [],
                        },
                        largest_niche: None,
+                       uninhabited: false,
                        variants: Single {
                            index: 0,
                        },
@@ -820,6 +840,7 @@ error: ABIs are not compatible
                            ),
                            fields: Primitive,
                            largest_niche: None,
+                           uninhabited: false,
                            variants: Single {
                                index: 0,
                            },
@@ -855,6 +876,7 @@ error: ABIs are not compatible
                            memory_index: [],
                        },
                        largest_niche: None,
+                       uninhabited: false,
                        variants: Single {
                            index: 0,
                        },
@@ -923,6 +945,7 @@ error: fn_abi_of(assoc_test) = FnAbi {
                                    valid_range: $NON_NULL,
                                },
                            ),
+                           uninhabited: false,
                            variants: Single {
                                index: 0,
                            },
@@ -960,6 +983,7 @@ error: fn_abi_of(assoc_test) = FnAbi {
                            memory_index: [],
                        },
                        largest_niche: None,
+                       uninhabited: false,
                        variants: Single {
                            index: 0,
                        },
diff --git a/tests/ui/abi/sysv64-zst.stderr b/tests/ui/abi/sysv64-zst.stderr
index 781e9b2f4c9d5..ec85030c10686 100644
--- a/tests/ui/abi/sysv64-zst.stderr
+++ b/tests/ui/abi/sysv64-zst.stderr
@@ -17,6 +17,7 @@ error: fn_abi_of(pass_zst) = FnAbi {
                                memory_index: [],
                            },
                            largest_niche: None,
+                           uninhabited: false,
                            variants: Single {
                                index: 0,
                            },
@@ -45,6 +46,7 @@ error: fn_abi_of(pass_zst) = FnAbi {
                            memory_index: [],
                        },
                        largest_niche: None,
+                       uninhabited: false,
                        variants: Single {
                            index: 0,
                        },
diff --git a/tests/ui/layout/debug.stderr b/tests/ui/layout/debug.stderr
index 319c0de26a90e..e3d37030ce472 100644
--- a/tests/ui/layout/debug.stderr
+++ b/tests/ui/layout/debug.stderr
@@ -31,6 +31,7 @@ error: layout_of(E) = Layout {
                    valid_range: 0..=0,
                },
            ),
+           uninhabited: false,
            variants: Multiple {
                tag: Initialized {
                    value: Int(
@@ -56,6 +57,7 @@ error: layout_of(E) = Layout {
                            memory_index: [],
                        },
                        largest_niche: None,
+                       uninhabited: false,
                        variants: Single {
                            index: 0,
                        },
@@ -69,7 +71,9 @@ error: layout_of(E) = Layout {
                            abi: Align(4 bytes),
                            pref: $SOME_ALIGN,
                        },
-                       abi: Uninhabited,
+                       abi: Memory {
+                           sized: true,
+                       },
                        fields: Arbitrary {
                            offsets: [
                                Size(4 bytes),
@@ -83,6 +87,7 @@ error: layout_of(E) = Layout {
                            ],
                        },
                        largest_niche: None,
+                       uninhabited: true,
                        variants: Single {
                            index: 1,
                        },
@@ -136,6 +141,7 @@ error: layout_of(S) = Layout {
                ],
            },
            largest_niche: None,
+           uninhabited: false,
            variants: Single {
                index: 0,
            },
@@ -161,6 +167,7 @@ error: layout_of(U) = Layout {
                2,
            ),
            largest_niche: None,
+           uninhabited: false,
            variants: Single {
                index: 0,
            },
@@ -213,6 +220,7 @@ error: layout_of(Result<i32, i32>) = Layout {
                    valid_range: 0..=1,
                },
            ),
+           uninhabited: false,
            variants: Multiple {
                tag: Initialized {
                    value: Int(
@@ -255,6 +263,7 @@ error: layout_of(Result<i32, i32>) = Layout {
                            ],
                        },
                        largest_niche: None,
+                       uninhabited: false,
                        variants: Single {
                            index: 0,
                        },
@@ -293,6 +302,7 @@ error: layout_of(Result<i32, i32>) = Layout {
                            ],
                        },
                        largest_niche: None,
+                       uninhabited: false,
                        variants: Single {
                            index: 1,
                        },
@@ -328,6 +338,7 @@ error: layout_of(i32) = Layout {
            ),
            fields: Primitive,
            largest_niche: None,
+           uninhabited: false,
            variants: Single {
                index: 0,
            },
@@ -353,6 +364,7 @@ error: layout_of(V) = Layout {
                2,
            ),
            largest_niche: None,
+           uninhabited: false,
            variants: Single {
                index: 0,
            },
@@ -378,6 +390,7 @@ error: layout_of(W) = Layout {
                2,
            ),
            largest_niche: None,
+           uninhabited: false,
            variants: Single {
                index: 0,
            },
@@ -403,6 +416,7 @@ error: layout_of(Y) = Layout {
                2,
            ),
            largest_niche: None,
+           uninhabited: false,
            variants: Single {
                index: 0,
            },
@@ -428,6 +442,7 @@ error: layout_of(P1) = Layout {
                1,
            ),
            largest_niche: None,
+           uninhabited: false,
            variants: Single {
                index: 0,
            },
@@ -453,6 +468,7 @@ error: layout_of(P2) = Layout {
                1,
            ),
            largest_niche: None,
+           uninhabited: false,
            variants: Single {
                index: 0,
            },
@@ -478,6 +494,7 @@ error: layout_of(P3) = Layout {
                1,
            ),
            largest_niche: None,
+           uninhabited: false,
            variants: Single {
                index: 0,
            },
@@ -503,6 +520,7 @@ error: layout_of(P4) = Layout {
                1,
            ),
            largest_niche: None,
+           uninhabited: false,
            variants: Single {
                index: 0,
            },
@@ -533,6 +551,7 @@ error: layout_of(P5) = Layout {
                2,
            ),
            largest_niche: None,
+           uninhabited: false,
            variants: Single {
                index: 0,
            },
@@ -563,6 +582,7 @@ error: layout_of(MaybeUninit<u8>) = Layout {
                2,
            ),
            largest_niche: None,
+           uninhabited: false,
            variants: Single {
                index: 0,
            },
diff --git a/tests/ui/layout/hexagon-enum.stderr b/tests/ui/layout/hexagon-enum.stderr
index 96f0a8c874086..90c06ba1f834e 100644
--- a/tests/ui/layout/hexagon-enum.stderr
+++ b/tests/ui/layout/hexagon-enum.stderr
@@ -31,6 +31,7 @@ error: layout_of(A) = Layout {
                    valid_range: 0..=0,
                },
            ),
+           uninhabited: false,
            variants: Multiple {
                tag: Initialized {
                    value: Int(
@@ -56,6 +57,7 @@ error: layout_of(A) = Layout {
                            memory_index: [],
                        },
                        largest_niche: None,
+                       uninhabited: false,
                        variants: Single {
                            index: 0,
                        },
@@ -107,6 +109,7 @@ error: layout_of(B) = Layout {
                    valid_range: 255..=255,
                },
            ),
+           uninhabited: false,
            variants: Multiple {
                tag: Initialized {
                    value: Int(
@@ -132,6 +135,7 @@ error: layout_of(B) = Layout {
                            memory_index: [],
                        },
                        largest_niche: None,
+                       uninhabited: false,
                        variants: Single {
                            index: 0,
                        },
@@ -183,6 +187,7 @@ error: layout_of(C) = Layout {
                    valid_range: 256..=256,
                },
            ),
+           uninhabited: false,
            variants: Multiple {
                tag: Initialized {
                    value: Int(
@@ -208,6 +213,7 @@ error: layout_of(C) = Layout {
                            memory_index: [],
                        },
                        largest_niche: None,
+                       uninhabited: false,
                        variants: Single {
                            index: 0,
                        },
@@ -259,6 +265,7 @@ error: layout_of(P) = Layout {
                    valid_range: 268435456..=268435456,
                },
            ),
+           uninhabited: false,
            variants: Multiple {
                tag: Initialized {
                    value: Int(
@@ -284,6 +291,7 @@ error: layout_of(P) = Layout {
                            memory_index: [],
                        },
                        largest_niche: None,
+                       uninhabited: false,
                        variants: Single {
                            index: 0,
                        },
@@ -335,6 +343,7 @@ error: layout_of(T) = Layout {
                    valid_range: 2164260864..=2164260864,
                },
            ),
+           uninhabited: false,
            variants: Multiple {
                tag: Initialized {
                    value: Int(
@@ -360,6 +369,7 @@ error: layout_of(T) = Layout {
                            memory_index: [],
                        },
                        largest_niche: None,
+                       uninhabited: false,
                        variants: Single {
                            index: 0,
                        },
diff --git a/tests/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.stderr b/tests/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.stderr
index cd9e4c0278150..3bdb9c5c143e4 100644
--- a/tests/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.stderr
+++ b/tests/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.stderr
@@ -37,6 +37,7 @@ error: layout_of(MissingPayloadField) = Layout {
                    valid_range: 0..=1,
                },
            ),
+           uninhabited: false,
            variants: Multiple {
                tag: Initialized {
                    value: Int(
@@ -78,6 +79,7 @@ error: layout_of(MissingPayloadField) = Layout {
                            ],
                        },
                        largest_niche: None,
+                       uninhabited: false,
                        variants: Single {
                            index: 0,
                        },
@@ -99,6 +101,7 @@ error: layout_of(MissingPayloadField) = Layout {
                            memory_index: [],
                        },
                        largest_niche: None,
+                       uninhabited: false,
                        variants: Single {
                            index: 1,
                        },
@@ -157,6 +160,7 @@ error: layout_of(CommonPayloadField) = Layout {
                    valid_range: 0..=1,
                },
            ),
+           uninhabited: false,
            variants: Multiple {
                tag: Initialized {
                    value: Int(
@@ -199,6 +203,7 @@ error: layout_of(CommonPayloadField) = Layout {
                            ],
                        },
                        largest_niche: None,
+                       uninhabited: false,
                        variants: Single {
                            index: 0,
                        },
@@ -237,6 +242,7 @@ error: layout_of(CommonPayloadField) = Layout {
                            ],
                        },
                        largest_niche: None,
+                       uninhabited: false,
                        variants: Single {
                            index: 1,
                        },
@@ -294,6 +300,7 @@ error: layout_of(CommonPayloadFieldIsMaybeUninit) = Layout {
                    valid_range: 0..=1,
                },
            ),
+           uninhabited: false,
            variants: Multiple {
                tag: Initialized {
                    value: Int(
@@ -335,6 +342,7 @@ error: layout_of(CommonPayloadFieldIsMaybeUninit) = Layout {
                            ],
                        },
                        largest_niche: None,
+                       uninhabited: false,
                        variants: Single {
                            index: 0,
                        },
@@ -372,6 +380,7 @@ error: layout_of(CommonPayloadFieldIsMaybeUninit) = Layout {
                            ],
                        },
                        largest_niche: None,
+                       uninhabited: false,
                        variants: Single {
                            index: 1,
                        },
@@ -429,6 +438,7 @@ error: layout_of(NicheFirst) = Layout {
                    valid_range: 0..=4,
                },
            ),
+           uninhabited: false,
            variants: Multiple {
                tag: Initialized {
                    value: Int(
@@ -486,6 +496,7 @@ error: layout_of(NicheFirst) = Layout {
                                valid_range: 0..=2,
                            },
                        ),
+                       uninhabited: false,
                        variants: Single {
                            index: 0,
                        },
@@ -507,6 +518,7 @@ error: layout_of(NicheFirst) = Layout {
                            memory_index: [],
                        },
                        largest_niche: None,
+                       uninhabited: false,
                        variants: Single {
                            index: 1,
                        },
@@ -528,6 +540,7 @@ error: layout_of(NicheFirst) = Layout {
                            memory_index: [],
                        },
                        largest_niche: None,
+                       uninhabited: false,
                        variants: Single {
                            index: 2,
                        },
@@ -585,6 +598,7 @@ error: layout_of(NicheSecond) = Layout {
                    valid_range: 0..=4,
                },
            ),
+           uninhabited: false,
            variants: Multiple {
                tag: Initialized {
                    value: Int(
@@ -642,6 +656,7 @@ error: layout_of(NicheSecond) = Layout {
                                valid_range: 0..=2,
                            },
                        ),
+                       uninhabited: false,
                        variants: Single {
                            index: 0,
                        },
@@ -663,6 +678,7 @@ error: layout_of(NicheSecond) = Layout {
                            memory_index: [],
                        },
                        largest_niche: None,
+                       uninhabited: false,
                        variants: Single {
                            index: 1,
                        },
@@ -684,6 +700,7 @@ error: layout_of(NicheSecond) = Layout {
                            memory_index: [],
                        },
                        largest_niche: None,
+                       uninhabited: false,
                        variants: Single {
                            index: 2,
                        },
diff --git a/tests/ui/layout/issue-96185-overaligned-enum.stderr b/tests/ui/layout/issue-96185-overaligned-enum.stderr
index 15a3f6004f50f..1d4e443644826 100644
--- a/tests/ui/layout/issue-96185-overaligned-enum.stderr
+++ b/tests/ui/layout/issue-96185-overaligned-enum.stderr
@@ -25,6 +25,7 @@ error: layout_of(Aligned1) = Layout {
                    valid_range: 0..=1,
                },
            ),
+           uninhabited: false,
            variants: Multiple {
                tag: Initialized {
                    value: Int(
@@ -50,6 +51,7 @@ error: layout_of(Aligned1) = Layout {
                            memory_index: [],
                        },
                        largest_niche: None,
+                       uninhabited: false,
                        variants: Single {
                            index: 0,
                        },
@@ -73,6 +75,7 @@ error: layout_of(Aligned1) = Layout {
                            memory_index: [],
                        },
                        largest_niche: None,
+                       uninhabited: false,
                        variants: Single {
                            index: 1,
                        },
@@ -128,6 +131,7 @@ error: layout_of(Aligned2) = Layout {
                    valid_range: 0..=1,
                },
            ),
+           uninhabited: false,
            variants: Multiple {
                tag: Initialized {
                    value: Int(
@@ -153,6 +157,7 @@ error: layout_of(Aligned2) = Layout {
                            memory_index: [],
                        },
                        largest_niche: None,
+                       uninhabited: false,
                        variants: Single {
                            index: 0,
                        },
@@ -176,6 +181,7 @@ error: layout_of(Aligned2) = Layout {
                            memory_index: [],
                        },
                        largest_niche: None,
+                       uninhabited: false,
                        variants: Single {
                            index: 1,
                        },
diff --git a/tests/ui/layout/thumb-enum.stderr b/tests/ui/layout/thumb-enum.stderr
index 120081d193c69..0c34331856474 100644
--- a/tests/ui/layout/thumb-enum.stderr
+++ b/tests/ui/layout/thumb-enum.stderr
@@ -31,6 +31,7 @@ error: layout_of(A) = Layout {
                    valid_range: 0..=0,
                },
            ),
+           uninhabited: false,
            variants: Multiple {
                tag: Initialized {
                    value: Int(
@@ -56,6 +57,7 @@ error: layout_of(A) = Layout {
                            memory_index: [],
                        },
                        largest_niche: None,
+                       uninhabited: false,
                        variants: Single {
                            index: 0,
                        },
@@ -107,6 +109,7 @@ error: layout_of(B) = Layout {
                    valid_range: 255..=255,
                },
            ),
+           uninhabited: false,
            variants: Multiple {
                tag: Initialized {
                    value: Int(
@@ -132,6 +135,7 @@ error: layout_of(B) = Layout {
                            memory_index: [],
                        },
                        largest_niche: None,
+                       uninhabited: false,
                        variants: Single {
                            index: 0,
                        },
@@ -183,6 +187,7 @@ error: layout_of(C) = Layout {
                    valid_range: 256..=256,
                },
            ),
+           uninhabited: false,
            variants: Multiple {
                tag: Initialized {
                    value: Int(
@@ -208,6 +213,7 @@ error: layout_of(C) = Layout {
                            memory_index: [],
                        },
                        largest_niche: None,
+                       uninhabited: false,
                        variants: Single {
                            index: 0,
                        },
@@ -259,6 +265,7 @@ error: layout_of(P) = Layout {
                    valid_range: 268435456..=268435456,
                },
            ),
+           uninhabited: false,
            variants: Multiple {
                tag: Initialized {
                    value: Int(
@@ -284,6 +291,7 @@ error: layout_of(P) = Layout {
                            memory_index: [],
                        },
                        largest_niche: None,
+                       uninhabited: false,
                        variants: Single {
                            index: 0,
                        },
@@ -335,6 +343,7 @@ error: layout_of(T) = Layout {
                    valid_range: 2164260864..=2164260864,
                },
            ),
+           uninhabited: false,
            variants: Multiple {
                tag: Initialized {
                    value: Int(
@@ -360,6 +369,7 @@ error: layout_of(T) = Layout {
                            memory_index: [],
                        },
                        largest_niche: None,
+                       uninhabited: false,
                        variants: Single {
                            index: 0,
                        },
diff --git a/tests/ui/layout/zero-sized-array-enum-niche.stderr b/tests/ui/layout/zero-sized-array-enum-niche.stderr
index b6fcc14c063c5..33d2eede22090 100644
--- a/tests/ui/layout/zero-sized-array-enum-niche.stderr
+++ b/tests/ui/layout/zero-sized-array-enum-niche.stderr
@@ -25,6 +25,7 @@ error: layout_of(Result<[u32; 0], bool>) = Layout {
                    valid_range: 0..=1,
                },
            ),
+           uninhabited: false,
            variants: Multiple {
                tag: Initialized {
                    value: Int(
@@ -54,6 +55,7 @@ error: layout_of(Result<[u32; 0], bool>) = Layout {
                            ],
                        },
                        largest_niche: None,
+                       uninhabited: false,
                        variants: Single {
                            index: 0,
                        },
@@ -88,6 +90,7 @@ error: layout_of(Result<[u32; 0], bool>) = Layout {
                                valid_range: 0..=1,
                            },
                        ),
+                       uninhabited: false,
                        variants: Single {
                            index: 1,
                        },
@@ -133,6 +136,7 @@ error: layout_of(MultipleAlignments) = Layout {
                    valid_range: 0..=2,
                },
            ),
+           uninhabited: false,
            variants: Multiple {
                tag: Initialized {
                    value: Int(
@@ -162,6 +166,7 @@ error: layout_of(MultipleAlignments) = Layout {
                            ],
                        },
                        largest_niche: None,
+                       uninhabited: false,
                        variants: Single {
                            index: 0,
                        },
@@ -187,6 +192,7 @@ error: layout_of(MultipleAlignments) = Layout {
                            ],
                        },
                        largest_niche: None,
+                       uninhabited: false,
                        variants: Single {
                            index: 1,
                        },
@@ -221,6 +227,7 @@ error: layout_of(MultipleAlignments) = Layout {
                                valid_range: 0..=1,
                            },
                        ),
+                       uninhabited: false,
                        variants: Single {
                            index: 2,
                        },
@@ -266,6 +273,7 @@ error: layout_of(Result<[u32; 0], Packed<NonZero<u16>>>) = Layout {
                    valid_range: 0..=1,
                },
            ),
+           uninhabited: false,
            variants: Multiple {
                tag: Initialized {
                    value: Int(
@@ -295,6 +303,7 @@ error: layout_of(Result<[u32; 0], Packed<NonZero<u16>>>) = Layout {
                            ],
                        },
                        largest_niche: None,
+                       uninhabited: false,
                        variants: Single {
                            index: 0,
                        },
@@ -329,6 +338,7 @@ error: layout_of(Result<[u32; 0], Packed<NonZero<u16>>>) = Layout {
                                valid_range: 1..=65535,
                            },
                        ),
+                       uninhabited: false,
                        variants: Single {
                            index: 1,
                        },
@@ -374,6 +384,7 @@ error: layout_of(Result<[u32; 0], Packed<U16IsZero>>) = Layout {
                    valid_range: 0..=1,
                },
            ),
+           uninhabited: false,
            variants: Multiple {
                tag: Initialized {
                    value: Int(
@@ -407,6 +418,7 @@ error: layout_of(Result<[u32; 0], Packed<U16IsZero>>) = Layout {
                            ],
                        },
                        largest_niche: None,
+                       uninhabited: false,
                        variants: Single {
                            index: 0,
                        },
@@ -441,6 +453,7 @@ error: layout_of(Result<[u32; 0], Packed<U16IsZero>>) = Layout {
                                valid_range: 0..=0,
                            },
                        ),
+                       uninhabited: false,
                        variants: Single {
                            index: 1,
                        },
diff --git a/tests/ui/repr/repr-c-dead-variants.aarch64-unknown-linux-gnu.stderr b/tests/ui/repr/repr-c-dead-variants.aarch64-unknown-linux-gnu.stderr
index 8e8f1d159b740..204db30786ee3 100644
--- a/tests/ui/repr/repr-c-dead-variants.aarch64-unknown-linux-gnu.stderr
+++ b/tests/ui/repr/repr-c-dead-variants.aarch64-unknown-linux-gnu.stderr
@@ -4,7 +4,15 @@ error: layout_of(Univariant) = Layout {
                abi: Align(4 bytes),
                pref: $SOME_ALIGN,
            },
-           abi: Uninhabited,
+           abi: Scalar(
+               Initialized {
+                   value: Int(
+                       I32,
+                       false,
+                   ),
+                   valid_range: 0..=0,
+               },
+           ),
            fields: Arbitrary {
                offsets: [
                    Size(0 bytes),
@@ -23,6 +31,7 @@ error: layout_of(Univariant) = Layout {
                    valid_range: 0..=0,
                },
            ),
+           uninhabited: true,
            variants: Multiple {
                tag: Initialized {
                    value: Int(
@@ -40,7 +49,15 @@ error: layout_of(Univariant) = Layout {
                            abi: Align(4 bytes),
                            pref: $SOME_ALIGN,
                        },
-                       abi: Uninhabited,
+                       abi: Scalar(
+                           Initialized {
+                               value: Int(
+                                   I32,
+                                   false,
+                               ),
+                               valid_range: 0..=0,
+                           },
+                       ),
                        fields: Arbitrary {
                            offsets: [
                                Size(4 bytes),
@@ -50,6 +67,7 @@ error: layout_of(Univariant) = Layout {
                            ],
                        },
                        largest_niche: None,
+                       uninhabited: true,
                        variants: Single {
                            index: 0,
                        },
@@ -107,6 +125,7 @@ error: layout_of(TwoVariants) = Layout {
                    valid_range: 0..=1,
                },
            ),
+           uninhabited: false,
            variants: Multiple {
                tag: Initialized {
                    value: Int(
@@ -119,12 +138,26 @@ error: layout_of(TwoVariants) = Layout {
                tag_field: 0,
                variants: [
                    Layout {
-                       size: Size(4 bytes),
+                       size: Size(8 bytes),
                        align: AbiAndPrefAlign {
                            abi: Align(4 bytes),
                            pref: $SOME_ALIGN,
                        },
-                       abi: Uninhabited,
+                       abi: ScalarPair(
+                           Initialized {
+                               value: Int(
+                                   I32,
+                                   false,
+                               ),
+                               valid_range: 0..=1,
+                           },
+                           Union {
+                               value: Int(
+                                   I8,
+                                   false,
+                               ),
+                           },
+                       ),
                        fields: Arbitrary {
                            offsets: [
                                Size(4 bytes),
@@ -134,6 +167,7 @@ error: layout_of(TwoVariants) = Layout {
                            ],
                        },
                        largest_niche: None,
+                       uninhabited: true,
                        variants: Single {
                            index: 0,
                        },
@@ -171,6 +205,7 @@ error: layout_of(TwoVariants) = Layout {
                            ],
                        },
                        largest_niche: None,
+                       uninhabited: false,
                        variants: Single {
                            index: 1,
                        },
@@ -216,6 +251,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout {
                    valid_range: 0..=1,
                },
            ),
+           uninhabited: false,
            variants: Multiple {
                tag: Initialized {
                    value: Int(
@@ -233,7 +269,9 @@ error: layout_of(DeadBranchHasOtherField) = Layout {
                            abi: Align(8 bytes),
                            pref: $SOME_ALIGN,
                        },
-                       abi: Uninhabited,
+                       abi: Memory {
+                           sized: true,
+                       },
                        fields: Arbitrary {
                            offsets: [
                                Size(8 bytes),
@@ -245,6 +283,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout {
                            ],
                        },
                        largest_niche: None,
+                       uninhabited: true,
                        variants: Single {
                            index: 0,
                        },
@@ -272,6 +311,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout {
                            ],
                        },
                        largest_niche: None,
+                       uninhabited: false,
                        variants: Single {
                            index: 1,
                        },
diff --git a/tests/ui/repr/repr-c-dead-variants.armebv7r-none-eabi.stderr b/tests/ui/repr/repr-c-dead-variants.armebv7r-none-eabi.stderr
index 2cd0960ce3eec..1fab00bf50c49 100644
--- a/tests/ui/repr/repr-c-dead-variants.armebv7r-none-eabi.stderr
+++ b/tests/ui/repr/repr-c-dead-variants.armebv7r-none-eabi.stderr
@@ -4,7 +4,15 @@ error: layout_of(Univariant) = Layout {
                abi: Align(1 bytes),
                pref: $SOME_ALIGN,
            },
-           abi: Uninhabited,
+           abi: Scalar(
+               Initialized {
+                   value: Int(
+                       I8,
+                       false,
+                   ),
+                   valid_range: 0..=0,
+               },
+           ),
            fields: Arbitrary {
                offsets: [
                    Size(0 bytes),
@@ -23,6 +31,7 @@ error: layout_of(Univariant) = Layout {
                    valid_range: 0..=0,
                },
            ),
+           uninhabited: true,
            variants: Multiple {
                tag: Initialized {
                    value: Int(
@@ -40,7 +49,15 @@ error: layout_of(Univariant) = Layout {
                            abi: Align(1 bytes),
                            pref: $SOME_ALIGN,
                        },
-                       abi: Uninhabited,
+                       abi: Scalar(
+                           Initialized {
+                               value: Int(
+                                   I8,
+                                   false,
+                               ),
+                               valid_range: 0..=0,
+                           },
+                       ),
                        fields: Arbitrary {
                            offsets: [
                                Size(1 bytes),
@@ -50,6 +67,7 @@ error: layout_of(Univariant) = Layout {
                            ],
                        },
                        largest_niche: None,
+                       uninhabited: true,
                        variants: Single {
                            index: 0,
                        },
@@ -107,6 +125,7 @@ error: layout_of(TwoVariants) = Layout {
                    valid_range: 0..=1,
                },
            ),
+           uninhabited: false,
            variants: Multiple {
                tag: Initialized {
                    value: Int(
@@ -119,12 +138,26 @@ error: layout_of(TwoVariants) = Layout {
                tag_field: 0,
                variants: [
                    Layout {
-                       size: Size(1 bytes),
+                       size: Size(2 bytes),
                        align: AbiAndPrefAlign {
                            abi: Align(1 bytes),
                            pref: $SOME_ALIGN,
                        },
-                       abi: Uninhabited,
+                       abi: ScalarPair(
+                           Initialized {
+                               value: Int(
+                                   I8,
+                                   false,
+                               ),
+                               valid_range: 0..=1,
+                           },
+                           Union {
+                               value: Int(
+                                   I8,
+                                   false,
+                               ),
+                           },
+                       ),
                        fields: Arbitrary {
                            offsets: [
                                Size(1 bytes),
@@ -134,6 +167,7 @@ error: layout_of(TwoVariants) = Layout {
                            ],
                        },
                        largest_niche: None,
+                       uninhabited: true,
                        variants: Single {
                            index: 0,
                        },
@@ -171,6 +205,7 @@ error: layout_of(TwoVariants) = Layout {
                            ],
                        },
                        largest_niche: None,
+                       uninhabited: false,
                        variants: Single {
                            index: 1,
                        },
@@ -216,6 +251,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout {
                    valid_range: 0..=1,
                },
            ),
+           uninhabited: false,
            variants: Multiple {
                tag: Initialized {
                    value: Int(
@@ -233,7 +269,9 @@ error: layout_of(DeadBranchHasOtherField) = Layout {
                            abi: Align(8 bytes),
                            pref: $SOME_ALIGN,
                        },
-                       abi: Uninhabited,
+                       abi: Memory {
+                           sized: true,
+                       },
                        fields: Arbitrary {
                            offsets: [
                                Size(8 bytes),
@@ -245,6 +283,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout {
                            ],
                        },
                        largest_niche: None,
+                       uninhabited: true,
                        variants: Single {
                            index: 0,
                        },
@@ -272,6 +311,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout {
                            ],
                        },
                        largest_niche: None,
+                       uninhabited: false,
                        variants: Single {
                            index: 1,
                        },
diff --git a/tests/ui/repr/repr-c-dead-variants.i686-pc-windows-msvc.stderr b/tests/ui/repr/repr-c-dead-variants.i686-pc-windows-msvc.stderr
index 8e8f1d159b740..204db30786ee3 100644
--- a/tests/ui/repr/repr-c-dead-variants.i686-pc-windows-msvc.stderr
+++ b/tests/ui/repr/repr-c-dead-variants.i686-pc-windows-msvc.stderr
@@ -4,7 +4,15 @@ error: layout_of(Univariant) = Layout {
                abi: Align(4 bytes),
                pref: $SOME_ALIGN,
            },
-           abi: Uninhabited,
+           abi: Scalar(
+               Initialized {
+                   value: Int(
+                       I32,
+                       false,
+                   ),
+                   valid_range: 0..=0,
+               },
+           ),
            fields: Arbitrary {
                offsets: [
                    Size(0 bytes),
@@ -23,6 +31,7 @@ error: layout_of(Univariant) = Layout {
                    valid_range: 0..=0,
                },
            ),
+           uninhabited: true,
            variants: Multiple {
                tag: Initialized {
                    value: Int(
@@ -40,7 +49,15 @@ error: layout_of(Univariant) = Layout {
                            abi: Align(4 bytes),
                            pref: $SOME_ALIGN,
                        },
-                       abi: Uninhabited,
+                       abi: Scalar(
+                           Initialized {
+                               value: Int(
+                                   I32,
+                                   false,
+                               ),
+                               valid_range: 0..=0,
+                           },
+                       ),
                        fields: Arbitrary {
                            offsets: [
                                Size(4 bytes),
@@ -50,6 +67,7 @@ error: layout_of(Univariant) = Layout {
                            ],
                        },
                        largest_niche: None,
+                       uninhabited: true,
                        variants: Single {
                            index: 0,
                        },
@@ -107,6 +125,7 @@ error: layout_of(TwoVariants) = Layout {
                    valid_range: 0..=1,
                },
            ),
+           uninhabited: false,
            variants: Multiple {
                tag: Initialized {
                    value: Int(
@@ -119,12 +138,26 @@ error: layout_of(TwoVariants) = Layout {
                tag_field: 0,
                variants: [
                    Layout {
-                       size: Size(4 bytes),
+                       size: Size(8 bytes),
                        align: AbiAndPrefAlign {
                            abi: Align(4 bytes),
                            pref: $SOME_ALIGN,
                        },
-                       abi: Uninhabited,
+                       abi: ScalarPair(
+                           Initialized {
+                               value: Int(
+                                   I32,
+                                   false,
+                               ),
+                               valid_range: 0..=1,
+                           },
+                           Union {
+                               value: Int(
+                                   I8,
+                                   false,
+                               ),
+                           },
+                       ),
                        fields: Arbitrary {
                            offsets: [
                                Size(4 bytes),
@@ -134,6 +167,7 @@ error: layout_of(TwoVariants) = Layout {
                            ],
                        },
                        largest_niche: None,
+                       uninhabited: true,
                        variants: Single {
                            index: 0,
                        },
@@ -171,6 +205,7 @@ error: layout_of(TwoVariants) = Layout {
                            ],
                        },
                        largest_niche: None,
+                       uninhabited: false,
                        variants: Single {
                            index: 1,
                        },
@@ -216,6 +251,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout {
                    valid_range: 0..=1,
                },
            ),
+           uninhabited: false,
            variants: Multiple {
                tag: Initialized {
                    value: Int(
@@ -233,7 +269,9 @@ error: layout_of(DeadBranchHasOtherField) = Layout {
                            abi: Align(8 bytes),
                            pref: $SOME_ALIGN,
                        },
-                       abi: Uninhabited,
+                       abi: Memory {
+                           sized: true,
+                       },
                        fields: Arbitrary {
                            offsets: [
                                Size(8 bytes),
@@ -245,6 +283,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout {
                            ],
                        },
                        largest_niche: None,
+                       uninhabited: true,
                        variants: Single {
                            index: 0,
                        },
@@ -272,6 +311,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout {
                            ],
                        },
                        largest_niche: None,
+                       uninhabited: false,
                        variants: Single {
                            index: 1,
                        },
diff --git a/tests/ui/repr/repr-c-dead-variants.x86_64-unknown-linux-gnu.stderr b/tests/ui/repr/repr-c-dead-variants.x86_64-unknown-linux-gnu.stderr
index 8e8f1d159b740..204db30786ee3 100644
--- a/tests/ui/repr/repr-c-dead-variants.x86_64-unknown-linux-gnu.stderr
+++ b/tests/ui/repr/repr-c-dead-variants.x86_64-unknown-linux-gnu.stderr
@@ -4,7 +4,15 @@ error: layout_of(Univariant) = Layout {
                abi: Align(4 bytes),
                pref: $SOME_ALIGN,
            },
-           abi: Uninhabited,
+           abi: Scalar(
+               Initialized {
+                   value: Int(
+                       I32,
+                       false,
+                   ),
+                   valid_range: 0..=0,
+               },
+           ),
            fields: Arbitrary {
                offsets: [
                    Size(0 bytes),
@@ -23,6 +31,7 @@ error: layout_of(Univariant) = Layout {
                    valid_range: 0..=0,
                },
            ),
+           uninhabited: true,
            variants: Multiple {
                tag: Initialized {
                    value: Int(
@@ -40,7 +49,15 @@ error: layout_of(Univariant) = Layout {
                            abi: Align(4 bytes),
                            pref: $SOME_ALIGN,
                        },
-                       abi: Uninhabited,
+                       abi: Scalar(
+                           Initialized {
+                               value: Int(
+                                   I32,
+                                   false,
+                               ),
+                               valid_range: 0..=0,
+                           },
+                       ),
                        fields: Arbitrary {
                            offsets: [
                                Size(4 bytes),
@@ -50,6 +67,7 @@ error: layout_of(Univariant) = Layout {
                            ],
                        },
                        largest_niche: None,
+                       uninhabited: true,
                        variants: Single {
                            index: 0,
                        },
@@ -107,6 +125,7 @@ error: layout_of(TwoVariants) = Layout {
                    valid_range: 0..=1,
                },
            ),
+           uninhabited: false,
            variants: Multiple {
                tag: Initialized {
                    value: Int(
@@ -119,12 +138,26 @@ error: layout_of(TwoVariants) = Layout {
                tag_field: 0,
                variants: [
                    Layout {
-                       size: Size(4 bytes),
+                       size: Size(8 bytes),
                        align: AbiAndPrefAlign {
                            abi: Align(4 bytes),
                            pref: $SOME_ALIGN,
                        },
-                       abi: Uninhabited,
+                       abi: ScalarPair(
+                           Initialized {
+                               value: Int(
+                                   I32,
+                                   false,
+                               ),
+                               valid_range: 0..=1,
+                           },
+                           Union {
+                               value: Int(
+                                   I8,
+                                   false,
+                               ),
+                           },
+                       ),
                        fields: Arbitrary {
                            offsets: [
                                Size(4 bytes),
@@ -134,6 +167,7 @@ error: layout_of(TwoVariants) = Layout {
                            ],
                        },
                        largest_niche: None,
+                       uninhabited: true,
                        variants: Single {
                            index: 0,
                        },
@@ -171,6 +205,7 @@ error: layout_of(TwoVariants) = Layout {
                            ],
                        },
                        largest_niche: None,
+                       uninhabited: false,
                        variants: Single {
                            index: 1,
                        },
@@ -216,6 +251,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout {
                    valid_range: 0..=1,
                },
            ),
+           uninhabited: false,
            variants: Multiple {
                tag: Initialized {
                    value: Int(
@@ -233,7 +269,9 @@ error: layout_of(DeadBranchHasOtherField) = Layout {
                            abi: Align(8 bytes),
                            pref: $SOME_ALIGN,
                        },
-                       abi: Uninhabited,
+                       abi: Memory {
+                           sized: true,
+                       },
                        fields: Arbitrary {
                            offsets: [
                                Size(8 bytes),
@@ -245,6 +283,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout {
                            ],
                        },
                        largest_niche: None,
+                       uninhabited: true,
                        variants: Single {
                            index: 0,
                        },
@@ -272,6 +311,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout {
                            ],
                        },
                        largest_niche: None,
+                       uninhabited: false,
                        variants: Single {
                            index: 1,
                        },
diff --git a/tests/ui/repr/repr-c-int-dead-variants.stderr b/tests/ui/repr/repr-c-int-dead-variants.stderr
index fa08b323dec2a..f852212deb908 100644
--- a/tests/ui/repr/repr-c-int-dead-variants.stderr
+++ b/tests/ui/repr/repr-c-int-dead-variants.stderr
@@ -4,7 +4,15 @@ error: layout_of(UnivariantU8) = Layout {
                abi: Align(1 bytes),
                pref: $SOME_ALIGN,
            },
-           abi: Uninhabited,
+           abi: Scalar(
+               Initialized {
+                   value: Int(
+                       I8,
+                       false,
+                   ),
+                   valid_range: 0..=0,
+               },
+           ),
            fields: Arbitrary {
                offsets: [
                    Size(0 bytes),
@@ -23,6 +31,7 @@ error: layout_of(UnivariantU8) = Layout {
                    valid_range: 0..=0,
                },
            ),
+           uninhabited: true,
            variants: Multiple {
                tag: Initialized {
                    value: Int(
@@ -40,7 +49,15 @@ error: layout_of(UnivariantU8) = Layout {
                            abi: Align(1 bytes),
                            pref: $SOME_ALIGN,
                        },
-                       abi: Uninhabited,
+                       abi: Scalar(
+                           Initialized {
+                               value: Int(
+                                   I8,
+                                   false,
+                               ),
+                               valid_range: 0..=0,
+                           },
+                       ),
                        fields: Arbitrary {
                            offsets: [
                                Size(1 bytes),
@@ -50,6 +67,7 @@ error: layout_of(UnivariantU8) = Layout {
                            ],
                        },
                        largest_niche: None,
+                       uninhabited: true,
                        variants: Single {
                            index: 0,
                        },
@@ -107,6 +125,7 @@ error: layout_of(TwoVariantsU8) = Layout {
                    valid_range: 0..=1,
                },
            ),
+           uninhabited: false,
            variants: Multiple {
                tag: Initialized {
                    value: Int(
@@ -119,12 +138,26 @@ error: layout_of(TwoVariantsU8) = Layout {
                tag_field: 0,
                variants: [
                    Layout {
-                       size: Size(1 bytes),
+                       size: Size(2 bytes),
                        align: AbiAndPrefAlign {
                            abi: Align(1 bytes),
                            pref: $SOME_ALIGN,
                        },
-                       abi: Uninhabited,
+                       abi: ScalarPair(
+                           Initialized {
+                               value: Int(
+                                   I8,
+                                   false,
+                               ),
+                               valid_range: 0..=1,
+                           },
+                           Union {
+                               value: Int(
+                                   I8,
+                                   false,
+                               ),
+                           },
+                       ),
                        fields: Arbitrary {
                            offsets: [
                                Size(1 bytes),
@@ -134,6 +167,7 @@ error: layout_of(TwoVariantsU8) = Layout {
                            ],
                        },
                        largest_niche: None,
+                       uninhabited: true,
                        variants: Single {
                            index: 0,
                        },
@@ -171,6 +205,7 @@ error: layout_of(TwoVariantsU8) = Layout {
                            ],
                        },
                        largest_niche: None,
+                       uninhabited: false,
                        variants: Single {
                            index: 1,
                        },
@@ -216,6 +251,7 @@ error: layout_of(DeadBranchHasOtherFieldU8) = Layout {
                    valid_range: 0..=1,
                },
            ),
+           uninhabited: false,
            variants: Multiple {
                tag: Initialized {
                    value: Int(
@@ -233,7 +269,9 @@ error: layout_of(DeadBranchHasOtherFieldU8) = Layout {
                            abi: Align(8 bytes),
                            pref: $SOME_ALIGN,
                        },
-                       abi: Uninhabited,
+                       abi: Memory {
+                           sized: true,
+                       },
                        fields: Arbitrary {
                            offsets: [
                                Size(8 bytes),
@@ -245,6 +283,7 @@ error: layout_of(DeadBranchHasOtherFieldU8) = Layout {
                            ],
                        },
                        largest_niche: None,
+                       uninhabited: true,
                        variants: Single {
                            index: 0,
                        },
@@ -272,6 +311,7 @@ error: layout_of(DeadBranchHasOtherFieldU8) = Layout {
                            ],
                        },
                        largest_niche: None,
+                       uninhabited: false,
                        variants: Single {
                            index: 1,
                        },
diff --git a/tests/ui/resolve/dot-notation-type-namespace-suggest-path-sep.rs b/tests/ui/resolve/dot-notation-type-namespace-suggest-path-sep.rs
new file mode 100644
index 0000000000000..432e3c0b77efc
--- /dev/null
+++ b/tests/ui/resolve/dot-notation-type-namespace-suggest-path-sep.rs
@@ -0,0 +1,123 @@
+// see also https://github.com/rust-lang/rust/issues/22692
+
+type Alias = Vec<u32>;
+
+mod foo {
+    fn bar() {}
+}
+
+fn main() {
+    let _ = String.new();
+    //~^ ERROR expected value, found struct `String`
+    //~| HELP use the path separator
+
+    let _ = String.default;
+    //~^ ERROR expected value, found struct `String`
+    //~| HELP use the path separator
+
+    let _ = Vec::<()>.with_capacity(1);
+    //~^ ERROR expected value, found struct `Vec`
+    //~| HELP use the path separator
+
+    let _ = Alias.new();
+    //~^ ERROR expected value, found type alias `Alias`
+    //~| HELP use the path separator
+
+    let _ = Alias.default;
+    //~^ ERROR expected value, found type alias `Alias`
+    //~| HELP use the path separator
+
+    let _ = foo.bar;
+    //~^ ERROR expected value, found module `foo`
+    //~| HELP use the path separator
+}
+
+macro_rules! Type {
+    () => {
+        ::std::cell::Cell
+        //~^ ERROR expected value, found struct `std::cell::Cell`
+        //~| ERROR expected value, found struct `std::cell::Cell`
+        //~| ERROR expected value, found struct `std::cell::Cell`
+    };
+    (alias) => {
+        Alias
+        //~^ ERROR expected value, found type alias `Alias`
+        //~| ERROR expected value, found type alias `Alias`
+        //~| ERROR expected value, found type alias `Alias`
+    };
+}
+
+macro_rules! create {
+    (type method) => {
+        Vec.new()
+        //~^ ERROR expected value, found struct `Vec`
+        //~| HELP use the path separator
+    };
+    (type field) => {
+        Vec.new
+        //~^ ERROR expected value, found struct `Vec`
+        //~| HELP use the path separator
+    };
+    (macro method) => {
+        Type!().new(0)
+        //~^ HELP use the path separator
+    };
+    (macro method alias) => {
+        Type!(alias).new(0)
+        //~^ HELP use the path separator
+    };
+}
+
+macro_rules! check_ty {
+    ($Ty:ident) => {
+        $Ty.foo
+        //~^ ERROR expected value, found type alias `Alias`
+        //~| HELP use the path separator
+    };
+}
+macro_rules! check_ident {
+    ($Ident:ident) => {
+        Alias.$Ident
+        //~^ ERROR expected value, found type alias `Alias`
+        //~| HELP use the path separator
+    };
+}
+macro_rules! check_ty_ident {
+    ($Ty:ident, $Ident:ident) => {
+        $Ty.$Ident
+        //~^ ERROR expected value, found type alias `Alias`
+        //~| HELP use the path separator
+    };
+}
+
+fn interaction_with_macros() {
+    //
+    // Verify that we do not only suggest to replace `.` with `::` if the receiver is a
+    // macro call but that we also correctly suggest to surround it with angle brackets.
+    //
+
+    Type!().get();
+    //~^ HELP use the path separator
+
+    Type! {}.get;
+    //~^ HELP use the path separator
+
+    Type!(alias).get();
+    //~^ HELP use the path separator
+
+    Type! {alias}.get;
+    //~^ HELP use the path separator
+
+    //
+    // Ensure that the suggestion is shown for expressions inside of macro definitions.
+    //
+
+    let _ = create!(type method);
+    let _ = create!(type field);
+    let _ = create!(macro method);
+    let _ = create!(macro method alias);
+
+    let _ = check_ty!(Alias);
+    let _ = check_ident!(foo);
+    let _ = check_ty_ident!(Alias, foo);
+}
diff --git a/tests/ui/resolve/dot-notation-type-namespace-suggest-path-sep.stderr b/tests/ui/resolve/dot-notation-type-namespace-suggest-path-sep.stderr
new file mode 100644
index 0000000000000..d74814dd876c2
--- /dev/null
+++ b/tests/ui/resolve/dot-notation-type-namespace-suggest-path-sep.stderr
@@ -0,0 +1,251 @@
+error[E0423]: expected value, found struct `String`
+  --> $DIR/dot-notation-type-namespace-suggest-path-sep.rs:10:13
+   |
+LL |     let _ = String.new();
+   |             ^^^^^^
+   |
+help: use the path separator to refer to an item
+   |
+LL -     let _ = String.new();
+LL +     let _ = String::new();
+   |
+
+error[E0423]: expected value, found struct `String`
+  --> $DIR/dot-notation-type-namespace-suggest-path-sep.rs:14:13
+   |
+LL |     let _ = String.default;
+   |             ^^^^^^
+   |
+help: use the path separator to refer to an item
+   |
+LL -     let _ = String.default;
+LL +     let _ = String::default;
+   |
+
+error[E0423]: expected value, found struct `Vec`
+  --> $DIR/dot-notation-type-namespace-suggest-path-sep.rs:18:13
+   |
+LL |     let _ = Vec::<()>.with_capacity(1);
+   |             ^^^^^^^^^
+   |
+help: use the path separator to refer to an item
+   |
+LL -     let _ = Vec::<()>.with_capacity(1);
+LL +     let _ = Vec::<()>::with_capacity(1);
+   |
+
+error[E0423]: expected value, found type alias `Alias`
+  --> $DIR/dot-notation-type-namespace-suggest-path-sep.rs:22:13
+   |
+LL |     let _ = Alias.new();
+   |             ^^^^^
+   |
+help: use the path separator to refer to an item
+   |
+LL -     let _ = Alias.new();
+LL +     let _ = Alias::new();
+   |
+
+error[E0423]: expected value, found type alias `Alias`
+  --> $DIR/dot-notation-type-namespace-suggest-path-sep.rs:26:13
+   |
+LL |     let _ = Alias.default;
+   |             ^^^^^
+   |
+help: use the path separator to refer to an item
+   |
+LL -     let _ = Alias.default;
+LL +     let _ = Alias::default;
+   |
+
+error[E0423]: expected value, found module `foo`
+  --> $DIR/dot-notation-type-namespace-suggest-path-sep.rs:30:13
+   |
+LL |     let _ = foo.bar;
+   |             ^^^
+   |
+help: use the path separator to refer to an item
+   |
+LL -     let _ = foo.bar;
+LL +     let _ = foo::bar;
+   |
+
+error[E0423]: expected value, found struct `std::cell::Cell`
+  --> $DIR/dot-notation-type-namespace-suggest-path-sep.rs:37:9
+   |
+LL |         ::std::cell::Cell
+   |         ^^^^^^^^^^^^^^^^^
+...
+LL |     Type!().get();
+   |     ------- in this macro invocation
+   |
+   = note: this error originates in the macro `Type` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: use the path separator to refer to an item
+   |
+LL -     Type!().get();
+LL +     <Type!()>::get();
+   |
+
+error[E0423]: expected value, found struct `std::cell::Cell`
+  --> $DIR/dot-notation-type-namespace-suggest-path-sep.rs:37:9
+   |
+LL |         ::std::cell::Cell
+   |         ^^^^^^^^^^^^^^^^^
+...
+LL |     Type! {}.get;
+   |     -------- in this macro invocation
+   |
+   = note: this error originates in the macro `Type` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: use the path separator to refer to an item
+   |
+LL -     Type! {}.get;
+LL +     <Type! {}>::get;
+   |
+
+error[E0423]: expected value, found type alias `Alias`
+  --> $DIR/dot-notation-type-namespace-suggest-path-sep.rs:43:9
+   |
+LL |         Alias
+   |         ^^^^^
+...
+LL |     Type!(alias).get();
+   |     ------------ in this macro invocation
+   |
+   = note: this error originates in the macro `Type` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: use the path separator to refer to an item
+   |
+LL -     Type!(alias).get();
+LL +     <Type!(alias)>::get();
+   |
+
+error[E0423]: expected value, found type alias `Alias`
+  --> $DIR/dot-notation-type-namespace-suggest-path-sep.rs:43:9
+   |
+LL |         Alias
+   |         ^^^^^
+...
+LL |     Type! {alias}.get;
+   |     ------------- in this macro invocation
+   |
+   = note: this error originates in the macro `Type` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: use the path separator to refer to an item
+   |
+LL -     Type! {alias}.get;
+LL +     <Type! {alias}>::get;
+   |
+
+error[E0423]: expected value, found struct `Vec`
+  --> $DIR/dot-notation-type-namespace-suggest-path-sep.rs:52:9
+   |
+LL |         Vec.new()
+   |         ^^^
+...
+LL |     let _ = create!(type method);
+   |             -------------------- in this macro invocation
+   |
+   = note: this error originates in the macro `create` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: use the path separator to refer to an item
+   |
+LL -         Vec.new()
+LL +         Vec::new()
+   |
+
+error[E0423]: expected value, found struct `Vec`
+  --> $DIR/dot-notation-type-namespace-suggest-path-sep.rs:57:9
+   |
+LL |         Vec.new
+   |         ^^^
+...
+LL |     let _ = create!(type field);
+   |             ------------------- in this macro invocation
+   |
+   = note: this error originates in the macro `create` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: use the path separator to refer to an item
+   |
+LL -         Vec.new
+LL +         Vec::new
+   |
+
+error[E0423]: expected value, found struct `std::cell::Cell`
+  --> $DIR/dot-notation-type-namespace-suggest-path-sep.rs:37:9
+   |
+LL |         ::std::cell::Cell
+   |         ^^^^^^^^^^^^^^^^^
+...
+LL |     let _ = create!(macro method);
+   |             --------------------- in this macro invocation
+   |
+   = note: this error originates in the macro `Type` which comes from the expansion of the macro `create` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: use the path separator to refer to an item
+   |
+LL -         Type!().new(0)
+LL +         <Type!()>::new(0)
+   |
+
+error[E0423]: expected value, found type alias `Alias`
+  --> $DIR/dot-notation-type-namespace-suggest-path-sep.rs:43:9
+   |
+LL |         Alias
+   |         ^^^^^
+...
+LL |     let _ = create!(macro method alias);
+   |             --------------------------- in this macro invocation
+   |
+   = note: this error originates in the macro `Type` which comes from the expansion of the macro `create` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: use the path separator to refer to an item
+   |
+LL -         Type!(alias).new(0)
+LL +         <Type!(alias)>::new(0)
+   |
+
+error[E0423]: expected value, found type alias `Alias`
+  --> $DIR/dot-notation-type-namespace-suggest-path-sep.rs:73:9
+   |
+LL |         $Ty.foo
+   |         ^^^
+...
+LL |     let _ = check_ty!(Alias);
+   |             ---------------- in this macro invocation
+   |
+   = note: this error originates in the macro `check_ty` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: use the path separator to refer to an item
+   |
+LL -         $Ty.foo
+LL +         $Ty::foo
+   |
+
+error[E0423]: expected value, found type alias `Alias`
+  --> $DIR/dot-notation-type-namespace-suggest-path-sep.rs:80:9
+   |
+LL |         Alias.$Ident
+   |         ^^^^^
+...
+LL |     let _ = check_ident!(foo);
+   |             ----------------- in this macro invocation
+   |
+   = note: this error originates in the macro `check_ident` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: use the path separator to refer to an item
+   |
+LL -         Alias.$Ident
+LL +         <Alias>::$Ident
+   |
+
+error[E0423]: expected value, found type alias `Alias`
+  --> $DIR/dot-notation-type-namespace-suggest-path-sep.rs:87:9
+   |
+LL |         $Ty.$Ident
+   |         ^^^
+...
+LL |     let _ = check_ty_ident!(Alias, foo);
+   |             --------------------------- in this macro invocation
+   |
+   = note: this error originates in the macro `check_ty_ident` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: use the path separator to refer to an item
+   |
+LL -         $Ty.$Ident
+LL +         <$Ty>::$Ident
+   |
+
+error: aborting due to 17 previous errors
+
+For more information about this error, try `rustc --explain E0423`.
diff --git a/tests/ui/resolve/enum-expected-value-suggest-variants.rs b/tests/ui/resolve/enum-expected-value-suggest-variants.rs
new file mode 100644
index 0000000000000..9f86a0a1ecc76
--- /dev/null
+++ b/tests/ui/resolve/enum-expected-value-suggest-variants.rs
@@ -0,0 +1,58 @@
+enum Foo {
+    //~^ HELP consider importing this tuple variant
+    A(u32),
+    B(u32),
+}
+
+enum Bar {
+    C(u32),
+    D(u32),
+    E,
+    F,
+}
+
+fn main() {
+    let _: Foo = Foo(0);
+    //~^ ERROR expected function
+    //~| HELP try to construct one of the enum's variants
+
+    let _: Foo = Foo.A(0);
+    //~^ ERROR expected value, found enum `Foo`
+    //~| HELP use the path separator to refer to a variant
+
+    let _: Foo = Foo.Bad(0);
+    //~^ ERROR expected value, found enum `Foo`
+    //~| HELP the following enum variants are available
+
+    let _: Bar = Bar(0);
+    //~^ ERROR expected function
+    //~| HELP try to construct one of the enum's variants
+    //~| HELP you might have meant to construct one of the enum's non-tuple variants
+
+    let _: Bar = Bar.C(0);
+    //~^ ERROR expected value, found enum `Bar`
+    //~| HELP use the path separator to refer to a variant
+
+    let _: Bar = Bar.E;
+    //~^ ERROR expected value, found enum `Bar`
+    //~| HELP use the path separator to refer to a variant
+
+    let _: Bar = Bar.Bad(0);
+    //~^ ERROR expected value, found enum `Bar`
+    //~| HELP you might have meant to use one of the following enum variants
+    //~| HELP alternatively, the following enum variants are also available
+
+    let _: Bar = Bar.Bad;
+    //~^ ERROR expected value, found enum `Bar`
+    //~| HELP you might have meant to use one of the following enum variants
+    //~| HELP alternatively, the following enum variants are also available
+
+    match Foo::A(42) {
+        A(..) => {}
+        //~^ ERROR cannot find tuple struct or tuple variant `A` in this scope
+        Foo(..) => {}
+        //~^ ERROR expected tuple struct or tuple variant
+        //~| HELP try to match against one of the enum's variants
+        _ => {}
+    }
+}
diff --git a/tests/ui/resolve/enum-expected-value-suggest-variants.stderr b/tests/ui/resolve/enum-expected-value-suggest-variants.stderr
new file mode 100644
index 0000000000000..f99aea0493a53
--- /dev/null
+++ b/tests/ui/resolve/enum-expected-value-suggest-variants.stderr
@@ -0,0 +1,244 @@
+error[E0423]: expected value, found enum `Foo`
+  --> $DIR/enum-expected-value-suggest-variants.rs:19:18
+   |
+LL |     let _: Foo = Foo.A(0);
+   |                  ^^^
+   |
+note: the enum is defined here
+  --> $DIR/enum-expected-value-suggest-variants.rs:1:1
+   |
+LL | / enum Foo {
+LL | |
+LL | |     A(u32),
+LL | |     B(u32),
+LL | | }
+   | |_^
+help: use the path separator to refer to a variant
+   |
+LL -     let _: Foo = Foo.A(0);
+LL +     let _: Foo = Foo::A(0);
+   |
+
+error[E0423]: expected value, found enum `Foo`
+  --> $DIR/enum-expected-value-suggest-variants.rs:23:18
+   |
+LL |     let _: Foo = Foo.Bad(0);
+   |                  ^^^
+   |
+note: the enum is defined here
+  --> $DIR/enum-expected-value-suggest-variants.rs:1:1
+   |
+LL | / enum Foo {
+LL | |
+LL | |     A(u32),
+LL | |     B(u32),
+LL | | }
+   | |_^
+help: the following enum variants are available
+   |
+LL -     let _: Foo = Foo.Bad(0);
+LL +     let _: Foo = (Foo::A(/* fields */)).Bad(0);
+   |
+LL -     let _: Foo = Foo.Bad(0);
+LL +     let _: Foo = (Foo::B(/* fields */)).Bad(0);
+   |
+
+error[E0423]: expected value, found enum `Bar`
+  --> $DIR/enum-expected-value-suggest-variants.rs:32:18
+   |
+LL |     let _: Bar = Bar.C(0);
+   |                  ^^^
+   |
+note: the enum is defined here
+  --> $DIR/enum-expected-value-suggest-variants.rs:7:1
+   |
+LL | / enum Bar {
+LL | |     C(u32),
+LL | |     D(u32),
+LL | |     E,
+LL | |     F,
+LL | | }
+   | |_^
+help: use the path separator to refer to a variant
+   |
+LL -     let _: Bar = Bar.C(0);
+LL +     let _: Bar = Bar::C(0);
+   |
+
+error[E0423]: expected value, found enum `Bar`
+  --> $DIR/enum-expected-value-suggest-variants.rs:36:18
+   |
+LL |     let _: Bar = Bar.E;
+   |                  ^^^
+   |
+note: the enum is defined here
+  --> $DIR/enum-expected-value-suggest-variants.rs:7:1
+   |
+LL | / enum Bar {
+LL | |     C(u32),
+LL | |     D(u32),
+LL | |     E,
+LL | |     F,
+LL | | }
+   | |_^
+help: use the path separator to refer to a variant
+   |
+LL -     let _: Bar = Bar.E;
+LL +     let _: Bar = Bar::E;
+   |
+
+error[E0423]: expected value, found enum `Bar`
+  --> $DIR/enum-expected-value-suggest-variants.rs:40:18
+   |
+LL |     let _: Bar = Bar.Bad(0);
+   |                  ^^^
+   |
+note: the enum is defined here
+  --> $DIR/enum-expected-value-suggest-variants.rs:7:1
+   |
+LL | / enum Bar {
+LL | |     C(u32),
+LL | |     D(u32),
+LL | |     E,
+LL | |     F,
+LL | | }
+   | |_^
+help: you might have meant to use one of the following enum variants
+   |
+LL -     let _: Bar = Bar.Bad(0);
+LL +     let _: Bar = Bar::E.Bad(0);
+   |
+LL -     let _: Bar = Bar.Bad(0);
+LL +     let _: Bar = Bar::F.Bad(0);
+   |
+help: alternatively, the following enum variants are also available
+   |
+LL -     let _: Bar = Bar.Bad(0);
+LL +     let _: Bar = (Bar::C(/* fields */)).Bad(0);
+   |
+LL -     let _: Bar = Bar.Bad(0);
+LL +     let _: Bar = (Bar::D(/* fields */)).Bad(0);
+   |
+
+error[E0423]: expected value, found enum `Bar`
+  --> $DIR/enum-expected-value-suggest-variants.rs:45:18
+   |
+LL |     let _: Bar = Bar.Bad;
+   |                  ^^^
+   |
+note: the enum is defined here
+  --> $DIR/enum-expected-value-suggest-variants.rs:7:1
+   |
+LL | / enum Bar {
+LL | |     C(u32),
+LL | |     D(u32),
+LL | |     E,
+LL | |     F,
+LL | | }
+   | |_^
+help: you might have meant to use one of the following enum variants
+   |
+LL -     let _: Bar = Bar.Bad;
+LL +     let _: Bar = Bar::E.Bad;
+   |
+LL -     let _: Bar = Bar.Bad;
+LL +     let _: Bar = Bar::F.Bad;
+   |
+help: alternatively, the following enum variants are also available
+   |
+LL -     let _: Bar = Bar.Bad;
+LL +     let _: Bar = (Bar::C(/* fields */)).Bad;
+   |
+LL -     let _: Bar = Bar.Bad;
+LL +     let _: Bar = (Bar::D(/* fields */)).Bad;
+   |
+
+error[E0531]: cannot find tuple struct or tuple variant `A` in this scope
+  --> $DIR/enum-expected-value-suggest-variants.rs:51:9
+   |
+LL |         A(..) => {}
+   |         ^ not found in this scope
+   |
+help: consider importing this tuple variant
+   |
+LL + use Foo::A;
+   |
+
+error[E0532]: expected tuple struct or tuple variant, found enum `Foo`
+  --> $DIR/enum-expected-value-suggest-variants.rs:53:9
+   |
+LL |         Foo(..) => {}
+   |         ^^^
+   |
+note: the enum is defined here
+  --> $DIR/enum-expected-value-suggest-variants.rs:1:1
+   |
+LL | / enum Foo {
+LL | |
+LL | |     A(u32),
+LL | |     B(u32),
+LL | | }
+   | |_^
+help: try to match against one of the enum's variants
+   |
+LL -         Foo(..) => {}
+LL +         Foo::A(..) => {}
+   |
+LL -         Foo(..) => {}
+LL +         Foo::B(..) => {}
+   |
+
+error[E0423]: expected function, tuple struct or tuple variant, found enum `Foo`
+  --> $DIR/enum-expected-value-suggest-variants.rs:15:18
+   |
+LL |     let _: Foo = Foo(0);
+   |                  ^^^
+   |
+note: the enum is defined here
+  --> $DIR/enum-expected-value-suggest-variants.rs:1:1
+   |
+LL | / enum Foo {
+LL | |
+LL | |     A(u32),
+LL | |     B(u32),
+LL | | }
+   | |_^
+help: try to construct one of the enum's variants
+   |
+LL -     let _: Foo = Foo(0);
+LL +     let _: Foo = Foo::A(0);
+   |
+LL -     let _: Foo = Foo(0);
+LL +     let _: Foo = Foo::B(0);
+   |
+
+error[E0423]: expected function, tuple struct or tuple variant, found enum `Bar`
+  --> $DIR/enum-expected-value-suggest-variants.rs:27:18
+   |
+LL |     let _: Bar = Bar(0);
+   |                  ^^^
+   |
+   = help: you might have meant to construct one of the enum's non-tuple variants
+note: the enum is defined here
+  --> $DIR/enum-expected-value-suggest-variants.rs:7:1
+   |
+LL | / enum Bar {
+LL | |     C(u32),
+LL | |     D(u32),
+LL | |     E,
+LL | |     F,
+LL | | }
+   | |_^
+help: try to construct one of the enum's variants
+   |
+LL -     let _: Bar = Bar(0);
+LL +     let _: Bar = Bar::C(0);
+   |
+LL -     let _: Bar = Bar(0);
+LL +     let _: Bar = Bar::D(0);
+   |
+
+error: aborting due to 10 previous errors
+
+Some errors have detailed explanations: E0423, E0531, E0532.
+For more information about an error, try `rustc --explain E0423`.
diff --git a/tests/ui/resolve/issue-22692.rs b/tests/ui/resolve/issue-22692.rs
deleted file mode 100644
index 31a76261408ef..0000000000000
--- a/tests/ui/resolve/issue-22692.rs
+++ /dev/null
@@ -1,60 +0,0 @@
-fn main() {
-    let _ = String.new();
-    //~^ ERROR expected value, found struct `String`
-    //~| HELP use the path separator
-
-    let _ = String.default;
-    //~^ ERROR expected value, found struct `String`
-    //~| HELP use the path separator
-
-    let _ = Vec::<()>.with_capacity(1);
-    //~^ ERROR expected value, found struct `Vec`
-    //~| HELP use the path separator
-}
-
-macro_rules! Type {
-    () => {
-        ::std::cell::Cell
-        //~^ ERROR expected value, found struct `std::cell::Cell`
-        //~| ERROR expected value, found struct `std::cell::Cell`
-        //~| ERROR expected value, found struct `std::cell::Cell`
-    };
-}
-
-macro_rules! create {
-    (type method) => {
-        Vec.new()
-        //~^ ERROR expected value, found struct `Vec`
-        //~| HELP use the path separator
-    };
-    (type field) => {
-        Vec.new
-        //~^ ERROR expected value, found struct `Vec`
-        //~| HELP use the path separator
-    };
-    (macro method) => {
-        Type!().new(0)
-        //~^ HELP use the path separator
-    };
-}
-
-fn interaction_with_macros() {
-    //
-    // Verify that we do not only suggest to replace `.` with `::` if the receiver is a
-    // macro call but that we also correctly suggest to surround it with angle brackets.
-    //
-
-    Type!().get();
-    //~^ HELP use the path separator
-
-    Type! {}.get;
-    //~^ HELP use the path separator
-
-    //
-    // Ensure that the suggestion is shown for expressions inside of macro definitions.
-    //
-
-    let _ = create!(type method);
-    let _ = create!(type field);
-    let _ = create!(macro method);
-}
diff --git a/tests/ui/resolve/issue-22692.stderr b/tests/ui/resolve/issue-22692.stderr
deleted file mode 100644
index 546f12b35c156..0000000000000
--- a/tests/ui/resolve/issue-22692.stderr
+++ /dev/null
@@ -1,119 +0,0 @@
-error[E0423]: expected value, found struct `String`
-  --> $DIR/issue-22692.rs:2:13
-   |
-LL |     let _ = String.new();
-   |             ^^^^^^
-   |
-help: use the path separator to refer to an item
-   |
-LL -     let _ = String.new();
-LL +     let _ = String::new();
-   |
-
-error[E0423]: expected value, found struct `String`
-  --> $DIR/issue-22692.rs:6:13
-   |
-LL |     let _ = String.default;
-   |             ^^^^^^
-   |
-help: use the path separator to refer to an item
-   |
-LL -     let _ = String.default;
-LL +     let _ = String::default;
-   |
-
-error[E0423]: expected value, found struct `Vec`
-  --> $DIR/issue-22692.rs:10:13
-   |
-LL |     let _ = Vec::<()>.with_capacity(1);
-   |             ^^^^^^^^^
-   |
-help: use the path separator to refer to an item
-   |
-LL -     let _ = Vec::<()>.with_capacity(1);
-LL +     let _ = Vec::<()>::with_capacity(1);
-   |
-
-error[E0423]: expected value, found struct `std::cell::Cell`
-  --> $DIR/issue-22692.rs:17:9
-   |
-LL |         ::std::cell::Cell
-   |         ^^^^^^^^^^^^^^^^^
-...
-LL |     Type!().get();
-   |     ------- in this macro invocation
-   |
-   = note: this error originates in the macro `Type` (in Nightly builds, run with -Z macro-backtrace for more info)
-help: use the path separator to refer to an item
-   |
-LL -     Type!().get();
-LL +     <Type!()>::get();
-   |
-
-error[E0423]: expected value, found struct `std::cell::Cell`
-  --> $DIR/issue-22692.rs:17:9
-   |
-LL |         ::std::cell::Cell
-   |         ^^^^^^^^^^^^^^^^^
-...
-LL |     Type! {}.get;
-   |     -------- in this macro invocation
-   |
-   = note: this error originates in the macro `Type` (in Nightly builds, run with -Z macro-backtrace for more info)
-help: use the path separator to refer to an item
-   |
-LL -     Type! {}.get;
-LL +     <Type! {}>::get;
-   |
-
-error[E0423]: expected value, found struct `Vec`
-  --> $DIR/issue-22692.rs:26:9
-   |
-LL |         Vec.new()
-   |         ^^^
-...
-LL |     let _ = create!(type method);
-   |             -------------------- in this macro invocation
-   |
-   = note: this error originates in the macro `create` (in Nightly builds, run with -Z macro-backtrace for more info)
-help: use the path separator to refer to an item
-   |
-LL -         Vec.new()
-LL +         Vec::new()
-   |
-
-error[E0423]: expected value, found struct `Vec`
-  --> $DIR/issue-22692.rs:31:9
-   |
-LL |         Vec.new
-   |         ^^^
-...
-LL |     let _ = create!(type field);
-   |             ------------------- in this macro invocation
-   |
-   = note: this error originates in the macro `create` (in Nightly builds, run with -Z macro-backtrace for more info)
-help: use the path separator to refer to an item
-   |
-LL -         Vec.new
-LL +         Vec::new
-   |
-
-error[E0423]: expected value, found struct `std::cell::Cell`
-  --> $DIR/issue-22692.rs:17:9
-   |
-LL |         ::std::cell::Cell
-   |         ^^^^^^^^^^^^^^^^^
-...
-LL |     let _ = create!(macro method);
-   |             --------------------- in this macro invocation
-   |
-   = note: this error originates in the macro `Type` which comes from the expansion of the macro `create` (in Nightly builds, run with -Z macro-backtrace for more info)
-help: use the path separator to refer to an item
-   |
-LL -         Type!().new(0)
-LL +         <Type!()>::new(0)
-   |
-
-error: aborting due to 8 previous errors
-
-For more information about this error, try `rustc --explain E0423`.
diff --git a/tests/ui/type/pattern_types/range_patterns.stderr b/tests/ui/type/pattern_types/range_patterns.stderr
index 7da8cfd4dbc2d..690592ba0b8da 100644
--- a/tests/ui/type/pattern_types/range_patterns.stderr
+++ b/tests/ui/type/pattern_types/range_patterns.stderr
@@ -31,6 +31,7 @@ error: layout_of(NonZero<u32>) = Layout {
                    valid_range: 1..=4294967295,
                },
            ),
+           uninhabited: false,
            variants: Single {
                index: 0,
            },
@@ -69,6 +70,7 @@ error: layout_of((u32) is 1..=) = Layout {
                    valid_range: 1..=4294967295,
                },
            ),
+           uninhabited: false,
            variants: Single {
                index: 0,
            },
@@ -105,6 +107,7 @@ error: layout_of(Option<(u32) is 1..=>) = Layout {
                ],
            },
            largest_niche: None,
+           uninhabited: false,
            variants: Multiple {
                tag: Initialized {
                    value: Int(
@@ -134,6 +137,7 @@ error: layout_of(Option<(u32) is 1..=>) = Layout {
                            memory_index: [],
                        },
                        largest_niche: None,
+                       uninhabited: false,
                        variants: Single {
                            index: 0,
                        },
@@ -174,6 +178,7 @@ error: layout_of(Option<(u32) is 1..=>) = Layout {
                                valid_range: 1..=4294967295,
                            },
                        ),
+                       uninhabited: false,
                        variants: Single {
                            index: 1,
                        },
@@ -216,6 +221,7 @@ error: layout_of(Option<NonZero<u32>>) = Layout {
                ],
            },
            largest_niche: None,
+           uninhabited: false,
            variants: Multiple {
                tag: Initialized {
                    value: Int(
@@ -245,6 +251,7 @@ error: layout_of(Option<NonZero<u32>>) = Layout {
                            memory_index: [],
                        },
                        largest_niche: None,
+                       uninhabited: false,
                        variants: Single {
                            index: 0,
                        },
@@ -285,6 +292,7 @@ error: layout_of(Option<NonZero<u32>>) = Layout {
                                valid_range: 1..=4294967295,
                            },
                        ),
+                       uninhabited: false,
                        variants: Single {
                            index: 1,
                        },
@@ -336,6 +344,7 @@ error: layout_of(NonZeroU32New) = Layout {
                    valid_range: 1..=4294967295,
                },
            ),
+           uninhabited: false,
            variants: Single {
                index: 0,
            },
diff --git a/tests/ui/uninhabited/uninhabited-transparent-return-abi.rs b/tests/ui/uninhabited/uninhabited-transparent-return-abi.rs
new file mode 100644
index 0000000000000..2c2788a3e5642
--- /dev/null
+++ b/tests/ui/uninhabited/uninhabited-transparent-return-abi.rs
@@ -0,0 +1,33 @@
+//@ run-pass
+//@ needs-unwind
+// See https://github.com/rust-lang/rust/issues/135802
+
+enum Void {}
+
+// Should be ABI-compatible with T, but wasn't prior to the PR adding this test.
+#[repr(transparent)]
+struct NoReturn<T>(T, Void);
+
+// Returned by invisible reference (in most ABIs)
+#[allow(dead_code)]
+struct Large(u64, u64, u64);
+
+// Prior to the PR adding this test, this function had a different ABI than
+// `fn() -> Large` (on `x86_64-unknown-linux-gnu` at least), so calling it as `fn() -> Large`
+// would pass the return place pointer in rdi and `correct` in rsi, but the function
+// would expect `correct` in rdi.
+fn never(correct: &mut bool) -> NoReturn<Large> {
+    *correct = true;
+    panic!("catch this")
+}
+
+fn main() {
+    let mut correct = false;
+    let never: fn(&mut bool) -> NoReturn<Large> = never;
+    // Safety: `NoReturn<Large>` is a `repr(transparent)` wrapper around `Large`,
+    // so they should be ABI-compatible.
+    let never: fn(&mut bool) -> Large = unsafe { std::mem::transmute(never) };
+    let result = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| never(&mut correct)));
+    assert!(result.is_err(), "function should have panicked");
+    assert!(correct, "function should have stored `true` into `correct`");
+}