diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs
index 614a99a6e1960..83931a8c1a960 100644
--- a/compiler/rustc_ast_passes/src/feature_gate.rs
+++ b/compiler/rustc_ast_passes/src/feature_gate.rs
@@ -4,9 +4,9 @@ use rustc_ast::{NodeId, PatKind, attr, token};
 use rustc_feature::{AttributeGate, BUILTIN_ATTRIBUTE_MAP, BuiltinAttribute, Features, GateIssue};
 use rustc_session::Session;
 use rustc_session::parse::{feature_err, feature_err_issue, feature_warn};
-use rustc_span::Span;
 use rustc_span::source_map::Spanned;
 use rustc_span::symbol::sym;
+use rustc_span::{Span, Symbol};
 use rustc_target::spec::abi;
 use thin_vec::ThinVec;
 
@@ -483,6 +483,8 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
 pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) {
     maybe_stage_features(sess, features, krate);
     check_incompatible_features(sess, features);
+    check_new_solver_banned_features(sess, features);
+
     let mut visitor = PostExpansionVisitor { sess, features };
 
     let spans = sess.psess.gated_spans.spans.borrow();
@@ -662,3 +664,22 @@ fn check_incompatible_features(sess: &Session, features: &Features) {
         }
     }
 }
+
+fn check_new_solver_banned_features(sess: &Session, features: &Features) {
+    if !sess.opts.unstable_opts.next_solver.is_some_and(|n| n.globally) {
+        return;
+    }
+
+    // Ban GCE with the new solver, because it does not implement GCE correctly.
+    if let Some(&(_, gce_span, _)) = features
+        .declared_lang_features
+        .iter()
+        .find(|&&(feat, _, _)| feat == sym::generic_const_exprs)
+    {
+        sess.dcx().emit_err(errors::IncompatibleFeatures {
+            spans: vec![gce_span],
+            f1: Symbol::intern("-Znext-solver=globally"),
+            f2: sym::generic_const_exprs,
+        });
+    }
+}
diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs
index 8e4385bee1aa3..fcf48d3e4a31c 100644
--- a/compiler/rustc_codegen_ssa/src/base.rs
+++ b/compiler/rustc_codegen_ssa/src/base.rs
@@ -37,6 +37,7 @@ use crate::back::write::{
     submit_codegened_module_to_llvm, submit_post_lto_module_to_llvm, submit_pre_lto_module_to_llvm,
 };
 use crate::common::{self, IntPredicate, RealPredicate, TypeKind};
+use crate::meth::load_vtable;
 use crate::mir::operand::OperandValue;
 use crate::mir::place::PlaceRef;
 use crate::traits::*;
@@ -135,14 +136,8 @@ fn unsized_info<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
 
             if let Some(entry_idx) = vptr_entry_idx {
                 let ptr_size = bx.data_layout().pointer_size;
-                let ptr_align = bx.data_layout().pointer_align.abi;
                 let vtable_byte_offset = u64::try_from(entry_idx).unwrap() * ptr_size.bytes();
-                let gep = bx.inbounds_ptradd(old_info, bx.const_usize(vtable_byte_offset));
-                let new_vptr = bx.load(bx.type_ptr(), gep, ptr_align);
-                bx.nonnull_metadata(new_vptr);
-                // VTable loads are invariant.
-                bx.set_invariant_load(new_vptr);
-                new_vptr
+                load_vtable(bx, old_info, bx.type_ptr(), vtable_byte_offset, source, true)
             } else {
                 old_info
             }
diff --git a/compiler/rustc_codegen_ssa/src/meth.rs b/compiler/rustc_codegen_ssa/src/meth.rs
index ecc3b2b24f1cf..7eb0ecd12ffec 100644
--- a/compiler/rustc_codegen_ssa/src/meth.rs
+++ b/compiler/rustc_codegen_ssa/src/meth.rs
@@ -28,27 +28,9 @@ impl<'a, 'tcx> VirtualIndex {
 
         let llty = bx.fn_ptr_backend_type(fn_abi);
         let ptr_size = bx.data_layout().pointer_size;
-        let ptr_align = bx.data_layout().pointer_align.abi;
         let vtable_byte_offset = self.0 * ptr_size.bytes();
 
-        if bx.cx().sess().opts.unstable_opts.virtual_function_elimination
-            && bx.cx().sess().lto() == Lto::Fat
-        {
-            let typeid = bx
-                .typeid_metadata(typeid_for_trait_ref(bx.tcx(), expect_dyn_trait_in_self(ty)))
-                .unwrap();
-            let func = bx.type_checked_load(llvtable, vtable_byte_offset, typeid);
-            func
-        } else {
-            let gep = bx.inbounds_ptradd(llvtable, bx.const_usize(vtable_byte_offset));
-            let ptr = bx.load(llty, gep, ptr_align);
-            // VTable loads are invariant.
-            bx.set_invariant_load(ptr);
-            if nonnull {
-                bx.nonnull_metadata(ptr);
-            }
-            ptr
-        }
+        load_vtable(bx, llvtable, llty, vtable_byte_offset, ty, nonnull)
     }
 
     pub(crate) fn get_optional_fn<Bx: BuilderMethods<'a, 'tcx>>(
@@ -75,31 +57,27 @@ impl<'a, 'tcx> VirtualIndex {
         self,
         bx: &mut Bx,
         llvtable: Bx::Value,
+        ty: Ty<'tcx>,
     ) -> Bx::Value {
         // Load the data pointer from the object.
         debug!("get_int({:?}, {:?})", llvtable, self);
 
         let llty = bx.type_isize();
         let ptr_size = bx.data_layout().pointer_size;
-        let ptr_align = bx.data_layout().pointer_align.abi;
         let vtable_byte_offset = self.0 * ptr_size.bytes();
 
-        let gep = bx.inbounds_ptradd(llvtable, bx.const_usize(vtable_byte_offset));
-        let ptr = bx.load(llty, gep, ptr_align);
-        // VTable loads are invariant.
-        bx.set_invariant_load(ptr);
-        ptr
+        load_vtable(bx, llvtable, llty, vtable_byte_offset, ty, false)
     }
 }
 
 /// This takes a valid `self` receiver type and extracts the principal trait
