about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2025-01-23 12:39:00 +0000
committerbors <bors@rust-lang.org>2025-01-23 12:39:00 +0000
commit99768c80a1c094a5cfc3b25a04e7a99de7210eae (patch)
tree95ad7b6fb6b1e0eb5455be41701b8207027b5286
parentfc0094f8d4eb91637ff540be7d9d87bfcdd2a208 (diff)
parent4b3d7ef888ac0b01a0964c2f2a64426f0191a46c (diff)
Auto merge of #135921 - matthiaskrgr:rollup-5mzn76m, r=matthiaskrgr
Rollup of 9 pull requests

Successful merges:

 - #134746 (Don't ICE in coerce when autoderef fails to structurally normalize non-WF type in new solver)
 - #135552 ([AIX] Lint on structs that have a different alignment in AIX's C ABI)
 - #135779 (CI: free disk on linux arm runner)
 - #135790 (Update windows-gnu targets to set `DebuginfoKind::DWARF`)
 - #135879 (fix outdated file path ref in llvm)
 - #135883 (Remove erroneous `unsafe` in `BTreeSet::upper_bound_mut`)
 - #135884 (remove implied end of slice)
 - #135887 (improvements on `build_steps::test` implementation)
 - #135898 (rustdoc-json-types: Finalize dyn compatibility renaming)

r? `@ghost`
`@rustbot` modify labels: rollup
-rw-r--r--compiler/rustc_hir_typeck/src/coercion.rs14
-rw-r--r--compiler/rustc_lint/messages.ftl2
-rw-r--r--compiler/rustc_lint/src/lints.rs4
-rw-r--r--compiler/rustc_lint/src/types.rs134
-rw-r--r--compiler/rustc_parse_format/src/lib.rs2
-rw-r--r--compiler/rustc_target/src/spec/base/windows_gnu.rs2
-rw-r--r--compiler/rustc_target/src/spec/base/windows_gnullvm.rs2
-rw-r--r--library/alloc/src/collections/btree/set.rs8
-rw-r--r--src/bootstrap/src/core/build_steps/llvm.rs2
-rw-r--r--src/bootstrap/src/core/build_steps/test.rs96
-rw-r--r--src/bootstrap/src/core/builder/cargo.rs4
-rw-r--r--src/bootstrap/src/core/config/tests.rs2
-rw-r--r--src/ci/github-actions/jobs.yml2
-rw-r--r--src/rustdoc-json-types/lib.rs3
-rw-r--r--tests/ui/debuginfo/windows_gnu_split_debuginfo_off.rs29
-rw-r--r--tests/ui/debuginfo/windows_gnu_split_debuginfo_packed.aarch64_gl.stderr4
-rw-r--r--tests/ui/debuginfo/windows_gnu_split_debuginfo_packed.i686_g.stderr4
-rw-r--r--tests/ui/debuginfo/windows_gnu_split_debuginfo_packed.i686_gl.stderr4
-rw-r--r--tests/ui/debuginfo/windows_gnu_split_debuginfo_packed.i686_uwp_g.stderr4
-rw-r--r--tests/ui/debuginfo/windows_gnu_split_debuginfo_packed.rs29
-rw-r--r--tests/ui/debuginfo/windows_gnu_split_debuginfo_packed.x86_64_g.stderr4
-rw-r--r--tests/ui/debuginfo/windows_gnu_split_debuginfo_packed.x86_64_gl.stderr4
-rw-r--r--tests/ui/debuginfo/windows_gnu_split_debuginfo_packed.x86_64_uwp_g.stderr4
-rw-r--r--tests/ui/debuginfo/windows_gnu_split_debuginfo_unpacked.aarch64_gl.stderr4
-rw-r--r--tests/ui/debuginfo/windows_gnu_split_debuginfo_unpacked.i686_g.stderr4
-rw-r--r--tests/ui/debuginfo/windows_gnu_split_debuginfo_unpacked.i686_gl.stderr4
-rw-r--r--tests/ui/debuginfo/windows_gnu_split_debuginfo_unpacked.i686_uwp_g.stderr4
-rw-r--r--tests/ui/debuginfo/windows_gnu_split_debuginfo_unpacked.rs29
-rw-r--r--tests/ui/debuginfo/windows_gnu_split_debuginfo_unpacked.x86_64_g.stderr4
-rw-r--r--tests/ui/debuginfo/windows_gnu_split_debuginfo_unpacked.x86_64_gl.stderr4
-rw-r--r--tests/ui/debuginfo/windows_gnu_split_debuginfo_unpacked.x86_64_uwp_g.stderr4
-rw-r--r--tests/ui/layout/reprc-power-alignment.rs152
-rw-r--r--tests/ui/layout/reprc-power-alignment.stderr112
-rw-r--r--tests/ui/lint/clashing-extern-fn.rs1
-rw-r--r--tests/ui/lint/clashing-extern-fn.stderr22
-rw-r--r--tests/ui/traits/next-solver/non-wf-in-coerce-pointers.rs17
-rw-r--r--tests/ui/traits/next-solver/non-wf-in-coerce-pointers.stderr39
37 files changed, 669 insertions, 94 deletions
diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs
index 3c25f4a8b7c..47abba1cc29 100644
--- a/compiler/rustc_hir_typeck/src/coercion.rs
+++ b/compiler/rustc_hir_typeck/src/coercion.rs
@@ -461,9 +461,17 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
         // to the target type), since that should be the least
         // confusing.
         let Some(InferOk { value: ty, mut obligations }) = found else {
-            let err = first_error.expect("coerce_borrowed_pointer had no error");
-            debug!("coerce_borrowed_pointer: failed with err = {:?}", err);
-            return Err(err);
+            if let Some(first_error) = first_error {
+                debug!("coerce_borrowed_pointer: failed with err = {:?}", first_error);
+                return Err(first_error);
+            } else {
+                // This may happen in the new trait solver since autoderef requires
+                // the pointee to be structurally normalizable, or else it'll just bail.
+                // So when we have a type like `&<not well formed>`, then we get no
+                // autoderef steps (even though there should be at least one). That means
+                // we get no type mismatches, since the loop above just exits early.
+                return Err(TypeError::Mismatch);
+            }
         };
 
         if ty == a && mt_a.mutbl.is_not() && autoderef.step_count() == 1 {
diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl
index 14f0787de3e..64c8f00cc83 100644
--- a/compiler/rustc_lint/messages.ftl
+++ b/compiler/rustc_lint/messages.ftl
@@ -972,6 +972,8 @@ lint_unused_result = unused result of type `{$ty}`
 
 lint_use_let_underscore_ignore_suggestion = use `let _ = ...` to ignore the expression or result
 
+lint_uses_power_alignment = repr(C) does not follow the power alignment rule. This may affect platform C ABI compatibility for this type
+
 lint_variant_size_differences =
     enum variant is more than three times larger ({$largest} bytes) than the next largest
 
diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs
index fea3d67ffeb..2f610802ff5 100644
--- a/compiler/rustc_lint/src/lints.rs
+++ b/compiler/rustc_lint/src/lints.rs
@@ -1695,6 +1695,10 @@ pub(crate) struct OverflowingLiteral<'a> {
 }
 
 #[derive(LintDiagnostic)]
+#[diag(lint_uses_power_alignment)]
+pub(crate) struct UsesPowerAlignment;
+
+#[derive(LintDiagnostic)]
 #[diag(lint_unused_comparisons)]
 pub(crate) struct UnusedComparisons;
 
diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs
index 3bd27a224e7..0757e6840c6 100644
--- a/compiler/rustc_lint/src/types.rs
+++ b/compiler/rustc_lint/src/types.rs
@@ -1,14 +1,15 @@
 use std::iter;
 use std::ops::ControlFlow;
 
