diff --git a/Cargo.lock b/Cargo.lock index 5fc3a5ac71722..3624ae6bbbb08 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -224,7 +224,7 @@ dependencies = [ "rustc-hash 2.1.1", "serde", "serde_derive", - "syn", + "syn 2.0.117", ] [[package]] @@ -418,7 +418,7 @@ checksum = "89385e82b5d1821d2219e0b095efa2cc1f246cbf99080f3be46a1a85c0d392d9" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.117", ] [[package]] @@ -647,7 +647,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn", + "syn 2.0.117", ] [[package]] @@ -817,7 +817,7 @@ dependencies = [ "nom", "proc-macro2", "quote", - "syn", + "syn 2.0.117", ] [[package]] @@ -1074,7 +1074,7 @@ dependencies = [ "proc-macro2", "quote", "scratch", - "syn", + "syn 2.0.117", ] [[package]] @@ -1088,7 +1088,7 @@ dependencies = [ "indexmap", "proc-macro2", "quote", - "syn", + "syn 2.0.117", ] [[package]] @@ -1106,7 +1106,7 @@ dependencies = [ "indexmap", "proc-macro2", "quote", - "syn", + "syn 2.0.117", ] [[package]] @@ -1130,7 +1130,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn", + "syn 2.0.117", ] [[package]] @@ -1141,7 +1141,7 @@ checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" dependencies = [ "darling_core", "quote", - "syn", + "syn 2.0.117", ] [[package]] @@ -1162,7 +1162,7 @@ checksum = "d08b3a0bcc0d079199cd476b2cae8435016ec11d1c0986c6901c5ac223041534" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.117", ] [[package]] @@ -1183,7 +1183,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn", + "syn 2.0.117", ] [[package]] @@ -1193,7 +1193,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ab63b0e2bf4d5928aff72e83a7dace85d7bba5fe12dcc3c5a572d78caffd3f3c" dependencies = [ "derive_builder_core", - "syn", + "syn 2.0.117", ] [[package]] @@ -1205,7 +1205,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn", + "syn 2.0.117", ] [[package]] @@ -1280,7 +1280,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.117", ] [[package]] @@ -2172,7 +2172,7 @@ checksum = "980af8b43c3ad5d8d349ace167ec8170839f753a42d233ba19e08afe1850fa69" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.117", ] [[package]] @@ -2602,7 +2602,7 @@ checksum = "4568f25ccbd45ab5d5603dc34318c1ec56b117531781260002151b8530a9f931" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.117", ] [[package]] @@ -2980,7 +2980,7 @@ dependencies = [ "pest_meta", "proc-macro2", "quote", - "syn", + "syn 2.0.117", ] [[package]] @@ -3169,7 +3169,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" dependencies = [ "proc-macro2", - "syn", + "syn 2.0.117", ] [[package]] @@ -3213,7 +3213,7 @@ checksum = "7347867d0a7e1208d93b46767be83e2b8f978c3dad35f775ac8d8847551d6fe1" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.117", ] [[package]] @@ -3397,7 +3397,7 @@ checksum = "b7186006dcb21920990093f30e3dea63b7d6e977bf1256be20c3563a5db070da" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.117", ] [[package]] @@ -3471,9 +3471,9 @@ dependencies = [ [[package]] name = "rkyv" -version = "0.8.16" +version = "0.8.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73389e0c99e664f919275ab5b5b0471391fe9a8de61e1dff9b1eaf56a90f16e3" +checksum = "d9776093b7ca170454ab1406954f7b7d97a57c51dc6c0642957fb2ef25c2d399" dependencies = [ "bytecheck", "bytes", @@ -3490,13 +3490,13 @@ dependencies = [ [[package]] name = "rkyv_derive" -version = "0.8.16" +version = "0.8.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d2ed0b54125315fb36bd021e82d314d1c126548f871634b483f46b31d13cac6" +checksum = "1c25ef604ac7dd839d44d64648952ea23c97866f124ff671b0ed2cf3ad9bb06e" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 3.0.3", ] [[package]] @@ -4217,7 +4217,7 @@ version = "0.0.0" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.117", ] [[package]] @@ -4366,7 +4366,7 @@ dependencies = [ "indexmap", "proc-macro2", "quote", - "syn", + "syn 2.0.117", "synstructure", ] @@ -4959,7 +4959,7 @@ dependencies = [ "indexmap", "proc-macro2", "quote", - "syn", + "syn 2.0.117", "synstructure", ] @@ -5059,7 +5059,7 @@ dependencies = [ "proc-macro2", "quote", "serde", - "syn", + "syn 2.0.117", ] [[package]] @@ -5167,7 +5167,7 @@ dependencies = [ "proc-macro2", "quote", "serde_derive_internals", - "syn", + "syn 2.0.117", ] [[package]] @@ -5253,7 +5253,7 @@ checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.117", ] [[package]] @@ -5264,7 +5264,7 @@ checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.117", ] [[package]] @@ -5479,6 +5479,17 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "syn" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53e9bae58849f64dfa4f5d5ae372c8341f7305f82a3868709269343628b659a3" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + [[package]] name = "synstructure" version = "0.13.2" @@ -5487,7 +5498,7 @@ checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.117", ] [[package]] @@ -5623,7 +5634,7 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.117", ] [[package]] @@ -5634,7 +5645,7 @@ checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.117", ] [[package]] @@ -5876,7 +5887,7 @@ checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.117", ] [[package]] @@ -6077,7 +6088,7 @@ checksum = "a1249a628de3ad34b821ecb1001355bca3940bcb2f88558f1a8bd82e977f75b5" dependencies = [ "proc-macro-hack", "quote", - "syn", + "syn 2.0.117", "unic-langid-impl", ] @@ -6340,7 +6351,7 @@ dependencies = [ "bumpalo", "proc-macro2", "quote", - "syn", + "syn 2.0.117", "wasm-bindgen-shared", ] @@ -6643,7 +6654,7 @@ checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.117", ] [[package]] @@ -6654,7 +6665,7 @@ checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.117", ] [[package]] @@ -6903,7 +6914,7 @@ dependencies = [ "heck", "indexmap", "prettyplease", - "syn", + "syn 2.0.117", "wasm-metadata 0.244.0", "wit-bindgen-core", "wit-component 0.244.0", @@ -6919,7 +6930,7 @@ dependencies = [ "prettyplease", "proc-macro2", "quote", - "syn", + "syn 2.0.117", "wit-bindgen-core", "wit-bindgen-rust", ] @@ -7047,7 +7058,7 @@ checksum = "de844c262c8848816172cef550288e7dc6c7b7814b4ee56b3e1553f275f1858e" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.117", "synstructure", ] @@ -7068,7 +7079,7 @@ checksum = "88d2b8d9c68ad2b9e4340d7832716a4d21a22a1154777ad56ea55c51a9cf3831" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.117", ] [[package]] @@ -7088,7 +7099,7 @@ checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.117", "synstructure", ] @@ -7124,7 +7135,7 @@ checksum = "625dc425cab0dca6dc3c3319506e6593dcb08a9f387ea3b284dbd52a92c40555" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.117", ] [[package]] diff --git a/library/core/src/net/parser.rs b/library/core/src/net/parser.rs index a6473735dd455..8e56fd323b0d7 100644 --- a/library/core/src/net/parser.rs +++ b/library/core/src/net/parser.rs @@ -480,7 +480,7 @@ enum AddrKind { /// use std::net::SocketAddr; /// /// // No problem, the `panic!` message has disappeared. -/// let _foo: SocketAddr = "127.0.0.1:8080".parse().expect("unreachable panic"); +/// let _foo: SocketAddr = "127.0.0.1:8080".parse().expect("`parse` should succeed"); /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[derive(Debug, Clone, PartialEq, Eq)] diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs index 87e2f0db25a76..295fd538d8cfd 100644 --- a/library/core/src/ptr/const_ptr.rs +++ b/library/core/src/ptr/const_ptr.rs @@ -611,7 +611,7 @@ impl *const T { /// ``` #[stable(feature = "ptr_offset_from", since = "1.47.0")] #[rustc_const_stable(feature = "const_ptr_offset_from", since = "1.65.0")] - #[inline] + #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn offset_from(self, origin: *const T) -> isize where @@ -1142,7 +1142,7 @@ impl *const T { /// [`ptr::read`]: crate::ptr::read() #[stable(feature = "pointer_methods", since = "1.26.0")] #[rustc_const_stable(feature = "const_ptr_read", since = "1.71.0")] - #[inline] + #[inline(always)] #[track_caller] pub const unsafe fn read(self) -> T where @@ -1164,7 +1164,7 @@ impl *const T { /// [`ptr::read_volatile`]: crate::ptr::read_volatile() #[stable(feature = "pointer_methods", since = "1.26.0")] #[rustc_const_unstable(feature = "const_volatile", issue = "159094")] - #[inline] + #[inline(always)] #[track_caller] pub const unsafe fn read_volatile(self) -> T where @@ -1184,7 +1184,7 @@ impl *const T { /// [`ptr::read_unaligned`]: crate::ptr::read_unaligned() #[stable(feature = "pointer_methods", since = "1.26.0")] #[rustc_const_stable(feature = "const_ptr_read", since = "1.71.0")] - #[inline] + #[inline(always)] #[track_caller] pub const unsafe fn read_unaligned(self) -> T where @@ -1204,7 +1204,7 @@ impl *const T { /// [`ptr::copy`]: crate::ptr::copy() #[rustc_const_stable(feature = "const_intrinsic_copy", since = "1.83.0")] #[stable(feature = "pointer_methods", since = "1.26.0")] - #[inline] + #[inline(always)] #[track_caller] pub const unsafe fn copy_to(self, dest: *mut T, count: usize) where @@ -1224,7 +1224,7 @@ impl *const T { /// [`ptr::copy_nonoverlapping`]: crate::ptr::copy_nonoverlapping() #[rustc_const_stable(feature = "const_intrinsic_copy", since = "1.83.0")] #[stable(feature = "pointer_methods", since = "1.26.0")] - #[inline] + #[inline(always)] #[track_caller] pub const unsafe fn copy_to_nonoverlapping(self, dest: *mut T, count: usize) where @@ -1435,7 +1435,7 @@ impl *const [T] { /// let slice: *const [i8] = ptr::slice_from_raw_parts(ptr::null(), 3); /// assert_eq!(slice.len(), 3); /// ``` - #[inline] + #[inline(always)] #[stable(feature = "slice_ptr_len", since = "1.79.0")] #[rustc_const_stable(feature = "const_slice_ptr_len", since = "1.79.0")] pub const fn len(self) -> usize { @@ -1472,7 +1472,7 @@ impl *const [T] { /// let slice: *const [i8] = ptr::slice_from_raw_parts(ptr::null(), 3); /// assert_eq!(slice.as_ptr(), ptr::null()); /// ``` - #[inline] + #[inline(always)] #[unstable(feature = "slice_ptr_get", issue = "74265")] pub const fn as_ptr(self) -> *const T { self as *const T @@ -1516,7 +1516,7 @@ impl *const [T] { /// ``` #[unstable(feature = "slice_ptr_get", issue = "74265")] #[rustc_const_unstable(feature = "const_index", issue = "143775")] - #[inline] + #[inline(always)] pub const unsafe fn get_unchecked(self, index: I) -> *const I::Output where I: [const] SliceIndex<[T]>, @@ -1561,7 +1561,7 @@ impl *const [T; N] { /// let arr: *const [i8; 3] = ptr::null(); /// assert_eq!(arr.as_ptr(), ptr::null()); /// ``` - #[inline] + #[inline(always)] #[unstable(feature = "array_ptr_get", issue = "119834")] pub const fn as_ptr(self) -> *const T { self as *const T @@ -1592,7 +1592,7 @@ impl *const [T; N] { note = "see issue #53020 for more information" )] impl PartialEq for *const T { - #[inline] + #[inline(always)] #[allow(ambiguous_wide_pointer_comparisons)] fn eq(&self, other: &*const T) -> bool { *self == *other @@ -1634,31 +1634,31 @@ impl Ord for *const T { note = "see issue #53020 for more information" )] impl PartialOrd for *const T { - #[inline] + #[inline(always)] #[allow(ambiguous_wide_pointer_comparisons)] fn partial_cmp(&self, other: &*const T) -> Option { Some(self.cmp(other)) } - #[inline] + #[inline(always)] #[allow(ambiguous_wide_pointer_comparisons)] fn lt(&self, other: &*const T) -> bool { *self < *other } - #[inline] + #[inline(always)] #[allow(ambiguous_wide_pointer_comparisons)] fn le(&self, other: &*const T) -> bool { *self <= *other } - #[inline] + #[inline(always)] #[allow(ambiguous_wide_pointer_comparisons)] fn gt(&self, other: &*const T) -> bool { *self > *other } - #[inline] + #[inline(always)] #[allow(ambiguous_wide_pointer_comparisons)] fn ge(&self, other: &*const T) -> bool { *self >= *other diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs index 41f4b837efaea..8b8a65d630189 100644 --- a/library/core/src/ptr/mod.rs +++ b/library/core/src/ptr/mod.rs @@ -1331,7 +1331,7 @@ pub const fn slice_from_raw_parts_mut(data: *mut T, len: usize) -> *mut [T] { /// assert_eq!([1, 0, 1, 2], array); /// } /// ``` -#[inline] +#[inline(always)] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_stable(feature = "const_swap", since = "1.85.0")] #[rustc_diagnostic_item = "ptr_swap"] @@ -1573,7 +1573,7 @@ unsafe fn swap_nonoverlapping_bytes(x: *mut u8, y: *mut u8, bytes: NonZero(dst: *mut T, src: T) -> T { /// ``` /// /// [valid]: self#safety -#[inline] +#[inline(always)] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_stable(feature = "const_ptr_read", since = "1.71.0")] #[track_caller] @@ -1826,7 +1826,7 @@ pub const unsafe fn read(src: *const T) -> T { /// unsafe { ptr.read_unaligned() } /// } /// ``` -#[inline] +#[inline(always)] #[stable(feature = "ptr_unaligned", since = "1.17.0")] #[rustc_const_stable(feature = "const_ptr_read", since = "1.71.0")] #[track_caller] @@ -1932,7 +1932,7 @@ pub const unsafe fn read_unaligned(src: *const T) -> T { /// assert_eq!(foo, "bar"); /// assert_eq!(bar, "foo"); /// ``` -#[inline] +#[inline(always)] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_stable(feature = "const_ptr_write", since = "1.83.0")] #[rustc_diagnostic_item = "ptr_write"] @@ -2036,7 +2036,7 @@ pub const unsafe fn write(dst: *mut T, src: T) { /// unsafe { ptr.write_unaligned(val) } /// } /// ``` -#[inline] +#[inline(always)] #[stable(feature = "ptr_unaligned", since = "1.17.0")] #[rustc_const_stable(feature = "const_ptr_write", since = "1.83.0")] #[rustc_diagnostic_item = "ptr_write_unaligned"] @@ -2141,7 +2141,7 @@ pub const unsafe fn write_unaligned(dst: *mut T, src: T) { /// assert_eq!(std::ptr::read_volatile(y), 12); /// } /// ``` -#[inline] +#[inline(always)] #[stable(feature = "volatile", since = "1.9.0")] #[rustc_const_unstable(feature = "const_volatile", issue = "159094")] #[track_caller] @@ -2247,7 +2247,7 @@ pub const unsafe fn read_volatile(src: *const T) -> T { /// assert_eq!(std::ptr::read_volatile(y), 12); /// } /// ``` -#[inline] +#[inline(always)] #[stable(feature = "volatile", since = "1.9.0")] #[rustc_const_unstable(feature = "const_volatile", issue = "159094")] #[rustc_diagnostic_item = "ptr_write_volatile"] diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs index 3b8499758d90d..77821ad29b3dd 100644 --- a/library/std/src/fs.rs +++ b/library/std/src/fs.rs @@ -1571,6 +1571,63 @@ impl Dir { .map(|inner| Self { inner }) } + /// Attempts to open a directory at `path` according to `opts`. + /// + /// This function opens a directory. To open a file instead, see [`File::open`]. + /// + /// # Errors + /// + /// This function will return an error if `path` does not point to an existing directory. + /// Other errors may also be returned according to [`OpenOptions::open`]. + /// + /// # Examples + /// + /// ```no_run + /// #![feature(dirfd)] + /// use std::{fs::{Dir, OpenOptions}, io}; + /// + /// fn main() -> std::io::Result<()> { + /// let dir = Dir::open_with("foo", &OpenOptions::new().read(true))?; + /// let mut f = dir.open_file("bar.txt")?; + /// let contents = io::read_to_string(f)?; + /// assert_eq!(contents, "Hello, world!"); + /// Ok(()) + /// } + /// ``` + #[unstable(feature = "dirfd", issue = "120426")] + pub fn open_with>(path: P, opts: &OpenOptions) -> io::Result { + fs_imp::Dir::open(path.as_ref(), &opts.0).map(|inner| Self { inner }) + } + + /// Attempts to open a directory at `path` with the minimum permissions for traversal. + /// + /// The permissions requested by this function are guaranteed to be sufficient to open a child + /// file or folder, but not necessarily to list all children. + /// + /// # Errors + /// + /// This function may return an error according to [`OpenOptions::open`]. + /// + /// # Examples + /// + /// ```no_run + /// #![feature(dirfd)] + /// use std::{fs::Dir, io}; + /// + /// fn main() -> std::io::Result<()> { + /// let foo = Dir::open_for_traversal("foo")?; + /// let foobar = foo.open_dir("bar")?; + /// let mut foobarbaz = foobar.open_file("baz")?; + /// let contents = io::read_to_string(foobarbaz)?; + /// assert_eq!(contents, "Hello, world!"); + /// Ok(()) + /// } + /// ``` + #[unstable(feature = "dirfd", issue = "120426")] + pub fn open_for_traversal>(path: P) -> io::Result { + fs_imp::Dir::open_for_traversal(path.as_ref()).map(|inner| Self { inner }) + } + /// Queries metadata about the underlying directory. /// /// # Examples @@ -1712,6 +1769,99 @@ impl Dir { ) -> io::Result<()> { self.inner.rename(from.as_ref(), &to_dir.inner, to.as_ref()) } + + /// Attempts to create a directory relative to this directory. + /// + /// This function interprets `path` relative to the directory provided by `self`. To create a directory + /// relative to the current working directory, or at an absolute path, see + /// [`fs::create_dir`][crate::fs::create_dir]. + #[unstable(feature = "dirfd", issue = "120426")] + pub fn create_dir>(&self, path: P) -> io::Result<()> { + self.inner.create_dir(path.as_ref()) + } + + /// Attempts to open a directory in read-only mode relative to this directory. + /// + /// This function interprets `path` relative to the directory provided by `self`. To open a directory + /// relative to the current working directory, or at an absolute path, see [`Dir::open`]. + /// + /// # Errors + /// + /// This function will return an error if `path` does not point to an existing directory. + /// Other errors may also be returned according to [`OpenOptions::open`]. + /// + /// # Examples + /// + /// ```no_run + /// #![feature(dirfd)] + /// use std::{fs::Dir}; + /// + /// fn main() -> std::io::Result<()> { + /// let dir = Dir::open("foo")?; + /// let foobar = dir.open_dir("bar")?; + /// Ok(()) + /// } + /// ``` + #[unstable(feature = "dirfd", issue = "120426")] + pub fn open_dir>(&self, path: P) -> io::Result { + self.inner + .open_dir(path.as_ref(), &OpenOptions::new().read(true).0) + .map(|inner| Self { inner }) + } + + /// Attempts to open a directory relative to this directory according to `opts`. + /// + /// This function interprets `path` relative to the directory provided by `self`. To open a directory + /// relative to the current working directory, or at an absolute path, see [`Dir::open`]. + /// + /// # Errors + /// + /// This function will return errors according to [`OpenOptions::open`]. + /// + /// # Examples + /// + /// ```no_run + /// #![feature(dirfd)] + /// use std::fs::{Dir, OpenOptions}; + /// + /// fn main() -> std::io::Result<()> { + /// let dir = Dir::open("foo")?; + /// let foobar_w = dir.open_dir_with("bar", &OpenOptions::new().write(true))?; + /// Ok(()) + /// } + /// ``` + #[unstable(feature = "dirfd", issue = "120426")] + pub fn open_dir_with>(&self, path: P, opts: &OpenOptions) -> io::Result { + self.inner.open_dir(path.as_ref(), &opts.0).map(|inner| Self { inner }) + } + + /// Attempts to remove a directory relative to this directory. + /// + /// This function interprets `path` relative to the directory provided by `self`. To remove a directory + /// relative to the current working directory, or at an absolute path, see + /// [`fs::remove_dir`][crate::fs::remove_dir]. + /// + /// # Errors + /// + /// This function will return an error if `path` does not point to an existing directory. + /// Other errors may also be returned according to [`OpenOptions::open`]. + /// + /// # Examples + /// + /// ```no_run + /// #![feature(dirfd)] + /// use std::{fs::Dir}; + /// + /// fn main() -> std::io::Result<()> { + /// let dir = Dir::open("foo")?; + /// dir.remove_dir("bar")?; + /// Ok(()) + /// } + /// ``` + #[unstable(feature = "dirfd", issue = "120426")] + pub fn remove_dir>(&self, path: P) -> io::Result<()> { + self.inner.remove_dir(path.as_ref()) + } } impl AsInner for Dir { diff --git a/library/std/src/fs/tests.rs b/library/std/src/fs/tests.rs index 2a656e2f8c196..0bb44f3a81c09 100644 --- a/library/std/src/fs/tests.rs +++ b/library/std/src/fs/tests.rs @@ -2736,3 +2736,38 @@ fn test_dir_rename_file() { check!(f.read_exact(&mut buf)); assert_eq!(b"bar", &buf); } + +#[test] +fn test_dir_remove_dir() { + let tmpdir = tmpdir(); + check!(fs::create_dir(tmpdir.join("foo"))); + let dir = check!(Dir::open(tmpdir.path())); + check!(dir.remove_dir("foo")); + assert!(!matches!(exists(tmpdir.join("foo")), Ok(true))); +} + +#[test] +fn test_dir_create_dir() { + let tmpdir = tmpdir(); + let dir = check!(Dir::open(tmpdir.path())); + check!(dir.create_dir("foo")); + check!(Dir::open(tmpdir.join("foo"))); +} + +#[test] +fn test_dir_open_dir() { + let tmpdir = tmpdir(); + let dir1 = check!(Dir::open(tmpdir.path())); + check!(dir1.create_dir("foo")); + let dir2 = check!(Dir::open(tmpdir.path().join("foo"))); + let mut f = + check!(dir2.open_file_with("bar.txt", &OpenOptions::new().create(true).write(true))); + check!(f.write(b"baz")); + check!(f.flush()); + drop(f); + let dir3 = check!(dir1.open_dir("foo")); + let mut f = check!(dir3.open_file("bar.txt")); + let mut buf = [0u8; 3]; + check!(f.read_exact(&mut buf)); + assert_eq!(b"baz", &buf); +} diff --git a/library/std/src/sys/fs/common.rs b/library/std/src/sys/fs/common.rs index 68aed39d1dcdf..8345d8e214a1c 100644 --- a/library/std/src/sys/fs/common.rs +++ b/library/std/src/sys/fs/common.rs @@ -1,6 +1,6 @@ #![allow(dead_code)] // not used on all platforms -use crate::fs::{remove_file, rename}; +use crate::fs::{create_dir, remove_dir, remove_file, rename}; use crate::io::{self, Error, ErrorKind}; use crate::path::{Path, PathBuf}; use crate::sys::IntoInner; @@ -71,6 +71,12 @@ impl Dir { path.canonicalize().map(|path| Self { path }) } + pub fn open_for_traversal(path: &Path) -> io::Result { + let mut opts = OpenOptions::new(); + opts.read(true); + Self::open(path, &opts) + } + pub fn open_file(&self, path: &Path, opts: &OpenOptions) -> io::Result { File::open(&self.path.join(path), &opts) } @@ -86,6 +92,18 @@ impl Dir { pub fn rename(&self, from: &Path, to_dir: &Self, to: &Path) -> io::Result<()> { rename(self.path.join(from), to_dir.path.join(to)) } + + pub fn create_dir(&self, path: &Path) -> io::Result<()> { + create_dir(self.path.join(path)) + } + + pub fn open_dir(&self, path: &Path, opts: &OpenOptions) -> io::Result { + Self::open(&self.path.join(path), opts) + } + + pub fn remove_dir(&self, path: &Path) -> io::Result<()> { + remove_dir(path) + } } impl fmt::Debug for Dir { diff --git a/library/std/src/sys/fs/unix/dir.rs b/library/std/src/sys/fs/unix/dir.rs index f3f612a225ed1..87bd9ee74689d 100644 --- a/library/std/src/sys/fs/unix/dir.rs +++ b/library/std/src/sys/fs/unix/dir.rs @@ -1,14 +1,12 @@ -use libc::{c_int, renameat, unlinkat}; +use libc::{c_int, mkdirat, renameat, unlinkat}; cfg_select! { - not( - any( - all(target_os = "linux", not(target_env = "musl")), - target_os = "l4re", - target_os = "android", - target_os = "hurd", - ) - ) => { + not(any( + all(target_os = "linux", not(target_env = "musl")), + target_os = "l4re", + target_os = "android", + target_os = "hurd", + )) => { use libc::{open as open64, openat as openat64}; } _ => { @@ -30,6 +28,13 @@ use crate::sys::helpers::run_path_with_cstr; use crate::sys::{AsInner, FromInner, IntoInner, cvt, cvt_r}; use crate::{fmt, fs, io}; +const TRAVERSE_DIRECTORY: i32 = cfg_select! { + any(target_os = "freebsd", target_os = "aix") => libc::O_EXEC, + any(target_os = "linux", target_os = "android", target_os = "l4re") => libc::O_PATH, + target_os = "illumos" => libc::O_SEARCH, + _ => libc::O_RDONLY, +}; + pub struct Dir(OwnedFd); impl Dir { @@ -37,8 +42,14 @@ impl Dir { run_path_with_cstr(path, &|path| Self::open_with_c(path, opts)) } + pub fn open_for_traversal(path: &Path) -> io::Result { + run_path_with_cstr(path, &|path| Self::open_traversal_c(path)) + } + pub fn open_file(&self, path: &Path, opts: &OpenOptions) -> io::Result { - run_path_with_cstr(path.as_ref(), &|path| self.open_file_c(path, &opts)) + run_path_with_cstr(path.as_ref(), &|path| self.open_file_c(path, &opts, 0)) + .map(|fd| FileDesc::from_inner(fd)) + .map(File) } pub fn metadata(&self) -> io::Result { @@ -61,7 +72,19 @@ impl Dir { }) } - pub fn open_with_c(path: &CStr, opts: &OpenOptions) -> io::Result { + pub fn open_dir(&self, path: &Path, opts: &OpenOptions) -> io::Result { + run_path_with_cstr(path, &|path| self.open_file_c(path, &opts, libc::O_DIRECTORY)).map(Self) + } + + pub fn create_dir(&self, path: &Path) -> io::Result<()> { + run_path_with_cstr(path.as_ref(), &|path| self.create_dir_c(path)) + } + + pub fn remove_dir(&self, path: &Path) -> io::Result<()> { + run_path_with_cstr(path, &|path| self.remove_c(path, true)) + } + + fn open_with_c(path: &CStr, opts: &OpenOptions) -> io::Result { let flags = libc::O_CLOEXEC | libc::O_DIRECTORY | opts.get_access_mode()? @@ -71,15 +94,27 @@ impl Dir { Ok(Self(unsafe { OwnedFd::from_raw_fd(fd) })) } - fn open_file_c(&self, path: &CStr, opts: &OpenOptions) -> io::Result { + fn open_traversal_c(path: &CStr) -> io::Result { + let flags = libc::O_CLOEXEC | libc::O_DIRECTORY | TRAVERSE_DIRECTORY; + let fd = cvt_r(|| unsafe { open64(path.as_ptr(), flags, 0) })?; + Ok(Self(unsafe { OwnedFd::from_raw_fd(fd) })) + } + + fn open_file_c( + &self, + path: &CStr, + opts: &OpenOptions, + extra_flags: c_int, + ) -> io::Result { let flags = libc::O_CLOEXEC | opts.get_access_mode()? | opts.get_creation_mode()? - | (opts.custom_flags as c_int & !libc::O_ACCMODE); + | (opts.custom_flags as c_int & !libc::O_ACCMODE) + | extra_flags; let fd = cvt_r(|| unsafe { openat64(self.0.as_raw_fd(), path.as_ptr(), flags, opts.mode as c_int) })?; - Ok(File(unsafe { FileDesc::from_raw_fd(fd) })) + Ok(unsafe { OwnedFd::from_raw_fd(fd) }) } fn remove_c(&self, path: &CStr, remove_dir: bool) -> io::Result<()> { @@ -99,6 +134,10 @@ impl Dir { }) .map(|_| ()) } + + fn create_dir_c(&self, path: &CStr) -> io::Result<()> { + cvt(unsafe { mkdirat(self.0.as_raw_fd(), path.as_ptr(), 0o777) }).map(|_| ()) + } } impl fmt::Debug for Dir { diff --git a/library/std/src/sys/fs/windows/dir.rs b/library/std/src/sys/fs/windows/dir.rs index 5e69515b66599..a7e19414c30d8 100644 --- a/library/std/src/sys/fs/windows/dir.rs +++ b/library/std/src/sys/fs/windows/dir.rs @@ -66,6 +66,12 @@ impl Dir { with_native_path(path, &|path| Self::open_with_native(path, opts)) } + pub fn open_for_traversal(path: &Path) -> io::Result { + let mut opts = OpenOptions::new(); + opts.access_mode(c::FILE_TRAVERSE); + with_native_path(path, &|path| Self::open_with_native(path, &opts)) + } + pub fn open_file(&self, path: &Path, opts: &OpenOptions) -> io::Result { // NtCreateFile will fail if given an absolute path and a non-null RootDirectory if path.is_absolute() { @@ -87,6 +93,22 @@ impl Dir { self.rename_native(&from, to_dir, &to, is_dir) } + pub fn create_dir(&self, path: &Path) -> io::Result<()> { + let mut opts = OpenOptions::new(); + opts.create_new(true); + self.open_dir(path, &opts).map(|_| ()) + } + + pub fn open_dir(&self, path: &Path, opts: &OpenOptions) -> io::Result { + let path = to_u16s_without_nul(&path)?; + self.open_file_native(&path, &opts, true).map(|handle| Self { handle }) + } + + pub fn remove_dir(&self, path: &Path) -> io::Result<()> { + let path = to_u16s_without_nul(&path)?; + self.remove_native(&path, true) + } + fn open_with_native(path: &WCStr, opts: &OpenOptions) -> io::Result { let creation = opts.get_creation_mode()?; let sa = c::SECURITY_ATTRIBUTES { diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs index 9028a7a340ca7..404d7d7b2aab0 100644 --- a/src/bootstrap/src/core/build_steps/dist.rs +++ b/src/bootstrap/src/core/build_steps/dist.rs @@ -748,6 +748,9 @@ impl Step for DebuggerScripts { cp_debugger_script("gdb_load_rust_pretty_printers.py"); cp_debugger_script("gdb_lookup.py"); cp_debugger_script("gdb_providers.py"); + if builder.build.unstable_features() { + cp_debugger_script("gdb_trim_paths.py"); + } // lldb debugger scripts builder.install( diff --git a/src/bootstrap/src/core/build_steps/setup.rs b/src/bootstrap/src/core/build_steps/setup.rs index 7b0bd1e3067fb..40c36b9e030c2 100644 --- a/src/bootstrap/src/core/build_steps/setup.rs +++ b/src/bootstrap/src/core/build_steps/setup.rs @@ -109,7 +109,10 @@ impl CommandLineStep for Profile { fn should_run(mut run: ShouldRun<'_>) -> ShouldRun<'_> { for choice in Profile::all() { - run = run.alias(choice.as_str()); + // Some of the profile names happen to coincide with actual directory names + // ("compiler" and "library"), so avoid the usual assertion that aliases + // don't exist on disk. + run = run.alias_without_assert(choice.as_str()); } run } diff --git a/src/bootstrap/src/core/build_steps/tool.rs b/src/bootstrap/src/core/build_steps/tool.rs index a3786788aec1e..bc029cdfed54d 100644 --- a/src/bootstrap/src/core/build_steps/tool.rs +++ b/src/bootstrap/src/core/build_steps/tool.rs @@ -1107,8 +1107,11 @@ impl CommandLineStep for RustAnalyzerProcMacroSrv { fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { // Allow building `rust-analyzer-proc-macro-srv` both as part of the `rust-analyzer` and as a stand-alone tool. - run.path("src/tools/rust-analyzer") - .path("src/tools/rust-analyzer/crates/proc-macro-srv-cli") + // FIXME(Zalathar): Should we stop registering "src/tools/rust-analyzer" here? + run.path("src/tools/rust-analyzer").path_with_alias( + "src/tools/rust-analyzer/crates/proc-macro-srv-cli", + "rust-analyzer-proc-macro-srv", + ) } fn is_default_step(builder: &Builder<'_>) -> bool { diff --git a/src/bootstrap/src/core/builder/cli_paths.rs b/src/bootstrap/src/core/builder/cli_paths.rs index 51a7ddaf62052..29daf64db49c7 100644 --- a/src/bootstrap/src/core/builder/cli_paths.rs +++ b/src/bootstrap/src/core/builder/cli_paths.rs @@ -10,63 +10,6 @@ use crate::core::builder::{Builder, CommandLineStepDescription, Kind, PathSet, S #[cfg(test)] mod tests; -pub(crate) const PATH_REMAP: &[(&str, &[&str])] = &[ - // bootstrap.toml uses `rust-analyzer-proc-macro-srv`, but the - // actual path is `proc-macro-srv-cli` - ("rust-analyzer-proc-macro-srv", &["src/tools/rust-analyzer/crates/proc-macro-srv-cli"]), - // Make `x test tests` function the same as `x t tests/*` - ( - "tests", - &[ - // tidy-alphabetical-start - "tests/assembly-llvm", - "tests/build-std", - "tests/codegen-llvm", - "tests/codegen-units", - "tests/coverage", - "tests/coverage-run-rustdoc", - "tests/crashes", - "tests/debuginfo", - "tests/incremental", - "tests/mir-opt", - "tests/pretty", - "tests/run-make", - "tests/run-make-cargo", - "tests/rustdoc-gui", - "tests/rustdoc-html", - "tests/rustdoc-js", - "tests/rustdoc-js-std", - "tests/rustdoc-json", - "tests/rustdoc-ui", - "tests/ui", - "tests/ui-fulldeps", - // tidy-alphabetical-end - ], - ), -]; - -pub(crate) fn remap_paths(paths: &mut Vec) { - let mut remove = vec![]; - let mut add = vec![]; - for (i, path) in paths.iter().enumerate().filter_map(|(i, path)| path.to_str().map(|s| (i, s))) - { - for &(search, replace) in PATH_REMAP { - // Remove leading and trailing slashes so `tests/` and `tests` are equivalent - if path.trim_matches(std::path::is_separator) == search { - remove.push(i); - add.extend(replace.iter().map(PathBuf::from)); - break; - } - } - } - remove.sort(); - remove.dedup(); - for idx in remove.into_iter().rev() { - paths.remove(idx); - } - paths.append(&mut add); -} - #[derive(Clone, PartialEq)] pub(crate) struct CLIStepPath { pub(crate) path: PathBuf, @@ -106,10 +49,7 @@ pub(crate) fn match_paths_to_steps_and_run( // paths to match it against. let steps = step_descs .iter() - .map(|desc| StepExtra { - desc, - should_run: (desc.should_run)(ShouldRun::new(builder, desc.kind)), - }) + .map(|desc| StepExtra { desc, should_run: (desc.should_run)(ShouldRun::new(builder)) }) .collect::>(); // FIXME(Zalathar): This particular check isn't related to path-to-step @@ -168,8 +108,6 @@ pub(crate) fn match_paths_to_steps_and_run( }) .collect(); - remap_paths(&mut paths); - // Handle all test suite paths. // (This is separate from the loop below to avoid having to handle multiple paths in `is_suite_path` somehow.) paths.retain(|path| { diff --git a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_build_proc_macro_srv_cli.snap b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_build_proc_macro_srv_cli.snap new file mode 100644 index 0000000000000..2fced82cf8b39 --- /dev/null +++ b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_build_proc_macro_srv_cli.snap @@ -0,0 +1,7 @@ +--- +source: src/bootstrap/src/core/builder/cli_paths/tests.rs +expression: build proc-macro-srv-cli +--- +[Build] tool::RustAnalyzerProcMacroSrv + targets: [x86_64-unknown-linux-gnu] + - Set({rust-analyzer-proc-macro-srv, src/tools/rust-analyzer/crates/proc-macro-srv-cli}) diff --git a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_build_rust_analyzer.snap b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_build_rust_analyzer.snap new file mode 100644 index 0000000000000..d625e56c97f20 --- /dev/null +++ b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_build_rust_analyzer.snap @@ -0,0 +1,10 @@ +--- +source: src/bootstrap/src/core/builder/cli_paths/tests.rs +expression: build rust-analyzer +--- +[Build] tool::RustAnalyzer + targets: [x86_64-unknown-linux-gnu] + - Set({src/tools/rust-analyzer}) +[Build] tool::RustAnalyzerProcMacroSrv + targets: [x86_64-unknown-linux-gnu] + - Set({src/tools/rust-analyzer}) diff --git a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_build_rust_analyzer_proc_macro_srv.snap b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_build_rust_analyzer_proc_macro_srv.snap new file mode 100644 index 0000000000000..6d173c8ee87d7 --- /dev/null +++ b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_build_rust_analyzer_proc_macro_srv.snap @@ -0,0 +1,7 @@ +--- +source: src/bootstrap/src/core/builder/cli_paths/tests.rs +expression: build rust-analyzer-proc-macro-srv +--- +[Build] tool::RustAnalyzerProcMacroSrv + targets: [x86_64-unknown-linux-gnu] + - Set({rust-analyzer-proc-macro-srv, src/tools/rust-analyzer/crates/proc-macro-srv-cli}) diff --git a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_build_rust_analyzer_proc_macro_srv_plus_full_path.snap b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_build_rust_analyzer_proc_macro_srv_plus_full_path.snap new file mode 100644 index 0000000000000..d76b93541bb64 --- /dev/null +++ b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_build_rust_analyzer_proc_macro_srv_plus_full_path.snap @@ -0,0 +1,7 @@ +--- +source: src/bootstrap/src/core/builder/cli_paths/tests.rs +expression: build rust-analyzer-proc-macro-srv src/tools/rust-analyzer/crates/proc-macro-srv-cli +--- +[Build] tool::RustAnalyzerProcMacroSrv + targets: [x86_64-unknown-linux-gnu] + - Set({rust-analyzer-proc-macro-srv, src/tools/rust-analyzer/crates/proc-macro-srv-cli}) diff --git a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_build_src_tools_rust_analyzer.snap b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_build_src_tools_rust_analyzer.snap new file mode 100644 index 0000000000000..a1a709137bfa7 --- /dev/null +++ b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_build_src_tools_rust_analyzer.snap @@ -0,0 +1,11 @@ +--- +source: src/bootstrap/src/core/builder/cli_paths/tests.rs +expression: build src/tools/rust-analyzer +--- +[Build] tool::RustAnalyzer + targets: [x86_64-unknown-linux-gnu] + - Set({src/tools/rust-analyzer}) +[Build] tool::RustAnalyzerProcMacroSrv + targets: [x86_64-unknown-linux-gnu] + - Set({rust-analyzer-proc-macro-srv, src/tools/rust-analyzer/crates/proc-macro-srv-cli}) + - Set({src/tools/rust-analyzer}) diff --git a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_build_src_tools_rust_analyzer_crates_proc_macro_srv_cli.snap b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_build_src_tools_rust_analyzer_crates_proc_macro_srv_cli.snap new file mode 100644 index 0000000000000..ad88f0b100041 --- /dev/null +++ b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_build_src_tools_rust_analyzer_crates_proc_macro_srv_cli.snap @@ -0,0 +1,7 @@ +--- +source: src/bootstrap/src/core/builder/cli_paths/tests.rs +expression: build src/tools/rust-analyzer/crates/proc-macro-srv-cli +--- +[Build] tool::RustAnalyzerProcMacroSrv + targets: [x86_64-unknown-linux-gnu] + - Set({rust-analyzer-proc-macro-srv, src/tools/rust-analyzer/crates/proc-macro-srv-cli}) diff --git a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_tests.snap b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_tests.snap index 15b54a5213fc8..c0105510ae416 100644 --- a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_tests.snap +++ b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_tests.snap @@ -2,66 +2,69 @@ source: src/bootstrap/src/core/builder/cli_paths/tests.rs expression: test tests --- -[Test] test::AssemblyLlvm +[Test] test::Ui targets: [aarch64-unknown-linux-gnu] - - Suite(tests/assembly-llvm) -[Test] test::BuildStd + - Suite(tests/ui) +[Test] test::Crashes targets: [aarch64-unknown-linux-gnu] - - Suite(tests/build-std) + - Suite(tests/crashes) +[Test] test::Coverage + targets: [aarch64-unknown-linux-gnu] + - Suite(tests/coverage) +[Test] test::MirOpt + targets: [aarch64-unknown-linux-gnu] + - Suite(tests/mir-opt) [Test] test::CodegenLlvm targets: [aarch64-unknown-linux-gnu] - Suite(tests/codegen-llvm) [Test] test::CodegenUnits targets: [aarch64-unknown-linux-gnu] - Suite(tests/codegen-units) -[Test] test::Coverage - targets: [aarch64-unknown-linux-gnu] - - Suite(tests/coverage) -[Test] test::CoverageRunRustdoc - targets: [x86_64-unknown-linux-gnu] - - Suite(tests/coverage-run-rustdoc) -[Test] test::Crashes - targets: [aarch64-unknown-linux-gnu] - - Suite(tests/crashes) -[Test] test::Debuginfo +[Test] test::AssemblyLlvm targets: [aarch64-unknown-linux-gnu] - - Suite(tests/debuginfo) + - Suite(tests/assembly-llvm) [Test] test::Incremental targets: [aarch64-unknown-linux-gnu] - Suite(tests/incremental) -[Test] test::MirOpt - targets: [aarch64-unknown-linux-gnu] - - Suite(tests/mir-opt) -[Test] test::Pretty - targets: [x86_64-unknown-linux-gnu] - - Suite(tests/pretty) -[Test] test::RunMake - targets: [aarch64-unknown-linux-gnu] - - Suite(tests/run-make) -[Test] test::RunMakeCargo +[Test] test::Debuginfo targets: [aarch64-unknown-linux-gnu] - - Suite(tests/run-make-cargo) -[Test] test::RustdocGUI + - Suite(tests/debuginfo) +[Test] test::UiFullDeps targets: [x86_64-unknown-linux-gnu] - - Suite(tests/rustdoc-gui) + - Suite(tests/ui-fulldeps) [Test] test::RustdocHtml targets: [x86_64-unknown-linux-gnu] - Suite(tests/rustdoc-html) -[Test] test::RustdocJSNotStd +[Test] test::CoverageRunRustdoc targets: [x86_64-unknown-linux-gnu] - - Suite(tests/rustdoc-js) + - Suite(tests/coverage-run-rustdoc) +[Test] test::Pretty + targets: [x86_64-unknown-linux-gnu] + - Suite(tests/pretty) +[Test] test::Clippy + targets: [x86_64-unknown-linux-gnu] + - Suite(src/tools/clippy/tests) [Test] test::RustdocJSStd targets: [x86_64-unknown-linux-gnu] - Suite(tests/rustdoc-js-std) -[Test] test::RustdocJson +[Test] test::RustdocJSNotStd targets: [x86_64-unknown-linux-gnu] - - Suite(tests/rustdoc-json) + - Suite(tests/rustdoc-js) +[Test] test::RustdocGUI + targets: [x86_64-unknown-linux-gnu] + - Suite(tests/rustdoc-gui) [Test] test::RustdocUi targets: [x86_64-unknown-linux-gnu] - Suite(tests/rustdoc-ui) -[Test] test::Ui - targets: [aarch64-unknown-linux-gnu] - - Suite(tests/ui) -[Test] test::UiFullDeps +[Test] test::RustdocJson targets: [x86_64-unknown-linux-gnu] - - Suite(tests/ui-fulldeps) + - Suite(tests/rustdoc-json) +[Test] test::RunMake + targets: [aarch64-unknown-linux-gnu] + - Suite(tests/run-make) +[Test] test::RunMakeCargo + targets: [aarch64-unknown-linux-gnu] + - Suite(tests/run-make-cargo) +[Test] test::BuildStd + targets: [aarch64-unknown-linux-gnu] + - Suite(tests/build-std) diff --git a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_tests_skip_coverage.snap b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_tests_skip_coverage.snap index a787c4a977f18..d1a90ca426918 100644 --- a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_tests_skip_coverage.snap +++ b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_tests_skip_coverage.snap @@ -2,63 +2,66 @@ source: src/bootstrap/src/core/builder/cli_paths/tests.rs expression: test tests --skip=coverage --- -[Test] test::AssemblyLlvm +[Test] test::Ui targets: [aarch64-unknown-linux-gnu] - - Suite(tests/assembly-llvm) -[Test] test::BuildStd + - Suite(tests/ui) +[Test] test::Crashes targets: [aarch64-unknown-linux-gnu] - - Suite(tests/build-std) + - Suite(tests/crashes) +[Test] test::MirOpt + targets: [aarch64-unknown-linux-gnu] + - Suite(tests/mir-opt) [Test] test::CodegenLlvm targets: [aarch64-unknown-linux-gnu] - Suite(tests/codegen-llvm) [Test] test::CodegenUnits targets: [aarch64-unknown-linux-gnu] - Suite(tests/codegen-units) -[Test] test::CoverageRunRustdoc - targets: [x86_64-unknown-linux-gnu] - - Suite(tests/coverage-run-rustdoc) -[Test] test::Crashes - targets: [aarch64-unknown-linux-gnu] - - Suite(tests/crashes) -[Test] test::Debuginfo +[Test] test::AssemblyLlvm targets: [aarch64-unknown-linux-gnu] - - Suite(tests/debuginfo) + - Suite(tests/assembly-llvm) [Test] test::Incremental targets: [aarch64-unknown-linux-gnu] - Suite(tests/incremental) -[Test] test::MirOpt - targets: [aarch64-unknown-linux-gnu] - - Suite(tests/mir-opt) -[Test] test::Pretty - targets: [x86_64-unknown-linux-gnu] - - Suite(tests/pretty) -[Test] test::RunMake - targets: [aarch64-unknown-linux-gnu] - - Suite(tests/run-make) -[Test] test::RunMakeCargo +[Test] test::Debuginfo targets: [aarch64-unknown-linux-gnu] - - Suite(tests/run-make-cargo) -[Test] test::RustdocGUI + - Suite(tests/debuginfo) +[Test] test::UiFullDeps targets: [x86_64-unknown-linux-gnu] - - Suite(tests/rustdoc-gui) + - Suite(tests/ui-fulldeps) [Test] test::RustdocHtml targets: [x86_64-unknown-linux-gnu] - Suite(tests/rustdoc-html) -[Test] test::RustdocJSNotStd +[Test] test::CoverageRunRustdoc targets: [x86_64-unknown-linux-gnu] - - Suite(tests/rustdoc-js) + - Suite(tests/coverage-run-rustdoc) +[Test] test::Pretty + targets: [x86_64-unknown-linux-gnu] + - Suite(tests/pretty) +[Test] test::Clippy + targets: [x86_64-unknown-linux-gnu] + - Suite(src/tools/clippy/tests) [Test] test::RustdocJSStd targets: [x86_64-unknown-linux-gnu] - Suite(tests/rustdoc-js-std) -[Test] test::RustdocJson +[Test] test::RustdocJSNotStd targets: [x86_64-unknown-linux-gnu] - - Suite(tests/rustdoc-json) + - Suite(tests/rustdoc-js) +[Test] test::RustdocGUI + targets: [x86_64-unknown-linux-gnu] + - Suite(tests/rustdoc-gui) [Test] test::RustdocUi targets: [x86_64-unknown-linux-gnu] - Suite(tests/rustdoc-ui) -[Test] test::Ui - targets: [aarch64-unknown-linux-gnu] - - Suite(tests/ui) -[Test] test::UiFullDeps +[Test] test::RustdocJson targets: [x86_64-unknown-linux-gnu] - - Suite(tests/ui-fulldeps) + - Suite(tests/rustdoc-json) +[Test] test::RunMake + targets: [aarch64-unknown-linux-gnu] + - Suite(tests/run-make) +[Test] test::RunMakeCargo + targets: [aarch64-unknown-linux-gnu] + - Suite(tests/run-make-cargo) +[Test] test::BuildStd + targets: [aarch64-unknown-linux-gnu] + - Suite(tests/build-std) diff --git a/src/bootstrap/src/core/builder/cli_paths/tests.rs b/src/bootstrap/src/core/builder/cli_paths/tests.rs index 0660667065c48..f075e7408e7c0 100644 --- a/src/bootstrap/src/core/builder/cli_paths/tests.rs +++ b/src/bootstrap/src/core/builder/cli_paths/tests.rs @@ -135,9 +135,21 @@ declare_tests!( (x_build_compiletest, "build compiletest"), (x_build_library, "build library"), (x_build_llvm, "build llvm"), + (x_build_proc_macro_srv_cli, "build proc-macro-srv-cli"), + (x_build_rust_analyzer, "build rust-analyzer"), + (x_build_rust_analyzer_proc_macro_srv, "build rust-analyzer-proc-macro-srv"), + ( + x_build_rust_analyzer_proc_macro_srv_plus_full_path, + "build rust-analyzer-proc-macro-srv src/tools/rust-analyzer/crates/proc-macro-srv-cli" + ), (x_build_rustc, "build rustc"), (x_build_rustc_llvm, "build rustc_llvm"), (x_build_rustdoc, "build rustdoc"), + (x_build_src_tools_rust_analyzer, "build src/tools/rust-analyzer"), + ( + x_build_src_tools_rust_analyzer_crates_proc_macro_srv_cli, + "build src/tools/rust-analyzer/crates/proc-macro-srv-cli" + ), (x_build_sysroot, "build sysroot"), (x_check, "check"), (x_check_bootstrap, "check bootstrap"), diff --git a/src/bootstrap/src/core/builder/mod.rs b/src/bootstrap/src/core/builder/mod.rs index 91fa2604df0c0..fb8b71b9155e7 100644 --- a/src/bootstrap/src/core/builder/mod.rs +++ b/src/bootstrap/src/core/builder/mod.rs @@ -7,7 +7,7 @@ use std::ops::Deref; use std::path::{Path, PathBuf}; use std::sync::OnceLock; use std::time::{Duration, Instant}; -use std::{env, fs}; +use std::{env, fs, iter}; use clap::ValueEnum; #[cfg(feature = "tracing")] @@ -355,6 +355,9 @@ struct CommandLineStepDescription { is_default_step_fn: fn(&Builder<'_>) -> bool, make_run: fn(RunConfig<'_>), name: &'static str, + + /// Kind that was passed to [`CommandLineStepDescription::from`]. + #[cfg_attr(not(test), expect(dead_code, reason = "currently only needed by tests"))] kind: Kind, } @@ -520,15 +523,14 @@ impl CommandLineStepDescription { /// correspond to. pub struct ShouldRun<'a> { pub builder: &'a Builder<'a>, - kind: Kind, // use a BTreeSet to maintain sort order paths: BTreeSet, } impl<'a> ShouldRun<'a> { - fn new(builder: &'a Builder<'_>, kind: Kind) -> ShouldRun<'a> { - ShouldRun { builder, kind, paths: BTreeSet::new() } + fn new(builder: &'a Builder<'_>) -> ShouldRun<'a> { + ShouldRun { builder, paths: BTreeSet::new() } } /// The corresponding step should run if the bootstrap command-line selects @@ -562,16 +564,25 @@ impl<'a> ShouldRun<'a> { } // single alias, which does not correspond to any on-disk path - pub fn alias(mut self, alias: &str) -> Self { - // exceptional case for `Kind::Setup` because its `library` - // and `compiler` options would otherwise naively match with - // `compiler` and `library` folders respectively. + pub fn alias(self, alias: &str) -> Self { + self.assert_valid_alias(alias); + self.alias_without_assert(alias) + } + + /// Like [`Self::alias`], but does not assert the absence of a path with the same name. + /// + /// Needed by [`setup::Profile`], which registers aliases named `compiler` and `library` + /// that happen to coincide with directory names. + pub fn alias_without_assert(mut self, alias: &str) -> Self { + self.paths.insert(PathSet::Set(iter::once(TaskPath { path: alias.into() }).collect())); + self + } + + fn assert_valid_alias(&self, alias: &str) { assert!( - self.kind == Kind::Setup || !self.builder.src.join(alias).exists(), + !self.builder.src.join(alias).exists(), "use `builder.path()` for real paths: {alias}" ); - self.paths.insert(PathSet::Set(std::iter::once(TaskPath { path: alias.into() }).collect())); - self } fn assert_valid_path(&self, path: &str) { @@ -598,6 +609,19 @@ impl<'a> ShouldRun<'a> { self } + /// Registers a path, and an alias that is treated as equivalent to that path. + pub fn path_with_alias(mut self, path: &str, alias: &str) -> Self { + self.assert_valid_path(path); + self.assert_valid_alias(alias); + + let set = [path, alias] + .into_iter() + .map(|p| TaskPath { path: PathBuf::from(p) }) + .collect::>(); + self.paths.insert(PathSet::Set(set)); + self + } + /// Multiple on-disk paths that should select the same unit of work. pub fn multi_path(mut self, paths: &[&str]) -> Self { let mut set = BTreeSet::new(); @@ -1061,11 +1085,9 @@ impl<'a> Builder<'a> { let builder = Self::new_internal(build, kind, vec![]); let builder = &builder; - // The "build" kind here is just a placeholder, it will be replaced with something else in - // the following statement. - let mut should_run = ShouldRun::new(builder, Kind::Build); + + let mut should_run = ShouldRun::new(builder); for desc in step_descriptions { - should_run.kind = desc.kind; should_run = (desc.should_run)(should_run); } let mut help = String::from("Available paths:\n"); @@ -1148,7 +1170,7 @@ impl<'a> Builder<'a> { continue; } - let should_run = (desc.should_run)(ShouldRun::new(self, Kind::Doc)); + let should_run = (desc.should_run)(ShouldRun::new(self)); let default_pathsets = should_run.default_pathsets(); let targets = if desc.is_host { &self.hosts } else { &self.targets }; @@ -1686,7 +1708,7 @@ Alternatively, you can set `build.local-rebuild=true` and use a stage0 compiler kind: Kind, ) -> Option { let desc = CommandLineStepDescription::from::(kind); - let should_run = (desc.should_run)(ShouldRun::new(self, desc.kind)); + let should_run = (desc.should_run)(ShouldRun::new(self)); // Avoid running steps contained in --skip for pathset in &should_run.paths { @@ -1702,7 +1724,7 @@ Alternatively, you can set `build.local-rebuild=true` and use a stage0 compiler /// Checks if any of the "should_run" paths is in the `Builder` paths. pub(crate) fn was_invoked_explicitly(&'a self, kind: Kind) -> bool { let desc = CommandLineStepDescription::from::(kind); - let should_run = (desc.should_run)(ShouldRun::new(self, desc.kind)); + let should_run = (desc.should_run)(ShouldRun::new(self)); for path in &self.paths { if should_run.paths.iter().any(|s| s.has(path)) diff --git a/src/bootstrap/src/core/builder/tests.rs b/src/bootstrap/src/core/builder/tests.rs index 79b6e86e95b96..54feac39b7153 100644 --- a/src/bootstrap/src/core/builder/tests.rs +++ b/src/bootstrap/src/core/builder/tests.rs @@ -5,7 +5,6 @@ use build_helper::stage0_parser::parse_stage0_file; use llvm::prebuilt_llvm_config; use super::*; -use crate::core::builder::cli_paths::PATH_REMAP; use crate::core::config::Config; use crate::utils::cache::ExecutedStep; use crate::utils::helpers::get_host_target; @@ -50,43 +49,6 @@ fn test_invalid() { check_cli(["test", "library/std", "x"]); } -#[test] -fn validate_path_remap() { - let build = Build::new(configure("test", &[TEST_TRIPLE_1], &[TEST_TRIPLE_1])); - - PATH_REMAP - .iter() - .flat_map(|(_, paths)| paths.iter()) - .map(|path| build.src.join(path)) - .for_each(|path| { - assert!(path.exists(), "{} should exist.", path.display()); - }); -} - -#[test] -fn check_missing_paths_for_x_test_tests() { - let build = Build::new(configure("test", &[TEST_TRIPLE_1], &[TEST_TRIPLE_1])); - - let (_, tests_remap_paths) = - PATH_REMAP.iter().find(|(target_path, _)| *target_path == "tests").unwrap(); - - let tests_dir = fs::read_dir(build.src.join("tests")).unwrap(); - for dir in tests_dir { - let path = dir.unwrap().path(); - - // Skip if not a test directory. - if path.ends_with("tests/auxiliary") || !path.is_dir() { - continue; - } - - assert!( - tests_remap_paths.iter().any(|item| path.ends_with(*item)), - "{} is missing in PATH_REMAP tests list.", - path.display() - ); - } -} - #[test] fn ci_rustc_if_unchanged_invalidate_on_compiler_changes() { git_test(|ctx| { diff --git a/src/etc/gdb_trim_paths.py b/src/etc/gdb_trim_paths.py new file mode 100644 index 0000000000000..695ef1b19a709 --- /dev/null +++ b/src/etc/gdb_trim_paths.py @@ -0,0 +1,105 @@ +# GDB Python script to handle Cargo `.trim-paths.jsonl` files from the trim-paths feature +# - https://github.com/rust-lang/cargo/issues/12137 +# - https://github.com/rust-lang/rust/issues/111540 + +import json +import os +import gdb +import sys + + +# https://doc.guix.gnu.org/gdb/16.3/en/html_node/Source-Path.html#index-set-substitute_002dpath +def _process_v1_trim_paths(lines, trim_paths_path): + for idx, line in enumerate(lines[2:], start=3): + try: + entry = json.loads(line) + if "from" in entry and "to" in entry: + cmd = f'set substitute-path "{entry["from"]}" "{entry["to"]}"' + gdb.execute(cmd) + except json.JSONDecodeError: + print( + f"(rust-gdb) warning: invalid JSON on line {idx} of {trim_paths_path}", + file=sys.stderr, + ) + + +def _load_trim_paths(filepath): + trim_paths_path = f"{filepath}.trim-paths.jsonl" + + # FIXME: It might be worth looking into the debuginfod fetch content if the local file + # doesn't exists (maybe with `debuginfod-find debuginfo`). + if not os.path.isfile(trim_paths_path): + return + + try: + # Load all the lines of the trim-paths file + with open(trim_paths_path, "r", encoding="utf-8") as f: + lines = [line.strip() for line in f] + + # Abort if we have less than 3 lines as that means that we cannot have any + # substitutions (header + metadata is already 2 lines) + if not lines or len(lines) < 3: + return + + # Try loading the header line, which contains the version (v) field + try: + header = json.loads(lines[0]) + ver = header["v"] + except json.JSONDecodeError: + print( + f"(rust-gdb) warning: header line 1 of {trim_paths_path} is not valid JSON", + file=sys.stderr, + ) + return + + # We only handle version 1 + if ver == 1: + _process_v1_trim_paths(lines, trim_paths_path) + else: + print( + f"(rust-gdb) warning: unsupported trim-paths version {ver}: {trim_paths_path}", + file=sys.stderr, + ) + except Exception as e: + print( + f"(rust-gdb) warning: failed to process trim-paths mappings: {e} of {trim_paths_path}", + file=sys.stderr, + ) + + +def _on_objfile(objfile): + filepath = objfile.filename + + if not filepath or not objfile.is_valid() or not os.path.isfile(filepath): + return + + _load_trim_paths(filepath) + + +def _on_progspace(progspace): + filepath = progspace.filename + + if not filepath or not os.path.isfile(filepath): + return + + _load_trim_paths(filepath) + + +def _on_new_objfile(event): + _on_objfile(event.new_objfile) + + +def _on_executable_changed(event): + _on_progspace(event.progspace) + + +# Setup the events for new objfile (so) and new executable +# https://doc.guix.gnu.org/gdb/16.3/en/html_node/Events-In-Python.html +# +# FIXME: should we handle clear/free events? +gdb.events.new_objfile.connect(_on_new_objfile) +gdb.events.executable_changed.connect(_on_executable_changed) + +# Load the trim-paths files for the already loaded objfiles +for objfile in gdb.objfiles(): + _on_objfile(objfile) diff --git a/src/etc/rust-gdb b/src/etc/rust-gdb index 9abed30ea6f73..885f69bfbc35a 100755 --- a/src/etc/rust-gdb +++ b/src/etc/rust-gdb @@ -16,13 +16,24 @@ GDB_PYTHON_MODULE_DIRECTORY="$RUSTC_SYSROOT/lib/rustlib/etc" # Get the commit hash for path remapping RUSTC_COMMIT_HASH="$("$RUSTC" -vV | sed -n 's/commit-hash: \([a-zA-Z0-9_]*\)/\1/p')" -# Run GDB with the additional arguments that load the pretty printers # Set the environment variable `RUST_GDB` to overwrite the call to a # different/specific command (defaults to `gdb`). RUST_GDB="${RUST_GDB:-gdb}" -PYTHONPATH="$PYTHONPATH:$GDB_PYTHON_MODULE_DIRECTORY" exec ${RUST_GDB} \ + +# Run GDB with the additional arguments that load the pretty printers +# Prepend base GDB flags ahead of any arguments passed by the user +set -- \ --directory="$GDB_PYTHON_MODULE_DIRECTORY" \ -iex "add-auto-load-safe-path $GDB_PYTHON_MODULE_DIRECTORY" \ -iex "set substitute-path /rustc/$RUSTC_COMMIT_HASH $RUSTC_SYSROOT/lib/rustlib/src/rust" \ "$@" - + +# Unstable (nightly-only) trim-paths feature, activated only if +# - RUST_GDB_TRIM_PATHS=unstable is set +# - and if the python file is present (only shipped on nightly) +GDB_TRIM_PATHS="$GDB_PYTHON_MODULE_DIRECTORY/gdb_trim_paths.py" +if [ "${RUST_GDB_TRIM_PATHS:-}" = "unstable" ] && [ -f "$GDB_TRIM_PATHS" ]; then + set -- -x "$GDB_TRIM_PATHS" "$@" +fi + +PYTHONPATH="$PYTHONPATH:$GDB_PYTHON_MODULE_DIRECTORY" exec ${RUST_GDB} "$@" diff --git a/tests/ui/abi/bad-custom.rs b/tests/ui/abi/bad-custom.rs index 793ef4d5dd3ea..82a27ac4af375 100644 --- a/tests/ui/abi/bad-custom.rs +++ b/tests/ui/abi/bad-custom.rs @@ -3,6 +3,19 @@ //@ needs-asm-support #![feature(abi_custom)] +#[unsafe(naked)] +unsafe extern "custom" fn return_explicit_unit() -> () { + std::arch::naked_asm!("") +} + +// Rejecting an alias is the status quo, this may change in the future. +type UnitAlias = (); +#[unsafe(naked)] +unsafe extern "custom" fn return_alias_unit() -> UnitAlias { + //~^ ERROR invalid signature for `extern "custom"` function + std::arch::naked_asm!("") +} + #[unsafe(naked)] extern "custom" fn must_be_unsafe(a: i64) -> i64 { //~^ ERROR functions with the "custom" ABI must be unsafe diff --git a/tests/ui/abi/bad-custom.stderr b/tests/ui/abi/bad-custom.stderr index 8aea96fd7257e..773026ba8b76f 100644 --- a/tests/ui/abi/bad-custom.stderr +++ b/tests/ui/abi/bad-custom.stderr @@ -1,5 +1,18 @@ +error: invalid signature for `extern "custom"` function + --> $DIR/bad-custom.rs:14:50 + | +LL | unsafe extern "custom" fn return_alias_unit() -> UnitAlias { + | ^^^^^^^^^ + | + = note: functions with the "custom" ABI cannot have any parameters or return type +help: remove the parameters and return type + | +LL - unsafe extern "custom" fn return_alias_unit() -> UnitAlias { +LL + unsafe extern "custom" fn return_alias_unit() { + | + error: functions with the "custom" ABI must be unsafe - --> $DIR/bad-custom.rs:7:1 + --> $DIR/bad-custom.rs:20:1 | LL | extern "custom" fn must_be_unsafe(a: i64) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -10,7 +23,7 @@ LL | unsafe extern "custom" fn must_be_unsafe(a: i64) -> i64 { | ++++++ error: invalid signature for `extern "custom"` function - --> $DIR/bad-custom.rs:7:35 + --> $DIR/bad-custom.rs:20:35 | LL | extern "custom" fn must_be_unsafe(a: i64) -> i64 { | ^^^^^^ ^^^ @@ -23,7 +36,7 @@ LL + extern "custom" fn must_be_unsafe() { | error: functions with the "custom" ABI must be unsafe - --> $DIR/bad-custom.rs:13:21 + --> $DIR/bad-custom.rs:26:21 | LL | type MustbeUnsafe = extern "custom" fn(i64) -> i64; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -34,7 +47,7 @@ LL | type MustbeUnsafe = unsafe extern "custom" fn(i64) -> i64; | ++++++ error: invalid signature for `extern "custom"` function - --> $DIR/bad-custom.rs:13:40 + --> $DIR/bad-custom.rs:26:40 | LL | type MustbeUnsafe = extern "custom" fn(i64) -> i64; | ^^^ ^^^ @@ -47,7 +60,7 @@ LL + type MustbeUnsafe = extern "custom" fn(); | error: invalid signature for `extern "custom"` function - --> $DIR/bad-custom.rs:18:41 + --> $DIR/bad-custom.rs:31:41 | LL | unsafe extern "custom" fn no_parameters(a: i64) { | ^^^^^^ @@ -60,7 +73,7 @@ LL + unsafe extern "custom" fn no_parameters() { | error: invalid signature for `extern "custom"` function - --> $DIR/bad-custom.rs:23:47 + --> $DIR/bad-custom.rs:36:47 | LL | type NoParameters = unsafe extern "custom" fn(i64); | ^^^ @@ -73,7 +86,7 @@ LL + type NoParameters = unsafe extern "custom" fn(); | error: invalid signature for `extern "custom"` function - --> $DIR/bad-custom.rs:27:47 + --> $DIR/bad-custom.rs:40:47 | LL | unsafe extern "custom" fn no_return_type() -> i64 { | ^^^ @@ -86,7 +99,7 @@ LL + unsafe extern "custom" fn no_return_type() { | error: invalid signature for `extern "custom"` function - --> $DIR/bad-custom.rs:32:52 + --> $DIR/bad-custom.rs:45:52 | LL | type NoReturnType = unsafe extern "custom" fn() -> i64; | ^^^ @@ -99,7 +112,7 @@ LL + type NoReturnType = unsafe extern "custom" fn(); | error: invalid signature for `extern "custom"` function - --> $DIR/bad-custom.rs:36:53 + --> $DIR/bad-custom.rs:49:53 | LL | unsafe extern "custom" fn no_never_return_type() -> ! { | ^ @@ -112,7 +125,7 @@ LL + unsafe extern "custom" fn no_never_return_type() { | error: invalid signature for `extern "custom"` function - --> $DIR/bad-custom.rs:41:57 + --> $DIR/bad-custom.rs:54:57 | LL | type NoNeverReturnType = unsafe extern "custom" fn() -> !; | ^ @@ -125,7 +138,7 @@ LL + type NoNeverReturnType = unsafe extern "custom" fn(); | error: invalid signature for `extern "custom"` function - --> $DIR/bad-custom.rs:44:36 + --> $DIR/bad-custom.rs:57:36 | LL | unsafe extern "custom" fn not_both(a: i64) -> i64 { | ^^^^^^ ^^^ @@ -138,7 +151,7 @@ LL + unsafe extern "custom" fn not_both() { | error: invalid signature for `extern "custom"` function - --> $DIR/bad-custom.rs:50:42 + --> $DIR/bad-custom.rs:63:42 | LL | type NotBoth = unsafe extern "custom" fn(i64) -> i64; | ^^^ ^^^ @@ -151,7 +164,7 @@ LL + type NotBoth = unsafe extern "custom" fn(); | error: functions with the "custom" ABI must be unsafe - --> $DIR/bad-custom.rs:56:5 + --> $DIR/bad-custom.rs:69:5 | LL | extern "custom" fn is_even(self) -> bool { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -162,7 +175,7 @@ LL | unsafe extern "custom" fn is_even(self) -> bool { | ++++++ error: invalid signature for `extern "custom"` function - --> $DIR/bad-custom.rs:56:32 + --> $DIR/bad-custom.rs:69:32 | LL | extern "custom" fn is_even(self) -> bool { | ^^^^ ^^^^ @@ -175,7 +188,7 @@ LL + extern "custom" fn is_even() { | error: functions with the "custom" ABI must be unsafe - --> $DIR/bad-custom.rs:65:5 + --> $DIR/bad-custom.rs:78:5 | LL | extern "custom" fn bitwise_not(a: i64) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -186,7 +199,7 @@ LL | unsafe extern "custom" fn bitwise_not(a: i64) -> i64 { | ++++++ error: invalid signature for `extern "custom"` function - --> $DIR/bad-custom.rs:65:36 + --> $DIR/bad-custom.rs:78:36 | LL | extern "custom" fn bitwise_not(a: i64) -> i64 { | ^^^^^^ ^^^ @@ -199,7 +212,7 @@ LL + extern "custom" fn bitwise_not() { | error: functions with the "custom" ABI must be unsafe - --> $DIR/bad-custom.rs:76:5 + --> $DIR/bad-custom.rs:89:5 | LL | extern "custom" fn negate(a: i64) -> i64; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -210,7 +223,7 @@ LL | unsafe extern "custom" fn negate(a: i64) -> i64; | ++++++ error: invalid signature for `extern "custom"` function - --> $DIR/bad-custom.rs:76:31 + --> $DIR/bad-custom.rs:89:31 | LL | extern "custom" fn negate(a: i64) -> i64; | ^^^^^^ ^^^ @@ -223,7 +236,7 @@ LL + extern "custom" fn negate(); | error: functions with the "custom" ABI must be unsafe - --> $DIR/bad-custom.rs:82:5 + --> $DIR/bad-custom.rs:95:5 | LL | extern "custom" fn negate(a: i64) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -234,7 +247,7 @@ LL | unsafe extern "custom" fn negate(a: i64) -> i64 { | ++++++ error: invalid signature for `extern "custom"` function - --> $DIR/bad-custom.rs:82:31 + --> $DIR/bad-custom.rs:95:31 | LL | extern "custom" fn negate(a: i64) -> i64 { | ^^^^^^ ^^^ @@ -247,7 +260,7 @@ LL + extern "custom" fn negate() { | error: invalid signature for `extern "custom"` function - --> $DIR/bad-custom.rs:91:18 + --> $DIR/bad-custom.rs:104:18 | LL | fn increment(a: i64) -> i64; | ^^^^^^ ^^^ @@ -260,7 +273,7 @@ LL + fn increment(); | error: foreign functions with the "custom" ABI cannot be safe - --> $DIR/bad-custom.rs:94:5 + --> $DIR/bad-custom.rs:107:5 | LL | safe fn extern_cannot_be_safe(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -272,7 +285,7 @@ LL + fn extern_cannot_be_safe(); | error: function pointers cannot be declared with `safe` safety qualifier - --> $DIR/bad-custom.rs:98:13 + --> $DIR/bad-custom.rs:111:13 | LL | type Safe = safe extern "custom" fn(); | ^^^^ @@ -284,7 +297,7 @@ LL + type Safe = extern "custom" fn(); | error: invalid signature for `extern "custom"` function - --> $DIR/bad-custom.rs:101:40 + --> $DIR/bad-custom.rs:114:40 | LL | fn caller(f: unsafe extern "custom" fn(i64) -> i64, mut x: i64) -> i64 { | ^^^ ^^^ @@ -297,7 +310,7 @@ LL + fn caller(f: unsafe extern "custom" fn(), mut x: i64) -> i64 { | error: invalid signature for `extern "custom"` function - --> $DIR/bad-custom.rs:107:48 + --> $DIR/bad-custom.rs:120:48 | LL | fn caller_by_ref(f: &unsafe extern "custom" fn(i64) -> i64, mut x: i64) -> i64 { | ^^^ ^^^ @@ -310,7 +323,7 @@ LL + fn caller_by_ref(f: &unsafe extern "custom" fn(), mut x: i64) -> i64 { | error: invalid signature for `extern "custom"` function - --> $DIR/bad-custom.rs:113:40 + --> $DIR/bad-custom.rs:126:40 | LL | type Alias = unsafe extern "custom" fn(i64) -> i64; | ^^^ ^^^ @@ -323,7 +336,7 @@ LL + type Alias = unsafe extern "custom" fn(); | error: functions with the "custom" ABI cannot be `async` - --> $DIR/bad-custom.rs:127:1 + --> $DIR/bad-custom.rs:140:1 | LL | async unsafe extern "custom" fn no_async_fn() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -335,7 +348,7 @@ LL + unsafe extern "custom" fn no_async_fn() { | error: items with the "custom" ABI can only be declared externally or defined via naked functions - --> $DIR/bad-custom.rs:127:1 + --> $DIR/bad-custom.rs:140:1 | LL | async unsafe extern "custom" fn no_async_fn() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -347,7 +360,7 @@ LL | async unsafe extern "custom" fn no_async_fn() { | error[E0277]: expected an `Fn()` closure, found `unsafe extern "custom" fn()` - --> $DIR/bad-custom.rs:132:64 + --> $DIR/bad-custom.rs:145:64 | LL | fn no_promotion_to_fn_trait(f: unsafe extern "custom" fn()) -> impl Fn() { | ^^^^^^^^^ call the function in a closure: `|| unsafe { /* code */ }` @@ -360,7 +373,7 @@ LL | f = note: unsafe function cannot be called generically without an unsafe block error: items with the "custom" ABI can only be declared externally or defined via naked functions - --> $DIR/bad-custom.rs:44:1 + --> $DIR/bad-custom.rs:57:1 | LL | unsafe extern "custom" fn not_both(a: i64) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -372,7 +385,7 @@ LL | unsafe extern "custom" fn not_both(a: i64) -> i64 { | error: items with the "custom" ABI can only be declared externally or defined via naked functions - --> $DIR/bad-custom.rs:56:5 + --> $DIR/bad-custom.rs:69:5 | LL | extern "custom" fn is_even(self) -> bool { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -384,7 +397,7 @@ LL | extern "custom" fn is_even(self) -> bool { | error: items with the "custom" ABI can only be declared externally or defined via naked functions - --> $DIR/bad-custom.rs:65:5 + --> $DIR/bad-custom.rs:78:5 | LL | extern "custom" fn bitwise_not(a: i64) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -396,7 +409,7 @@ LL | extern "custom" fn bitwise_not(a: i64) -> i64 { | error: items with the "custom" ABI can only be declared externally or defined via naked functions - --> $DIR/bad-custom.rs:82:5 + --> $DIR/bad-custom.rs:95:5 | LL | extern "custom" fn negate(a: i64) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -408,96 +421,96 @@ LL | extern "custom" fn negate(a: i64) -> i64 { | error: functions with the "custom" ABI cannot be called - --> $DIR/bad-custom.rs:103:14 + --> $DIR/bad-custom.rs:116:14 | LL | unsafe { f(x) } | ^^^^ | note: an `extern "custom"` function can only be called using inline assembly - --> $DIR/bad-custom.rs:103:14 + --> $DIR/bad-custom.rs:116:14 | LL | unsafe { f(x) } | ^^^^ error: functions with the "custom" ABI cannot be called - --> $DIR/bad-custom.rs:109:14 + --> $DIR/bad-custom.rs:122:14 | LL | unsafe { f(x) } | ^^^^ | note: an `extern "custom"` function can only be called using inline assembly - --> $DIR/bad-custom.rs:109:14 + --> $DIR/bad-custom.rs:122:14 | LL | unsafe { f(x) } | ^^^^ error: functions with the "custom" ABI cannot be called - --> $DIR/bad-custom.rs:117:14 + --> $DIR/bad-custom.rs:130:14 | LL | unsafe { f(x) } | ^^^^ | note: an `extern "custom"` function can only be called using inline assembly - --> $DIR/bad-custom.rs:117:14 + --> $DIR/bad-custom.rs:130:14 | LL | unsafe { f(x) } | ^^^^ error: functions with the "custom" ABI cannot be called - --> $DIR/bad-custom.rs:139:20 + --> $DIR/bad-custom.rs:152:20 | LL | assert_eq!(not_both(21), 42); | ^^^^^^^^^^^^ | note: an `extern "custom"` function can only be called using inline assembly - --> $DIR/bad-custom.rs:139:20 + --> $DIR/bad-custom.rs:152:20 | LL | assert_eq!(not_both(21), 42); | ^^^^^^^^^^^^ error: functions with the "custom" ABI cannot be called - --> $DIR/bad-custom.rs:142:29 + --> $DIR/bad-custom.rs:155:29 | LL | assert_eq!(unsafe { increment(41) }, 42); | ^^^^^^^^^^^^^ | note: an `extern "custom"` function can only be called using inline assembly - --> $DIR/bad-custom.rs:142:29 + --> $DIR/bad-custom.rs:155:29 | LL | assert_eq!(unsafe { increment(41) }, 42); | ^^^^^^^^^^^^^ error: functions with the "custom" ABI cannot be called - --> $DIR/bad-custom.rs:145:17 + --> $DIR/bad-custom.rs:158:17 | LL | assert!(Thing(41).is_even()); | ^^^^^^^^^^^^^^^^^^^ | note: an `extern "custom"` function can only be called using inline assembly - --> $DIR/bad-custom.rs:145:17 + --> $DIR/bad-custom.rs:158:17 | LL | assert!(Thing(41).is_even()); | ^^^^^^^^^^^^^^^^^^^ error: functions with the "custom" ABI cannot be called - --> $DIR/bad-custom.rs:148:20 + --> $DIR/bad-custom.rs:161:20 | LL | assert_eq!(Thing::bitwise_not(42), !42); | ^^^^^^^^^^^^^^^^^^^^^^ | note: an `extern "custom"` function can only be called using inline assembly - --> $DIR/bad-custom.rs:148:20 + --> $DIR/bad-custom.rs:161:20 | LL | assert_eq!(Thing::bitwise_not(42), !42); | ^^^^^^^^^^^^^^^^^^^^^^ error[E0015]: inline assembly is not allowed in constant functions - --> $DIR/bad-custom.rs:123:5 + --> $DIR/bad-custom.rs:136:5 | LL | std::arch::naked_asm!("") | ^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 41 previous errors +error: aborting due to 42 previous errors Some errors have detailed explanations: E0015, E0277. For more information about an error, try `rustc --explain E0015`. diff --git a/tests/ui/abi/custom.rs b/tests/ui/abi/custom.rs index 0f6ff77f58084..dae3925f19916 100644 --- a/tests/ui/abi/custom.rs +++ b/tests/ui/abi/custom.rs @@ -44,6 +44,11 @@ trait BitwiseNot { impl BitwiseNot for Thing {} +#[unsafe(naked)] +unsafe extern "C" fn type_generic() { + naked_asm!("mov rax, {}", "ret", const size_of::()); +} + #[unsafe(naked)] unsafe extern "C" fn const_generic() { naked_asm!( @@ -78,6 +83,14 @@ pub fn main() { assert_eq!(caller(double, 2), 4); + let x: usize; + unsafe { asm!("call {}", sym type_generic::, out("rax") x) }; + assert_eq!(x, 1); + + let x: usize; + unsafe { asm!("call {}", sym type_generic::, out("rax") x) }; + assert_eq!(x, 16); + let x: u64; unsafe { asm!("call {}", sym const_generic::<42>, out("rax") x) }; assert_eq!(x, 42);