-/// ref of the type.
-fn expect_dyn_trait_in_self(ty: Ty<'_>) -> ty::PolyExistentialTraitRef<'_> {
+/// ref of the type. Return `None` if there is no principal trait.
+fn dyn_trait_in_self(ty: Ty<'_>) -> Option<ty::PolyExistentialTraitRef<'_>> {
     for arg in ty.peel_refs().walk() {
         if let GenericArgKind::Type(ty) = arg.unpack()
             && let ty::Dynamic(data, _, _) = ty.kind()
         {
-            return data.principal().expect("expected principal trait object");
+            return data.principal();
         }
     }
 
@@ -138,3 +116,36 @@ pub(crate) fn get_vtable<'tcx, Cx: CodegenMethods<'tcx>>(
     cx.vtables().borrow_mut().insert((ty, trait_ref), vtable);
     vtable
 }
+
+/// Call this function whenever you need to load a vtable.
+pub(crate) fn load_vtable<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
+    bx: &mut Bx,
+    llvtable: Bx::Value,
+    llty: Bx::Type,
+    vtable_byte_offset: u64,
+    ty: Ty<'tcx>,
+    nonnull: bool,
+) -> Bx::Value {
+    let ptr_align = bx.data_layout().pointer_align.abi;
+
+    if bx.cx().sess().opts.unstable_opts.virtual_function_elimination
+        && bx.cx().sess().lto() == Lto::Fat
+    {
+        if let Some(trait_ref) = dyn_trait_in_self(ty) {
+            let typeid = bx.typeid_metadata(typeid_for_trait_ref(bx.tcx(), trait_ref)).unwrap();
+            let func = bx.type_checked_load(llvtable, vtable_byte_offset, typeid);
+            return func;
+        } else if nonnull {
+            bug!("load nonnull value from a vtable without a principal trait")
+        }
+    }
+
+    let gep = bx.inbounds_ptradd(llvtable, bx.const_usize(vtable_byte_offset));
+    let ptr = bx.load(llty, gep, ptr_align);
+    // VTable loads are invariant.
+    bx.set_invariant_load(ptr);
+    if nonnull {
+        bx.nonnull_metadata(ptr);
+    }
+    ptr
+}
diff --git a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs
index 71541e6ab41a1..32cc78187b9eb 100644
--- a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs
@@ -126,7 +126,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                     sym::vtable_align => ty::COMMON_VTABLE_ENTRIES_ALIGN,
                     _ => bug!(),
                 };
-                let value = meth::VirtualIndex::from_index(idx).get_usize(bx, vtable);
+                let value = meth::VirtualIndex::from_index(idx).get_usize(bx, vtable, callee_ty);
                 match name {
                     // Size is always <= isize::MAX.
                     sym::vtable_size => {
diff --git a/compiler/rustc_codegen_ssa/src/size_of_val.rs b/compiler/rustc_codegen_ssa/src/size_of_val.rs
index 3f3ae21035d5a..827b939217e82 100644
--- a/compiler/rustc_codegen_ssa/src/size_of_val.rs
+++ b/compiler/rustc_codegen_ssa/src/size_of_val.rs
@@ -28,9 +28,9 @@ pub fn size_and_align_of_dst<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
             // Load size/align from vtable.
             let vtable = info.unwrap();
             let size = meth::VirtualIndex::from_index(ty::COMMON_VTABLE_ENTRIES_SIZE)
-                .get_usize(bx, vtable);
+                .get_usize(bx, vtable, t);
             let align = meth::VirtualIndex::from_index(ty::COMMON_VTABLE_ENTRIES_ALIGN)
-                .get_usize(bx, vtable);
+                .get_usize(bx, vtable, t);
 
             // Size is always <= isize::MAX.
             let size_bound = bx.data_layout().ptr_sized_integer().signed_max() as u128;
diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs
index 3f0b23a595c03..f327c1fd17902 100644
--- a/compiler/rustc_target/src/spec/mod.rs
+++ b/compiler/rustc_target/src/spec/mod.rs
@@ -1840,6 +1840,8 @@ supported_targets! {
     ("powerpc-wrs-vxworks", powerpc_wrs_vxworks),
     ("powerpc-wrs-vxworks-spe", powerpc_wrs_vxworks_spe),
     ("powerpc64-wrs-vxworks", powerpc64_wrs_vxworks),
+    ("riscv32-wrs-vxworks", riscv32_wrs_vxworks),
+    ("riscv64-wrs-vxworks", riscv64_wrs_vxworks),
 
     ("aarch64-kmc-solid_asp3", aarch64_kmc_solid_asp3),
     ("armv7a-kmc-solid_asp3-eabi", armv7a_kmc_solid_asp3_eabi),
diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_ohos.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_ohos.rs
index 0942f5d896bbc..9d5bce053500c 100644
--- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_ohos.rs
+++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_ohos.rs
@@ -5,8 +5,7 @@ pub(crate) fn target() -> Target {
     base.max_atomic_width = Some(128);
 
     Target {
-        // LLVM 15 doesn't support OpenHarmony yet, use a linux target instead.
-        llvm_target: "aarch64-unknown-linux-musl".into(),
+        llvm_target: "aarch64-unknown-linux-ohos".into(),
         metadata: crate::spec::TargetMetadata {
             description: Some("ARM64 OpenHarmony".into()),
             tier: Some(2),
diff --git a/compiler/rustc_target/src/spec/targets/aarch64_wrs_vxworks.rs b/compiler/rustc_target/src/spec/targets/aarch64_wrs_vxworks.rs
index b74c49f0a0901..dd5298944e0d1 100644
--- a/compiler/rustc_target/src/spec/targets/aarch64_wrs_vxworks.rs
+++ b/compiler/rustc_target/src/spec/targets/aarch64_wrs_vxworks.rs
@@ -7,7 +7,7 @@ pub(crate) fn target() -> Target {
             description: None,
             tier: Some(3),
             host_tools: Some(false),
-            std: None, // ?
+            std: Some(true),
         },
         pointer_width: 64,
         data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(),
diff --git a/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_ohos.rs b/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_ohos.rs
index 04ea9e3468d2c..92b09bcc45c48 100644
--- a/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_ohos.rs
+++ b/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_ohos.rs
@@ -7,8 +7,7 @@ pub(crate) fn target() -> Target {
     // Most of these settings are copied from the armv7_unknown_linux_musleabi
     // target.
     Target {
-        // LLVM 15 doesn't support OpenHarmony yet, use a linux target instead.
-        llvm_target: "armv7-unknown-linux-gnueabi".into(),
+        llvm_target: "armv7-unknown-linux-ohos".into(),
         metadata: crate::spec::TargetMetadata {
             description: Some("Armv7-A OpenHarmony".into()),
             tier: Some(2),
diff --git a/compiler/rustc_target/src/spec/targets/i686_wrs_vxworks.rs b/compiler/rustc_target/src/spec/targets/i686_wrs_vxworks.rs
index c2b9bc14ca438..dfffa6e138f85 100644
--- a/compiler/rustc_target/src/spec/targets/i686_wrs_vxworks.rs
+++ b/compiler/rustc_target/src/spec/targets/i686_wrs_vxworks.rs
@@ -13,7 +13,7 @@ pub(crate) fn target() -> Target {
             description: None,
             tier: Some(3),
             host_tools: Some(false),
-            std: None, // ?
+            std: Some(true),
         },
         pointer_width: 32,
         data_layout: "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-\
diff --git a/compiler/rustc_target/src/spec/targets/loongarch64_unknown_linux_ohos.rs b/compiler/rustc_target/src/spec/targets/loongarch64_unknown_linux_ohos.rs
index f9f7098684e6e..32a856be66907 100644
--- a/compiler/rustc_target/src/spec/targets/loongarch64_unknown_linux_ohos.rs
+++ b/compiler/rustc_target/src/spec/targets/loongarch64_unknown_linux_ohos.rs
@@ -2,8 +2,7 @@ use crate::spec::{Target, TargetOptions, base};
 
 pub(crate) fn target() -> Target {
     Target {
-        // LLVM 15 doesn't support OpenHarmony yet, use a linux target instead.
-        llvm_target: "loongarch64-unknown-linux-musl".into(),
+        llvm_target: "loongarch64-unknown-linux-ohos".into(),
         metadata: crate::spec::TargetMetadata {
             description: Some("LoongArch64 OpenHarmony".into()),
             tier: Some(3),
diff --git a/compiler/rustc_target/src/spec/targets/powerpc64_wrs_vxworks.rs b/compiler/rustc_target/src/spec/targets/powerpc64_wrs_vxworks.rs
index 11cf957cc1859..1d3d9f1b77df8 100644
--- a/compiler/rustc_target/src/spec/targets/powerpc64_wrs_vxworks.rs
+++ b/compiler/rustc_target/src/spec/targets/powerpc64_wrs_vxworks.rs
@@ -14,7 +14,7 @@ pub(crate) fn target() -> Target {
             description: None,
             tier: Some(3),
             host_tools: Some(false),
-            std: None, // ?
+            std: Some(true),
         },
         pointer_width: 64,
         data_layout: "E-m:e-Fi64-i64:64-n32:64-S128-v256:256:256-v512:512:512".into(),
diff --git a/compiler/rustc_target/src/spec/targets/powerpc_wrs_vxworks.rs b/compiler/rustc_target/src/spec/targets/powerpc_wrs_vxworks.rs
index 24cad76b00040..22b38208b108a 100644
--- a/compiler/rustc_target/src/spec/targets/powerpc_wrs_vxworks.rs
+++ b/compiler/rustc_target/src/spec/targets/powerpc_wrs_vxworks.rs
@@ -13,7 +13,7 @@ pub(crate) fn target() -> Target {
             description: None,
             tier: Some(3),
             host_tools: Some(false),
-            std: None, // ?
+            std: Some(true),
         },
         pointer_width: 32,
         data_layout: "E-m:e-p:32:32-Fn32-i64:64-n32".into(),
diff --git a/compiler/rustc_target/src/spec/targets/riscv32_wrs_vxworks.rs b/compiler/rustc_target/src/spec/targets/riscv32_wrs_vxworks.rs
new file mode 100644
index 0000000000000..4d3df78a56365
--- /dev/null
+++ b/compiler/rustc_target/src/spec/targets/riscv32_wrs_vxworks.rs
@@ -0,0 +1,24 @@
+use crate::spec::{StackProbeType, Target, TargetOptions, base};
+
+pub(crate) fn target() -> Target {
+    Target {
+        llvm_target: "riscv32".into(),
+        metadata: crate::spec::TargetMetadata {
+            description: None,
+            tier: Some(3),
+            host_tools: Some(false),
+            std: Some(true),
+        },
+        pointer_width: 32,
+        data_layout: "e-m:e-p:32:32-i64:64-n32-S128".into(),
+        arch: "riscv32".into(),
+        options: TargetOptions {
+            cpu: "generic-rv32".into(),
+            llvm_abiname: "ilp32d".into(),
+            max_atomic_width: Some(32),
+            features: "+m,+a,+f,+d,+c".into(),
+            stack_probes: StackProbeType::Inline,
+            ..base::vxworks::opts()
+        },
+    }
+}
diff --git a/compiler/rustc_target/src/spec/targets/riscv64_wrs_vxworks.rs b/compiler/rustc_target/src/spec/targets/riscv64_wrs_vxworks.rs
new file mode 100644
index 0000000000000..720549e6a0173
--- /dev/null
+++ b/compiler/rustc_target/src/spec/targets/riscv64_wrs_vxworks.rs
@@ -0,0 +1,24 @@
+use crate::spec::{StackProbeType, Target, TargetOptions, base};
+
+pub(crate) fn target() -> Target {
+    Target {
+        llvm_target: "riscv64".into(),
+        metadata: crate::spec::TargetMetadata {
+            description: None,
+            tier: Some(3),
+            host_tools: Some(false),
+            std: Some(true),
+        },
+        pointer_width: 64,
+        data_layout: "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128".into(),
+        arch: "riscv64".into(),
+        options: TargetOptions {
+            cpu: "generic-rv64".into(),
+            llvm_abiname: "lp64d".into(),
+            max_atomic_width: Some(64),
+            features: "+m,+a,+f,+d,+c".into(),
+            stack_probes: StackProbeType::Inline,
+            ..base::vxworks::opts()
+        },
+    }
+}
diff --git a/compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_ohos.rs b/compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_ohos.rs
index e455aad5f51ae..522943c91a5e0 100644
--- a/compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_ohos.rs
+++ b/compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_ohos.rs
@@ -15,8 +15,7 @@ pub(crate) fn target() -> Target {
     base.supports_xray = true;
 
     Target {
-        // LLVM 15 doesn't support OpenHarmony yet, use a linux target instead.
-        llvm_target: "x86_64-unknown-linux-musl".into(),
+        llvm_target: "x86_64-unknown-linux-ohos".into(),
         metadata: crate::spec::TargetMetadata {
             description: Some("x86_64 OpenHarmony".into()),
             tier: Some(2),
diff --git a/compiler/rustc_target/src/spec/targets/x86_64_wrs_vxworks.rs b/compiler/rustc_target/src/spec/targets/x86_64_wrs_vxworks.rs
index 8fbdd8f57f658..f003f939ad115 100644
--- a/compiler/rustc_target/src/spec/targets/x86_64_wrs_vxworks.rs
+++ b/compiler/rustc_target/src/spec/targets/x86_64_wrs_vxworks.rs
@@ -15,7 +15,7 @@ pub(crate) fn target() -> Target {
             description: None,
             tier: Some(3),
             host_tools: Some(false),
-            std: None, // ?
+            std: Some(true),
         },
         pointer_width: 64,
         data_layout:
diff --git a/library/panic_unwind/src/lib.rs b/library/panic_unwind/src/lib.rs
index 4552fb68d26d5..6cd4dffb8aa30 100644
--- a/library/panic_unwind/src/lib.rs
+++ b/library/panic_unwind/src/lib.rs
@@ -48,7 +48,7 @@ cfg_if::cfg_if! {
         target_os = "psp",
         target_os = "xous",
         target_os = "solid_asp3",
-        all(target_family = "unix", not(any(target_os = "espidf", target_os = "rtems"))),
+        all(target_family = "unix", not(any(target_os = "espidf", target_os = "rtems", target_os = "nuttx"))),
         all(target_vendor = "fortanix", target_env = "sgx"),
         target_family = "wasm",
     ))] {
diff --git a/library/std/build.rs b/library/std/build.rs
index ba1eece46f3ce..359ae4f20eea8 100644
--- a/library/std/build.rs
+++ b/library/std/build.rs
@@ -54,6 +54,7 @@ fn main() {
         || target_os == "teeos"
         || target_os == "zkvm"
         || target_os == "rtems"
+        || target_os == "nuttx"
 
         // See src/bootstrap/src/core/build_steps/synthetic_targets.rs
         || env::var("RUSTC_BOOTSTRAP_SYNTHETIC_TARGET").is_ok()
diff --git a/library/std/src/os/mod.rs b/library/std/src/os/mod.rs
index a2496baa63fb1..6701173d1e005 100644
--- a/library/std/src/os/mod.rs
+++ b/library/std/src/os/mod.rs
@@ -139,6 +139,8 @@ pub mod macos;
 pub mod netbsd;
 #[cfg(target_os = "nto")]
 pub mod nto;
+#[cfg(target_os = "nuttx")]
+pub mod nuttx;
 #[cfg(target_os = "openbsd")]
 pub mod openbsd;
 #[cfg(target_os = "redox")]
diff --git a/library/std/src/os/nuttx/fs.rs b/library/std/src/os/nuttx/fs.rs
new file mode 100644
index 0000000000000..7d6d8d16eca79
--- /dev/null
+++ b/library/std/src/os/nuttx/fs.rs
@@ -0,0 +1,92 @@
+#![stable(feature = "metadata_ext", since = "1.1.0")]
+
+use crate::fs::Metadata;
+use crate::sys_common::AsInner;
+
+#[stable(feature = "metadata_ext", since = "1.1.0")]
+pub trait MetadataExt {
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_dev(&self) -> u64;
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_ino(&self) -> u64;
+    #[stable(feature = "metadata_ext", since = "1.1.0")]
+    fn st_mode(&self) -> u32;
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_nlink(&self) -> u64;
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_uid(&self) -> u32;
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_gid(&self) -> u32;
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_rdev(&self) -> u64;
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_size(&self) -> u64;
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_atime(&self) -> i64;
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_atime_nsec(&self) -> i64;
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_mtime(&self) -> i64;
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_mtime_nsec(&self) -> i64;
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_ctime(&self) -> i64;
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_ctime_nsec(&self) -> i64;
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_blksize(&self) -> u64;
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_blocks(&self) -> u64;
+}
+
+#[stable(feature = "metadata_ext", since = "1.1.0")]
+impl MetadataExt for Metadata {
+    fn st_dev(&self) -> u64 {
+        self.as_inner().as_inner().st_dev as u64
+    }
+    fn st_ino(&self) -> u64 {
+        self.as_inner().as_inner().st_ino as u64
+    }
+    fn st_mode(&self) -> u32 {
+        self.as_inner().as_inner().st_mode as u32
+    }
+    fn st_nlink(&self) -> u64 {
+        self.as_inner().as_inner().st_nlink as u64
+    }
+    fn st_uid(&self) -> u32 {
+        self.as_inner().as_inner().st_uid as u32
+    }
+    fn st_gid(&self) -> u32 {
+        self.as_inner().as_inner().st_gid as u32
+    }
+    fn st_rdev(&self) -> u64 {
+        self.as_inner().as_inner().st_rdev as u64
+    }
+    fn st_size(&self) -> u64 {
+        self.as_inner().as_inner().st_size as u64
+    }
+    fn st_atime(&self) -> i64 {
+        self.as_inner().as_inner().st_atim.tv_sec as i64
+    }
+    fn st_atime_nsec(&self) -> i64 {
+        self.as_inner().as_inner().st_atim.tv_nsec as i64
+    }
+    fn st_mtime(&self) -> i64 {
+        self.as_inner().as_inner().st_mtim.tv_sec as i64
+    }
+    fn st_mtime_nsec(&self) -> i64 {
+        self.as_inner().as_inner().st_mtim.tv_nsec as i64
+    }
+    fn st_ctime(&self) -> i64 {
+        self.as_inner().as_inner().st_ctim.tv_sec as i64
+    }
+    fn st_ctime_nsec(&self) -> i64 {
+        self.as_inner().as_inner().st_ctim.tv_nsec as i64
+    }
+    fn st_blksize(&self) -> u64 {
+        self.as_inner().as_inner().st_blksize as u64
+    }
+    fn st_blocks(&self) -> u64 {
+        self.as_inner().as_inner().st_blocks as u64
+    }
+}
diff --git a/library/std/src/os/nuttx/mod.rs b/library/std/src/os/nuttx/mod.rs
new file mode 100644
index 0000000000000..7275bfd1765d5
--- /dev/null
+++ b/library/std/src/os/nuttx/mod.rs
@@ -0,0 +1,4 @@
+#![stable(feature = "raw_ext", since = "1.1.0")]
+#![forbid(unsafe_op_in_unsafe_fn)]
+pub mod fs;
+pub(crate) mod raw;
diff --git a/library/std/src/os/nuttx/raw.rs b/library/std/src/os/nuttx/raw.rs
new file mode 100644
index 0000000000000..113079cf4abdc
--- /dev/null
+++ b/library/std/src/os/nuttx/raw.rs
@@ -0,0 +1,33 @@
+//! rtems raw type definitions
+
+#![stable(feature = "raw_ext", since = "1.1.0")]
+#![deprecated(
+    since = "1.8.0",
+    note = "these type aliases are no longer supported by \
+            the standard library, the `libc` crate on \
+            crates.io should be used instead for the correct \
+            definitions"
+)]
+#![allow(deprecated)]
+
+#[stable(feature = "pthread_t", since = "1.8.0")]
+pub type pthread_t = libc::pthread_t;
+
+#[stable(feature = "raw_ext", since = "1.1.0")]
+pub type blkcnt_t = libc::blkcnt_t;
+
+#[stable(feature = "raw_ext", since = "1.1.0")]
+pub type blksize_t = libc::blksize_t;
+#[stable(feature = "raw_ext", since = "1.1.0")]
+pub type dev_t = libc::dev_t;
+#[stable(feature = "raw_ext", since = "1.1.0")]
+pub type ino_t = libc::ino_t;
+#[stable(feature = "raw_ext", since = "1.1.0")]
+pub type mode_t = libc::mode_t;
+#[stable(feature = "raw_ext", since = "1.1.0")]
+pub type nlink_t = libc::nlink_t;
+#[stable(feature = "raw_ext", since = "1.1.0")]
+pub type off_t = libc::off_t;
+
+#[stable(feature = "raw_ext", since = "1.1.0")]
+pub type time_t = libc::time_t;
diff --git a/library/std/src/os/unix/mod.rs b/library/std/src/os/unix/mod.rs
index 7d2f0bd4efea7..5c2ec8ef994d4 100644
--- a/library/std/src/os/unix/mod.rs
+++ b/library/std/src/os/unix/mod.rs
@@ -69,6 +69,8 @@ mod platform {
     pub use crate::os::netbsd::*;
     #[cfg(target_os = "nto")]
     pub use crate::os::nto::*;
+    #[cfg(target_os = "nuttx")]
+    pub use crate::os::nuttx::*;
     #[cfg(target_os = "openbsd")]
     pub use crate::os::openbsd::*;
     #[cfg(target_os = "redox")]
diff --git a/library/std/src/sys/alloc/unix.rs b/library/std/src/sys/alloc/unix.rs
index 266b69cdc1e3e..1af9d76629014 100644
--- a/library/std/src/sys/alloc/unix.rs
+++ b/library/std/src/sys/alloc/unix.rs
@@ -71,6 +71,7 @@ cfg_if::cfg_if! {
         }
     } else {
         #[inline]
+        #[cfg_attr(target_os = "vxworks", allow(unused_unsafe))]
         unsafe fn aligned_malloc(layout: &Layout) -> *mut u8 {
             let mut out = ptr::null_mut();
             // We prefer posix_memalign over aligned_alloc since it is more widely available, and
diff --git a/library/std/src/sys/dbg.rs b/library/std/src/sys/dbg.rs
index 383ed84cfa251..7266a739e785d 100644
--- a/library/std/src/sys/dbg.rs
+++ b/library/std/src/sys/dbg.rs
@@ -105,84 +105,7 @@ mod os {
     }
 }
 
-#[cfg(target_os = "linux")]
-mod os {
-    use super::DebuggerPresence;
-    use crate::fs::File;
-    use crate::io::Read;
-
-    pub(super) fn is_debugger_present() -> Option<DebuggerPresence> {
-        // This function is crafted with the following goals:
-        // * Memory efficiency: It avoids crashing the panicking process due to
-        //   out-of-memory (OOM) conditions by not using large heap buffers or
-        //   allocating significant stack space, which could lead to stack overflow.
-        // * Minimal binary size: The function uses a minimal set of facilities
-        //   from the standard library to avoid increasing the resulting binary size.
-        //
-        // To achieve these goals, the function does not use `[std::io::BufReader]`
-        // and instead reads the file byte by byte using a sliding window approach.
-        // It's important to note that the "/proc/self/status" pseudo-file is synthesized
-        // by the Virtual File System (VFS), meaning it is not read from a slow or
-        // non-volatile storage medium so buffering might not be as beneficial because
-        // all data is read from memory, though this approach does incur a syscall for
-        // each byte read.
-        //
-        // We cannot make assumptions about the file size or the position of the
-        // target prefix ("TracerPid:"), so the function does not use
-        // `[std::fs::read_to_string]` thus not employing UTF-8 to ASCII checking,
-        // conversion, or parsing as we're looking for an ASCII prefix.
-        //
-        // These condiderations make the function deviate from the familiar concise pattern
-        // of searching for a string in a text file.
-
-        fn read_byte(file: &mut File) -> Option<u8> {
-            let mut buffer = [0];
-            file.read_exact(&mut buffer).ok()?;
-            Some(buffer[0])
-        }
-
-        // The ASCII prefix of the datum we're interested in.
-        const TRACER_PID: &[u8] = b"TracerPid:\t";
-
-        let mut file = File::open("/proc/self/status").ok()?;
-        let mut matched = 0;
-
-        // Look for the `TRACER_PID` prefix.
-        while let Some(byte) = read_byte(&mut file) {
-            if byte == TRACER_PID[matched] {
-                matched += 1;
-                if matched == TRACER_PID.len() {
-                    break;
-                }
-            } else {
-                matched = 0;
-            }
-        }
-
-        // Was the prefix found?
-        if matched != TRACER_PID.len() {
-            return None;
-        }
-
-        // It was; get the ASCII representation of the first digit
-        // of the PID. That is enough to see if there is a debugger
-        // attached as the kernel does not pad the PID on the left
-        // with the leading zeroes.
-        let byte = read_byte(&mut file)?;
-        if byte.is_ascii_digit() && byte != b'0' {
-            Some(DebuggerPresence::Detected)
-        } else {
-            Some(DebuggerPresence::NotDetected)
-        }
-    }
-}
-
-#[cfg(not(any(
-    target_os = "windows",
-    target_vendor = "apple",
-    target_os = "freebsd",
-    target_os = "linux"
-)))]
+#[cfg(not(any(target_os = "windows", target_vendor = "apple", target_os = "freebsd")))]
 mod os {
     pub(super) fn is_debugger_present() -> Option<super::DebuggerPresence> {
         None
diff --git a/library/std/src/sys/pal/unix/args.rs b/library/std/src/sys/pal/unix/args.rs
index a943e3a581a83..8438a61e90feb 100644
--- a/library/std/src/sys/pal/unix/args.rs
+++ b/library/std/src/sys/pal/unix/args.rs
@@ -113,6 +113,7 @@ impl DoubleEndedIterator for Args {
     target_os = "nto",
     target_os = "hurd",
     target_os = "rtems",
+    target_os = "nuttx",
 ))]
 mod imp {
     use crate::ffi::c_char;
diff --git a/library/std/src/sys/pal/unix/env.rs b/library/std/src/sys/pal/unix/env.rs
index b2d399b8791b5..2aee0b5d46056 100644
--- a/library/std/src/sys/pal/unix/env.rs
+++ b/library/std/src/sys/pal/unix/env.rs
@@ -283,3 +283,14 @@ pub mod os {
     pub const EXE_SUFFIX: &str = "";
     pub const EXE_EXTENSION: &str = "";
 }
+
+#[cfg(target_os = "nuttx")]
+pub mod os {
+    pub const FAMILY: &str = "unix";
+    pub const OS: &str = "nuttx";
+    pub const DLL_PREFIX: &str = "lib";
+    pub const DLL_SUFFIX: &str = ".so";
+    pub const DLL_EXTENSION: &str = "so";
+    pub const EXE_SUFFIX: &str = "";
+    pub const EXE_EXTENSION: &str = "";
+}
diff --git a/library/std/src/sys/pal/unix/fd.rs b/library/std/src/sys/pal/unix/fd.rs
index 135042779ad84..6a28799ca55eb 100644
--- a/library/std/src/sys/pal/unix/fd.rs
+++ b/library/std/src/sys/pal/unix/fd.rs
@@ -98,7 +98,12 @@ impl FileDesc {
         Ok(ret as usize)
     }
 
-    #[cfg(not(any(target_os = "espidf", target_os = "horizon", target_os = "vita")))]
+    #[cfg(not(any(
+        target_os = "espidf",
+        target_os = "horizon",
+        target_os = "vita",
+        target_os = "nuttx"
+    )))]
     pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
         let ret = cvt(unsafe {
             libc::readv(
@@ -110,14 +115,24 @@ impl FileDesc {
         Ok(ret as usize)
     }
 
-    #[cfg(any(target_os = "espidf", target_os = "horizon", target_os = "vita"))]
+    #[cfg(any(
+        target_os = "espidf",
+        target_os = "horizon",
+        target_os = "vita",
+        target_os = "nuttx"
+    ))]
     pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
         io::default_read_vectored(|b| self.read(b), bufs)
     }
 
     #[inline]
     pub fn is_read_vectored(&self) -> bool {
-        cfg!(not(any(target_os = "espidf", target_os = "horizon", target_os = "vita")))
+        cfg!(not(any(
+            target_os = "espidf",
+            target_os = "horizon",
+            target_os = "vita",
+            target_os = "nuttx"
+        )))
     }
 
     pub fn read_to_end(&self, buf: &mut Vec<u8>) -> io::Result<usize> {
@@ -297,7 +312,12 @@ impl FileDesc {
         Ok(ret as usize)
     }
 
-    #[cfg(not(any(target_os = "espidf", target_os = "horizon", target_os = "vita")))]
+    #[cfg(not(any(
+        target_os = "espidf",
+        target_os = "horizon",
+        target_os = "vita",
+        target_os = "nuttx"
+    )))]
     pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
         let ret = cvt(unsafe {
             libc::writev(
@@ -309,14 +329,24 @@ impl FileDesc {
         Ok(ret as usize)
     }
 
-    #[cfg(any(target_os = "espidf", target_os = "horizon", target_os = "vita"))]
+    #[cfg(any(
+        target_os = "espidf",
+        target_os = "horizon",
+        target_os = "vita",
+        target_os = "nuttx"
+    ))]
     pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
         io::default_write_vectored(|b| self.write(b), bufs)
     }
 
     #[inline]
     pub fn is_write_vectored(&self) -> bool {
-        cfg!(not(any(target_os = "espidf", target_os = "horizon", target_os = "vita")))
+        cfg!(not(any(
+            target_os = "espidf",
+            target_os = "horizon",
+            target_os = "vita",
+            target_os = "nuttx"
+        )))
     }
 
     #[cfg_attr(target_os = "vxworks", allow(unused_unsafe))]
diff --git a/library/std/src/sys/pal/unix/fs.rs b/library/std/src/sys/pal/unix/fs.rs
index dade6d6bbaeea..86342c2add0e7 100644
--- a/library/std/src/sys/pal/unix/fs.rs
+++ b/library/std/src/sys/pal/unix/fs.rs
@@ -479,6 +479,7 @@ impl FileAttr {
         target_os = "vita",
         target_os = "hurd",
         target_os = "rtems",
+        target_os = "nuttx",
     )))]
     pub fn modified(&self) -> io::Result<SystemTime> {
         #[cfg(target_pointer_width = "32")]
@@ -501,7 +502,7 @@ impl FileAttr {
         SystemTime::new(self.stat.st_mtime as i64, 0)
     }
 
-    #[cfg(any(target_os = "horizon", target_os = "hurd"))]
+    #[cfg(any(target_os = "horizon", target_os = "hurd", target_os = "nuttx"))]
     pub fn modified(&self) -> io::Result<SystemTime> {
         SystemTime::new(self.stat.st_mtim.tv_sec as i64, self.stat.st_mtim.tv_nsec as i64)
     }
@@ -513,6 +514,7 @@ impl FileAttr {
         target_os = "vita",
         target_os = "hurd",
         target_os = "rtems",
+        target_os = "nuttx",
     )))]
     pub fn accessed(&self) -> io::Result<SystemTime> {
         #[cfg(target_pointer_width = "32")]
@@ -535,7 +537,7 @@ impl FileAttr {
         SystemTime::new(self.stat.st_atime as i64, 0)
     }
 
-    #[cfg(any(target_os = "horizon", target_os = "hurd"))]
+    #[cfg(any(target_os = "horizon", target_os = "hurd", target_os = "nuttx"))]
     pub fn accessed(&self) -> io::Result<SystemTime> {
         SystemTime::new(self.stat.st_atim.tv_sec as i64, self.stat.st_atim.tv_nsec as i64)
     }
@@ -866,6 +868,7 @@ impl Drop for Dir {
             target_os = "horizon",
             target_os = "vxworks",
             target_os = "rtems",
+            target_os = "nuttx",
         )))]
         {
             let fd = unsafe { libc::dirfd(self.0) };
@@ -1000,6 +1003,13 @@ impl DirEntry {
         self.entry.d_fileno as u64
     }
 
+    #[cfg(target_os = "nuttx")]
+    pub fn ino(&self) -> u64 {
+        // Leave this 0 for now, as NuttX does not provide an inode number
+        // in its directory entries.
+        0
+    }
+
     #[cfg(any(
         target_os = "netbsd",
         target_os = "openbsd",
@@ -1327,7 +1337,8 @@ impl File {
             target_os = "redox",
             target_os = "espidf",
             target_os = "horizon",
-            target_os = "vxworks"
+            target_os = "vxworks",
+            target_os = "nuttx",
         )))]
         let to_timespec = |time: Option<SystemTime>| match time {
             Some(time) if let Some(ts) = time.t.to_timespec() => Ok(ts),
@@ -1342,7 +1353,7 @@ impl File {
             None => Ok(libc::timespec { tv_sec: 0, tv_nsec: libc::UTIME_OMIT as _ }),
         };
         cfg_if::cfg_if! {
-            if #[cfg(any(target_os = "redox", target_os = "espidf", target_os = "horizon", target_os = "vxworks"))] {
+            if #[cfg(any(target_os = "redox", target_os = "espidf", target_os = "horizon", target_os = "vxworks", target_os = "nuttx"))] {
                 // Redox doesn't appear to support `UTIME_OMIT`.
                 // ESP-IDF and HorizonOS do not support `futimens` at all and the behavior for those OS is therefore
                 // the same as for Redox.
diff --git a/library/std/src/sys/pal/unix/mod.rs b/library/std/src/sys/pal/unix/mod.rs
index 0d63b1119d59a..4fe18daa2040f 100644
--- a/library/std/src/sys/pal/unix/mod.rs
+++ b/library/std/src/sys/pal/unix/mod.rs
@@ -222,6 +222,7 @@ static ON_BROKEN_PIPE_FLAG_USED: crate::sync::atomic::AtomicBool =
     target_os = "horizon",
     target_os = "vxworks",
     target_os = "vita",
+    target_os = "nuttx",
 )))]
 pub(crate) fn on_broken_pipe_flag_used() -> bool {
     ON_BROKEN_PIPE_FLAG_USED.load(crate::sync::atomic::Ordering::Relaxed)
@@ -425,7 +426,7 @@ cfg_if::cfg_if! {
     }
 }
 