-use rustc_abi::{BackendRepr, ExternAbi, TagEncoding, Variants, WrappingRange};
+use rustc_abi::{BackendRepr, ExternAbi, TagEncoding, VariantIdx, Variants, WrappingRange};
 use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::DiagMessage;
 use rustc_hir::{Expr, ExprKind, LangItem};
 use rustc_middle::bug;
 use rustc_middle::ty::layout::{LayoutOf, SizeSkeleton};
 use rustc_middle::ty::{
-    self, AdtKind, GenericArgsRef, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt,
+    self, Adt, AdtKind, GenericArgsRef, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable,
+    TypeVisitableExt,
 };
 use rustc_session::{declare_lint, declare_lint_pass, impl_lint_pass};
 use rustc_span::def_id::LocalDefId;
@@ -23,7 +24,7 @@ use crate::lints::{
     AmbiguousWidePointerComparisonsAddrSuggestion, AtomicOrderingFence, AtomicOrderingLoad,
     AtomicOrderingStore, ImproperCTypes, InvalidAtomicOrderingDiag, InvalidNanComparisons,
     InvalidNanComparisonsSuggestion, UnpredictableFunctionPointerComparisons,
-    UnpredictableFunctionPointerComparisonsSuggestion, UnusedComparisons,
+    UnpredictableFunctionPointerComparisonsSuggestion, UnusedComparisons, UsesPowerAlignment,
     VariantSizeDifferencesDiag,
 };
 use crate::{LateContext, LateLintPass, LintContext, fluent_generated as fluent};
@@ -727,7 +728,60 @@ declare_lint! {
     "proper use of libc types in foreign item definitions"
 }
 
-declare_lint_pass!(ImproperCTypesDefinitions => [IMPROPER_CTYPES_DEFINITIONS]);
+declare_lint! {
+    /// The `uses_power_alignment` lint detects specific `repr(C)`
+    /// aggregates on AIX.
+    /// In its platform C ABI, AIX uses the "power" (as in PowerPC) alignment
+    /// rule (detailed in https://www.ibm.com/docs/en/xl-c-and-cpp-aix/16.1?topic=data-using-alignment-modes#alignment),
+    /// which can also be set for XLC by `#pragma align(power)` or
+    /// `-qalign=power`. Aggregates with a floating-point type as the
+    /// recursively first field (as in "at offset 0") modify the layout of
+    /// *subsequent* fields of the associated structs to use an alignment value
+    /// where the floating-point type is aligned on a 4-byte boundary.
+    ///
+    /// The power alignment rule for structs needed for C compatibility is
+    /// unimplementable within `repr(C)` in the compiler without building in
+    /// handling of references to packed fields and infectious nested layouts,
+    /// so a warning is produced in these situations.
+    ///
+    /// ### Example
+    ///
+    /// ```rust,ignore (fails on non-powerpc64-ibm-aix)
+    /// #[repr(C)]
+    /// pub struct Floats {
+    ///     a: f64,
+    ///     b: u8,
+    ///     c: f64,
+    /// }
+    /// ```
+    ///
+    /// This will produce:
+    ///
+    /// ```text
+    /// warning: repr(C) does not follow the power alignment rule. This may affect platform C ABI compatibility for this type
+    ///  --> <source>:5:3
+    ///   |
+    /// 5 |   c: f64,
+    ///   |   ^^^^^^
+    ///   |
+    ///   = note: `#[warn(uses_power_alignment)]` on by default
+    /// ```
+    ///
+    /// ### Explanation
+    ///
+    /// The power alignment rule specifies that the above struct has the
+    /// following alignment:
+    ///  - offset_of!(Floats, a) == 0
+    ///  - offset_of!(Floats, b) == 8
+    ///  - offset_of!(Floats, c) == 12
+    /// However, rust currently aligns `c` at offset_of!(Floats, c) == 16.
+    /// Thus, a warning should be produced for the above struct in this case.
+    USES_POWER_ALIGNMENT,
+    Warn,
+    "Structs do not follow the power alignment rule under repr(C)"
+}
+
+declare_lint_pass!(ImproperCTypesDefinitions => [IMPROPER_CTYPES_DEFINITIONS, USES_POWER_ALIGNMENT]);
 
 #[derive(Clone, Copy)]
 pub(crate) enum CItemKind {
@@ -1539,6 +1593,71 @@ impl ImproperCTypesDefinitions {
             vis.check_type_for_ffi_and_report_errors(span, fn_ptr_ty, true, false);
         }
     }
+
+    fn check_arg_for_power_alignment<'tcx>(
+        &mut self,
+        cx: &LateContext<'tcx>,
+        ty: Ty<'tcx>,
+    ) -> bool {
+        // Structs (under repr(C)) follow the power alignment rule if:
+        //   - the first field of the struct is a floating-point type that
+        //     is greater than 4-bytes, or
+        //   - the first field of the struct is an aggregate whose
+        //     recursively first field is a floating-point type greater than
+        //     4 bytes.
+        if cx.tcx.sess.target.os != "aix" {
+            return false;
+        }
+        if ty.is_floating_point() && ty.primitive_size(cx.tcx).bytes() > 4 {
+            return true;
+        } else if let Adt(adt_def, _) = ty.kind()
+            && adt_def.is_struct()
+        {
+            let struct_variant = adt_def.variant(VariantIdx::ZERO);
+            // Within a nested struct, all fields are examined to correctly
+            // report if any fields after the nested struct within the
+            // original struct are misaligned.
+            for struct_field in &struct_variant.fields {
+                let field_ty = cx.tcx.type_of(struct_field.did).instantiate_identity();
+                if self.check_arg_for_power_alignment(cx, field_ty) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    fn check_struct_for_power_alignment<'tcx>(
+        &mut self,
+        cx: &LateContext<'tcx>,
+        item: &'tcx hir::Item<'tcx>,
+    ) {
+        let adt_def = cx.tcx.adt_def(item.owner_id.to_def_id());
+        if adt_def.repr().c()
+            && !adt_def.repr().packed()
+            && cx.tcx.sess.target.os == "aix"
+            && !adt_def.all_fields().next().is_none()
+        {
+            let struct_variant_data = item.expect_struct().0;
+            for (index, ..) in struct_variant_data.fields().iter().enumerate() {
+                // Struct fields (after the first field) are checked for the
+                // power alignment rule, as fields after the first are likely
+                // to be the fields that are misaligned.
+                if index != 0 {
+                    let first_field_def = struct_variant_data.fields()[index];
+                    let def_id = first_field_def.def_id;
+                    let ty = cx.tcx.type_of(def_id).instantiate_identity();
+                    if self.check_arg_for_power_alignment(cx, ty) {
+                        cx.emit_span_lint(
+                            USES_POWER_ALIGNMENT,
+                            first_field_def.span,
+                            UsesPowerAlignment,
+                        );
+                    }
+                }
+            }
+        }
+    }
 }
 
 /// `ImproperCTypesDefinitions` checks items outside of foreign items (e.g. stuff that isn't in
@@ -1562,8 +1681,13 @@ impl<'tcx> LateLintPass<'tcx> for ImproperCTypesDefinitions {
             }
             // See `check_fn`..
             hir::ItemKind::Fn { .. } => {}
+            // Structs are checked based on if they follow the power alignment
+            // rule (under repr(C)).
+            hir::ItemKind::Struct(..) => {
+                self.check_struct_for_power_alignment(cx, item);
+            }
             // See `check_field_def`..
-            hir::ItemKind::Union(..) | hir::ItemKind::Struct(..) | hir::ItemKind::Enum(..) => {}
+            hir::ItemKind::Union(..) | hir::ItemKind::Enum(..) => {}
             // Doesn't define something that can contain a external type to be checked.
             hir::ItemKind::Impl(..)
             | hir::ItemKind::TraitAlias(..)
diff --git a/compiler/rustc_parse_format/src/lib.rs b/compiler/rustc_parse_format/src/lib.rs
index 9eb335cb34c..9a3e79c16b4 100644
--- a/compiler/rustc_parse_format/src/lib.rs
+++ b/compiler/rustc_parse_format/src/lib.rs
@@ -545,7 +545,7 @@ impl<'a> Parser<'a> {
                 }
             }
         }
-        &self.input[start..self.input.len()]
+        &self.input[start..]
     }
 
     /// Parses an `Argument` structure, or what's contained within braces inside the format string.
