about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2025-06-09 02:20:44 +0000
committerbors <bors@rust-lang.org>2025-06-09 02:20:44 +0000
commit334ba812755b974ecc46713fcdd38836b6182746 (patch)
tree97733c915e4e9299e6da38942a60d2fb2645e72a /compiler
parentc31cccb7b5cc098b1a8c1794ed38d7fdbec0ccb0 (diff)
parente91f985717687e7a960121667cf7d8f8010a6cd0 (diff)
downloadrust-334ba812755b974ecc46713fcdd38836b6182746.tar.gz
rust-334ba812755b974ecc46713fcdd38836b6182746.zip
Auto merge of #142220 - workingjubilee:rollup-idgfpof, r=workingjubilee
Rollup of 12 pull requests

Successful merges:

 - rust-lang/rust#141803 (Remove rustc's notion of "preferred" alignment AKA `__alignof`)
 - rust-lang/rust#142053 (Add new Tier-3 targets: `loongarch32-unknown-none*`)
 - rust-lang/rust#142089 (Replace all uses of sysroot_candidates with get_or_default_sysroot)
 - rust-lang/rust#142108 (compiler: Add track_caller to AbiMapping::unwrap)
 - rust-lang/rust#142132 (`tests/ui`: A New Order [6/N])
 - rust-lang/rust#142162 (UnsafePinned: update get() docs and signature to allow shared mutation)
 - rust-lang/rust#142171 (`tests/ui`: A New Order [7/N])
 - rust-lang/rust#142179 (store `target.min_global_align` as an `Align`)
 - rust-lang/rust#142183 (Added test for 30904)
 - rust-lang/rust#142194 (Remove all unused feature gates from the compiler)
 - rust-lang/rust#142199 (Do not free disk space in the `mingw-check-tidy` job)
 - rust-lang/rust#142210 (Run `mingw-check-tidy` on auto builds)

r? `@ghost`
`@rustbot` modify labels: rollup
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_abi/src/layout.rs20
-rw-r--r--compiler/rustc_abi/src/layout/ty.rs4
-rw-r--r--compiler/rustc_abi/src/lib.rs100
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs2
-rw-r--r--compiler/rustc_builtin_macros/src/lib.rs1
-rw-r--r--compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs6
-rw-r--r--compiler/rustc_codegen_gcc/example/alloc_system.rs1
-rw-r--r--compiler/rustc_codegen_gcc/messages.ftl3
-rw-r--r--compiler/rustc_codegen_gcc/src/consts.rs10
-rw-r--r--compiler/rustc_codegen_gcc/src/errors.rs6
-rw-r--r--compiler/rustc_codegen_gcc/src/lib.rs2
-rw-r--r--compiler/rustc_codegen_llvm/Cargo.toml2
-rw-r--r--compiler/rustc_codegen_llvm/messages.ftl6
-rw-r--r--compiler/rustc_codegen_llvm/src/asm.rs2
-rw-r--r--compiler/rustc_codegen_llvm/src/consts.rs26
-rw-r--r--compiler/rustc_codegen_llvm/src/errors.rs12
-rw-r--r--compiler/rustc_codegen_llvm/src/lib.rs1
-rw-r--r--compiler/rustc_codegen_ssa/Cargo.toml2
-rw-r--r--compiler/rustc_codegen_ssa/src/back/link/raw_dylib.rs1
-rw-r--r--compiler/rustc_codegen_ssa/src/back/metadata.rs2
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/intrinsic.rs6
-rw-r--r--compiler/rustc_const_eval/src/interpret/intrinsics.rs15
-rw-r--r--compiler/rustc_data_structures/src/lib.rs1
-rw-r--r--compiler/rustc_error_messages/Cargo.toml1
-rw-r--r--compiler/rustc_error_messages/src/lib.rs6
-rw-r--r--compiler/rustc_errors/src/lib.rs2
-rw-r--r--compiler/rustc_expand/src/lib.rs1
-rw-r--r--compiler/rustc_feature/src/removed.rs2
-rw-r--r--compiler/rustc_fluent_macro/src/lib.rs1
-rw-r--r--compiler/rustc_hir/src/lib.rs1
-rw-r--r--compiler/rustc_hir_typeck/src/lib.rs2
-rw-r--r--compiler/rustc_infer/src/lib.rs1
-rw-r--r--compiler/rustc_interface/src/interface.rs5
-rw-r--r--compiler/rustc_interface/src/util.rs21
-rw-r--r--compiler/rustc_macros/src/lib.rs1
-rw-r--r--compiler/rustc_middle/src/lib.rs1
-rw-r--r--compiler/rustc_mir_transform/src/lib.rs3
-rw-r--r--compiler/rustc_parse/src/lib.rs1
-rw-r--r--compiler/rustc_passes/src/lib.rs2
-rw-r--r--compiler/rustc_query_system/src/lib.rs1
-rw-r--r--compiler/rustc_session/src/filesearch.rs62
-rw-r--r--compiler/rustc_session/src/session.rs6
-rw-r--r--compiler/rustc_span/src/lib.rs1
-rw-r--r--compiler/rustc_target/Cargo.toml2
-rw-r--r--compiler/rustc_target/src/asm/mod.rs14
-rw-r--r--compiler/rustc_target/src/callconv/mod.rs4
-rw-r--r--compiler/rustc_target/src/lib.rs2
-rw-r--r--compiler/rustc_target/src/spec/abi_map.rs1
-rw-r--r--compiler/rustc_target/src/spec/json.rs21
-rw-r--r--compiler/rustc_target/src/spec/mod.rs11
-rw-r--r--compiler/rustc_target/src/spec/targets/loongarch32_unknown_none.rs29
-rw-r--r--compiler/rustc_target/src/spec/targets/loongarch32_unknown_none_softfloat.rs30
-rw-r--r--compiler/rustc_target/src/spec/targets/s390x_unknown_linux_gnu.rs4
-rw-r--r--compiler/rustc_target/src/spec/targets/s390x_unknown_linux_musl.rs4
-rw-r--r--compiler/rustc_target/src/target_features.rs6
-rw-r--r--compiler/rustc_trait_selection/src/lib.rs2
56 files changed, 223 insertions, 259 deletions
diff --git a/compiler/rustc_abi/src/layout.rs b/compiler/rustc_abi/src/layout.rs
index 21fd6be39fa..58a7fcae9f6 100644
--- a/compiler/rustc_abi/src/layout.rs
+++ b/compiler/rustc_abi/src/layout.rs
@@ -8,7 +8,7 @@ use rustc_index::bit_set::BitMatrix;
 use tracing::debug;
 
 use crate::{
-    AbiAndPrefAlign, Align, BackendRepr, FieldsShape, HasDataLayout, IndexSlice, IndexVec, Integer,
+    AbiAlign, Align, BackendRepr, FieldsShape, HasDataLayout, IndexSlice, IndexVec, Integer,
     LayoutData, Niche, NonZeroUsize, Primitive, ReprOptions, Scalar, Size, StructKind, TagEncoding,
     Variants, WrappingRange,
 };
@@ -173,13 +173,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
             // Non-power-of-two vectors have padding up to the next power-of-two.
             // If we're a packed repr, remove the padding while keeping the alignment as close
             // to a vector as possible.
-            (
-                BackendRepr::Memory { sized: true },
-                AbiAndPrefAlign {
-                    abi: Align::max_aligned_factor(size),
-                    pref: dl.llvmlike_vector_align(size).pref,
-                },
-            )
+            (BackendRepr::Memory { sized: true }, AbiAlign { abi: Align::max_aligned_factor(size) })
         } else {
             (BackendRepr::SimdVector { element: e_repr, count }, dl.llvmlike_vector_align(size))
         };
@@ -435,13 +429,13 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
         }
 
         if let Some(pack) = repr.pack {
-            align = align.min(AbiAndPrefAlign::new(pack));
+            align = align.min(AbiAlign::new(pack));
         }
         // The unadjusted ABI alignment does not include repr(align), but does include repr(pack).
         // See documentation on `LayoutS::unadjusted_abi_align`.
         let unadjusted_abi_align = align.abi;
         if let Some(repr_align) = repr.align {
-            align = align.max(AbiAndPrefAlign::new(repr_align));
+            align = align.max(AbiAlign::new(repr_align));
         }
         // `align` must not be modified after this, or `unadjusted_abi_align` could be inaccurate.
         let align = align;