-#[cfg(any(target_os = "espidf", target_os = "horizon", target_os = "vita"))]
+#[cfg(any(target_os = "espidf", target_os = "horizon", target_os = "vita", target_os = "nuttx"))]
 mod unsupported {
     use crate::io;
 
diff --git a/library/std/src/sys/pal/unix/net.rs b/library/std/src/sys/pal/unix/net.rs
index e98232ba89ac4..0f2e015bbcdd7 100644
--- a/library/std/src/sys/pal/unix/net.rs
+++ b/library/std/src/sys/pal/unix/net.rs
@@ -38,19 +38,19 @@ pub fn cvt_gai(err: c_int) -> io::Result<()> {
     // We may need to trigger a glibc workaround. See on_resolver_failure() for details.
     on_resolver_failure();
 
-    #[cfg(not(target_os = "espidf"))]
+    #[cfg(not(any(target_os = "espidf", target_os = "nuttx")))]
     if err == libc::EAI_SYSTEM {
         return Err(io::Error::last_os_error());
     }
 
-    #[cfg(not(target_os = "espidf"))]
+    #[cfg(not(any(target_os = "espidf", target_os = "nuttx")))]
     let detail = unsafe {
         // We can't always expect a UTF-8 environment. When we don't get that luxury,
         // it's better to give a low-quality error message than none at all.
         CStr::from_ptr(libc::gai_strerror(err)).to_string_lossy()
     };
 
-    #[cfg(target_os = "espidf")]
+    #[cfg(any(target_os = "espidf", target_os = "nuttx"))]
     let detail = "";
 
     Err(io::Error::new(
diff --git a/library/std/src/sys/pal/unix/os.rs b/library/std/src/sys/pal/unix/os.rs
index 503f8915256ee..d99bde2f9a503 100644
--- a/library/std/src/sys/pal/unix/os.rs
+++ b/library/std/src/sys/pal/unix/os.rs
@@ -48,6 +48,7 @@ extern "C" {
             target_os = "openbsd",
             target_os = "android",
             target_os = "redox",
+            target_os = "nuttx",
             target_env = "newlib"
         ),
         link_name = "__errno"
@@ -399,6 +400,7 @@ pub fn current_exe() -> io::Result<PathBuf> {
     target_os = "linux",
     target_os = "hurd",
     target_os = "android",
+    target_os = "nuttx",
     target_os = "emscripten"
 ))]
 pub fn current_exe() -> io::Result<PathBuf> {
@@ -717,6 +719,7 @@ pub fn home_dir() -> Option<PathBuf> {
         target_os = "espidf",
         target_os = "horizon",
         target_os = "vita",
+        target_os = "nuttx",
         all(target_vendor = "apple", not(target_os = "macos")),
     ))]
     unsafe fn fallback() -> Option<OsString> {
@@ -730,6 +733,7 @@ pub fn home_dir() -> Option<PathBuf> {
         target_os = "espidf",
         target_os = "horizon",
         target_os = "vita",
+        target_os = "nuttx",
         all(target_vendor = "apple", not(target_os = "macos")),
     )))]
     unsafe fn fallback() -> Option<OsString> {
diff --git a/library/std/src/sys/pal/unix/process/mod.rs b/library/std/src/sys/pal/unix/process/mod.rs
index 074f0a105e329..2751d51c44d2a 100644
--- a/library/std/src/sys/pal/unix/process/mod.rs
+++ b/library/std/src/sys/pal/unix/process/mod.rs
@@ -2,10 +2,10 @@ pub use self::process_common::{Command, CommandArgs, ExitCode, Stdio, StdioPipes
 pub use self::process_inner::{ExitStatus, ExitStatusError, Process};
 pub use crate::ffi::OsString as EnvKey;
 
-#[cfg_attr(any(target_os = "espidf", target_os = "horizon"), allow(unused))]
+#[cfg_attr(any(target_os = "espidf", target_os = "horizon", target_os = "nuttx"), allow(unused))]
 mod process_common;
 
-#[cfg(any(target_os = "espidf", target_os = "horizon", target_os = "vita"))]
+#[cfg(any(target_os = "espidf", target_os = "horizon", target_os = "vita", target_os = "nuttx"))]
 mod process_unsupported;
 
 cfg_if::cfg_if! {
@@ -16,7 +16,7 @@ cfg_if::cfg_if! {
     } else if #[cfg(target_os = "vxworks")] {
         #[path = "process_vxworks.rs"]
         mod process_inner;
-    } else if #[cfg(any(target_os = "espidf", target_os = "horizon", target_os = "vita"))] {
+    } else if #[cfg(any(target_os = "espidf", target_os = "horizon", target_os = "vita", target_os = "nuttx"))] {
         mod process_inner {
             pub use super::process_unsupported::*;
         }
diff --git a/library/std/src/sys/pal/unix/thread.rs b/library/std/src/sys/pal/unix/thread.rs
index 7fe9b6c3e52f4..a0cf3b3210382 100644
--- a/library/std/src/sys/pal/unix/thread.rs
+++ b/library/std/src/sys/pal/unix/thread.rs
@@ -140,7 +140,12 @@ impl Thread {
         }
     }
 