diff --git a/compiler/rustc_target/src/spec/base/windows_gnu.rs b/compiler/rustc_target/src/spec/base/windows_gnu.rs
index e975102e238..d8b6ae8cf32 100644
--- a/compiler/rustc_target/src/spec/base/windows_gnu.rs
+++ b/compiler/rustc_target/src/spec/base/windows_gnu.rs
@@ -97,9 +97,9 @@ pub(crate) fn opts() -> TargetOptions {
         emit_debug_gdb_scripts: false,
         requires_uwtable: true,
         eh_frame_header: false,
+        debuginfo_kind: DebuginfoKind::Dwarf,
         // FIXME(davidtwco): Support Split DWARF on Windows GNU - may require LLVM changes to
         // output DWO, despite using DWARF, doesn't use ELF..
-        debuginfo_kind: DebuginfoKind::Pdb,
         supported_split_debuginfo: Cow::Borrowed(&[SplitDebuginfo::Off]),
         ..Default::default()
     }
diff --git a/compiler/rustc_target/src/spec/base/windows_gnullvm.rs b/compiler/rustc_target/src/spec/base/windows_gnullvm.rs
index 4f370ec8bd0..86e52117dbf 100644
--- a/compiler/rustc_target/src/spec/base/windows_gnullvm.rs
+++ b/compiler/rustc_target/src/spec/base/windows_gnullvm.rs
@@ -44,9 +44,9 @@ pub(crate) fn opts() -> TargetOptions {
         has_thread_local: true,
         crt_static_allows_dylibs: true,
         crt_static_respected: true,
+        debuginfo_kind: DebuginfoKind::Dwarf,
         // FIXME(davidtwco): Support Split DWARF on Windows GNU - may require LLVM changes to
         // output DWO, despite using DWARF, doesn't use ELF..
-        debuginfo_kind: DebuginfoKind::Pdb,
         supported_split_debuginfo: Cow::Borrowed(&[SplitDebuginfo::Off]),
         ..Default::default()
     }
diff --git a/library/alloc/src/collections/btree/set.rs b/library/alloc/src/collections/btree/set.rs
index 9660023d694..041f80c1f2c 100644
--- a/library/alloc/src/collections/btree/set.rs
+++ b/library/alloc/src/collections/btree/set.rs
@@ -1442,20 +1442,20 @@ impl<T, A: Allocator + Clone> BTreeSet<T, A> {
     ///
     /// let mut set = BTreeSet::from([1, 2, 3, 4]);
     ///
-    /// let mut cursor = unsafe { set.upper_bound_mut(Bound::Included(&3)) };
+    /// let mut cursor = set.upper_bound_mut(Bound::Included(&3));
     /// assert_eq!(cursor.peek_prev(), Some(&3));
     /// assert_eq!(cursor.peek_next(), Some(&4));
     ///
-    /// let mut cursor = unsafe { set.upper_bound_mut(Bound::Excluded(&3)) };
+    /// let mut cursor = set.upper_bound_mut(Bound::Excluded(&3));
     /// assert_eq!(cursor.peek_prev(), Some(&2));
     /// assert_eq!(cursor.peek_next(), Some(&3));
     ///
-    /// let mut cursor = unsafe { set.upper_bound_mut(Bound::Unbounded) };
+    /// let mut cursor = set.upper_bound_mut(Bound::Unbounded);
     /// assert_eq!(cursor.peek_prev(), Some(&4));
     /// assert_eq!(cursor.peek_next(), None);
     /// ```
     #[unstable(feature = "btree_cursors", issue = "107540")]
-    pub unsafe fn upper_bound_mut<Q: ?Sized>(&mut self, bound: Bound<&Q>) -> CursorMut<'_, T, A>
+    pub fn upper_bound_mut<Q: ?Sized>(&mut self, bound: Bound<&Q>) -> CursorMut<'_, T, A>
     where
         T: Borrow<Q> + Ord,
         Q: Ord,
diff --git a/src/bootstrap/src/core/build_steps/llvm.rs b/src/bootstrap/src/core/build_steps/llvm.rs
index cf55fff4078..3cf25373b89 100644
--- a/src/bootstrap/src/core/build_steps/llvm.rs
+++ b/src/bootstrap/src/core/build_steps/llvm.rs
@@ -1338,7 +1338,7 @@ impl Step for CrtBeginEnd {
             .file(crtbegin_src)
             .file(crtend_src);
 
-        // Those flags are defined in src/llvm-project/compiler-rt/lib/crt/CMakeLists.txt
+        // Those flags are defined in src/llvm-project/compiler-rt/lib/builtins/CMakeLists.txt
         // Currently only consumer of those objects is musl, which use .init_array/.fini_array
         // instead of .ctors/.dtors
         cfg.flag("-std=c11")
diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs
index 9f3e4d9cc89..0d3ab6ad97d 100644
--- a/src/bootstrap/src/core/build_steps/test.rs
+++ b/src/bootstrap/src/core/build_steps/test.rs
@@ -87,7 +87,7 @@ impl Step for CrateBootstrap {
             &[],
         );
         let crate_name = path.rsplit_once('/').unwrap().1;
-        run_cargo_test(cargo, &[], &[], crate_name, crate_name, compiler, bootstrap_host, builder);
+        run_cargo_test(cargo, &[], &[], crate_name, crate_name, bootstrap_host, builder);
     }
 }
 
@@ -143,7 +143,6 @@ You can skip linkcheck with --skip src/tools/linkchecker"
             &[],
             "linkchecker",
             "linkchecker self tests",
-            compiler,
             bootstrap_host,
             builder,
         );
@@ -312,7 +311,7 @@ impl Step for Cargo {
         );
 
         // NOTE: can't use `run_cargo_test` because we need to overwrite `PATH`
-        let mut cargo = prepare_cargo_test(cargo, &[], &[], "cargo", compiler, self.host, builder);
+        let mut cargo = prepare_cargo_test(cargo, &[], &[], "cargo", self.host, builder);
 
         // Don't run cross-compile tests, we may not have cross-compiled libstd libs
         // available.
@@ -397,7 +396,7 @@ impl Step for RustAnalyzer {
         cargo.env("SKIP_SLOW_TESTS", "1");
 
         cargo.add_rustc_lib_path(builder);
-        run_cargo_test(cargo, &[], &[], "rust-analyzer", "rust-analyzer", compiler, host, builder);
+        run_cargo_test(cargo, &[], &[], "rust-analyzer", "rust-analyzer", host, builder);
     }
 }
 
@@ -445,7 +444,7 @@ impl Step for Rustfmt {
 
         cargo.add_rustc_lib_path(builder);
 
-        run_cargo_test(cargo, &[], &[], "rustfmt", "rustfmt", compiler, host, builder);
+        run_cargo_test(cargo, &[], &[], "rustfmt", "rustfmt", host, builder);
     }
 }
 
@@ -565,7 +564,7 @@ impl Step for Miri {
 
         // We can NOT use `run_cargo_test` since Miri's integration tests do not use the usual test
         // harness and therefore do not understand the flags added by `add_flags_and_try_run_test`.
-        let mut cargo = prepare_cargo_test(cargo, &[], &[], "miri", host_compiler, host, builder);
+        let mut cargo = prepare_cargo_test(cargo, &[], &[], "miri", host, builder);
 
         // miri tests need to know about the stage sysroot
         cargo.env("MIRI_SYSROOT", &miri_sysroot);
@@ -713,16 +712,7 @@ impl Step for CompiletestTest {
             &[],
         );
         cargo.allow_features("test");
-        run_cargo_test(
-            cargo,
-            &[],
-            &[],
-            "compiletest",
-            "compiletest self test",
-            compiler,
-            host,
-            builder,
-        );
+        run_cargo_test(cargo, &[], &[], "compiletest", "compiletest self test", host, builder);
     }
 }
 
