diff --git a/library/std/src/os/raw/char.md b/library/core/src/ffi/c_char.md
similarity index 100%
rename from library/std/src/os/raw/char.md
rename to library/core/src/ffi/c_char.md
diff --git a/library/std/src/os/raw/double.md b/library/core/src/ffi/c_double.md
similarity index 100%
rename from library/std/src/os/raw/double.md
rename to library/core/src/ffi/c_double.md
diff --git a/library/std/src/os/raw/float.md b/library/core/src/ffi/c_float.md
similarity index 100%
rename from library/std/src/os/raw/float.md
rename to library/core/src/ffi/c_float.md
diff --git a/library/std/src/os/raw/int.md b/library/core/src/ffi/c_int.md
similarity index 100%
rename from library/std/src/os/raw/int.md
rename to library/core/src/ffi/c_int.md
diff --git a/library/std/src/os/raw/long.md b/library/core/src/ffi/c_long.md
similarity index 100%
rename from library/std/src/os/raw/long.md
rename to library/core/src/ffi/c_long.md
diff --git a/library/std/src/os/raw/longlong.md b/library/core/src/ffi/c_longlong.md
similarity index 100%
rename from library/std/src/os/raw/longlong.md
rename to library/core/src/ffi/c_longlong.md
diff --git a/library/std/src/os/raw/schar.md b/library/core/src/ffi/c_schar.md
similarity index 100%
rename from library/std/src/os/raw/schar.md
rename to library/core/src/ffi/c_schar.md
diff --git a/library/std/src/os/raw/short.md b/library/core/src/ffi/c_short.md
similarity index 100%
rename from library/std/src/os/raw/short.md
rename to library/core/src/ffi/c_short.md
diff --git a/library/std/src/os/raw/uchar.md b/library/core/src/ffi/c_uchar.md
similarity index 100%
rename from library/std/src/os/raw/uchar.md
rename to library/core/src/ffi/c_uchar.md
diff --git a/library/std/src/os/raw/uint.md b/library/core/src/ffi/c_uint.md
similarity index 100%
rename from library/std/src/os/raw/uint.md
rename to library/core/src/ffi/c_uint.md
diff --git a/library/std/src/os/raw/ulong.md b/library/core/src/ffi/c_ulong.md
similarity index 100%
rename from library/std/src/os/raw/ulong.md
rename to library/core/src/ffi/c_ulong.md
diff --git a/library/std/src/os/raw/ulonglong.md b/library/core/src/ffi/c_ulonglong.md
similarity index 100%
rename from library/std/src/os/raw/ulonglong.md
rename to library/core/src/ffi/c_ulonglong.md
diff --git a/library/std/src/os/raw/ushort.md b/library/core/src/ffi/c_ushort.md
similarity index 100%
rename from library/std/src/os/raw/ushort.md
rename to library/core/src/ffi/c_ushort.md
diff --git a/library/core/src/ffi/c_void.md b/library/core/src/ffi/c_void.md
new file mode 100644
index 00000000000..ee7403aa040
--- /dev/null
+++ b/library/core/src/ffi/c_void.md
@@ -0,0 +1,16 @@
+Equivalent to C's `void` type when used as a [pointer].
+
+In essence, `*const c_void` is equivalent to C's `const void*`
+and `*mut c_void` is equivalent to C's `void*`. That said, this is
+*not* the same as C's `void` return type, which is Rust's `()` type.
+
+To model pointers to opaque types in FFI, until `extern type` is
+stabilized, it is recommended to use a newtype wrapper around an empty
+byte array. See the [Nomicon] for details.
+
+One could use `std::os::raw::c_void` if they want to support old Rust
+compiler down to 1.1.0. After Rust 1.30.0, it was re-exported by
+this definition. For more information, please read [RFC 2521].
+
+[Nomicon]: https://doc.rust-lang.org/nomicon/ffi.html#representing-opaque-structs
+[RFC 2521]: https://github.com/rust-lang/rfcs/blob/master/text/2521-c_void-reunification.md
diff --git a/library/core/src/ffi.rs b/library/core/src/ffi/mod.rs
similarity index 67%
rename from library/core/src/ffi.rs
rename to library/core/src/ffi/mod.rs
index 9c4cf89b6bc..e5255686ff9 100644
--- a/library/core/src/ffi.rs
+++ b/library/core/src/ffi/mod.rs
@@ -1,28 +1,157 @@
+//! Platform-specific types, as defined by C.
+//!
+//! Code that interacts via FFI will almost certainly be using the
+//! base types provided by C, which aren't nearly as nicely defined
+//! as Rust's primitive types. This module provides types which will
+//! match those defined by C, so that code that interacts with C will
+//! refer to the correct types.
+
 #![stable(feature = "", since = "1.30.0")]
 #![allow(non_camel_case_types)]
 