@@ -1289,7 +1283,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
         if let StructKind::Prefixed(prefix_size, prefix_align) = kind {
             let prefix_align =
                 if let Some(pack) = pack { prefix_align.min(pack) } else { prefix_align };
-            align = align.max(AbiAndPrefAlign::new(prefix_align));
+            align = align.max(AbiAlign::new(prefix_align));
             offset = prefix_size.align_to(prefix_align);
         }
         for &i in &inverse_memory_index {
@@ -1308,7 +1302,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
 
             // Invariant: offset < dl.obj_size_bound() <= 1<<61
             let field_align = if let Some(pack) = pack {
-                field.align.min(AbiAndPrefAlign::new(pack))
+                field.align.min(AbiAlign::new(pack))
             } else {
                 field.align
             };
@@ -1342,7 +1336,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
         // See documentation on `LayoutS::unadjusted_abi_align`.
         let unadjusted_abi_align = align.abi;
         if let Some(repr_align) = repr.align {
-            align = align.max(AbiAndPrefAlign::new(repr_align));
+            align = align.max(AbiAlign::new(repr_align));
         }
         // `align` must not be modified after this point, or `unadjusted_abi_align` could be inaccurate.
         let align = align;
diff --git a/compiler/rustc_abi/src/layout/ty.rs b/compiler/rustc_abi/src/layout/ty.rs
index b5f93351d68..bb880a58e52 100644
--- a/compiler/rustc_abi/src/layout/ty.rs
+++ b/compiler/rustc_abi/src/layout/ty.rs
@@ -5,7 +5,7 @@ use rustc_data_structures::intern::Interned;
 use rustc_macros::HashStable_Generic;
 
 use crate::{
-    AbiAndPrefAlign, Align, BackendRepr, FieldsShape, Float, HasDataLayout, LayoutData, Niche,
+    AbiAlign, Align, BackendRepr, FieldsShape, Float, HasDataLayout, LayoutData, Niche,
     PointeeInfo, Primitive, Scalar, Size, TargetDataLayout, Variants,
 };
 
@@ -100,7 +100,7 @@ impl<'a> Layout<'a> {
         self.0.0.largest_niche
     }
 
-    pub fn align(self) -> AbiAndPrefAlign {
+    pub fn align(self) -> AbiAlign {
         self.0.0.align
     }
 
diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs
index 46b7a0c1e77..4268e68b2e4 100644
--- a/compiler/rustc_abi/src/lib.rs
+++ b/compiler/rustc_abi/src/lib.rs
@@ -43,7 +43,7 @@ use std::fmt;
 #[cfg(feature = "nightly")]
 use std::iter::Step;
 use std::num::{NonZeroUsize, ParseIntError};
-use std::ops::{Add, AddAssign, Mul, RangeInclusive, Sub};
+use std::ops::{Add, AddAssign, Deref, Mul, RangeInclusive, Sub};
 use std::str::FromStr;
 
 use bitflags::bitflags;
@@ -226,22 +226,22 @@ pub const MAX_SIMD_LANES: u64 = 1 << 0xF;
 #[derive(Debug, PartialEq, Eq)]
 pub struct TargetDataLayout {
     pub endian: Endian,
-    pub i1_align: AbiAndPrefAlign,
-    pub i8_align: AbiAndPrefAlign,
-    pub i16_align: AbiAndPrefAlign,
-    pub i32_align: AbiAndPrefAlign,
-    pub i64_align: AbiAndPrefAlign,
-    pub i128_align: AbiAndPrefAlign,
-    pub f16_align: AbiAndPrefAlign,
-    pub f32_align: AbiAndPrefAlign,
-    pub f64_align: AbiAndPrefAlign,
-    pub f128_align: AbiAndPrefAlign,
+    pub i1_align: AbiAlign,
+    pub i8_align: AbiAlign,
+    pub i16_align: AbiAlign,
+    pub i32_align: AbiAlign,
+    pub i64_align: AbiAlign,
+    pub i128_align: AbiAlign,
+    pub f16_align: AbiAlign,
+    pub f32_align: AbiAlign,
+    pub f64_align: AbiAlign,
+    pub f128_align: AbiAlign,
     pub pointer_size: Size,
-    pub pointer_align: AbiAndPrefAlign,
-    pub aggregate_align: AbiAndPrefAlign,
+    pub pointer_align: AbiAlign,
+    pub aggregate_align: AbiAlign,
 
     /// Alignments for vector types.
-    pub vector_align: Vec<(Size, AbiAndPrefAlign)>,
+    pub vector_align: Vec<(Size, AbiAlign)>,
 
     pub instruction_address_space: AddressSpace,
 
@@ -257,22 +257,22 @@ impl Default for TargetDataLayout {
         let align = |bits| Align::from_bits(bits).unwrap();
         TargetDataLayout {
             endian: Endian::Big,
-            i1_align: AbiAndPrefAlign::new(align(8)),
-            i8_align: AbiAndPrefAlign::new(align(8)),
-            i16_align: AbiAndPrefAlign::new(align(16)),
-            i32_align: AbiAndPrefAlign::new(align(32)),
-            i64_align: AbiAndPrefAlign { abi: align(32), pref: align(64) },
-            i128_align: AbiAndPrefAlign { abi: align(32), pref: align(64) },
-            f16_align: AbiAndPrefAlign::new(align(16)),
-            f32_align: AbiAndPrefAlign::new(align(32)),
-            f64_align: AbiAndPrefAlign::new(align(64)),
-            f128_align: AbiAndPrefAlign::new(align(128)),
+            i1_align: AbiAlign::new(align(8)),
+            i8_align: AbiAlign::new(align(8)),
+            i16_align: AbiAlign::new(align(16)),
+            i32_align: AbiAlign::new(align(32)),
+            i64_align: AbiAlign::new(align(32)),
+            i128_align: AbiAlign::new(align(32)),
+            f16_align: AbiAlign::new(align(16)),
+            f32_align: AbiAlign::new(align(32)),
+            f64_align: AbiAlign::new(align(64)),
+            f128_align: AbiAlign::new(align(128)),
             pointer_size: Size::from_bits(64),
-            pointer_align: AbiAndPrefAlign::new(align(64)),
-            aggregate_align: AbiAndPrefAlign { abi: align(0), pref: align(64) },
+            pointer_align: AbiAlign::new(align(64)),
+            aggregate_align: AbiAlign { abi: align(8) },
             vector_align: vec![
-                (Size::from_bits(64), AbiAndPrefAlign::new(align(64))),
-                (Size::from_bits(128), AbiAndPrefAlign::new(align(128))),
+                (Size::from_bits(64), AbiAlign::new(align(64))),
+                (Size::from_bits(128), AbiAlign::new(align(128))),
             ],
             instruction_address_space: AddressSpace::DATA,
             c_enum_min_size: Integer::I32,
@@ -330,8 +330,7 @@ impl TargetDataLayout {
                     .map_err(|err| TargetDataLayoutErrors::InvalidAlignment { cause, err })
             };
             let abi = parse_bits(s[0], "alignment", cause)?;
-            let pref = s.get(1).map_or(Ok(abi), |pref| parse_bits(pref, "alignment", cause))?;
-            Ok(AbiAndPrefAlign { abi: align_from_bits(abi)?, pref: align_from_bits(pref)? })
+            Ok(AbiAlign::new(align_from_bits(abi)?))
         };
 
         let mut dl = TargetDataLayout::default();
@@ -426,7 +425,7 @@ impl TargetDataLayout {
 
     /// psABI-mandated alignment for a vector type, if any
     #[inline]
-    fn cabi_vector_align(&self, vec_size: Size) -> Option<AbiAndPrefAlign> {
+    fn cabi_vector_align(&self, vec_size: Size) -> Option<AbiAlign> {
         self.vector_align
             .iter()
             .find(|(size, _align)| *size == vec_size)
@@ -435,8 +434,8 @@ impl TargetDataLayout {
 
     /// an alignment resembling the one LLVM would pick for a vector
     #[inline]
-    pub fn llvmlike_vector_align(&self, vec_size: Size) -> AbiAndPrefAlign {
-        self.cabi_vector_align(vec_size).unwrap_or(AbiAndPrefAlign::new(
+    pub fn llvmlike_vector_align(&self, vec_size: Size) -> AbiAlign {
+        self.cabi_vector_align(vec_size).unwrap_or(AbiAlign::new(
             Align::from_bytes(vec_size.bytes().next_power_of_two()).unwrap(),
         ))
     }
@@ -864,25 +863,32 @@ impl Align {
 /// It is of effectively no consequence for layout in structs and on the stack.
 #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
 #[cfg_attr(feature = "nightly", derive(HashStable_Generic))]
-pub struct AbiAndPrefAlign {
+pub struct AbiAlign {
     pub abi: Align,
-    pub pref: Align,
 }
 
-impl AbiAndPrefAlign {
+impl AbiAlign {
     #[inline]
-    pub fn new(align: Align) -> AbiAndPrefAlign {
-        AbiAndPrefAlign { abi: align, pref: align }
+    pub fn new(align: Align) -> AbiAlign {
+        AbiAlign { abi: align }
     }
 
     #[inline]
-    pub fn min(self, other: AbiAndPrefAlign) -> AbiAndPrefAlign {
-        AbiAndPrefAlign { abi: self.abi.min(other.abi), pref: self.pref.min(other.pref) }
+    pub fn min(self, other: AbiAlign) -> AbiAlign {
+        AbiAlign { abi: self.abi.min(other.abi) }
     }
 
     #[inline]
-    pub fn max(self, other: AbiAndPrefAlign) -> AbiAndPrefAlign {
-        AbiAndPrefAlign { abi: self.abi.max(other.abi), pref: self.pref.max(other.pref) }
+    pub fn max(self, other: AbiAlign) -> AbiAlign {
+        AbiAlign { abi: self.abi.max(other.abi) }
+    }
+}
+
+impl Deref for AbiAlign {
+    type Target = Align;
+
+    fn deref(&self) -> &Self::Target {
+        &self.abi
     }
 }
 
@@ -945,7 +951,7 @@ impl Integer {
         }
     }
 
-    pub fn align<C: HasDataLayout>(self, cx: &C) -> AbiAndPrefAlign {
+    pub fn align<C: HasDataLayout>(self, cx: &C) -> AbiAlign {
         use Integer::*;
         let dl = cx.data_layout();
 
@@ -1058,7 +1064,7 @@ impl Float {
         }
     }
 
-    pub fn align<C: HasDataLayout>(self, cx: &C) -> AbiAndPrefAlign {
+    pub fn align<C: HasDataLayout>(self, cx: &C) -> AbiAlign {
         use Float::*;
         let dl = cx.data_layout();
 
@@ -1102,7 +1108,7 @@ impl Primitive {
         }
     }
 
-    pub fn align<C: HasDataLayout>(self, cx: &C) -> AbiAndPrefAlign {
+    pub fn align<C: HasDataLayout>(self, cx: &C) -> AbiAlign {
         use Primitive::*;
         let dl = cx.data_layout();
 
@@ -1225,7 +1231,7 @@ impl Scalar {
         }
     }
 
-    pub fn align(self, cx: &impl HasDataLayout) -> AbiAndPrefAlign {
+    pub fn align(self, cx: &impl HasDataLayout) -> AbiAlign {
         self.primitive().align(cx)
     }
 
@@ -1731,7 +1737,7 @@ pub struct LayoutData<FieldIdx: Idx, VariantIdx: Idx> {
     /// especially in the case of by-pointer struct returns, which allocate stack even when unused.
     pub uninhabited: bool,
 
-    pub align: AbiAndPrefAlign,
+    pub align: AbiAlign,
     pub size: Size,
 
     /// The largest alignment explicitly requested with `repr(align)` on this type or any field.
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index 3004be40334..b99df8bd7e5 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -33,9 +33,7 @@
 // tidy-alphabetical-start
 #![allow(internal_features)]
 #![doc(rust_logo)]
-#![feature(assert_matches)]
 #![feature(box_patterns)]
-#![feature(exact_size_is_empty)]
 #![feature(if_let_guard)]
 #![feature(rustdoc_internals)]
 // tidy-alphabetical-end
diff --git a/compiler/rustc_builtin_macros/src/lib.rs b/compiler/rustc_builtin_macros/src/lib.rs
index aa52c3bd281..9e7d0ec9e81 100644
--- a/compiler/rustc_builtin_macros/src/lib.rs
+++ b/compiler/rustc_builtin_macros/src/lib.rs
@@ -15,7 +15,6 @@
 #![feature(proc_macro_internals)]
 #![feature(proc_macro_quote)]
 #![feature(rustdoc_internals)]
-#![feature(string_from_utf8_lossy_owned)]
 #![feature(try_blocks)]
 #![recursion_limit = "256"]
 // tidy-alphabetical-end
diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs
index a0f96d85dc3..1d1cf884e48 100644
--- a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs
+++ b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs
@@ -812,11 +812,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
             dest.write_cvalue(fx, val);
         }
 
-        sym::pref_align_of
-        | sym::needs_drop
-        | sym::type_id
-        | sym::type_name
-        | sym::variant_count => {
+        sym::needs_drop | sym::type_id | sym::type_name | sym::variant_count => {
             intrinsic_args!(fx, args => (); intrinsic);
 
             let const_val = fx
diff --git a/compiler/rustc_codegen_gcc/example/alloc_system.rs b/compiler/rustc_codegen_gcc/example/alloc_system.rs
index 945d34063a6..4d70122496b 100644
--- a/compiler/rustc_codegen_gcc/example/alloc_system.rs
+++ b/compiler/rustc_codegen_gcc/example/alloc_system.rs
@@ -8,6 +8,7 @@
 // add fast paths for low alignment values.
 #[cfg(any(target_arch = "x86",
               target_arch = "arm",
+              target_arch = "loongarch32",
               target_arch = "m68k",
               target_arch = "mips",
               target_arch = "mips32r6",
diff --git a/compiler/rustc_codegen_gcc/messages.ftl b/compiler/rustc_codegen_gcc/messages.ftl
index 882fff8673a..546bfc87b68 100644
--- a/compiler/rustc_codegen_gcc/messages.ftl
+++ b/compiler/rustc_codegen_gcc/messages.ftl
@@ -2,9 +2,6 @@ codegen_gcc_unknown_ctarget_feature_prefix =
     unknown feature specified for `-Ctarget-feature`: `{$feature}`
     .note = features must begin with a `+` to enable or `-` to disable it
 
-codegen_gcc_invalid_minimum_alignment =
-    invalid minimum global alignment: {$err}
-
 codegen_gcc_forbidden_ctarget_feature =
     target feature `{$feature}` cannot be toggled with `-Ctarget-feature`: {$reason}
 
diff --git a/compiler/rustc_codegen_gcc/src/consts.rs b/compiler/rustc_codegen_gcc/src/consts.rs
index deb13ddf755..1690641a5bc 100644
--- a/compiler/rustc_codegen_gcc/src/consts.rs
+++ b/compiler/rustc_codegen_gcc/src/consts.rs
@@ -18,7 +18,6 @@ use rustc_span::def_id::DefId;
 
 use crate::base;
 use crate::context::CodegenCx;
-use crate::errors::InvalidMinimumAlignment;
 use crate::type_of::LayoutGccExt;
 
 fn set_global_alignment<'gcc, 'tcx>(
@@ -29,13 +28,8 @@ fn set_global_alignment<'gcc, 'tcx>(
     // The target may require greater alignment for globals than the type does.
     // Note: GCC and Clang also allow `__attribute__((aligned))` on variables,
     // which can force it to be smaller. Rust doesn't support this yet.
-    if let Some(min) = cx.sess().target.min_global_align {
-        match Align::from_bits(min) {
-            Ok(min) => align = align.max(min),
-            Err(err) => {
-                cx.sess().dcx().emit_err(InvalidMinimumAlignment { err: err.to_string() });
-            }
-        }
+    if let Some(min_global) = cx.sess().target.min_global_align {
+        align = Ord::max(align, min_global);
     }
     gv.set_alignment(align.bytes() as i32);
 }
diff --git a/compiler/rustc_codegen_gcc/src/errors.rs b/compiler/rustc_codegen_gcc/src/errors.rs
index 1b59b9ac169..ccd9abe3804 100644
--- a/compiler/rustc_codegen_gcc/src/errors.rs
+++ b/compiler/rustc_codegen_gcc/src/errors.rs
@@ -48,12 +48,6 @@ pub(crate) struct UnwindingInlineAsm {
 }
 
 #[derive(Diagnostic)]
-#[diag(codegen_gcc_invalid_minimum_alignment)]
-pub(crate) struct InvalidMinimumAlignment {
-    pub err: String,
-}
-
-#[derive(Diagnostic)]
 #[diag(codegen_gcc_copy_bitcode)]
 pub(crate) struct CopyBitcode {
     pub err: std::io::Error,
diff --git a/compiler/rustc_codegen_gcc/src/lib.rs b/compiler/rustc_codegen_gcc/src/lib.rs
index f79ba2dcfc7..0591ffa42e4 100644
--- a/compiler/rustc_codegen_gcc/src/lib.rs
+++ b/compiler/rustc_codegen_gcc/src/lib.rs
@@ -16,7 +16,7 @@
 #![allow(internal_features)]
 #![doc(rust_logo)]
 #![feature(rustdoc_internals)]
-#![feature(rustc_private, decl_macro, never_type, trusted_len)]
+#![feature(rustc_private)]
 #![allow(broken_intra_doc_links)]
 #![recursion_limit = "256"]
 #![warn(rust_2018_idioms)]
diff --git a/compiler/rustc_codegen_llvm/Cargo.toml b/compiler/rustc_codegen_llvm/Cargo.toml
index bf8ec8c3b91..88efc8ac96b 100644
--- a/compiler/rustc_codegen_llvm/Cargo.toml
+++ b/compiler/rustc_codegen_llvm/Cargo.toml
@@ -15,7 +15,7 @@ gimli = "0.31"
 itertools = "0.12"
 libc = "0.2"
 measureme = "12.0.1"
-object = { version = "0.36.3", default-features = false, features = ["std", "read"] }
+object = { version = "0.37.0", default-features = false, features = ["std", "read"] }
 rustc-demangle = "0.1.21"
 rustc_abi = { path = "../rustc_abi" }
 rustc_ast = { path = "../rustc_ast" }
diff --git a/compiler/rustc_codegen_llvm/messages.ftl b/compiler/rustc_codegen_llvm/messages.ftl
index 41391b096cc..bda121c67fb 100644
--- a/compiler/rustc_codegen_llvm/messages.ftl
+++ b/compiler/rustc_codegen_llvm/messages.ftl
@@ -19,12 +19,6 @@ codegen_llvm_from_llvm_diag = {$message}
 
 codegen_llvm_from_llvm_optimization_diag = {$filename}:{$line}:{$column} {$pass_name} ({$kind}): {$message}
 
-codegen_llvm_invalid_minimum_alignment_not_power_of_two =
-    invalid minimum global alignment: {$align} is not power of 2
-
-codegen_llvm_invalid_minimum_alignment_too_large =
-    invalid minimum global alignment: {$align} is too large
-
 codegen_llvm_load_bitcode = failed to load bitcode of module "{$name}"
 codegen_llvm_load_bitcode_with_llvm_err = failed to load bitcode of module "{$name}": {$llvm_err}
 
diff --git a/compiler/rustc_codegen_llvm/src/asm.rs b/compiler/rustc_codegen_llvm/src/asm.rs
index 9e3893d5314..4185aef8b31 100644
--- a/compiler/rustc_codegen_llvm/src/asm.rs
+++ b/compiler/rustc_codegen_llvm/src/asm.rs
@@ -251,7 +251,7 @@ impl<'ll, 'tcx> AsmBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
                 InlineAsmArch::Nvptx64 => {}
                 InlineAsmArch::PowerPC | InlineAsmArch::PowerPC64 => {}
                 InlineAsmArch::Hexagon => {}
-                InlineAsmArch::LoongArch64 => {
+                InlineAsmArch::LoongArch32 | InlineAsmArch::LoongArch64 => {
                     constraints.extend_from_slice(&[
                         "~{$fcc0}".to_string(),
                         "~{$fcc1}".to_string(),
diff --git a/compiler/rustc_codegen_llvm/src/consts.rs b/compiler/rustc_codegen_llvm/src/consts.rs
index 73def2711dc..a4492d76c3c 100644
--- a/compiler/rustc_codegen_llvm/src/consts.rs
+++ b/compiler/rustc_codegen_llvm/src/consts.rs
@@ -1,8 +1,6 @@
 use std::ops::Range;
 
-use rustc_abi::{
-    Align, AlignFromBytesError, HasDataLayout, Primitive, Scalar, Size, WrappingRange,
-};
+use rustc_abi::{Align, HasDataLayout, Primitive, Scalar, Size, WrappingRange};
 use rustc_codegen_ssa::common;
 use rustc_codegen_ssa::traits::*;
 use rustc_hir::LangItem;
@@ -20,9 +18,7 @@ use rustc_middle::{bug, span_bug};
 use tracing::{debug, instrument, trace};
 
 use crate::common::{AsCCharPtr, CodegenCx};
-use crate::errors::{
-    InvalidMinimumAlignmentNotPowerOfTwo, InvalidMinimumAlignmentTooLarge, SymbolAlreadyDefined,
-};
+use crate::errors::SymbolAlreadyDefined;
 use crate::llvm::{self, True};
 use crate::type_::Type;
 use crate::type_of::LayoutLlvmExt;
@@ -149,22 +145,10 @@ fn set_global_alignment<'ll>(cx: &CodegenCx<'ll, '_>, gv: &'ll Value, mut align:
     // The target may require greater alignment for globals than the type does.
     // Note: GCC and Clang also allow `__attribute__((aligned))` on variables,
     // which can force it to be smaller. Rust doesn't support this yet.
-    if let Some(min) = cx.sess().target.min_global_align {
-        match Align::from_bits(min) {
-            Ok(min) => align = align.max(min),
-            Err(err) => match err {
-                AlignFromBytesError::NotPowerOfTwo(align) => {
-                    cx.sess().dcx().emit_err(InvalidMinimumAlignmentNotPowerOfTwo { align });
-                }
-                AlignFromBytesError::TooLarge(align) => {
-                    cx.sess().dcx().emit_err(InvalidMinimumAlignmentTooLarge { align });
-                }
-            },
-        }
-    }
-    unsafe {
-        llvm::LLVMSetAlignment(gv, align.bytes() as u32);
+    if let Some(min_global) = cx.sess().target.min_global_align {
+        align = Ord::max(align, min_global);
     }
+    llvm::set_alignment(gv, align);
 }
 
 fn check_and_apply_linkage<'ll, 'tcx>(
diff --git a/compiler/rustc_codegen_llvm/src/errors.rs b/compiler/rustc_codegen_llvm/src/errors.rs
index ecf108f988f..eaafc680712 100644
--- a/compiler/rustc_codegen_llvm/src/errors.rs
+++ b/compiler/rustc_codegen_llvm/src/errors.rs
@@ -58,18 +58,6 @@ pub(crate) struct SymbolAlreadyDefined<'a> {
 }
 
 #[derive(Diagnostic)]
-#[diag(codegen_llvm_invalid_minimum_alignment_not_power_of_two)]
-pub(crate) struct InvalidMinimumAlignmentNotPowerOfTwo {
-    pub align: u64,
-}
-
-#[derive(Diagnostic)]
-#[diag(codegen_llvm_invalid_minimum_alignment_too_large)]
-pub(crate) struct InvalidMinimumAlignmentTooLarge {
-    pub align: u64,
-}
-
-#[derive(Diagnostic)]
 #[diag(codegen_llvm_sanitizer_memtag_requires_mte)]
 pub(crate) struct SanitizerMemtagRequiresMte;
 
diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs
index fd376ea8d80..6890923a594 100644
--- a/compiler/rustc_codegen_llvm/src/lib.rs
+++ b/compiler/rustc_codegen_llvm/src/lib.rs
@@ -9,7 +9,6 @@
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
 #![doc(rust_logo)]
 #![feature(assert_matches)]
-#![feature(exact_size_is_empty)]
 #![feature(extern_types)]
 #![feature(file_buffered)]
 #![feature(if_let_guard)]
diff --git a/compiler/rustc_codegen_ssa/Cargo.toml b/compiler/rustc_codegen_ssa/Cargo.toml
index 337c6944177..e9c4c255bce 100644
--- a/compiler/rustc_codegen_ssa/Cargo.toml
+++ b/compiler/rustc_codegen_ssa/Cargo.toml
@@ -54,7 +54,7 @@ libc = "0.2.50"
 # tidy-alphabetical-end
 
 [dependencies.object]
-version = "0.36.2"
+version = "0.37.0"
 default-features = false
 features = ["read_core", "elf", "macho", "pe", "xcoff", "unaligned", "archive", "write", "wasm"]
 
diff --git a/compiler/rustc_codegen_ssa/src/back/link/raw_dylib.rs b/compiler/rustc_codegen_ssa/src/back/link/raw_dylib.rs
index 2c24378afe1..74f39022afb 100644
--- a/compiler/rustc_codegen_ssa/src/back/link/raw_dylib.rs
+++ b/compiler/rustc_codegen_ssa/src/back/link/raw_dylib.rs
@@ -287,6 +287,7 @@ fn create_elf_raw_dylib_stub(sess: &Session, soname: &str, symbols: &[DllImport]
         (Architecture::X86_64, None) => elf::EM_X86_64,
         (Architecture::X86_64_X32, None) => elf::EM_X86_64,
         (Architecture::Hexagon, None) => elf::EM_HEXAGON,
+        (Architecture::LoongArch32, None) => elf::EM_LOONGARCH,
         (Architecture::LoongArch64, None) => elf::EM_LOONGARCH,
         (Architecture::M68k, None) => elf::EM_68K,
         (Architecture::Mips, None) => elf::EM_MIPS,
diff --git a/compiler/rustc_codegen_ssa/src/back/metadata.rs b/compiler/rustc_codegen_ssa/src/back/metadata.rs
index ec46c71b0e4..a16862c41ee 100644
--- a/compiler/rustc_codegen_ssa/src/back/metadata.rs
+++ b/compiler/rustc_codegen_ssa/src/back/metadata.rs
@@ -348,7 +348,7 @@ pub(super) fn elf_e_flags(architecture: Architecture, sess: &Session) -> u32 {
 
             e_flags
         }
-        Architecture::LoongArch64 => {
+        Architecture::LoongArch32 | Architecture::LoongArch64 => {
             // Source: https://github.com/loongson/la-abi-specs/blob/release/laelf.adoc#e_flags-identifies-abi-type-and-version
             let mut e_flags: u32 = elf::EF_LARCH_OBJABI_V1;
 
diff --git a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs
index a3f09f64a3e..e217c09939e 100644
--- a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs
@@ -150,11 +150,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                 }
                 value
             }
-            sym::pref_align_of
-            | sym::needs_drop
-            | sym::type_id
-            | sym::type_name
-            | sym::variant_count => {
+            sym::needs_drop | sym::type_id | sym::type_name | sym::variant_count => {
                 let value = bx.tcx().const_eval_instance(bx.typing_env(), instance, span).unwrap();
                 OperandRef::from_const(bx, value, result.layout.ty).immediate_or_packed_pair(bx)
             }
diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs
index 64467a90136..ab27182c211 100644
--- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs
+++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs
@@ -50,13 +50,6 @@ pub(crate) fn eval_nullary_intrinsic<'tcx>(
             ensure_monomorphic_enough(tcx, tp_ty)?;
             ConstValue::from_bool(tp_ty.needs_drop(tcx, typing_env))
         }
-        sym::pref_align_of => {
-            // Correctly handles non-monomorphic calls, so there is no need for ensure_monomorphic_enough.
-            let layout = tcx
-                .layout_of(typing_env.as_query_input(tp_ty))
-                .map_err(|e| err_inval!(Layout(*e)))?;
-            ConstValue::from_target_usize(layout.align.pref.bytes(), &tcx)
-        }
         sym::type_id => {
             ensure_monomorphic_enough(tcx, tp_ty)?;
             ConstValue::from_u128(tcx.type_id_hash(tp_ty).as_u128())
@@ -144,14 +137,10 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
                 self.write_scalar(Scalar::from_target_usize(result, self), dest)?;
             }
 
-            sym::pref_align_of
-            | sym::needs_drop
-            | sym::type_id
-            | sym::type_name
-            | sym::variant_count => {
+            sym::needs_drop | sym::type_id | sym::type_name | sym::variant_count => {
                 let gid = GlobalId { instance, promoted: None };
                 let ty = match intrinsic_name {
-                    sym::pref_align_of | sym::variant_count => self.tcx.types.usize,
+                    sym::variant_count => self.tcx.types.usize,
                     sym::needs_drop => self.tcx.types.bool,
                     sym::type_id => self.tcx.types.u128,
                     sym::type_name => Ty::new_static_str(self.tcx.tcx),
diff --git a/compiler/rustc_data_structures/src/lib.rs b/compiler/rustc_data_structures/src/lib.rs
index b7447e24731..eb3817a80a7 100644
--- a/compiler/rustc_data_structures/src/lib.rs
+++ b/compiler/rustc_data_structures/src/lib.rs
@@ -25,7 +25,6 @@
 #![feature(dropck_eyepatch)]
 #![feature(extend_one)]
 #![feature(file_buffered)]
-#![feature(macro_metavar_expr)]
 #![feature(map_try_insert)]
 #![feature(min_specialization)]
 #![feature(negative_impls)]
diff --git a/compiler/rustc_error_messages/Cargo.toml b/compiler/rustc_error_messages/Cargo.toml
index 0951859fa53..5dc582b9c3a 100644
--- a/compiler/rustc_error_messages/Cargo.toml
+++ b/compiler/rustc_error_messages/Cargo.toml
@@ -16,6 +16,7 @@ rustc_data_structures = { path = "../rustc_data_structures" }
 rustc_macros = { path = "../rustc_macros" }
 rustc_serialize = { path = "../rustc_serialize" }
 rustc_span = { path = "../rustc_span" }
+smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
 tracing = "0.1"
 unic-langid = { version = "0.9.0", features = ["macros"] }
 # tidy-alphabetical-end
diff --git a/compiler/rustc_error_messages/src/lib.rs b/compiler/rustc_error_messages/src/lib.rs
index 3c6df147b1b..1d3b5b20751 100644
--- a/compiler/rustc_error_messages/src/lib.rs
+++ b/compiler/rustc_error_messages/src/lib.rs
@@ -21,6 +21,7 @@ use intl_memoizer::concurrent::IntlLangMemoizer;
 use rustc_data_structures::sync::IntoDynSyncSend;
 use rustc_macros::{Decodable, Encodable};
 use rustc_span::Span;
+use smallvec::SmallVec;
 use tracing::{instrument, trace};
 pub use unic_langid::{LanguageIdentifier, langid};
 
@@ -106,8 +107,7 @@ impl From<Vec<FluentError>> for TranslationBundleError {
 /// (overriding any conflicting messages).
 #[instrument(level = "trace")]
 pub fn fluent_bundle(
-    sysroot: PathBuf,
-    sysroot_candidates: Vec<PathBuf>,
+    sysroot_candidates: SmallVec<[PathBuf; 2]>,
     requested_locale: Option<LanguageIdentifier>,
     additional_ftl_path: Option<&Path>,
     with_directionality_markers: bool,
@@ -141,7 +141,7 @@ pub fn fluent_bundle(
     // If the user requests the default locale then don't try to load anything.
     if let Some(requested_locale) = requested_locale {
         let mut found_resources = false;
-        for mut sysroot in Some(sysroot).into_iter().chain(sysroot_candidates.into_iter()) {
+        for mut sysroot in sysroot_candidates {
             sysroot.push("share");
             sysroot.push("locale");
             sysroot.push(requested_locale.to_string());
diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs
index 6f0090a0bd6..133bd361ee7 100644
--- a/compiler/rustc_errors/src/lib.rs
+++ b/compiler/rustc_errors/src/lib.rs
@@ -15,12 +15,10 @@
 #![feature(box_patterns)]
 #![feature(default_field_values)]
 #![feature(error_reporter)]
-#![feature(if_let_guard)]
 #![feature(negative_impls)]
 #![feature(never_type)]
 #![feature(rustc_attrs)]
 #![feature(rustdoc_internals)]
-#![feature(trait_alias)]
 #![feature(try_blocks)]
 #![feature(yeet_expr)]
 // tidy-alphabetical-end
diff --git a/compiler/rustc_expand/src/lib.rs b/compiler/rustc_expand/src/lib.rs
index 35b38d99c70..515d82296ca 100644
--- a/compiler/rustc_expand/src/lib.rs
+++ b/compiler/rustc_expand/src/lib.rs
@@ -6,7 +6,6 @@
 #![feature(associated_type_defaults)]
 #![feature(if_let_guard)]
 #![feature(macro_metavar_expr)]
-#![feature(map_try_insert)]
 #![feature(proc_macro_diagnostic)]
 #![feature(proc_macro_internals)]
 #![feature(rustdoc_internals)]
diff --git a/compiler/rustc_feature/src/removed.rs b/compiler/rustc_feature/src/removed.rs
index 687d859df53..013e1d5d0fa 100644
--- a/compiler/rustc_feature/src/removed.rs
+++ b/compiler/rustc_feature/src/removed.rs
@@ -207,6 +207,8 @@ declare_features! (
     /// Allows exhaustive integer pattern matching with `usize::MAX`/`isize::MIN`/`isize::MAX`.
     (removed, precise_pointer_size_matching, "1.32.0", Some(56354),
      Some("removed in favor of half-open ranges")),
+    (removed, pref_align_of, "CURRENT_RUSTC_VERSION", Some(91971),
+     Some("removed due to marginal use and inducing compiler complications")),
     (removed, proc_macro_expr, "1.27.0", Some(54727),
      Some("subsumed by `#![feature(proc_macro_hygiene)]`")),
     (removed, proc_macro_gen, "1.27.0", Some(54727),
diff --git a/compiler/rustc_fluent_macro/src/lib.rs b/compiler/rustc_fluent_macro/src/lib.rs
index c6e0484b921..6f85e05f29a 100644
--- a/compiler/rustc_fluent_macro/src/lib.rs
+++ b/compiler/rustc_fluent_macro/src/lib.rs
@@ -4,7 +4,6 @@
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
 #![doc(rust_logo)]
 #![feature(proc_macro_diagnostic)]
-#![feature(proc_macro_span)]
 #![feature(rustdoc_internals)]
 #![feature(track_path)]
 // tidy-alphabetical-end
diff --git a/compiler/rustc_hir/src/lib.rs b/compiler/rustc_hir/src/lib.rs
index 7a5ff890689..c6fe475b460 100644
--- a/compiler/rustc_hir/src/lib.rs
+++ b/compiler/rustc_hir/src/lib.rs
@@ -5,7 +5,6 @@
 // tidy-alphabetical-start
 #![allow(internal_features)]
 #![feature(associated_type_defaults)]
-#![feature(box_patterns)]
 #![feature(closure_track_caller)]
 #![feature(debug_closure_helpers)]
 #![feature(exhaustive_patterns)]
diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs
index b0346f8d32e..fe3a23289fe 100644
--- a/compiler/rustc_hir_typeck/src/lib.rs
+++ b/compiler/rustc_hir_typeck/src/lib.rs
@@ -1,13 +1,11 @@
 // tidy-alphabetical-start
 #![allow(rustc::diagnostic_outside_of_impl)]
 #![allow(rustc::untranslatable_diagnostic)]
-#![feature(array_windows)]
 #![feature(assert_matches)]
 #![feature(box_patterns)]
 #![feature(if_let_guard)]
 #![feature(iter_intersperse)]
 #![feature(never_type)]
-#![feature(try_blocks)]
 // tidy-alphabetical-end
 
 mod _match;
diff --git a/compiler/rustc_infer/src/lib.rs b/compiler/rustc_infer/src/lib.rs
index ab7b7060c09..550707ed4bc 100644
--- a/compiler/rustc_infer/src/lib.rs
+++ b/compiler/rustc_infer/src/lib.rs
@@ -20,7 +20,6 @@
 #![doc(rust_logo)]
 #![feature(assert_matches)]
 #![feature(extend_one)]
-#![feature(iterator_try_collect)]
 #![feature(rustdoc_internals)]
 #![recursion_limit = "512"] // For rustdoc
 // tidy-alphabetical-end
diff --git a/compiler/rustc_interface/src/interface.rs b/compiler/rustc_interface/src/interface.rs
index cf494f8d686..e824e9d4aa9 100644
--- a/compiler/rustc_interface/src/interface.rs
+++ b/compiler/rustc_interface/src/interface.rs
@@ -18,7 +18,7 @@ use rustc_parse::parser::attr::AllowLeadingUnsafe;
 use rustc_query_impl::QueryCtxt;
 use rustc_query_system::query::print_query_stack;
 use rustc_session::config::{self, Cfg, CheckCfg, ExpectedValues, Input, OutFileName};
-use rustc_session::filesearch::sysroot_candidates;
+use rustc_session::filesearch::sysroot_with_fallback;
 use rustc_session::parse::ParseSess;
 use rustc_session::{CompilerIO, EarlyDiagCtxt, Session, lint};
 use rustc_span::source_map::{FileLoader, RealFileLoader, SourceMapInputs};
@@ -442,8 +442,7 @@ pub fn run_compiler<R: Send>(config: Config, f: impl FnOnce(&Compiler) -> R + Se
             let temps_dir = config.opts.unstable_opts.temps_dir.as_deref().map(PathBuf::from);
 
             let bundle = match rustc_errors::fluent_bundle(
-                config.opts.sysroot.clone(),
-                sysroot_candidates().to_vec(),
+                sysroot_with_fallback(&config.opts.sysroot),
                 config.opts.unstable_opts.translate_lang.clone(),
                 config.opts.unstable_opts.translate_additional_ftl.as_deref(),
                 config.opts.unstable_opts.translate_directionality_markers,
diff --git a/compiler/rustc_interface/src/util.rs b/compiler/rustc_interface/src/util.rs
index 087b11fdf9d..8bdc24d47d9 100644
--- a/compiler/rustc_interface/src/util.rs
+++ b/compiler/rustc_interface/src/util.rs
@@ -2,7 +2,7 @@ use std::env::consts::{DLL_PREFIX, DLL_SUFFIX};
 use std::path::{Path, PathBuf};
 use std::sync::atomic::{AtomicBool, Ordering};
 use std::sync::{Arc, OnceLock};
-use std::{env, iter, thread};
+use std::{env, thread};
 
 use rustc_ast as ast;
 use rustc_codegen_ssa::traits::CodegenBackend;
@@ -12,7 +12,6 @@ use rustc_metadata::{DylibError, load_symbol_from_dylib};
 use rustc_middle::ty::CurrentGcx;
 use rustc_parse::validate_attr;
 use rustc_session::config::{Cfg, OutFileName, OutputFilenames, OutputTypes, host_tuple};
-use rustc_session::filesearch::sysroot_candidates;
 use rustc_session::lint::{self, BuiltinLintDiag, LintBuffer};
 use rustc_session::output::{CRATE_TYPES, categorize_crate_type};
 use rustc_session::{EarlyDiagCtxt, Session, filesearch};
@@ -346,14 +345,10 @@ pub fn rustc_path<'a>() -> Option<&'a Path> {
 }
 
 fn get_rustc_path_inner(bin_path: &str) -> Option<PathBuf> {
-    sysroot_candidates().iter().find_map(|sysroot| {
-        let candidate = sysroot.join(bin_path).join(if cfg!(target_os = "windows") {
-            "rustc.exe"
-        } else {
-            "rustc"
-        });
-        candidate.exists().then_some(candidate)
-    })
+    let candidate = filesearch::get_or_default_sysroot()
+        .join(bin_path)
+        .join(if cfg!(target_os = "windows") { "rustc.exe" } else { "rustc" });
+    candidate.exists().then_some(candidate)
 }
 
 #[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable
@@ -374,10 +369,10 @@ fn get_codegen_sysroot(
     );
 
     let target = host_tuple();
-    let sysroot_candidates = sysroot_candidates();
+    let sysroot_candidates = filesearch::sysroot_with_fallback(&sysroot);
 
-    let sysroot = iter::once(sysroot)
-        .chain(sysroot_candidates.iter().map(<_>::as_ref))
+    let sysroot = sysroot_candidates
+        .iter()
         .map(|sysroot| {
             filesearch::make_target_lib_path(sysroot, target).with_file_name("codegen-backends")
         })
diff --git a/compiler/rustc_macros/src/lib.rs b/compiler/rustc_macros/src/lib.rs
index 81817018cb1..42d006ef301 100644
--- a/compiler/rustc_macros/src/lib.rs
+++ b/compiler/rustc_macros/src/lib.rs
@@ -3,7 +3,6 @@
 #![feature(if_let_guard)]
 #![feature(never_type)]
 #![feature(proc_macro_diagnostic)]
-#![feature(proc_macro_span)]
 #![feature(proc_macro_tracked_env)]
 // tidy-alphabetical-end
 
diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs
index 7135b8f04a2..667361b3ca0 100644
--- a/compiler/rustc_middle/src/lib.rs
+++ b/compiler/rustc_middle/src/lib.rs
@@ -54,7 +54,6 @@
 #![feature(round_char_boundary)]
 #![feature(rustc_attrs)]
 #![feature(rustdoc_internals)]
-#![feature(trusted_len)]
 #![feature(try_blocks)]
 #![feature(try_trait_v2)]
 #![feature(try_trait_v2_yeet)]
diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs
index d26e4468715..572ad585c8c 100644
--- a/compiler/rustc_mir_transform/src/lib.rs
+++ b/compiler/rustc_mir_transform/src/lib.rs
@@ -7,10 +7,7 @@
 #![feature(file_buffered)]
 #![feature(if_let_guard)]
 #![feature(impl_trait_in_assoc_type)]
-#![feature(map_try_insert)]
-#![feature(never_type)]
 #![feature(try_blocks)]
-#![feature(vec_deque_pop_if)]
 #![feature(yeet_expr)]
 // tidy-alphabetical-end
 
diff --git a/compiler/rustc_parse/src/lib.rs b/compiler/rustc_parse/src/lib.rs
index 3ab726d9d9d..8ea535599c9 100644
--- a/compiler/rustc_parse/src/lib.rs
+++ b/compiler/rustc_parse/src/lib.rs
@@ -9,7 +9,6 @@
 #![feature(debug_closure_helpers)]
 #![feature(if_let_guard)]
 #![feature(iter_intersperse)]
-#![feature(string_from_utf8_lossy_owned)]
 #![recursion_limit = "256"]
 // tidy-alphabetical-end
 
diff --git a/compiler/rustc_passes/src/lib.rs b/compiler/rustc_passes/src/lib.rs
index 639ca683cf6..1831f45a9ec 100644
--- a/compiler/rustc_passes/src/lib.rs
+++ b/compiler/rustc_passes/src/lib.rs
@@ -8,10 +8,8 @@
 #![allow(internal_features)]
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
 #![doc(rust_logo)]
-#![feature(box_patterns)]
 #![feature(map_try_insert)]
 #![feature(rustdoc_internals)]
-#![feature(try_blocks)]
 // tidy-alphabetical-end
 
 use rustc_middle::util::Providers;
diff --git a/compiler/rustc_query_system/src/lib.rs b/compiler/rustc_query_system/src/lib.rs
index d36cb6f0e5b..7fa643d91aa 100644
--- a/compiler/rustc_query_system/src/lib.rs
+++ b/compiler/rustc_query_system/src/lib.rs
@@ -2,7 +2,6 @@
 #![allow(internal_features)]
 #![feature(assert_matches)]
 #![feature(core_intrinsics)]
-#![feature(dropck_eyepatch)]
 #![feature(min_specialization)]
 // tidy-alphabetical-end
 
diff --git a/compiler/rustc_session/src/filesearch.rs b/compiler/rustc_session/src/filesearch.rs
index 0e711890e07..def2cc97f06 100644
--- a/compiler/rustc_session/src/filesearch.rs
+++ b/compiler/rustc_session/src/filesearch.rs
@@ -3,7 +3,7 @@
 use std::path::{Path, PathBuf};
 use std::{env, fs};
 
-use rustc_fs_util::{fix_windows_verbatim_for_gcc, try_canonicalize};
+use rustc_fs_util::try_canonicalize;
 use rustc_target::spec::Target;
 use smallvec::{SmallVec, smallvec};
 
@@ -87,7 +87,7 @@ fn current_dll_path() -> Result<PathBuf, String> {
                 };
                 let bytes = CStr::from_ptr(fname_ptr).to_bytes();
                 let os = OsStr::from_bytes(bytes);
-                Ok(PathBuf::from(os))
+                try_canonicalize(Path::new(os)).map_err(|e| e.to_string())
             }
 
             #[cfg(target_os = "aix")]
@@ -122,7 +122,7 @@ fn current_dll_path() -> Result<PathBuf, String> {
                     if (data_base..data_end).contains(&addr) {
                         let bytes = CStr::from_ptr(&(*current).ldinfo_filename[0]).to_bytes();
                         let os = OsStr::from_bytes(bytes);
-                        return Ok(PathBuf::from(os));
+                        return try_canonicalize(Path::new(os)).map_err(|e| e.to_string());
                     }
                     if (*current).ldinfo_next == 0 {
                         break;
@@ -169,7 +169,12 @@ fn current_dll_path() -> Result<PathBuf, String> {
 
     filename.truncate(n);
 
-    Ok(OsString::from_wide(&filename).into())
+    let path = try_canonicalize(OsString::from_wide(&filename)).map_err(|e| e.to_string())?;
+
+    // See comments on this target function, but the gist is that
+    // gcc chokes on verbatim paths which fs::canonicalize generates
+    // so we try to avoid those kinds of paths.
+    Ok(rustc_fs_util::fix_windows_verbatim_for_gcc(&path))
 }
 
 #[cfg(target_os = "wasi")]
@@ -177,37 +182,13 @@ fn current_dll_path() -> Result<PathBuf, String> {
     Err("current_dll_path is not supported on WASI".to_string())
 }
 
-pub fn sysroot_candidates() -> SmallVec<[PathBuf; 2]> {
-    let target = crate::config::host_tuple();
-    let mut sysroot_candidates: SmallVec<[PathBuf; 2]> = smallvec![get_or_default_sysroot()];
-    let path = current_dll_path().and_then(|s| try_canonicalize(s).map_err(|e| e.to_string()));
-    if let Ok(dll) = path {
-        // use `parent` twice to chop off the file name and then also the
-        // directory containing the dll which should be either `lib` or `bin`.
-        if let Some(path) = dll.parent().and_then(|p| p.parent()) {
-            // The original `path` pointed at the `rustc_driver` crate's dll.
-            // Now that dll should only be in one of two locations. The first is
-            // in the compiler's libdir, for example `$sysroot/lib/*.dll`. The
-            // other is the target's libdir, for example
-            // `$sysroot/lib/rustlib/$target/lib/*.dll`.
-            //
-            // We don't know which, so let's assume that if our `path` above
-            // ends in `$target` we *could* be in the target libdir, and always
-            // assume that we may be in the main libdir.
-            sysroot_candidates.push(path.to_owned());
-
-            if path.ends_with(target) {
-                sysroot_candidates.extend(
-                    path.parent() // chop off `$target`
-                        .and_then(|p| p.parent()) // chop off `rustlib`
-                        .and_then(|p| p.parent()) // chop off `lib`
-                        .map(|s| s.to_owned()),
-                );
-            }
-        }
+pub fn sysroot_with_fallback(sysroot: &Path) -> SmallVec<[PathBuf; 2]> {
+    let mut candidates = smallvec![sysroot.to_owned()];
+    let default_sysroot = get_or_default_sysroot();
+    if default_sysroot != sysroot {
+        candidates.push(default_sysroot);
     }
-
-    sysroot_candidates
+    candidates
 }
 
 /// Returns the provided sysroot or calls [`get_or_default_sysroot`] if it's none.
@@ -219,17 +200,8 @@ pub fn materialize_sysroot(maybe_sysroot: Option<PathBuf>) -> PathBuf {
 /// This function checks if sysroot is found using env::args().next(), and if it
 /// is not found, finds sysroot from current rustc_driver dll.
 pub fn get_or_default_sysroot() -> PathBuf {
-    // Follow symlinks. If the resolved path is relative, make it absolute.
-    fn canonicalize(path: PathBuf) -> PathBuf {
-        let path = try_canonicalize(&path).unwrap_or(path);
-        // See comments on this target function, but the gist is that
-        // gcc chokes on verbatim paths which fs::canonicalize generates
-        // so we try to avoid those kinds of paths.
-        fix_windows_verbatim_for_gcc(&path)
-    }
-
     fn default_from_rustc_driver_dll() -> Result<PathBuf, String> {
-        let dll = current_dll_path().map(|s| canonicalize(s))?;
+        let dll = current_dll_path()?;
 
         // `dll` will be in one of the following two:
         // - compiler's libdir: $sysroot/lib/*.dll
@@ -242,7 +214,7 @@ pub fn get_or_default_sysroot() -> PathBuf {
             dll.display()
         ))?;
 
-        // if `dir` points target's dir, move up to the sysroot
+        // if `dir` points to target's dir, move up to the sysroot
         let mut sysroot_dir = if dir.ends_with(crate::config::host_tuple()) {
             dir.parent() // chop off `$target`
                 .and_then(|p| p.parent()) // chop off `rustlib`
diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs
index 010ae42c280..6b85e0abc86 100644
--- a/compiler/rustc_session/src/session.rs
+++ b/compiler/rustc_session/src/session.rs
@@ -458,13 +458,9 @@ impl Session {
     /// directories are also returned, for example if `--sysroot` is used but tools are missing
     /// (#125246): we also add the bin directories to the sysroot where rustc is located.
     pub fn get_tools_search_paths(&self, self_contained: bool) -> Vec<PathBuf> {
-        let bin_path = filesearch::make_target_bin_path(&self.sysroot, config::host_tuple());
-        let fallback_sysroot_paths = filesearch::sysroot_candidates()
+        let search_paths = filesearch::sysroot_with_fallback(&self.sysroot)
             .into_iter()
-            // Ignore sysroot candidate if it was the same as the sysroot path we just used.
-            .filter(|sysroot| *sysroot != self.sysroot)
             .map(|sysroot| filesearch::make_target_bin_path(&sysroot, config::host_tuple()));
-        let search_paths = std::iter::once(bin_path).chain(fallback_sysroot_paths);
 
         if self_contained {
             // The self-contained tools are expected to be e.g. in `bin/self-contained` in the
diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs
index e950493f135..ed74dea5f1e 100644
--- a/compiler/rustc_span/src/lib.rs
+++ b/compiler/rustc_span/src/lib.rs
@@ -23,7 +23,6 @@
 #![doc(rust_logo)]
 #![feature(array_windows)]
 #![feature(core_io_borrowed_buf)]
-#![feature(hash_set_entry)]
 #![feature(if_let_guard)]
 #![feature(map_try_insert)]
 #![feature(negative_impls)]
diff --git a/compiler/rustc_target/Cargo.toml b/compiler/rustc_target/Cargo.toml
index 189b19b0286..0121c752dbd 100644
--- a/compiler/rustc_target/Cargo.toml
+++ b/compiler/rustc_target/Cargo.toml
@@ -20,5 +20,5 @@ tracing = "0.1"
 # tidy-alphabetical-start
 default-features = false
 features = ["elf", "macho"]
-version = "0.36.2"
+version = "0.37.0"
 # tidy-alphabetical-end
diff --git a/compiler/rustc_target/src/asm/mod.rs b/compiler/rustc_target/src/asm/mod.rs
index 9f791603c72..e06f881e4b1 100644
--- a/compiler/rustc_target/src/asm/mod.rs
+++ b/compiler/rustc_target/src/asm/mod.rs
@@ -226,6 +226,7 @@ pub enum InlineAsmArch {
     RiscV64,
     Nvptx64,
     Hexagon,
+    LoongArch32,
     LoongArch64,
     Mips,
     Mips64,
@@ -260,6 +261,7 @@ impl FromStr for InlineAsmArch {
             "powerpc" => Ok(Self::PowerPC),
             "powerpc64" => Ok(Self::PowerPC64),
             "hexagon" => Ok(Self::Hexagon),
+            "loongarch32" => Ok(Self::LoongArch32),
             "loongarch64" => Ok(Self::LoongArch64),
             "mips" | "mips32r6" => Ok(Self::Mips),
             "mips64" | "mips64r6" => Ok(Self::Mips64),
@@ -365,7 +367,9 @@ impl InlineAsmReg {
                 Self::PowerPC(PowerPCInlineAsmReg::parse(name)?)
             }
             InlineAsmArch::Hexagon => Self::Hexagon(HexagonInlineAsmReg::parse(name)?),
-            InlineAsmArch::LoongArch64 => Self::LoongArch(LoongArchInlineAsmReg::parse(name)?),
+            InlineAsmArch::LoongArch32 | InlineAsmArch::LoongArch64 => {
+                Self::LoongArch(LoongArchInlineAsmReg::parse(name)?)
+            }
             InlineAsmArch::Mips | InlineAsmArch::Mips64 => {
                 Self::Mips(MipsInlineAsmReg::parse(name)?)
             }
@@ -652,7 +656,9 @@ impl InlineAsmRegClass {
                 Self::PowerPC(PowerPCInlineAsmRegClass::parse(name)?)
             }
             InlineAsmArch::Hexagon => Self::Hexagon(HexagonInlineAsmRegClass::parse(name)?),
-            InlineAsmArch::LoongArch64 => Self::LoongArch(LoongArchInlineAsmRegClass::parse(name)?),
+            InlineAsmArch::LoongArch32 | InlineAsmArch::LoongArch64 => {
+                Self::LoongArch(LoongArchInlineAsmRegClass::parse(name)?)
+            }
             InlineAsmArch::Mips | InlineAsmArch::Mips64 => {
                 Self::Mips(MipsInlineAsmRegClass::parse(name)?)
             }
@@ -860,7 +866,7 @@ pub fn allocatable_registers(
             hexagon::fill_reg_map(arch, reloc_model, target_features, target, &mut map);
             map
         }
-        InlineAsmArch::LoongArch64 => {
+        InlineAsmArch::LoongArch32 | InlineAsmArch::LoongArch64 => {
             let mut map = loongarch::regclass_map();
             loongarch::fill_reg_map(arch, reloc_model, target_features, target, &mut map);
             map
@@ -992,7 +998,7 @@ impl InlineAsmClobberAbi {
                 "C" | "system" => Ok(InlineAsmClobberAbi::Avr),
                 _ => Err(&["C", "system"]),
             },
-            InlineAsmArch::LoongArch64 => match name {
+            InlineAsmArch::LoongArch32 | InlineAsmArch::LoongArch64 => match name {
                 "C" | "system" => Ok(InlineAsmClobberAbi::LoongArch),
                 _ => Err(&["C", "system"]),
             },
diff --git a/compiler/rustc_target/src/callconv/mod.rs b/compiler/rustc_target/src/callconv/mod.rs
index dcb79cce759..f9ecf02f857 100644
--- a/compiler/rustc_target/src/callconv/mod.rs
+++ b/compiler/rustc_target/src/callconv/mod.rs
@@ -648,7 +648,7 @@ impl<'a, Ty> FnAbi<'a, Ty> {
             "amdgpu" => amdgpu::compute_abi_info(cx, self),
             "arm" => arm::compute_abi_info(cx, self),
             "avr" => avr::compute_abi_info(self),
-            "loongarch64" => loongarch::compute_abi_info(cx, self),
+            "loongarch32" | "loongarch64" => loongarch::compute_abi_info(cx, self),
             "m68k" => m68k::compute_abi_info(self),
             "csky" => csky::compute_abi_info(self),
             "mips" | "mips32r6" => mips::compute_abi_info(cx, self),
@@ -691,7 +691,7 @@ impl<'a, Ty> FnAbi<'a, Ty> {
         match &*spec.arch {
             "x86" => x86::compute_rust_abi_info(cx, self),
             "riscv32" | "riscv64" => riscv::compute_rust_abi_info(cx, self),
-            "loongarch64" => loongarch::compute_rust_abi_info(cx, self),
+            "loongarch32" | "loongarch64" => loongarch::compute_rust_abi_info(cx, self),
             "aarch64" => aarch64::compute_rust_abi_info(cx, self),
             _ => {}
         };
diff --git a/compiler/rustc_target/src/lib.rs b/compiler/rustc_target/src/lib.rs
index 566bee75c7f..91657fef803 100644
--- a/compiler/rustc_target/src/lib.rs
+++ b/compiler/rustc_target/src/lib.rs
@@ -11,10 +11,8 @@
 #![allow(internal_features)]
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
 #![doc(rust_logo)]
-#![feature(assert_matches)]
 #![feature(debug_closure_helpers)]
 #![feature(iter_intersperse)]
-#![feature(rustc_attrs)]
 #![feature(rustdoc_internals)]
 // tidy-alphabetical-end
 
diff --git a/compiler/rustc_target/src/spec/abi_map.rs b/compiler/rustc_target/src/spec/abi_map.rs
index d9101f79f04..be94e18dc39 100644
--- a/compiler/rustc_target/src/spec/abi_map.rs
+++ b/compiler/rustc_target/src/spec/abi_map.rs
@@ -29,6 +29,7 @@ impl AbiMapping {
         }
     }
 
+    #[track_caller]
     pub fn unwrap(self) -> CanonAbi {
         self.into_option().unwrap()
     }
diff --git a/compiler/rustc_target/src/spec/json.rs b/compiler/rustc_target/src/spec/json.rs
index 54b06d9f9b4..039056a5a25 100644
--- a/compiler/rustc_target/src/spec/json.rs
+++ b/compiler/rustc_target/src/spec/json.rs
@@ -2,7 +2,7 @@ use std::borrow::Cow;
 use std::collections::BTreeMap;
 use std::str::FromStr;
 
-use rustc_abi::ExternAbi;
+use rustc_abi::{Align, AlignFromBytesError, ExternAbi};
 use serde_json::Value;
 
 use super::{Target, TargetKind, TargetOptions, TargetWarnings};
@@ -57,6 +57,14 @@ impl Target {
             base.metadata.std = metadata.remove("std").and_then(|host| host.as_bool());
         }
 
+        let alignment_error = |field_name: &str, error: AlignFromBytesError| -> String {
+            let msg = match error {
+                AlignFromBytesError::NotPowerOfTwo(_) => "not a power of 2 number of bytes",
+                AlignFromBytesError::TooLarge(_) => "too large",
+            };
+            format!("`{}` bits is not a valid value for {field_name}: {msg}", error.align() * 8)
+        };
+
         let mut incorrect_type = vec![];
 
         macro_rules! key {
@@ -111,6 +119,15 @@ impl Target {
                     base.$key_name = Some(s.into());
                 }
             } );
+            ($key_name:ident, Option<Align>) => ( {
+                let name = (stringify!($key_name)).replace("_", "-");
+                if let Some(b) = obj.remove(&name).and_then(|b| b.as_u64()) {
+                    match Align::from_bits(b) {
+                        Ok(align) => base.$key_name = Some(align),
+                        Err(e) => return Err(alignment_error(&name, e)),
+                    }
+                }
+            } );
             ($key_name:ident, BinaryFormat) => ( {
                 let name = (stringify!($key_name)).replace("_", "-");
                 obj.remove(&name).and_then(|f| f.as_str().and_then(|s| {
@@ -617,7 +634,7 @@ impl Target {
         key!(crt_static_default, bool);
         key!(crt_static_respected, bool);
         key!(stack_probes, StackProbeType)?;
-        key!(min_global_align, Option<u64>);
+        key!(min_global_align, Option<Align>);
         key!(default_codegen_units, Option<u64>);
         key!(default_codegen_backend, Option<StaticCow<str>>);
         key!(trap_unreachable, bool);
diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs
index 6529c2d72c8..1726de4d471 100644
--- a/compiler/rustc_target/src/spec/mod.rs
+++ b/compiler/rustc_target/src/spec/mod.rs
@@ -1697,6 +1697,12 @@ impl ToJson for BinaryFormat {
     }
 }
 
+impl ToJson for Align {
+    fn to_json(&self) -> Json {
+        self.bits().to_json()
+    }
+}
+
 macro_rules! supported_targets {
     ( $(($tuple:literal, $module:ident),)+ ) => {
         mod targets {
@@ -1981,6 +1987,8 @@ supported_targets! {
 
     ("sparc-unknown-none-elf", sparc_unknown_none_elf),
 
+    ("loongarch32-unknown-none", loongarch32_unknown_none),
+    ("loongarch32-unknown-none-softfloat", loongarch32_unknown_none_softfloat),
     ("loongarch64-unknown-none", loongarch64_unknown_none),
     ("loongarch64-unknown-none-softfloat", loongarch64_unknown_none_softfloat),
 
@@ -2513,7 +2521,7 @@ pub struct TargetOptions {
     pub stack_probes: StackProbeType,
 
     /// The minimum alignment for global symbols.
-    pub min_global_align: Option<u64>,
+    pub min_global_align: Option<Align>,
 
     /// Default number of codegen units to use in debug mode
     pub default_codegen_units: Option<u64>,
@@ -3502,6 +3510,7 @@ impl Target {
             "msp430" => (Architecture::Msp430, None),
             "hexagon" => (Architecture::Hexagon, None),
             "bpf" => (Architecture::Bpf, None),
+            "loongarch32" => (Architecture::LoongArch32, None),
             "loongarch64" => (Architecture::LoongArch64, None),
             "csky" => (Architecture::Csky, None),
             "arm64ec" => (Architecture::Aarch64, Some(object::SubArchitecture::Arm64EC)),
diff --git a/compiler/rustc_target/src/spec/targets/loongarch32_unknown_none.rs b/compiler/rustc_target/src/spec/targets/loongarch32_unknown_none.rs
new file mode 100644
index 00000000000..fb4963b88b0
--- /dev/null
+++ b/compiler/rustc_target/src/spec/targets/loongarch32_unknown_none.rs
@@ -0,0 +1,29 @@
+use crate::spec::{
+    Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions,
+};
+
+pub(crate) fn target() -> Target {
+    Target {
+        llvm_target: "loongarch32-unknown-none".into(),
+        metadata: TargetMetadata {
+            description: Some("Freestanding/bare-metal LoongArch32".into()),
+            tier: Some(3),
+            host_tools: Some(false),
+            std: Some(false),
+        },
+        pointer_width: 32,
+        data_layout: "e-m:e-p:32:32-i64:64-n32-S128".into(),
+        arch: "loongarch32".into(),
+        options: TargetOptions {
+            cpu: "generic".into(),
+            features: "+f,+d".into(),
+            linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes),
+            linker: Some("rust-lld".into()),
+            llvm_abiname: "ilp32d".into(),
+            max_atomic_width: Some(32),
+            relocation_model: RelocModel::Static,
+            panic_strategy: PanicStrategy::Abort,
+            ..Default::default()
+        },
+    }
+}
diff --git a/compiler/rustc_target/src/spec/targets/loongarch32_unknown_none_softfloat.rs b/compiler/rustc_target/src/spec/targets/loongarch32_unknown_none_softfloat.rs
new file mode 100644
index 00000000000..0e65f83a71c
--- /dev/null
+++ b/compiler/rustc_target/src/spec/targets/loongarch32_unknown_none_softfloat.rs
@@ -0,0 +1,30 @@
+use crate::spec::{
+    Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions,
+};
+
+pub(crate) fn target() -> Target {
+    Target {
+        llvm_target: "loongarch32-unknown-none".into(),
+        metadata: TargetMetadata {
+            description: Some("Freestanding/bare-metal LoongArch32 softfloat".into()),
+            tier: Some(3),
+            host_tools: Some(false),
+            std: Some(false),
+        },
+        pointer_width: 32,
+        data_layout: "e-m:e-p:32:32-i64:64-n32-S128".into(),
+        arch: "loongarch32".into(),
+        options: TargetOptions {
+            cpu: "generic".into(),
+            features: "-f,-d".into(),
+            abi: "softfloat".into(),
+            linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes),
+            linker: Some("rust-lld".into()),
+            llvm_abiname: "ilp32s".into(),
+            max_atomic_width: Some(32),
+            relocation_model: RelocModel::Static,
+            panic_strategy: PanicStrategy::Abort,
+            ..Default::default()
+        },
+    }
+}
diff --git a/compiler/rustc_target/src/spec/targets/s390x_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/targets/s390x_unknown_linux_gnu.rs
index e0d16a7bfa5..cdcf7d62a3e 100644
--- a/compiler/rustc_target/src/spec/targets/s390x_unknown_linux_gnu.rs
+++ b/compiler/rustc_target/src/spec/targets/s390x_unknown_linux_gnu.rs
@@ -1,4 +1,4 @@
-use rustc_abi::Endian;
+use rustc_abi::{Align, Endian};
 
 use crate::spec::{SanitizerSet, StackProbeType, Target, TargetMetadata, base};
 
@@ -8,7 +8,7 @@ pub(crate) fn target() -> Target {
     // z10 is the oldest CPU supported by LLVM
     base.cpu = "z10".into();
     base.max_atomic_width = Some(128);
-    base.min_global_align = Some(16);
+    base.min_global_align = Some(Align::from_bits(16).unwrap());
     base.stack_probes = StackProbeType::Inline;
     base.supported_sanitizers =
         SanitizerSet::ADDRESS | SanitizerSet::LEAK | SanitizerSet::MEMORY | SanitizerSet::THREAD;
diff --git a/compiler/rustc_target/src/spec/targets/s390x_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/targets/s390x_unknown_linux_musl.rs
index 47050c1f769..e9522ac760e 100644
--- a/compiler/rustc_target/src/spec/targets/s390x_unknown_linux_musl.rs
+++ b/compiler/rustc_target/src/spec/targets/s390x_unknown_linux_musl.rs
@@ -1,4 +1,4 @@
-use rustc_abi::Endian;
+use rustc_abi::{Align, Endian};
 
 use crate::spec::{SanitizerSet, StackProbeType, Target, TargetMetadata, base};
 
@@ -8,7 +8,7 @@ pub(crate) fn target() -> Target {
     // z10 is the oldest CPU supported by LLVM
     base.cpu = "z10".into();
     base.max_atomic_width = Some(128);
-    base.min_global_align = Some(16);
+    base.min_global_align = Some(Align::from_bits(16).unwrap());
     base.static_position_independent_executables = true;
     base.stack_probes = StackProbeType::Inline;
     base.supported_sanitizers =
diff --git a/compiler/rustc_target/src/target_features.rs b/compiler/rustc_target/src/target_features.rs
index 682c4c5068f..c1f128fdc87 100644
--- a/compiler/rustc_target/src/target_features.rs
+++ b/compiler/rustc_target/src/target_features.rs
@@ -846,7 +846,7 @@ impl Target {
             "wasm32" | "wasm64" => WASM_FEATURES,
             "bpf" => BPF_FEATURES,
             "csky" => CSKY_FEATURES,
-            "loongarch64" => LOONGARCH_FEATURES,
+            "loongarch32" | "loongarch64" => LOONGARCH_FEATURES,
             "s390x" => IBMZ_FEATURES,
             "sparc" | "sparc64" => SPARC_FEATURES,
             "m68k" => M68K_FEATURES,
@@ -860,7 +860,7 @@ impl Target {
             "aarch64" | "arm64ec" => AARCH64_FEATURES_FOR_CORRECT_VECTOR_ABI,
             "arm" => ARM_FEATURES_FOR_CORRECT_VECTOR_ABI,
             "powerpc" | "powerpc64" => POWERPC_FEATURES_FOR_CORRECT_VECTOR_ABI,
-            "loongarch64" => LOONGARCH_FEATURES_FOR_CORRECT_VECTOR_ABI,
+            "loongarch32" | "loongarch64" => LOONGARCH_FEATURES_FOR_CORRECT_VECTOR_ABI,
             "riscv32" | "riscv64" => RISCV_FEATURES_FOR_CORRECT_VECTOR_ABI,
             "wasm32" | "wasm64" => WASM_FEATURES_FOR_CORRECT_VECTOR_ABI,
             "s390x" => S390X_FEATURES_FOR_CORRECT_VECTOR_ABI,
@@ -1034,7 +1034,7 @@ impl Target {
                     _ => unreachable!(),
                 }
             }
-            "loongarch64" => {
+            "loongarch32" | "loongarch64" => {
                 // LoongArch handles ABI in a very sane way, being fully explicit via `llvm_abiname`
                 // about what the intended ABI is.
                 match &*self.llvm_abiname {
diff --git a/compiler/rustc_trait_selection/src/lib.rs b/compiler/rustc_trait_selection/src/lib.rs
index 67328defe36..e2b22f7bab7 100644
--- a/compiler/rustc_trait_selection/src/lib.rs
+++ b/compiler/rustc_trait_selection/src/lib.rs
@@ -19,14 +19,12 @@
 #![feature(assert_matches)]
 #![feature(associated_type_defaults)]
 #![feature(box_patterns)]
-#![feature(cfg_version)]
 #![feature(if_let_guard)]
 #![feature(iter_intersperse)]
 #![feature(iterator_try_reduce)]
 #![feature(never_type)]
 #![feature(rustdoc_internals)]
 #![feature(try_blocks)]
-#![feature(type_alias_impl_trait)]
 #![feature(unwrap_infallible)]
 #![feature(yeet_expr)]
 #![recursion_limit = "512"] // For rustdoc