@@ -769,7 +759,7 @@ impl Step for Clippy {
         cargo.env("HOST_LIBS", host_libs);
 
         cargo.add_rustc_lib_path(builder);
-        let cargo = prepare_cargo_test(cargo, &[], &[], "clippy", compiler, host, builder);
+        let cargo = prepare_cargo_test(cargo, &[], &[], "clippy", host, builder);
 
         let _guard = builder.msg_sysroot_tool(Kind::Test, compiler.stage, "clippy", host, host);
 
@@ -1294,7 +1284,6 @@ impl Step for CrateRunMakeSupport {
             &[],
             "run-make-support",
             "run-make-support self test",
-            compiler,
             host,
             builder,
         );
@@ -1334,16 +1323,7 @@ impl Step for CrateBuildHelper {
             &[],
         );
         cargo.allow_features("test");
-        run_cargo_test(
-            cargo,
-            &[],
-            &[],
-            "build_helper",
-            "build_helper self test",
-            compiler,
-            host,
-            builder,
-        );
+        run_cargo_test(cargo, &[], &[], "build_helper", "build_helper self test", host, builder);
     }
 }
 
@@ -2540,19 +2520,17 @@ impl Step for CrateLibrustc {
 /// Given a `cargo test` subcommand, add the appropriate flags and run it.
 ///
 /// Returns whether the test succeeded.
-#[allow(clippy::too_many_arguments)] // FIXME: reduce the number of args and remove this.
 fn run_cargo_test<'a>(
-    cargo: impl Into<BootstrapCommand>,
+    cargo: builder::Cargo,
     libtest_args: &[&str],
     crates: &[String],
     primary_crate: &str,
     description: impl Into<Option<&'a str>>,
-    compiler: Compiler,
     target: TargetSelection,
     builder: &Builder<'_>,
 ) -> bool {
-    let mut cargo =
-        prepare_cargo_test(cargo, libtest_args, crates, primary_crate, compiler, target, builder);
+    let compiler = cargo.compiler();
+    let mut cargo = prepare_cargo_test(cargo, libtest_args, crates, primary_crate, target, builder);
     let _time = helpers::timeit(builder);
     let _group = description.into().and_then(|what| {
         builder.msg_sysroot_tool(Kind::Test, compiler.stage, what, compiler.host, target)
@@ -2573,15 +2551,15 @@ fn run_cargo_test<'a>(
 
 /// Given a `cargo test` subcommand, pass it the appropriate test flags given a `builder`.
 fn prepare_cargo_test(
-    cargo: impl Into<BootstrapCommand>,
+    cargo: builder::Cargo,
     libtest_args: &[&str],
     crates: &[String],
     primary_crate: &str,
-    compiler: Compiler,
     target: TargetSelection,
     builder: &Builder<'_>,
 ) -> BootstrapCommand {
-    let mut cargo = cargo.into();
+    let compiler = cargo.compiler();
+    let mut cargo: BootstrapCommand = cargo.into();
 
     // Propagate `--bless` if it has not already been set/unset
     // Any tools that want to use this should bless if `RUSTC_BLESS` is set to
@@ -2793,7 +2771,6 @@ impl Step for Crate {
             &self.crates,
             &self.crates[0],
             &*crate_description(&self.crates),
-            compiler,
             target,
             builder,
         );
@@ -2895,7 +2872,6 @@ impl Step for CrateRustdoc {
             &["rustdoc:0.0.0".to_string()],
             "rustdoc",
             "rustdoc",
-            compiler,
             target,
             builder,
         );
@@ -2956,7 +2932,6 @@ impl Step for CrateRustdocJsonTypes {
             &["rustdoc-json-types".to_string()],
             "rustdoc-json-types",
             "rustdoc-json-types",
-            compiler,
             target,
             builder,
         );
@@ -3113,23 +3088,25 @@ impl Step for Bootstrap {
         // Use `python -m unittest` manually if you want to pass arguments.
         check_bootstrap.delay_failure().run(builder);
 
-        let mut cmd = command(&builder.initial_cargo);
-        cmd.arg("test")
-            .current_dir(builder.src.join("src/bootstrap"))
-            .env("RUSTFLAGS", "--cfg test -Cdebuginfo=2")
+        let mut cargo = tool::prepare_tool_cargo(
+            builder,
+            compiler,
+            Mode::ToolBootstrap,
+            host,
+            Kind::Test,
+            "src/bootstrap",
+            SourceType::InTree,
+            &[],
+        );
+
+        cargo
+            .rustflag("-Cdebuginfo=2")
             .env("CARGO_TARGET_DIR", builder.out.join("bootstrap"))
-            .env("RUSTC_BOOTSTRAP", "1")
-            .env("RUSTDOC", builder.rustdoc(compiler))
-            .env("RUSTC", &builder.initial_rustc);
-        if let Some(flags) = option_env!("RUSTFLAGS") {
-            // Use the same rustc flags for testing as for "normal" compilation,
-            // so that Cargo doesn’t recompile the entire dependency graph every time:
-            // https://github.com/rust-lang/rust/issues/49215
-            cmd.env("RUSTFLAGS", flags);
-        }
+            .env("RUSTC_BOOTSTRAP", "1");
+
         // bootstrap tests are racy on directory creation so just run them one at a time.
         // Since there's not many this shouldn't be a problem.
-        run_cargo_test(cmd, &["--test-threads=1"], &[], "bootstrap", None, compiler, host, builder);
+        run_cargo_test(cargo, &["--test-threads=1"], &[], "bootstrap", None, host, builder);
     }
 
     fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
@@ -3254,7 +3231,7 @@ impl Step for RustInstaller {
             bootstrap_host,
             bootstrap_host,
         );
-        run_cargo_test(cargo, &[], &[], "installer", None, compiler, bootstrap_host, builder);
+        run_cargo_test(cargo, &[], &[], "installer", None, bootstrap_host, builder);
 
         // We currently don't support running the test.sh script outside linux(?) environments.
         // Eventually this should likely migrate to #[test]s in rust-installer proper rather than a
@@ -3639,16 +3616,7 @@ impl Step for TestFloatParse {
             &[],
         );
 
-        run_cargo_test(
-            cargo_test,
-            &[],
-            &[],
-            crate_name,
-            crate_name,
-            compiler,
-            bootstrap_host,
-            builder,
-        );
+        run_cargo_test(cargo_test, &[], &[], crate_name, crate_name, bootstrap_host, builder);
 
         // Run the actual parse tests.
         let mut cargo_run = tool::prepare_tool_cargo(
diff --git a/src/bootstrap/src/core/builder/cargo.rs b/src/bootstrap/src/core/builder/cargo.rs
index f9fb19ddb09..6b792108784 100644
--- a/src/bootstrap/src/core/builder/cargo.rs
+++ b/src/bootstrap/src/core/builder/cargo.rs
@@ -121,6 +121,10 @@ impl Cargo {
         cargo
     }
 
+    pub fn compiler(&self) -> Compiler {
+        self.compiler
+    }
+
     pub fn into_cmd(self) -> BootstrapCommand {
         self.into()
     }
diff --git a/src/bootstrap/src/core/config/tests.rs b/src/bootstrap/src/core/config/tests.rs
index c5e578ff351..f0a185ee3a7 100644
--- a/src/bootstrap/src/core/config/tests.rs
+++ b/src/bootstrap/src/core/config/tests.rs
@@ -92,7 +92,7 @@ fn detect_src_and_out() {
             //     `{build-dir}/bootstrap/debug/deps/bootstrap-c7ee91d5661e2804`
             // `{build-dir}` can be anywhere, not just in the rust project directory.
             let dep = Path::new(args.first().unwrap());
-            let expected_out = dep.ancestors().nth(4).unwrap();
+            let expected_out = dep.ancestors().nth(5).unwrap();
 
             assert_eq!(&cfg.out, expected_out);
         }
diff --git a/src/ci/github-actions/jobs.yml b/src/ci/github-actions/jobs.yml
index c5b33a45db7..5e95e3721df 100644
--- a/src/ci/github-actions/jobs.yml
+++ b/src/ci/github-actions/jobs.yml
@@ -48,6 +48,8 @@ runners:
     <<: *base-job
 
   - &job-aarch64-linux
+    # Free some disk space to avoid running out of space during the build.
+    free_disk: true
     os: ubuntu-22.04-arm
 
 envs:
diff --git a/src/rustdoc-json-types/lib.rs b/src/rustdoc-json-types/lib.rs
index 5a99977ded5..916f0ab3cc8 100644
--- a/src/rustdoc-json-types/lib.rs
+++ b/src/rustdoc-json-types/lib.rs
@@ -1099,8 +1099,7 @@ pub struct Trait {
     pub is_auto: bool,
     /// Whether the trait is marked as `unsafe`.
     pub is_unsafe: bool,
-    // FIXME(dyn_compat_renaming): Update the URL once the Reference is updated and hits stable.
-    /// Whether the trait is [dyn compatible](https://doc.rust-lang.org/reference/items/traits.html#object-safety)[^1].
+    /// Whether the trait is [dyn compatible](https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility)[^1].
     ///
     /// [^1]: Formerly known as "object safe".
     pub is_dyn_compatible: bool,
diff --git a/tests/ui/debuginfo/windows_gnu_split_debuginfo_off.rs b/tests/ui/debuginfo/windows_gnu_split_debuginfo_off.rs
new file mode 100644
index 00000000000..3a8d9c998cf
--- /dev/null
+++ b/tests/ui/debuginfo/windows_gnu_split_debuginfo_off.rs
@@ -0,0 +1,29 @@
+//@ revisions: aarch64_gl i686_g i686_gl i686_uwp_g x86_64_g x86_64_gl x86_64_uwp_g
+//@ compile-flags: --crate-type cdylib -Csplit-debuginfo=off
+//@ check-pass
+
+//@[aarch64_gl] compile-flags: --target aarch64-pc-windows-gnullvm
+//@[aarch64_gl] needs-llvm-components: aarch64
+
+//@[i686_g] compile-flags: --target i686-pc-windows-gnu
+//@[i686_g] needs-llvm-components: x86
+
+//@[i686_gl] compile-flags: --target i686-pc-windows-gnullvm
+//@[i686_gl] needs-llvm-components: x86
+
+//@[i686_uwp_g] compile-flags: --target i686-uwp-windows-gnu
+//@[i686_uwp_g] needs-llvm-components: x86
+
+//@[x86_64_g] compile-flags: --target x86_64-pc-windows-gnu
+//@[x86_64_g] needs-llvm-components: x86
+
+//@[x86_64_gl] compile-flags: --target x86_64-pc-windows-gnullvm
+//@[x86_64_gl] needs-llvm-components: x86
+
+//@[x86_64_uwp_g] compile-flags: --target x86_64-uwp-windows-gnu
+//@[x86_64_uwp_g] needs-llvm-components: x86
+
+#![feature(no_core)]
+
+#![no_core]
+#![no_std]
diff --git a/tests/ui/debuginfo/windows_gnu_split_debuginfo_packed.aarch64_gl.stderr b/tests/ui/debuginfo/windows_gnu_split_debuginfo_packed.aarch64_gl.stderr
new file mode 100644
index 00000000000..f3465e64976
--- /dev/null
+++ b/tests/ui/debuginfo/windows_gnu_split_debuginfo_packed.aarch64_gl.stderr
@@ -0,0 +1,4 @@
+error: `-Csplit-debuginfo=packed` is unstable on this platform
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/debuginfo/windows_gnu_split_debuginfo_packed.i686_g.stderr b/tests/ui/debuginfo/windows_gnu_split_debuginfo_packed.i686_g.stderr
new file mode 100644
index 00000000000..f3465e64976
--- /dev/null
+++ b/tests/ui/debuginfo/windows_gnu_split_debuginfo_packed.i686_g.stderr
@@ -0,0 +1,4 @@
+error: `-Csplit-debuginfo=packed` is unstable on this platform
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/debuginfo/windows_gnu_split_debuginfo_packed.i686_gl.stderr b/tests/ui/debuginfo/windows_gnu_split_debuginfo_packed.i686_gl.stderr
new file mode 100644
index 00000000000..f3465e64976
--- /dev/null
+++ b/tests/ui/debuginfo/windows_gnu_split_debuginfo_packed.i686_gl.stderr
@@ -0,0 +1,4 @@
+error: `-Csplit-debuginfo=packed` is unstable on this platform
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/debuginfo/windows_gnu_split_debuginfo_packed.i686_uwp_g.stderr b/tests/ui/debuginfo/windows_gnu_split_debuginfo_packed.i686_uwp_g.stderr
new file mode 100644
index 00000000000..f3465e64976
--- /dev/null
+++ b/tests/ui/debuginfo/windows_gnu_split_debuginfo_packed.i686_uwp_g.stderr
@@ -0,0 +1,4 @@
+error: `-Csplit-debuginfo=packed` is unstable on this platform
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/debuginfo/windows_gnu_split_debuginfo_packed.rs b/tests/ui/debuginfo/windows_gnu_split_debuginfo_packed.rs
new file mode 100644
index 00000000000..896bbac7d8e
--- /dev/null
+++ b/tests/ui/debuginfo/windows_gnu_split_debuginfo_packed.rs
@@ -0,0 +1,29 @@
+//@ revisions: aarch64_gl i686_g i686_gl i686_uwp_g x86_64_g x86_64_gl x86_64_uwp_g
+//@ compile-flags: --crate-type cdylib -Csplit-debuginfo=packed
+//@ error-pattern: error: `-Csplit-debuginfo=packed` is unstable on this platform
+
+//@[aarch64_gl] compile-flags: --target aarch64-pc-windows-gnullvm
+//@[aarch64_gl] needs-llvm-components: aarch64
+
+//@[i686_g] compile-flags: --target i686-pc-windows-gnu
+//@[i686_g] needs-llvm-components: x86
+
+//@[i686_gl] compile-flags: --target i686-pc-windows-gnullvm
+//@[i686_gl] needs-llvm-components: x86
+
+//@[i686_uwp_g] compile-flags: --target i686-uwp-windows-gnu
+//@[i686_uwp_g] needs-llvm-components: x86
+
+//@[x86_64_g] compile-flags: --target x86_64-pc-windows-gnu
+//@[x86_64_g] needs-llvm-components: x86
+
+//@[x86_64_gl] compile-flags: --target x86_64-pc-windows-gnullvm
+//@[x86_64_gl] needs-llvm-components: x86
+
+//@[x86_64_uwp_g] compile-flags: --target x86_64-uwp-windows-gnu
+//@[x86_64_uwp_g] needs-llvm-components: x86
+
+#![feature(no_core)]
+
+#![no_core]
+#![no_std]
diff --git a/tests/ui/debuginfo/windows_gnu_split_debuginfo_packed.x86_64_g.stderr b/tests/ui/debuginfo/windows_gnu_split_debuginfo_packed.x86_64_g.stderr
new file mode 100644
index 00000000000..f3465e64976
--- /dev/null
+++ b/tests/ui/debuginfo/windows_gnu_split_debuginfo_packed.x86_64_g.stderr
@@ -0,0 +1,4 @@
+error: `-Csplit-debuginfo=packed` is unstable on this platform
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/debuginfo/windows_gnu_split_debuginfo_packed.x86_64_gl.stderr b/tests/ui/debuginfo/windows_gnu_split_debuginfo_packed.x86_64_gl.stderr
new file mode 100644
index 00000000000..f3465e64976
--- /dev/null
+++ b/tests/ui/debuginfo/windows_gnu_split_debuginfo_packed.x86_64_gl.stderr
@@ -0,0 +1,4 @@
+error: `-Csplit-debuginfo=packed` is unstable on this platform
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/debuginfo/windows_gnu_split_debuginfo_packed.x86_64_uwp_g.stderr b/tests/ui/debuginfo/windows_gnu_split_debuginfo_packed.x86_64_uwp_g.stderr
new file mode 100644
index 00000000000..f3465e64976
--- /dev/null
+++ b/tests/ui/debuginfo/windows_gnu_split_debuginfo_packed.x86_64_uwp_g.stderr
@@ -0,0 +1,4 @@
+error: `-Csplit-debuginfo=packed` is unstable on this platform
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/debuginfo/windows_gnu_split_debuginfo_unpacked.aarch64_gl.stderr b/tests/ui/debuginfo/windows_gnu_split_debuginfo_unpacked.aarch64_gl.stderr
new file mode 100644
index 00000000000..0964e21b13b
--- /dev/null
+++ b/tests/ui/debuginfo/windows_gnu_split_debuginfo_unpacked.aarch64_gl.stderr
@@ -0,0 +1,4 @@
+error: `-Csplit-debuginfo=unpacked` is unstable on this platform
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/debuginfo/windows_gnu_split_debuginfo_unpacked.i686_g.stderr b/tests/ui/debuginfo/windows_gnu_split_debuginfo_unpacked.i686_g.stderr
new file mode 100644
index 00000000000..0964e21b13b
--- /dev/null
+++ b/tests/ui/debuginfo/windows_gnu_split_debuginfo_unpacked.i686_g.stderr
@@ -0,0 +1,4 @@
+error: `-Csplit-debuginfo=unpacked` is unstable on this platform
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/debuginfo/windows_gnu_split_debuginfo_unpacked.i686_gl.stderr b/tests/ui/debuginfo/windows_gnu_split_debuginfo_unpacked.i686_gl.stderr
new file mode 100644
index 00000000000..0964e21b13b
--- /dev/null
+++ b/tests/ui/debuginfo/windows_gnu_split_debuginfo_unpacked.i686_gl.stderr
@@ -0,0 +1,4 @@
+error: `-Csplit-debuginfo=unpacked` is unstable on this platform
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/debuginfo/windows_gnu_split_debuginfo_unpacked.i686_uwp_g.stderr b/tests/ui/debuginfo/windows_gnu_split_debuginfo_unpacked.i686_uwp_g.stderr
new file mode 100644
index 00000000000..0964e21b13b
--- /dev/null
+++ b/tests/ui/debuginfo/windows_gnu_split_debuginfo_unpacked.i686_uwp_g.stderr
@@ -0,0 +1,4 @@
+error: `-Csplit-debuginfo=unpacked` is unstable on this platform
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/debuginfo/windows_gnu_split_debuginfo_unpacked.rs b/tests/ui/debuginfo/windows_gnu_split_debuginfo_unpacked.rs
new file mode 100644
index 00000000000..54a88c91217
--- /dev/null
+++ b/tests/ui/debuginfo/windows_gnu_split_debuginfo_unpacked.rs
@@ -0,0 +1,29 @@
+//@ revisions: aarch64_gl i686_g i686_gl i686_uwp_g x86_64_g x86_64_gl x86_64_uwp_g
+//@ compile-flags: --crate-type cdylib -Csplit-debuginfo=unpacked
+//@ error-pattern: error: `-Csplit-debuginfo=unpacked` is unstable on this platform
+
+//@[aarch64_gl] compile-flags: --target aarch64-pc-windows-gnullvm
+//@[aarch64_gl] needs-llvm-components: aarch64
+
+//@[i686_g] compile-flags: --target i686-pc-windows-gnu
+//@[i686_g] needs-llvm-components: x86
+
+//@[i686_gl] compile-flags: --target i686-pc-windows-gnullvm
+//@[i686_gl] needs-llvm-components: x86
+
+//@[i686_uwp_g] compile-flags: --target i686-uwp-windows-gnu
+//@[i686_uwp_g] needs-llvm-components: x86
+
+//@[x86_64_g] compile-flags: --target x86_64-pc-windows-gnu
+//@[x86_64_g] needs-llvm-components: x86
+
+//@[x86_64_gl] compile-flags: --target x86_64-pc-windows-gnullvm
+//@[x86_64_gl] needs-llvm-components: x86
+
+//@[x86_64_uwp_g] compile-flags: --target x86_64-uwp-windows-gnu
+//@[x86_64_uwp_g] needs-llvm-components: x86
+
+#![feature(no_core)]
+
+#![no_core]
+#![no_std]
diff --git a/tests/ui/debuginfo/windows_gnu_split_debuginfo_unpacked.x86_64_g.stderr b/tests/ui/debuginfo/windows_gnu_split_debuginfo_unpacked.x86_64_g.stderr
new file mode 100644
index 00000000000..0964e21b13b
--- /dev/null
+++ b/tests/ui/debuginfo/windows_gnu_split_debuginfo_unpacked.x86_64_g.stderr
@@ -0,0 +1,4 @@
+error: `-Csplit-debuginfo=unpacked` is unstable on this platform
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/debuginfo/windows_gnu_split_debuginfo_unpacked.x86_64_gl.stderr b/tests/ui/debuginfo/windows_gnu_split_debuginfo_unpacked.x86_64_gl.stderr
new file mode 100644
index 00000000000..0964e21b13b
--- /dev/null
+++ b/tests/ui/debuginfo/windows_gnu_split_debuginfo_unpacked.x86_64_gl.stderr
@@ -0,0 +1,4 @@
+error: `-Csplit-debuginfo=unpacked` is unstable on this platform
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/debuginfo/windows_gnu_split_debuginfo_unpacked.x86_64_uwp_g.stderr b/tests/ui/debuginfo/windows_gnu_split_debuginfo_unpacked.x86_64_uwp_g.stderr
new file mode 100644
index 00000000000..0964e21b13b
--- /dev/null
+++ b/tests/ui/debuginfo/windows_gnu_split_debuginfo_unpacked.x86_64_uwp_g.stderr
@@ -0,0 +1,4 @@
+error: `-Csplit-debuginfo=unpacked` is unstable on this platform
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/layout/reprc-power-alignment.rs b/tests/ui/layout/reprc-power-alignment.rs
new file mode 100644
index 00000000000..f6c1df55988
--- /dev/null
+++ b/tests/ui/layout/reprc-power-alignment.rs
@@ -0,0 +1,152 @@
+//@ check-pass
+//@ compile-flags: --target powerpc64-ibm-aix
+//@ needs-llvm-components: powerpc
+//@ add-core-stubs
+#![feature(no_core)]
+#![no_core]
+#![no_std]
+
+extern crate minicore;
+use minicore::*;
+
+#[warn(uses_power_alignment)]
+
+#[repr(C)]
+pub struct Floats {
+    a: f64,
+    b: u8,
+    c: f64, //~ WARNING repr(C) does not follow the power alignment rule. This may affect platform C ABI compatibility for this type
+    d: f32,
+}
+
+pub struct Floats2 {
+    a: f64,
+    b: u32,
+    c: f64,
+}
+
+#[repr(C)]
+pub struct Floats3 {
+    a: f32,
+    b: f32,
+    c: i64,
+}
+
+#[repr(C)]
+pub struct Floats4 {
+    a: u64,
+    b: u32,
+    c: f32,
+}
+
+#[repr(C)]
+pub struct Floats5 {
+    a: f32,
+    b: f64, //~ WARNING repr(C) does not follow the power alignment rule. This may affect platform C ABI compatibility for this type
+    c: f32,
+}
+
+#[repr(C)]
+pub struct FloatAgg1 {
+    x: Floats,
+    y: f64, //~ WARNING repr(C) does not follow the power alignment rule. This may affect platform C ABI compatibility for this type
+}
+
+#[repr(C)]
+pub struct FloatAgg2 {
+    x: i64,
+    y: Floats, //~ WARNING repr(C) does not follow the power alignment rule. This may affect platform C ABI compatibility for this type
+}
+
+#[repr(C)]
+pub struct FloatAgg3 {
+    x: FloatAgg1,
+    // NOTE: the "power" alignment rule is infectious to nested struct fields.
+    y: FloatAgg2, //~ WARNING repr(C) does not follow the power alignment rule. This may affect platform C ABI compatibility for this type
+    z: FloatAgg2, //~ WARNING repr(C) does not follow the power alignment rule. This may affect platform C ABI compatibility for this type
+}
+
+#[repr(C)]
+pub struct FloatAgg4 {
+    x: FloatAgg1,
+    y: FloatAgg2, //~ WARNING repr(C) does not follow the power alignment rule. This may affect platform C ABI compatibility for this type
+}
+
+#[repr(C)]
+pub struct FloatAgg5 {
+    x: FloatAgg1,
+    y: FloatAgg2, //~ WARNING repr(C) does not follow the power alignment rule. This may affect platform C ABI compatibility for this type
+    z: FloatAgg3, //~ WARNING repr(C) does not follow the power alignment rule. This may affect platform C ABI compatibility for this type
+}
+
+#[repr(C)]
+pub struct FloatAgg6 {
+    x: i64,
+    y: Floats, //~ WARNING repr(C) does not follow the power alignment rule. This may affect platform C ABI compatibility for this type
+    z: u8,
+}
+
+#[repr(C)]
+pub struct FloatAgg7 {
+    x: i64,
+    y: Floats, //~ WARNING repr(C) does not follow the power alignment rule. This may affect platform C ABI compatibility for this type
+    z: u8,
+    zz: f32,
+}
+
+#[repr(C)]
+pub struct A {
+  d: f64,
+}
+#[repr(C)]
+pub struct B {
+  a: A,
+  f: f32,
+  d: f64, //~ WARNING repr(C) does not follow the power alignment rule. This may affect platform C ABI compatibility for this type
+}
+#[repr(C)]
+pub struct C {
+  c: u8,
+  b: B, //~ WARNING repr(C) does not follow the power alignment rule. This may affect platform C ABI compatibility for this type
+}
+#[repr(C)]
+pub struct D {
+  x: f64,
+}
+#[repr(C)]
+pub struct E {
+  x: i32,
+  d: D, //~ WARNING repr(C) does not follow the power alignment rule. This may affect platform C ABI compatibility for this type
+}
+#[repr(C)]
+pub struct F {
+  a: u8,
+  b: f64, //~ WARNING repr(C) does not follow the power alignment rule. This may affect platform C ABI compatibility for this type
+}
+#[repr(C)]
+pub struct G {
+    a: u8,
+    b: u8,
+    c: f64, //~ WARNING repr(C) does not follow the power alignment rule. This may affect platform C ABI compatibility for this type
+    d: f32,
+    e: f64, //~ WARNING repr(C) does not follow the power alignment rule. This may affect platform C ABI compatibility for this type
+}
+// Should not warn on #[repr(packed)].
+#[repr(packed)]
+pub struct H {
+    a: u8,
+    b: u8,
+    c: f64,
+    d: f32,
+    e: f64,
+}
+#[repr(C, packed)]
+pub struct I {
+    a: u8,
+    b: u8,
+    c: f64,
+    d: f32,
+    e: f64,
+}
+
+fn main() { }
diff --git a/tests/ui/layout/reprc-power-alignment.stderr b/tests/ui/layout/reprc-power-alignment.stderr
new file mode 100644
index 00000000000..18664e4d655
--- /dev/null
+++ b/tests/ui/layout/reprc-power-alignment.stderr
@@ -0,0 +1,112 @@
+warning: repr(C) does not follow the power alignment rule. This may affect platform C ABI compatibility for this type
+  --> $DIR/reprc-power-alignment.rs:18:5
+   |
+LL |     c: f64,
+   |     ^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/reprc-power-alignment.rs:12:8
+   |
+LL | #[warn(uses_power_alignment)]
+   |        ^^^^^^^^^^^^^^^^^^^^
+
+warning: repr(C) does not follow the power alignment rule. This may affect platform C ABI compatibility for this type
+  --> $DIR/reprc-power-alignment.rs:45:5
+   |
+LL |     b: f64,
+   |     ^^^^^^
+   |
+   = note: `#[warn(uses_power_alignment)]` on by default
+
+warning: repr(C) does not follow the power alignment rule. This may affect platform C ABI compatibility for this type
+  --> $DIR/reprc-power-alignment.rs:52:5
+   |
+LL |     y: f64,
+   |     ^^^^^^
+
+warning: repr(C) does not follow the power alignment rule. This may affect platform C ABI compatibility for this type
+  --> $DIR/reprc-power-alignment.rs:58:5
+   |
+LL |     y: Floats,
+   |     ^^^^^^^^^
+
+warning: repr(C) does not follow the power alignment rule. This may affect platform C ABI compatibility for this type
+  --> $DIR/reprc-power-alignment.rs:65:5
+   |
+LL |     y: FloatAgg2,
+   |     ^^^^^^^^^^^^
+
+warning: repr(C) does not follow the power alignment rule. This may affect platform C ABI compatibility for this type
+  --> $DIR/reprc-power-alignment.rs:66:5
+   |
+LL |     z: FloatAgg2,
+   |     ^^^^^^^^^^^^
+
+warning: repr(C) does not follow the power alignment rule. This may affect platform C ABI compatibility for this type
+  --> $DIR/reprc-power-alignment.rs:72:5
+   |
+LL |     y: FloatAgg2,
+   |     ^^^^^^^^^^^^
+
+warning: repr(C) does not follow the power alignment rule. This may affect platform C ABI compatibility for this type
+  --> $DIR/reprc-power-alignment.rs:78:5
+   |
+LL |     y: FloatAgg2,
+   |     ^^^^^^^^^^^^
+
+warning: repr(C) does not follow the power alignment rule. This may affect platform C ABI compatibility for this type
+  --> $DIR/reprc-power-alignment.rs:79:5
+   |
+LL |     z: FloatAgg3,
+   |     ^^^^^^^^^^^^
+
+warning: repr(C) does not follow the power alignment rule. This may affect platform C ABI compatibility for this type
+  --> $DIR/reprc-power-alignment.rs:85:5
+   |
+LL |     y: Floats,
+   |     ^^^^^^^^^
+
+warning: repr(C) does not follow the power alignment rule. This may affect platform C ABI compatibility for this type
+  --> $DIR/reprc-power-alignment.rs:92:5
+   |
+LL |     y: Floats,
+   |     ^^^^^^^^^
+
+warning: repr(C) does not follow the power alignment rule. This may affect platform C ABI compatibility for this type
+  --> $DIR/reprc-power-alignment.rs:105:3
+   |
+LL |   d: f64,
+   |   ^^^^^^
+
+warning: repr(C) does not follow the power alignment rule. This may affect platform C ABI compatibility for this type
+  --> $DIR/reprc-power-alignment.rs:110:3
+   |
+LL |   b: B,
+   |   ^^^^
+
+warning: repr(C) does not follow the power alignment rule. This may affect platform C ABI compatibility for this type
+  --> $DIR/reprc-power-alignment.rs:119:3
+   |
+LL |   d: D,
+   |   ^^^^
+
+warning: repr(C) does not follow the power alignment rule. This may affect platform C ABI compatibility for this type
+  --> $DIR/reprc-power-alignment.rs:124:3
+   |
+LL |   b: f64,
+   |   ^^^^^^
+
+warning: repr(C) does not follow the power alignment rule. This may affect platform C ABI compatibility for this type
+  --> $DIR/reprc-power-alignment.rs:130:5
+   |
+LL |     c: f64,
+   |     ^^^^^^
+
+warning: repr(C) does not follow the power alignment rule. This may affect platform C ABI compatibility for this type
+  --> $DIR/reprc-power-alignment.rs:132:5
+   |
+LL |     e: f64,
+   |     ^^^^^^
+
+warning: 17 warnings emitted
+
diff --git a/tests/ui/lint/clashing-extern-fn.rs b/tests/ui/lint/clashing-extern-fn.rs
index a12fe81eecd..9bbb20246df 100644
--- a/tests/ui/lint/clashing-extern-fn.rs
+++ b/tests/ui/lint/clashing-extern-fn.rs
@@ -248,6 +248,7 @@ mod sameish_members {
 
 mod same_sized_members_clash {
     mod a {
+        #[allow(uses_power_alignment)]
         #[repr(C)]
         struct Point3 {
             x: f32,
diff --git a/tests/ui/lint/clashing-extern-fn.stderr b/tests/ui/lint/clashing-extern-fn.stderr
index b30dd476a1d..48dd1adbc1f 100644
--- a/tests/ui/lint/clashing-extern-fn.stderr
+++ b/tests/ui/lint/clashing-extern-fn.stderr
@@ -1,5 +1,5 @@
 warning: `extern` block uses type `Option<TransparentNoNiche>`, which is not FFI-safe
-  --> $DIR/clashing-extern-fn.rs:482:55
+  --> $DIR/clashing-extern-fn.rs:483:55
    |
 LL |             fn hidden_niche_transparent_no_niche() -> Option<TransparentNoNiche>;
    |                                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
@@ -9,7 +9,7 @@ LL |             fn hidden_niche_transparent_no_niche() -> Option<TransparentNoN
    = note: `#[warn(improper_ctypes)]` on by default
 
 warning: `extern` block uses type `Option<UnsafeCell<NonZero<usize>>>`, which is not FFI-safe
-  --> $DIR/clashing-extern-fn.rs:486:46
+  --> $DIR/clashing-extern-fn.rs:487:46
    |
 LL |             fn hidden_niche_unsafe_cell() -> Option<UnsafeCell<NonZero<usize>>>;
    |                                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
@@ -151,7 +151,7 @@ LL |             fn draw_point(p: Point);
               found `unsafe extern "C" fn(sameish_members::b::Point)`
 
 warning: `origin` redeclared with a different signature
-  --> $DIR/clashing-extern-fn.rs:269:13
+  --> $DIR/clashing-extern-fn.rs:270:13
    |
 LL |             fn origin() -> Point3;
    |             ---------------------- `origin` previously declared here
@@ -163,7 +163,7 @@ LL |             fn origin() -> Point3;
               found `unsafe extern "C" fn() -> same_sized_members_clash::b::Point3`
 
 warning: `transparent_incorrect` redeclared with a different signature
-  --> $DIR/clashing-extern-fn.rs:292:13
+  --> $DIR/clashing-extern-fn.rs:293:13
    |
 LL |             fn transparent_incorrect() -> T;
    |             -------------------------------- `transparent_incorrect` previously declared here
@@ -175,7 +175,7 @@ LL |             fn transparent_incorrect() -> isize;
               found `unsafe extern "C" fn() -> isize`
 
 warning: `missing_return_type` redeclared with a different signature
-  --> $DIR/clashing-extern-fn.rs:310:13
+  --> $DIR/clashing-extern-fn.rs:311:13
    |
 LL |             fn missing_return_type() -> usize;
    |             ---------------------------------- `missing_return_type` previously declared here
@@ -187,7 +187,7 @@ LL |             fn missing_return_type();
               found `unsafe extern "C" fn()`
 
 warning: `non_zero_usize` redeclared with a different signature
-  --> $DIR/clashing-extern-fn.rs:328:13
+  --> $DIR/clashing-extern-fn.rs:329:13
    |
 LL |             fn non_zero_usize() -> core::num::NonZero<usize>;
    |             ------------------------------------------------- `non_zero_usize` previously declared here
@@ -199,7 +199,7 @@ LL |             fn non_zero_usize() -> usize;
               found `unsafe extern "C" fn() -> usize`
 
 warning: `non_null_ptr` redeclared with a different signature
-  --> $DIR/clashing-extern-fn.rs:330:13
+  --> $DIR/clashing-extern-fn.rs:331:13
    |
 LL |             fn non_null_ptr() -> core::ptr::NonNull<usize>;
    |             ----------------------------------------------- `non_null_ptr` previously declared here
@@ -211,7 +211,7 @@ LL |             fn non_null_ptr() -> *const usize;
               found `unsafe extern "C" fn() -> *const usize`
 
 warning: `option_non_zero_usize_incorrect` redeclared with a different signature
-  --> $DIR/clashing-extern-fn.rs:424:13
+  --> $DIR/clashing-extern-fn.rs:425:13
    |
 LL |             fn option_non_zero_usize_incorrect() -> usize;
    |             ---------------------------------------------- `option_non_zero_usize_incorrect` previously declared here
@@ -223,7 +223,7 @@ LL |             fn option_non_zero_usize_incorrect() -> isize;
               found `unsafe extern "C" fn() -> isize`
 
 warning: `option_non_null_ptr_incorrect` redeclared with a different signature
-  --> $DIR/clashing-extern-fn.rs:426:13
+  --> $DIR/clashing-extern-fn.rs:427:13
    |
 LL |             fn option_non_null_ptr_incorrect() -> *const usize;
    |             --------------------------------------------------- `option_non_null_ptr_incorrect` previously declared here
@@ -235,7 +235,7 @@ LL |             fn option_non_null_ptr_incorrect() -> *const isize;
               found `unsafe extern "C" fn() -> *const isize`
 
 warning: `hidden_niche_transparent_no_niche` redeclared with a different signature
-  --> $DIR/clashing-extern-fn.rs:482:13
+  --> $DIR/clashing-extern-fn.rs:483:13
    |
 LL |             fn hidden_niche_transparent_no_niche() -> usize;
    |             ------------------------------------------------ `hidden_niche_transparent_no_niche` previously declared here
@@ -247,7 +247,7 @@ LL |             fn hidden_niche_transparent_no_niche() -> Option<TransparentNoN
               found `unsafe extern "C" fn() -> Option<TransparentNoNiche>`
 
 warning: `hidden_niche_unsafe_cell` redeclared with a different signature
-  --> $DIR/clashing-extern-fn.rs:486:13
+  --> $DIR/clashing-extern-fn.rs:487:13
    |
 LL |             fn hidden_niche_unsafe_cell() -> usize;
    |             --------------------------------------- `hidden_niche_unsafe_cell` previously declared here
diff --git a/tests/ui/traits/next-solver/non-wf-in-coerce-pointers.rs b/tests/ui/traits/next-solver/non-wf-in-coerce-pointers.rs
new file mode 100644
index 00000000000..d05def2cb75
--- /dev/null
+++ b/tests/ui/traits/next-solver/non-wf-in-coerce-pointers.rs
@@ -0,0 +1,17 @@
+//@ compile-flags: -Znext-solver
+
+trait Wf {
+    type Assoc;
+}
+
+struct S {
+    f: &'static <() as Wf>::Assoc,
+    //~^ ERROR the trait bound `(): Wf` is not satisfied
+}
+
+fn main() {
+    let x: S = todo!();
+    let y: &() = x.f;
+    //~^ ERROR mismatched types
+    //~| ERROR the trait bound `(): Wf` is not satisfied
+}
diff --git a/tests/ui/traits/next-solver/non-wf-in-coerce-pointers.stderr b/tests/ui/traits/next-solver/non-wf-in-coerce-pointers.stderr
new file mode 100644
index 00000000000..32a7766a638
--- /dev/null
+++ b/tests/ui/traits/next-solver/non-wf-in-coerce-pointers.stderr
@@ -0,0 +1,39 @@
+error[E0277]: the trait bound `(): Wf` is not satisfied
+  --> $DIR/non-wf-in-coerce-pointers.rs:8:17
+   |
+LL |     f: &'static <() as Wf>::Assoc,
+   |                 ^^^^^^^^^^^^^^^^^ the trait `Wf` is not implemented for `()`
+   |
+help: this trait has no implementations, consider adding one
+  --> $DIR/non-wf-in-coerce-pointers.rs:3:1
+   |
+LL | trait Wf {
+   | ^^^^^^^^
+
+error[E0308]: mismatched types
+  --> $DIR/non-wf-in-coerce-pointers.rs:14:18
+   |
+LL |     let y: &() = x.f;
+   |            ---   ^^^ types differ
+   |            |
+   |            expected due to this
+   |
+   = note: expected reference `&()`
+              found reference `&'static <() as Wf>::Assoc`
+
+error[E0277]: the trait bound `(): Wf` is not satisfied
+  --> $DIR/non-wf-in-coerce-pointers.rs:14:18
+   |
+LL |     let y: &() = x.f;
+   |                  ^^^ the trait `Wf` is not implemented for `()`
+   |
+help: this trait has no implementations, consider adding one
+  --> $DIR/non-wf-in-coerce-pointers.rs:3:1
+   |
+LL | trait Wf {
+   | ^^^^^^^^
+
+error: aborting due to 3 previous errors
+
+Some errors have detailed explanations: E0277, E0308.
+For more information about an error, try `rustc --explain E0277`.