-//! Utilities related to foreign function interface (FFI) bindings.
-
 use crate::fmt;
 use crate::marker::PhantomData;
+use crate::num::*;
 use crate::ops::{Deref, DerefMut};
 
-/// Equivalent to C's `void` type when used as a [pointer].
+macro_rules! type_alias_no_nz {
+    {
+      $Docfile:tt, $Alias:ident = $Real:ty;
+      $( $Cfg:tt )*
+    } => {
+        #[doc = include_str!($Docfile)]
+        $( $Cfg )*
+        #[unstable(feature = "core_ffi_c", issue = "94501")]
+        pub type $Alias = $Real;
+    }
+}
+
+// To verify that the NonZero types in this file's macro invocations correspond
+//
+//  perl -n < library/std/src/os/raw/mod.rs -e 'next unless m/type_alias\!/; die "$_ ?" unless m/, (c_\w+) = (\w+), NonZero_(\w+) = NonZero(\w+)/; die "$_ ?" unless $3 eq $1 and $4 eq ucfirst $2'
+//
+// NB this does not check that the main c_* types are right.
+
+macro_rules! type_alias {
+    {
+      $Docfile:tt, $Alias:ident = $Real:ty, $NZAlias:ident = $NZReal:ty;
+      $( $Cfg:tt )*
+    } => {
+        type_alias_no_nz! { $Docfile, $Alias = $Real; $( $Cfg )* }
+
+        #[doc = concat!("Type alias for `NonZero` version of [`", stringify!($Alias), "`]")]
+        #[unstable(feature = "raw_os_nonzero", issue = "82363")]
+        $( $Cfg )*
+        pub type $NZAlias = $NZReal;
+    }
+}
+
+type_alias! { "c_char.md", c_char = c_char_definition::c_char, NonZero_c_char = c_char_definition::NonZero_c_char;
+// Make this type alias appear cfg-dependent so that Clippy does not suggest
+// replacing `0 as c_char` with `0_i8`/`0_u8`. This #[cfg(all())] can be removed
+// after the false positive in https://github.com/rust-lang/rust-clippy/issues/8093
+// is fixed.
+#[cfg(all())]
+#[doc(cfg(all()))] }
+type_alias! { "c_schar.md", c_schar = i8, NonZero_c_schar = NonZeroI8; }
+type_alias! { "c_uchar.md", c_uchar = u8, NonZero_c_uchar = NonZeroU8; }
+type_alias! { "c_short.md", c_short = i16, NonZero_c_short = NonZeroI16; }
+type_alias! { "c_ushort.md", c_ushort = u16, NonZero_c_ushort = NonZeroU16; }
+type_alias! { "c_int.md", c_int = i32, NonZero_c_int = NonZeroI32; }
+type_alias! { "c_uint.md", c_uint = u32, NonZero_c_uint = NonZeroU32; }
+type_alias! { "c_long.md", c_long = i32, NonZero_c_long = NonZeroI32;
+#[doc(cfg(all()))]
+#[cfg(any(target_pointer_width = "32", windows))] }
+type_alias! { "c_ulong.md", c_ulong = u32, NonZero_c_ulong = NonZeroU32;
+#[doc(cfg(all()))]
+#[cfg(any(target_pointer_width = "32", windows))] }
+type_alias! { "c_long.md", c_long = i64, NonZero_c_long = NonZeroI64;
+#[doc(cfg(all()))]
+#[cfg(all(target_pointer_width = "64", not(windows)))] }
+type_alias! { "c_ulong.md", c_ulong = u64, NonZero_c_ulong = NonZeroU64;
+#[doc(cfg(all()))]
+#[cfg(all(target_pointer_width = "64", not(windows)))] }
+type_alias! { "c_longlong.md", c_longlong = i64, NonZero_c_longlong = NonZeroI64; }
+type_alias! { "c_ulonglong.md", c_ulonglong = u64, NonZero_c_ulonglong = NonZeroU64; }
+type_alias_no_nz! { "c_float.md", c_float = f32; }
+type_alias_no_nz! { "c_double.md", c_double = f64; }
+
+/// Equivalent to C's `size_t` type, from `stddef.h` (or `cstddef` for C++).
 ///
-/// In essence, `*const c_void` is equivalent to C's `const void*`
-/// and `*mut c_void` is equivalent to C's `void*`. That said, this is
-/// *not* the same as C's `void` return type, which is Rust's `()` type.
+/// This type is currently always [`usize`], however in the future there may be
+/// platforms where this is not the case.
+#[unstable(feature = "c_size_t", issue = "88345")]
+pub type c_size_t = usize;
+
+/// Equivalent to C's `ptrdiff_t` type, from `stddef.h` (or `cstddef` for C++).
 ///
-/// To model pointers to opaque types in FFI, until `extern type` is
-/// stabilized, it is recommended to use a newtype wrapper around an empty
-/// byte array. See the [Nomicon] for details.
+/// This type is currently always [`isize`], however in the future there may be
+/// platforms where this is not the case.
+#[unstable(feature = "c_size_t", issue = "88345")]
+pub type c_ptrdiff_t = isize;
+
+/// Equivalent to C's `ssize_t` (on POSIX) or `SSIZE_T` (on Windows) type.
 ///
-/// One could use `std::os::raw::c_void` if they want to support old Rust
-/// compiler down to 1.1.0. After Rust 1.30.0, it was re-exported by
-/// this definition. For more information, please read [RFC 2521].
-///
-/// [Nomicon]: https://doc.rust-lang.org/nomicon/ffi.html#representing-opaque-structs
-/// [RFC 2521]: https://github.com/rust-lang/rfcs/blob/master/text/2521-c_void-reunification.md
+/// This type is currently always [`isize`], however in the future there may be
+/// platforms where this is not the case.
+#[unstable(feature = "c_size_t", issue = "88345")]
+pub type c_ssize_t = isize;
+
+mod c_char_definition {
+    cfg_if! {
+        // These are the targets on which c_char is unsigned.
+        if #[cfg(any(
+            all(
+                target_os = "linux",
+                any(
+                    target_arch = "aarch64",
+                    target_arch = "arm",
+                    target_arch = "hexagon",
+                    target_arch = "powerpc",
+                    target_arch = "powerpc64",
+                    target_arch = "s390x",
+                    target_arch = "riscv64",
+                    target_arch = "riscv32"
+                )
+            ),
+            all(target_os = "android", any(target_arch = "aarch64", target_arch = "arm")),
+            all(target_os = "l4re", target_arch = "x86_64"),
+            all(
+                target_os = "freebsd",
+                any(
+                    target_arch = "aarch64",
+                    target_arch = "arm",
+                    target_arch = "powerpc",
+                    target_arch = "powerpc64",
+                    target_arch = "riscv64"
+                )
+            ),
+            all(
+                target_os = "netbsd",
+                any(target_arch = "aarch64", target_arch = "arm", target_arch = "powerpc")
+            ),
+            all(target_os = "openbsd", target_arch = "aarch64"),
+            all(
+                target_os = "vxworks",
+                any(
+                    target_arch = "aarch64",
+                    target_arch = "arm",
+                    target_arch = "powerpc64",
+                    target_arch = "powerpc"
+                )
+            ),
+            all(target_os = "fuchsia", target_arch = "aarch64")
+        ))] {
+            pub type c_char = u8;
+            pub type NonZero_c_char = crate::num::NonZeroU8;
+        } else {
+            // On every other target, c_char is signed.
+            pub type c_char = i8;
+            pub type NonZero_c_char = crate::num::NonZeroI8;
+        }
+    }
+}
+
 // N.B., for LLVM to recognize the void pointer type and by extension
 //     functions like malloc(), we need to have it represented as i8* in
 //     LLVM bitcode. The enum used here ensures this and prevents misuse
@@ -31,6 +160,7 @@ use crate::ops::{Deref, DerefMut};
 //     otherwise and we need at least one variant as otherwise the enum
 //     would be uninhabited and at least dereferencing such pointers would
 //     be UB.
+#[doc = include_str!("c_void.md")]
 #[repr(u8)]
 #[stable(feature = "core_c_void", since = "1.30.0")]
 pub enum c_void {
diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs
index 1e0d9b79b9f..4603b5aae20 100644
--- a/library/std/src/lib.rs
+++ b/library/std/src/lib.rs
@@ -261,6 +261,7 @@
 #![feature(const_socketaddr)]
 #![feature(const_trait_impl)]
 #![feature(container_error_extra)]
+#![feature(core_ffi_c)]
 #![feature(core_intrinsics)]
 #![feature(core_panic)]
 #![feature(custom_test_frameworks)]
@@ -315,6 +316,7 @@
 #![feature(prelude_import)]
 #![feature(ptr_as_uninit)]
 #![feature(ptr_internals)]
+#![feature(raw_os_nonzero)]
 #![feature(rustc_attrs)]
 #![feature(rustc_private)]
 #![feature(saturating_int_impl)]
diff --git a/library/std/src/os/raw/mod.rs b/library/std/src/os/raw/mod.rs
index b6d5199341c..19d0ffb2e39 100644
--- a/library/std/src/os/raw/mod.rs
+++ b/library/std/src/os/raw/mod.rs
@@ -1,156 +1,31 @@
-//! Platform-specific types, as defined by C.
-//!
-//! Code that interacts via FFI will almost certainly be using the
-//! base types provided by C, which aren't nearly as nicely defined
-//! as Rust's primitive types. This module provides types which will
-//! match those defined by C, so that code that interacts with C will
-//! refer to the correct types.
+//! Compatibility module for C platform-specific types. Use [`core::ffi`] instead.
 
 #![stable(feature = "raw_os", since = "1.1.0")]
 
 #[cfg(test)]
 mod tests;
 
-use core::num::*;
-
-macro_rules! type_alias_no_nz {
-    {
-      $Docfile:tt, $Alias:ident = $Real:ty;
-      $( $Cfg:tt )*
-    } => {
-        #[doc = include_str!($Docfile)]
-        $( $Cfg )*
+macro_rules! alias_core_ffi {
+    ($($t:ident)*) => {$(
         #[stable(feature = "raw_os", since = "1.1.0")]
-        pub type $Alias = $Real;
-    }
+        #[doc = include_str!(concat!("../../../../core/src/ffi/", stringify!($t), ".md"))]
+        // Make this type alias appear cfg-dependent so that Clippy does not suggest
+        // replacing expressions like `0 as c_char` with `0_i8`/`0_u8`. This #[cfg(all())] can be
+        // removed after the false positive in https://github.com/rust-lang/rust-clippy/issues/8093
+        // is fixed.
+        #[cfg(all())]
+        #[doc(cfg(all()))]
+        pub type $t = core::ffi::$t;
+    )*}
 }
 
-// To verify that the NonZero types in this file's macro invocations correspond
-//
-//  perl -n < library/std/src/os/raw/mod.rs -e 'next unless m/type_alias\!/; die "$_ ?" unless m/, (c_\w+) = (\w+), NonZero_(\w+) = NonZero(\w+)/; die "$_ ?" unless $3 eq $1 and $4 eq ucfirst $2'
-//
-// NB this does not check that the main c_* types are right.
-
-macro_rules! type_alias {
-    {
-      $Docfile:tt, $Alias:ident = $Real:ty, $NZAlias:ident = $NZReal:ty;
-      $( $Cfg:tt )*
-    } => {
-        type_alias_no_nz! { $Docfile, $Alias = $Real; $( $Cfg )* }
-
-        #[doc = concat!("Type alias for `NonZero` version of [`", stringify!($Alias), "`]")]
-        #[unstable(feature = "raw_os_nonzero", issue = "82363")]
-        $( $Cfg )*
-        pub type $NZAlias = $NZReal;
-    }
-}
-
-type_alias! { "char.md", c_char = c_char_definition::c_char, NonZero_c_char = c_char_definition::NonZero_c_char;
-// Make this type alias appear cfg-dependent so that Clippy does not suggest
-// replacing `0 as c_char` with `0_i8`/`0_u8`. This #[cfg(all())] can be removed
-// after the false positive in https://github.com/rust-lang/rust-clippy/issues/8093
-// is fixed.
-#[cfg(all())]
-#[doc(cfg(all()))] }
-type_alias! { "schar.md", c_schar = i8, NonZero_c_schar = NonZeroI8; }
-type_alias! { "uchar.md", c_uchar = u8, NonZero_c_uchar = NonZeroU8; }
-type_alias! { "short.md", c_short = i16, NonZero_c_short = NonZeroI16; }
-type_alias! { "ushort.md", c_ushort = u16, NonZero_c_ushort = NonZeroU16; }
-type_alias! { "int.md", c_int = i32, NonZero_c_int = NonZeroI32; }
-type_alias! { "uint.md", c_uint = u32, NonZero_c_uint = NonZeroU32; }
-type_alias! { "long.md", c_long = i32, NonZero_c_long = NonZeroI32;
-#[doc(cfg(all()))]
-#[cfg(any(target_pointer_width = "32", windows))] }
-type_alias! { "ulong.md", c_ulong = u32, NonZero_c_ulong = NonZeroU32;
-#[doc(cfg(all()))]
-#[cfg(any(target_pointer_width = "32", windows))] }
-type_alias! { "long.md", c_long = i64, NonZero_c_long = NonZeroI64;
-#[doc(cfg(all()))]
-#[cfg(all(target_pointer_width = "64", not(windows)))] }
-type_alias! { "ulong.md", c_ulong = u64, NonZero_c_ulong = NonZeroU64;
-#[doc(cfg(all()))]
-#[cfg(all(target_pointer_width = "64", not(windows)))] }
-type_alias! { "longlong.md", c_longlong = i64, NonZero_c_longlong = NonZeroI64; }
-type_alias! { "ulonglong.md", c_ulonglong = u64, NonZero_c_ulonglong = NonZeroU64; }
-type_alias_no_nz! { "float.md", c_float = f32; }
-type_alias_no_nz! { "double.md", c_double = f64; }
-
-#[stable(feature = "raw_os", since = "1.1.0")]
-#[doc(no_inline)]
-pub use core::ffi::c_void;
-
-/// Equivalent to C's `size_t` type, from `stddef.h` (or `cstddef` for C++).
-///
-/// This type is currently always [`usize`], however in the future there may be
-/// platforms where this is not the case.
-#[unstable(feature = "c_size_t", issue = "88345")]
-pub type c_size_t = usize;
-
-/// Equivalent to C's `ptrdiff_t` type, from `stddef.h` (or `cstddef` for C++).
-///
-/// This type is currently always [`isize`], however in the future there may be
-/// platforms where this is not the case.
-#[unstable(feature = "c_size_t", issue = "88345")]
-pub type c_ptrdiff_t = isize;
-
-/// Equivalent to C's `ssize_t` (on POSIX) or `SSIZE_T` (on Windows) type.
-///
-/// This type is currently always [`isize`], however in the future there may be
-/// platforms where this is not the case.
-#[unstable(feature = "c_size_t", issue = "88345")]
-pub type c_ssize_t = isize;
-
-mod c_char_definition {
-    cfg_if::cfg_if! {
-        // These are the targets on which c_char is unsigned.
-        if #[cfg(any(
-            all(
-                target_os = "linux",
-                any(
-                    target_arch = "aarch64",
-                    target_arch = "arm",
-                    target_arch = "hexagon",
-                    target_arch = "powerpc",
-                    target_arch = "powerpc64",
-                    target_arch = "s390x",
-                    target_arch = "riscv64",
-                    target_arch = "riscv32"
-                )
-            ),
-            all(target_os = "android", any(target_arch = "aarch64", target_arch = "arm")),
-            all(target_os = "l4re", target_arch = "x86_64"),
-            all(
-                target_os = "freebsd",
-                any(
-                    target_arch = "aarch64",
-                    target_arch = "arm",
-                    target_arch = "powerpc",
-                    target_arch = "powerpc64",
-                    target_arch = "riscv64"
-                )
-            ),
-            all(
-                target_os = "netbsd",
-                any(target_arch = "aarch64", target_arch = "arm", target_arch = "powerpc")
-            ),
-            all(target_os = "openbsd", target_arch = "aarch64"),
-            all(
-                target_os = "vxworks",
-                any(
-                    target_arch = "aarch64",
-                    target_arch = "arm",
-                    target_arch = "powerpc64",
-                    target_arch = "powerpc"
-                )
-            ),
-            all(target_os = "fuchsia", target_arch = "aarch64")
-        ))] {
-            pub type c_char = u8;
-            pub type NonZero_c_char = core::num::NonZeroU8;
-        } else {
-            // On every other target, c_char is signed.
-            pub type c_char = i8;
-            pub type NonZero_c_char = core::num::NonZeroI8;
-        }
-    }
+alias_core_ffi! {
+    c_char c_schar c_uchar
+    c_short c_ushort
+    c_int c_uint
+    c_long c_ulong
+    c_longlong c_ulonglong
+    c_float
+    c_double
+    c_void
 }
diff --git a/library/std/src/sys/unix/process/process_unix.rs b/library/std/src/sys/unix/process/process_unix.rs
index 9fc2d9fce4d..07a0339c066 100644
--- a/library/std/src/sys/unix/process/process_unix.rs
+++ b/library/std/src/sys/unix/process/process_unix.rs
@@ -3,11 +3,11 @@ use crate::fmt;
 use crate::io::{self, Error, ErrorKind};
 use crate::mem;
 use crate::num::NonZeroI32;
-use crate::os::raw::NonZero_c_int;
 use crate::ptr;
 use crate::sys;
 use crate::sys::cvt;
 use crate::sys::process::process_common::*;
+use core::ffi::NonZero_c_int;
 
 #[cfg(target_os = "linux")]
 use crate::os::linux::process::PidFd;
diff --git a/library/std/src/sys/unix/process/process_unsupported.rs b/library/std/src/sys/unix/process/process_unsupported.rs
index 7d549d060fd..bbabdf787d9 100644
--- a/library/std/src/sys/unix/process/process_unsupported.rs
+++ b/library/std/src/sys/unix/process/process_unsupported.rs
@@ -3,12 +3,12 @@ use crate::fmt;
 use crate::io;
 use crate::io::ErrorKind;
 use crate::num::NonZeroI32;
-use crate::os::raw::NonZero_c_int;
 use crate::sys;
 use crate::sys::cvt;
 use crate::sys::pipe::AnonPipe;
 use crate::sys::process::process_common::*;
 use crate::sys::unix::unsupported::*;
+use core::ffi::NonZero_c_int;
 
 use libc::{c_int, pid_t};
 
diff --git a/library/std/src/sys/unix/process/process_vxworks.rs b/library/std/src/sys/unix/process/process_vxworks.rs
index c6714d3aae2..56ed6cfeb6a 100644
--- a/library/std/src/sys/unix/process/process_vxworks.rs
+++ b/library/std/src/sys/unix/process/process_vxworks.rs
@@ -2,11 +2,11 @@ use crate::convert::{TryFrom, TryInto};
 use crate::fmt;
 use crate::io::{self, Error, ErrorKind};
 use crate::num::NonZeroI32;
-use crate::os::raw::NonZero_c_int;
 use crate::sys;
 use crate::sys::cvt;
 use crate::sys::process::process_common::*;
 use crate::sys_common::thread;
+use core::ffi::NonZero_c_int;
 use libc::RTP_ID;
 use libc::{self, c_char, c_int};
 
diff --git a/library/std/src/sys/windows/c.rs b/library/std/src/sys/windows/c.rs
index c7b6290693e..2affd7e75b0 100644
--- a/library/std/src/sys/windows/c.rs
+++ b/library/std/src/sys/windows/c.rs
@@ -5,9 +5,9 @@
 #![unstable(issue = "none", feature = "windows_c")]
 
 use crate::mem;
-use crate::os::raw::NonZero_c_ulong;
 use crate::os::raw::{c_char, c_int, c_long, c_longlong, c_uint, c_ulong, c_ushort};
 use crate::ptr;
+use core::ffi::NonZero_c_ulong;
 
 use libc::{c_void, size_t, wchar_t};
 
diff --git a/src/tools/tidy/src/pal.rs b/src/tools/tidy/src/pal.rs
index cb6d56a167d..f5ff3860afe 100644
--- a/src/tools/tidy/src/pal.rs
+++ b/src/tools/tidy/src/pal.rs
@@ -46,7 +46,7 @@ const EXCEPTION_PATHS: &[&str] = &[
     // pointer regardless of the target architecture. As a result,
     // we must use `#[cfg(windows)]` to conditionally compile the
     // correct `VaList` structure for windows.
-    "library/core/src/ffi.rs",
+    "library/core/src/ffi/mod.rs",
     "library/std/src/sys/", // Platform-specific code for std lives here.
     "library/std/src/os",   // Platform-specific public interfaces
     // Temporary `std` exceptions