-    #[cfg(any(target_os = "freebsd", target_os = "dragonfly", target_os = "openbsd"))]
+    #[cfg(any(
+        target_os = "freebsd",
+        target_os = "dragonfly",
+        target_os = "openbsd",
+        target_os = "nuttx"
+    ))]
     pub fn set_name(name: &CStr) {
         unsafe {
             libc::pthread_set_name_np(libc::pthread_self(), name.as_ptr());
@@ -747,12 +752,15 @@ unsafe fn min_stack_size(attr: *const libc::pthread_attr_t) -> usize {
 }
 
 // No point in looking up __pthread_get_minstack() on non-glibc platforms.
-#[cfg(all(not(all(target_os = "linux", target_env = "gnu")), not(target_os = "netbsd")))]
+#[cfg(all(
+    not(all(target_os = "linux", target_env = "gnu")),
+    not(any(target_os = "netbsd", target_os = "nuttx"))
+))]
 unsafe fn min_stack_size(_: *const libc::pthread_attr_t) -> usize {
     libc::PTHREAD_STACK_MIN
 }
 
-#[cfg(target_os = "netbsd")]
+#[cfg(any(target_os = "netbsd", target_os = "nuttx"))]
 unsafe fn min_stack_size(_: *const libc::pthread_attr_t) -> usize {
     static STACK: crate::sync::OnceLock<usize> = crate::sync::OnceLock::new();
 
diff --git a/library/std/src/sys/personality/mod.rs b/library/std/src/sys/personality/mod.rs
index 68085d026c40a..9754e840d151a 100644
--- a/library/std/src/sys/personality/mod.rs
+++ b/library/std/src/sys/personality/mod.rs
@@ -31,7 +31,7 @@ cfg_if::cfg_if! {
         target_os = "psp",
         target_os = "xous",
         target_os = "solid_asp3",
-        all(target_family = "unix", not(target_os = "espidf"), not(target_os = "l4re"), not(target_os = "rtems")),
+        all(target_family = "unix", not(target_os = "espidf"), not(target_os = "l4re"), not(target_os = "rtems"), not(target_os = "nuttx")),
         all(target_vendor = "fortanix", target_env = "sgx"),
     ))] {
         mod gcc;
diff --git a/library/std/src/sys/random/mod.rs b/library/std/src/sys/random/mod.rs
index 16fb8c64c9b8f..d625814d15b39 100644
--- a/library/std/src/sys/random/mod.rs
+++ b/library/std/src/sys/random/mod.rs
@@ -42,6 +42,7 @@ cfg_if::cfg_if! {
         target_os = "hurd",
         target_os = "l4re",
         target_os = "nto",
+        target_os = "nuttx",
     ))] {
         mod unix_legacy;
         pub use unix_legacy::fill_bytes;
diff --git a/library/std/src/sys_common/net.rs b/library/std/src/sys_common/net.rs
index 85a82b088cd4f..57f07d05cae30 100644
--- a/library/std/src/sys_common/net.rs
+++ b/library/std/src/sys_common/net.rs
@@ -21,6 +21,7 @@ cfg_if::cfg_if! {
         target_os = "haiku",
         target_os = "l4re",
         target_os = "nto",
+        target_os = "nuttx",
         target_vendor = "apple",
     ))] {
         use crate::sys::net::netc::IPV6_JOIN_GROUP as IPV6_ADD_MEMBERSHIP;
diff --git a/library/unwind/src/lib.rs b/library/unwind/src/lib.rs
index 26ed00bfbd53e..46026324d2f82 100644
--- a/library/unwind/src/lib.rs
+++ b/library/unwind/src/lib.rs
@@ -23,6 +23,7 @@ cfg_if::cfg_if! {
         target_os = "none",
         target_os = "espidf",
         target_os = "rtems",
+        target_os = "nuttx",
     ))] {
         // These "unix" family members do not have unwinder.
     } else if #[cfg(any(
diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md
index 999eb9b8a7c60..207eb5d6d4f76 100644
--- a/src/doc/rustc/src/platform-support.md
+++ b/src/doc/rustc/src/platform-support.md
@@ -358,12 +358,14 @@ target | std | host | notes
 [`riscv32imc-esp-espidf`](platform-support/esp-idf.md) | ✓ |  | RISC-V ESP-IDF
 [`riscv32imac-esp-espidf`](platform-support/esp-idf.md) | ✓ |  | RISC-V ESP-IDF
 [`riscv32imafc-esp-espidf`](platform-support/esp-idf.md) | ✓ |  | RISC-V ESP-IDF
+[`riscv32-wrs-vxworks`](platform-support/vxworks.md) | ✓ |  |
 [`riscv64gc-unknown-hermit`](platform-support/hermit.md) | ✓ |   | RISC-V Hermit
 `riscv64gc-unknown-freebsd` |   |   | RISC-V FreeBSD
 `riscv64gc-unknown-fuchsia` |   |   | RISC-V Fuchsia
 [`riscv64gc-unknown-netbsd`](platform-support/netbsd.md) | ✓ | ✓ | RISC-V NetBSD
 [`riscv64gc-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | OpenBSD/riscv64
 [`riscv64-linux-android`](platform-support/android.md) |   |   | RISC-V 64-bit Android
+[`riscv64-wrs-vxworks`](platform-support/vxworks.md) | ✓ |  |
 `s390x-unknown-linux-musl` |  |  | S390x Linux (kernel 3.2, musl 1.2.3)
 `sparc-unknown-linux-gnu` | ✓ |  | 32-bit SPARC Linux
 [`sparc-unknown-none-elf`](./platform-support/sparc-unknown-none-elf.md) | * |  | Bare 32-bit SPARC V7+
diff --git a/src/doc/rustc/src/platform-support/vxworks.md b/src/doc/rustc/src/platform-support/vxworks.md
index f1860346c8f24..6aa3d8b73618a 100644
--- a/src/doc/rustc/src/platform-support/vxworks.md
+++ b/src/doc/rustc/src/platform-support/vxworks.md
@@ -14,6 +14,8 @@ Target triplets available:
 - `powerpc-wrs-vxworks`
 - `powerpc64-wrs-vxworks`
 - `powerpc-wrs-vxworks-spe`
+- `riscv32-wrs-vxworks`
+- `riscv64-wrs-vxworks`
 
 ## Target maintainers
 
diff --git a/tests/assembly/targets/targets-elf.rs b/tests/assembly/targets/targets-elf.rs
index e0f8e9cab7968..7d1d05e2d5589 100644
--- a/tests/assembly/targets/targets-elf.rs
+++ b/tests/assembly/targets/targets-elf.rs
@@ -372,6 +372,9 @@
 //@ revisions: powerpc_wrs_vxworks_spe
 //@ [powerpc_wrs_vxworks_spe] compile-flags: --target powerpc-wrs-vxworks-spe
 //@ [powerpc_wrs_vxworks_spe] needs-llvm-components: powerpc
+//@ revisions: riscv32_wrs_vxworks
+//@ [riscv32_wrs_vxworks] compile-flags: --target riscv32-wrs-vxworks
+//@ [riscv32_wrs_vxworks] needs-llvm-components: riscv
 //@ revisions: riscv32gc_unknown_linux_gnu
 //@ [riscv32gc_unknown_linux_gnu] compile-flags: --target riscv32gc-unknown-linux-gnu
 //@ [riscv32gc_unknown_linux_gnu] needs-llvm-components: riscv
@@ -414,6 +417,9 @@
 //@ revisions: riscv64_linux_android
 //@ [riscv64_linux_android] compile-flags: --target riscv64-linux-android
 //@ [riscv64_linux_android] needs-llvm-components: riscv
+//@ revisions: riscv64_wrs_vxworks
+//@ [riscv64_wrs_vxworks] compile-flags: --target riscv64-wrs-vxworks
+//@ [riscv64_wrs_vxworks] needs-llvm-components: riscv
 //@ revisions: riscv64gc_unknown_freebsd
 //@ [riscv64gc_unknown_freebsd] compile-flags: --target riscv64gc-unknown-freebsd
 //@ [riscv64gc_unknown_freebsd] needs-llvm-components: riscv
diff --git a/tests/crashes/123955.rs b/tests/crashes/123955.rs
deleted file mode 100644
index fdd58c84794cf..0000000000000
--- a/tests/crashes/123955.rs
+++ /dev/null
@@ -1,6 +0,0 @@
-//@ known-bug: #123955
-//@ compile-flags: -Clto -Zvirtual-function-elimination
-//@ only-x86_64
-pub fn main() {
-    _ = Box::new(()) as Box<dyn Send>;
-}
diff --git a/tests/crashes/124092.rs b/tests/crashes/124092.rs
deleted file mode 100644
index c03db384e76ea..0000000000000
--- a/tests/crashes/124092.rs
+++ /dev/null
@@ -1,7 +0,0 @@
-//@ known-bug: #124092
-//@ compile-flags: -Zvirtual-function-elimination=true -Clto=true
-//@ only-x86_64
-const X: for<'b> fn(&'b ()) = |&()| ();
-fn main() {
-    let dyn_debug = Box::new(X) as Box<fn(&'static ())> as Box<dyn Send>;
-}
diff --git a/tests/ui/codegen/virtual-function-elimination.rs b/tests/ui/codegen/virtual-function-elimination.rs
new file mode 100644
index 0000000000000..3cbeb1293e50a
--- /dev/null
+++ b/tests/ui/codegen/virtual-function-elimination.rs
@@ -0,0 +1,17 @@
+//@ build-pass
+//@ compile-flags: -Zvirtual-function-elimination=true -Clto=true
+//@ only-x86_64
+//@ no-prefer-dynamic
+
+// issue #123955
+pub fn test0() {
+    _ = Box::new(()) as Box<dyn Send>;
+}
+
+// issue #124092
+const X: for<'b> fn(&'b ()) = |&()| ();
+pub fn test1() {
+    let _dyn_debug = Box::new(X) as Box<fn(&'static ())> as Box<dyn Send>;
+}
+
+fn main() {}
diff --git a/tests/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.stderr b/tests/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.stderr
index db93bcca60fb3..bae8249845c02 100644
--- a/tests/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.stderr
+++ b/tests/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.stderr
@@ -1,3 +1,11 @@
+error: `-Znext-solver=globally` and `generic_const_exprs` are incompatible, using them at the same time is not allowed
+  --> $DIR/unify-op-with-fn-call.rs:3:12
+   |
+LL | #![feature(generic_const_exprs, adt_const_params, const_trait_impl, effects)]
+   |            ^^^^^^^^^^^^^^^^^^^
+   |
+   = help: remove one of these features
+
 error: const `impl` for trait `Add` which is not marked with `#[const_trait]`
   --> $DIR/unify-op-with-fn-call.rs:10:12
    |
@@ -67,7 +75,7 @@ error[E0284]: type annotations needed: cannot normalize `foo2<N>::{constant#0}`
 LL |     bar2::<{ std::ops::Add::add(N, N) }>();
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot normalize `foo2<N>::{constant#0}`
 
-error: aborting due to 8 previous errors
+error: aborting due to 9 previous errors
 
 Some errors have detailed explanations: E0284, E0741.
 For more information about an error, try `rustc --explain E0284`.
diff --git a/tests/ui/const-generics/issues/issue-88119.stderr b/tests/ui/const-generics/issues/issue-88119.stderr
index b5eec3046fd9e..98bb81968100b 100644
--- a/tests/ui/const-generics/issues/issue-88119.stderr
+++ b/tests/ui/const-generics/issues/issue-88119.stderr
@@ -1,3 +1,11 @@
+error: `-Znext-solver=globally` and `generic_const_exprs` are incompatible, using them at the same time is not allowed
+  --> $DIR/issue-88119.rs:4:39
+   |
+LL | #![feature(const_trait_impl, effects, generic_const_exprs)]
+   |                                       ^^^^^^^^^^^^^^^^^^^
+   |
+   = help: remove one of these features
+
 error[E0284]: type annotations needed: cannot normalize `<&T as ConstName>::{constant#0}`
   --> $DIR/issue-88119.rs:19:49
    |
@@ -28,6 +36,6 @@ LL | where
 LL |     [(); name_len::<T>()]:,
    |     --------------------- unsatisfied trait bound introduced here
 
-error: aborting due to 2 previous errors
+error: aborting due to 3 previous errors
 
 For more information about this error, try `rustc --explain E0284`.
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-trait-bounds.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-trait-bounds.stderr
index 7db6a77c77bf6..698b1b5b57817 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-trait-bounds.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-trait-bounds.stderr
@@ -1,3 +1,11 @@
+error: `-Znext-solver=globally` and `generic_const_exprs` are incompatible, using them at the same time is not allowed
+  --> $DIR/const-trait-bounds.rs:4:39
+   |
+LL | #![feature(const_trait_impl, effects, generic_const_exprs)]
+   |                                       ^^^^^^^^^^^^^^^^^^^
+   |
+   = help: remove one of these features
+
 error[E0284]: type annotations needed: cannot normalize `process<T>::{constant#0}`
   --> $DIR/const-trait-bounds.rs:12:35
    |
@@ -16,6 +24,6 @@ error[E0284]: type annotations needed: cannot normalize `process<T>::{constant#1
 LL |     input
    |     ^^^^^ cannot normalize `process<T>::{constant#1}`
 
-error: aborting due to 3 previous errors
+error: aborting due to 4 previous errors
 
 For more information about this error, try `rustc --explain E0284`.
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/unsatisfied-const-trait-bound.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/unsatisfied-const-trait-bound.rs
index c50c755f667fc..5fffe54fc1a99 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/unsatisfied-const-trait-bound.rs
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/unsatisfied-const-trait-bound.rs
@@ -1,3 +1,4 @@
+//@ known-bug: unknown
 // Ensure that we print unsatisfied always-const trait bounds as `const Trait` in diagnostics.
 //@ compile-flags: -Znext-solver
 
@@ -19,7 +20,7 @@ impl Trait for Ty {
 
 fn main() {
     // FIXME(effects): improve diagnostics on this
-    require::<Ty>(); //~ ERROR the trait bound `Trait::{synthetic#0}: const Compat` is not satisfied
+    require::<Ty>();
 }
 
 struct Container<const N: u32>;
@@ -27,9 +28,7 @@ struct Container<const N: u32>;
 // FIXME(effects): Somehow emit `the trait bound `T: const Trait` is not satisfied` here instead
 //                 and suggest changing `Trait` to `const Trait`.
 fn accept0<T: Trait>(_: Container<{ T::make() }>) {}
-//~^ ERROR mismatched types
 
 // FIXME(effects): Instead of suggesting `+ const Trait`, suggest
 //                 changing `~const Trait` to `const Trait`.
 const fn accept1<T: ~const Trait>(_: Container<{ T::make() }>) {}
-//~^ ERROR mismatched types
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/unsatisfied-const-trait-bound.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/unsatisfied-const-trait-bound.stderr
index b9f6c9e883562..0806ffa4b5df6 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/unsatisfied-const-trait-bound.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/unsatisfied-const-trait-bound.stderr
@@ -1,5 +1,13 @@
+error: `-Znext-solver=globally` and `generic_const_exprs` are incompatible, using them at the same time is not allowed
+  --> $DIR/unsatisfied-const-trait-bound.rs:5:39
+   |
+LL | #![feature(const_trait_impl, effects, generic_const_exprs)]
+   |                                       ^^^^^^^^^^^^^^^^^^^
+   |
+   = help: remove one of these features
+
 error[E0308]: mismatched types
-  --> $DIR/unsatisfied-const-trait-bound.rs:29:37
+  --> $DIR/unsatisfied-const-trait-bound.rs:30:37
    |
 LL | fn accept0<T: Trait>(_: Container<{ T::make() }>) {}
    |                                     ^^^^^^^^^ expected `false`, found `true`
@@ -17,18 +25,18 @@ LL | const fn accept1<T: ~const Trait>(_: Container<{ T::make() }>) {}
               found constant `host`
 
 error[E0277]: the trait bound `Trait::{synthetic#0}: const Compat` is not satisfied
-  --> $DIR/unsatisfied-const-trait-bound.rs:22:15
+  --> $DIR/unsatisfied-const-trait-bound.rs:23:15
    |
 LL |     require::<Ty>();
    |               ^^ the trait `const Compat` is not implemented for `Trait::{synthetic#0}`
    |
 note: required by a bound in `require`
-  --> $DIR/unsatisfied-const-trait-bound.rs:7:15
+  --> $DIR/unsatisfied-const-trait-bound.rs:8:15
    |
 LL | fn require<T: const Trait>() {}
    |               ^^^^^^^^^^^ required by this bound in `require`
 
-error: aborting due to 3 previous errors
+error: aborting due to 4 previous errors
 
 Some errors have detailed explanations: E0277, E0308.
 For more information about an error, try `rustc --explain E0277`.