From 1bbabb7ff744f18edaf3da30f841a287de2077d6 Mon Sep 17 00:00:00 2001 From: David Carlier Date: Thu, 4 Apr 2024 23:36:13 +0100 Subject: [PATCH 01/15] std::net: adding `unix_socket_exclbind` feature for solaris/illumos. allows to have a tigher control over the binding exclusivness of the socket. --- library/std/src/os/illumos/mod.rs | 1 + library/std/src/os/illumos/net.rs | 50 +++++++++++++++++++ library/std/src/os/solaris/mod.rs | 1 + library/std/src/os/solaris/net.rs | 50 +++++++++++++++++++ .../std/src/sys/net/connection/socket/unix.rs | 15 ++++++ 5 files changed, 117 insertions(+) create mode 100644 library/std/src/os/illumos/net.rs create mode 100644 library/std/src/os/solaris/net.rs diff --git a/library/std/src/os/illumos/mod.rs b/library/std/src/os/illumos/mod.rs index e61926f89356a..5fbe352e7cfbd 100644 --- a/library/std/src/os/illumos/mod.rs +++ b/library/std/src/os/illumos/mod.rs @@ -3,4 +3,5 @@ #![stable(feature = "raw_ext", since = "1.1.0")] pub mod fs; +pub mod net; pub mod raw; diff --git a/library/std/src/os/illumos/net.rs b/library/std/src/os/illumos/net.rs new file mode 100644 index 0000000000000..5ef4e1ec89e36 --- /dev/null +++ b/library/std/src/os/illumos/net.rs @@ -0,0 +1,50 @@ +//! illumos-specific networking functionality. + +#![unstable(feature = "unix_socket_exclbind", issue = "123481")] + +use crate::io; +use crate::os::unix::net; +use crate::sealed::Sealed; +use crate::sys_common::AsInner; + +/// illumos-specific functionality for `AF_UNIX` sockets [`UnixDatagram`] +/// and [`UnixStream`]. +/// +/// [`UnixDatagram`]: net::UnixDatagram +/// [`UnixStream`]: net::UnixStream +#[unstable(feature = "unix_socket_exclbind", issue = "123481")] +pub trait UnixSocketExt: Sealed { + /// Enables exclusive binding on the socket. + /// + /// If true and if the socket had been set with `SO_REUSEADDR`, + /// it neutralises its effect. + /// See [`man 3 tcp`](https://docs.oracle.com/cd/E88353_01/html/E37843/setsockopt-3c.html) + #[unstable(feature = "unix_socket_exclbind", issue = "123481")] + fn so_exclbind(&self, excl: bool) -> io::Result<()>; + + /// Get the bind exclusivity bind state of the socket. + #[unstable(feature = "unix_socket_exclbind", issue = "123481")] + fn exclbind(&self) -> io::Result; +} + +#[unstable(feature = "unix_socket_exclbind", issue = "123481")] +impl UnixSocketExt for net::UnixDatagram { + fn exclbind(&self) -> io::Result { + self.as_inner().exclbind() + } + + fn so_exclbind(&self, excl: bool) -> io::Result<()> { + self.as_inner().set_exclbind(excl) + } +} + +#[unstable(feature = "unix_socket_exclbind", issue = "123481")] +impl UnixSocketExt for net::UnixStream { + fn exclbind(&self) -> io::Result { + self.as_inner().exclbind() + } + + fn so_exclbind(&self, excl: bool) -> io::Result<()> { + self.as_inner().set_exclbind(excl) + } +} diff --git a/library/std/src/os/solaris/mod.rs b/library/std/src/os/solaris/mod.rs index e4cfd53291a6e..b4e836208491c 100644 --- a/library/std/src/os/solaris/mod.rs +++ b/library/std/src/os/solaris/mod.rs @@ -3,4 +3,5 @@ #![stable(feature = "raw_ext", since = "1.1.0")] pub mod fs; +pub mod net; pub mod raw; diff --git a/library/std/src/os/solaris/net.rs b/library/std/src/os/solaris/net.rs new file mode 100644 index 0000000000000..ca841f15b0e72 --- /dev/null +++ b/library/std/src/os/solaris/net.rs @@ -0,0 +1,50 @@ +//! solaris-specific networking functionality. + +#![unstable(feature = "unix_socket_exclbind", issue = "123481")] + +use crate::io; +use crate::os::unix::net; +use crate::sealed::Sealed; +use crate::sys_common::AsInner; + +/// solaris-specific functionality for `AF_UNIX` sockets [`UnixDatagram`] +/// and [`UnixStream`]. +/// +/// [`UnixDatagram`]: net::UnixDatagram +/// [`UnixStream`]: net::UnixStream +#[unstable(feature = "unix_socket_exclbind", issue = "123481")] +pub trait UnixSocketExt: Sealed { + /// Enables exclusive binding on the socket. + /// + /// If true and if the socket had been set with `SO_REUSEADDR`, + /// it neutralises its effect. + /// See [`man 3 tcp`](https://docs.oracle.com/cd/E88353_01/html/E37843/setsockopt-3c.html) + #[unstable(feature = "unix_socket_exclbind", issue = "123481")] + fn so_exclbind(&self, excl: bool) -> io::Result<()>; + + /// Get the bind exclusivity bind state of the socket. + #[unstable(feature = "unix_socket_exclbind", issue = "123481")] + fn exclbind(&self) -> io::Result; +} + +#[unstable(feature = "unix_socket_exclbind", issue = "123481")] +impl UnixSocketExt for net::UnixDatagram { + fn exclbind(&self) -> io::Result { + self.as_inner().exclbind() + } + + fn so_exclbind(&self, excl: bool) -> io::Result<()> { + self.as_inner().set_exclbind(excl) + } +} + +#[unstable(feature = "unix_socket_exclbind", issue = "123481")] +impl UnixSocketExt for net::UnixStream { + fn exclbind(&self) -> io::Result { + self.as_inner().exclbind() + } + + fn so_exclbind(&self, excl: bool) -> io::Result<()> { + self.as_inner().set_exclbind(excl) + } +} diff --git a/library/std/src/sys/net/connection/socket/unix.rs b/library/std/src/sys/net/connection/socket/unix.rs index b35d5d2aa8418..37d4078b9639b 100644 --- a/library/std/src/sys/net/connection/socket/unix.rs +++ b/library/std/src/sys/net/connection/socket/unix.rs @@ -514,6 +514,21 @@ impl Socket { Ok(name) } + #[cfg(any(target_os = "solaris", target_os = "illumos"))] + pub fn set_exclbind(&self, excl: bool) -> io::Result<()> { + // not yet on libc crate + const SO_EXCLBIND: i32 = 0x1015; + setsockopt(self, libc::SOL_SOCKET, SO_EXCLBIND, excl) + } + + #[cfg(any(target_os = "solaris", target_os = "illumos"))] + pub fn exclbind(&self) -> io::Result { + // not yet on libc crate + const SO_EXCLBIND: i32 = 0x1015; + let raw: c_int = getsockopt(self, libc::SOL_SOCKET, SO_EXCLBIND)?; + Ok(raw != 0) + } + #[cfg(any(target_os = "android", target_os = "linux",))] pub fn set_passcred(&self, passcred: bool) -> io::Result<()> { setsockopt(self, libc::SOL_SOCKET, libc::SO_PASSCRED, passcred as libc::c_int) From f3383e4942bca64ce523b7736a2bedd1b8426c11 Mon Sep 17 00:00:00 2001 From: Alice Ryhl Date: Thu, 12 Jun 2025 10:56:43 +0000 Subject: [PATCH 02/15] Do not include NUL-terminator in computed length --- .../src/util/caller_location.rs | 12 +++---- library/core/src/panic/location.rs | 35 ++++++++++++------- 2 files changed, 27 insertions(+), 20 deletions(-) diff --git a/compiler/rustc_const_eval/src/util/caller_location.rs b/compiler/rustc_const_eval/src/util/caller_location.rs index 671214002a0d8..a51a5751dc47c 100644 --- a/compiler/rustc_const_eval/src/util/caller_location.rs +++ b/compiler/rustc_const_eval/src/util/caller_location.rs @@ -22,13 +22,14 @@ fn alloc_caller_location<'tcx>( assert!(!filename.as_str().as_bytes().contains(&0)); let loc_details = ecx.tcx.sess.opts.unstable_opts.location_detail; - let file_wide_ptr = { + let filename = { let filename = if loc_details.file { filename.as_str() } else { "" }; let filename_with_nul = filename.to_owned() + "\0"; // This can fail if rustc runs out of memory right here. Trying to emit an error would be // pointless, since that would require allocating more memory than these short strings. let file_ptr = ecx.allocate_bytes_dedup(filename_with_nul.as_bytes()).unwrap(); - Immediate::new_slice(file_ptr.into(), filename_with_nul.len().try_into().unwrap(), ecx) + let file_len = u64::try_from(filename.len()).unwrap(); + Immediate::new_slice(file_ptr.into(), file_len, ecx) }; let line = if loc_details.line { Scalar::from_u32(line) } else { Scalar::from_u32(0) }; let col = if loc_details.column { Scalar::from_u32(col) } else { Scalar::from_u32(0) }; @@ -42,11 +43,8 @@ fn alloc_caller_location<'tcx>( let location = ecx.allocate(loc_layout, MemoryKind::CallerLocation).unwrap(); // Initialize fields. - ecx.write_immediate( - file_wide_ptr, - &ecx.project_field(&location, FieldIdx::from_u32(0)).unwrap(), - ) - .expect("writing to memory we just allocated cannot fail"); + ecx.write_immediate(filename, &ecx.project_field(&location, FieldIdx::from_u32(0)).unwrap()) + .expect("writing to memory we just allocated cannot fail"); ecx.write_scalar(line, &ecx.project_field(&location, FieldIdx::from_u32(1)).unwrap()) .expect("writing to memory we just allocated cannot fail"); ecx.write_scalar(col, &ecx.project_field(&location, FieldIdx::from_u32(2)).unwrap()) diff --git a/library/core/src/panic/location.rs b/library/core/src/panic/location.rs index f1eedede8aab9..1e950d6e4988b 100644 --- a/library/core/src/panic/location.rs +++ b/library/core/src/panic/location.rs @@ -1,5 +1,6 @@ use crate::ffi::CStr; use crate::fmt; +use crate::marker::PhantomData; /// A struct containing information about the location of a panic. /// @@ -33,14 +34,13 @@ use crate::fmt; #[derive(Copy, Clone, Eq, Hash, Ord, PartialEq, PartialOrd)] #[stable(feature = "panic_hooks", since = "1.10.0")] pub struct Location<'a> { - // Note: this filename will have exactly one nul byte at its end, but otherwise - // it must never contain interior nul bytes. This is relied on for the conversion - // to `CStr` below. - // - // The prefix of the string without the trailing nul byte will be a regular UTF8 `str`. - file_bytes_with_nul: &'a [u8], + // A raw pointer is used rather than a reference because the pointer is valid for one more byte + // than the length stored in this pointer; the additional byte is the NUL-terminator used by + // `Location::file_with_nul`. + filename: *const str, line: u32, col: u32, + _filename: PhantomData<&'a str>, } #[stable(feature = "panic_hooks", since = "1.10.0")] @@ -143,10 +143,8 @@ impl<'a> Location<'a> { #[stable(feature = "panic_hooks", since = "1.10.0")] #[rustc_const_stable(feature = "const_location_fields", since = "1.79.0")] pub const fn file(&self) -> &str { - let str_len = self.file_bytes_with_nul.len() - 1; - // SAFETY: `file_bytes_with_nul` without the trailing nul byte is guaranteed to be - // valid UTF8. - unsafe { crate::str::from_raw_parts(self.file_bytes_with_nul.as_ptr(), str_len) } + // SAFETY: The filename is valid. + unsafe { &*self.filename } } /// Returns the name of the source file as a nul-terminated `CStr`. @@ -157,9 +155,15 @@ impl<'a> Location<'a> { #[unstable(feature = "file_with_nul", issue = "141727")] #[inline] pub const fn file_with_nul(&self) -> &CStr { - // SAFETY: `file_bytes_with_nul` is guaranteed to have a trailing nul byte and no - // interior nul bytes. - unsafe { CStr::from_bytes_with_nul_unchecked(self.file_bytes_with_nul) } + // SAFETY: The filename is valid for `filename_len+1` bytes, so this addition can't + // overflow. + let cstr_len = unsafe { crate::mem::size_of_val_raw(self.filename).unchecked_add(1) }; + + // SAFETY: The filename is valid for `filename_len+1` bytes. + let slice = unsafe { crate::slice::from_raw_parts(self.filename as *const _, cstr_len) }; + + // SAFETY: The filename is guaranteed to have a trailing nul byte and no interior nul bytes. + unsafe { CStr::from_bytes_with_nul_unchecked(slice) } } /// Returns the line number from which the panic originated. @@ -220,3 +224,8 @@ impl fmt::Display for Location<'_> { write!(formatter, "{}:{}:{}", self.file(), self.line, self.col) } } + +#[stable(feature = "panic_hooks", since = "1.10.0")] +unsafe impl Send for Location<'_> {} +#[stable(feature = "panic_hooks", since = "1.10.0")] +unsafe impl Sync for Location<'_> {} From 6a1b7df4854b0023e34b18e2196d3069906da796 Mon Sep 17 00:00:00 2001 From: Alice Ryhl Date: Mon, 23 Jun 2025 13:45:56 +0000 Subject: [PATCH 03/15] Use a NonNull pointer --- library/core/src/panic/location.rs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/library/core/src/panic/location.rs b/library/core/src/panic/location.rs index 1e950d6e4988b..972270208852a 100644 --- a/library/core/src/panic/location.rs +++ b/library/core/src/panic/location.rs @@ -1,6 +1,7 @@ use crate::ffi::CStr; use crate::fmt; use crate::marker::PhantomData; +use crate::ptr::NonNull; /// A struct containing information about the location of a panic. /// @@ -37,7 +38,7 @@ pub struct Location<'a> { // A raw pointer is used rather than a reference because the pointer is valid for one more byte // than the length stored in this pointer; the additional byte is the NUL-terminator used by // `Location::file_with_nul`. - filename: *const str, + filename: NonNull, line: u32, col: u32, _filename: PhantomData<&'a str>, @@ -144,7 +145,7 @@ impl<'a> Location<'a> { #[rustc_const_stable(feature = "const_location_fields", since = "1.79.0")] pub const fn file(&self) -> &str { // SAFETY: The filename is valid. - unsafe { &*self.filename } + unsafe { self.filename.as_ref() } } /// Returns the name of the source file as a nul-terminated `CStr`. @@ -155,12 +156,14 @@ impl<'a> Location<'a> { #[unstable(feature = "file_with_nul", issue = "141727")] #[inline] pub const fn file_with_nul(&self) -> &CStr { + let filename = self.filename.as_ptr(); + // SAFETY: The filename is valid for `filename_len+1` bytes, so this addition can't // overflow. - let cstr_len = unsafe { crate::mem::size_of_val_raw(self.filename).unchecked_add(1) }; + let cstr_len = unsafe { crate::mem::size_of_val_raw(filename).unchecked_add(1) }; // SAFETY: The filename is valid for `filename_len+1` bytes. - let slice = unsafe { crate::slice::from_raw_parts(self.filename as *const _, cstr_len) }; + let slice = unsafe { crate::slice::from_raw_parts(filename.cast(), cstr_len) }; // SAFETY: The filename is guaranteed to have a trailing nul byte and no interior nul bytes. unsafe { CStr::from_bytes_with_nul_unchecked(slice) } From e0f8e865dbf9f1dc9d1d917efc04320e2eb123f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Tue, 24 Jun 2025 15:51:08 +0200 Subject: [PATCH 04/15] Skip unnecessary components in x64 try builds --- src/tools/opt-dist/src/exec.rs | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/src/tools/opt-dist/src/exec.rs b/src/tools/opt-dist/src/exec.rs index 64ce5cc377522..75569eacacdea 100644 --- a/src/tools/opt-dist/src/exec.rs +++ b/src/tools/opt-dist/src/exec.rs @@ -113,7 +113,7 @@ impl Bootstrap { "library/std", ]) .env("RUST_BACKTRACE", "full"); - let cmd = add_shared_x_flags(env, cmd); + let mut cmd = add_shared_x_flags(env, cmd); Self { cmd, metrics_path } } @@ -122,7 +122,12 @@ impl Bootstrap { let metrics_path = env.build_root().join("build").join("metrics.json"); let args = dist_args.iter().map(|arg| arg.as_str()).collect::>(); let cmd = cmd(&args).env("RUST_BACKTRACE", "full"); - let cmd = add_shared_x_flags(env, cmd); + let mut cmd = add_shared_x_flags(env, cmd); + if env.is_fast_try_build() { + // We set build.extended=false for fast try builds, but we still need Cargo + cmd = cmd.arg("cargo"); + } + Self { cmd, metrics_path } } @@ -188,6 +193,19 @@ impl Bootstrap { } } -fn add_shared_x_flags(env: &Environment, cmd: CmdBuilder) -> CmdBuilder { - if env.is_fast_try_build() { cmd.arg("--set").arg("rust.deny-warnings=false") } else { cmd } +fn add_shared_x_flags(env: &Environment, mut cmd: CmdBuilder) -> CmdBuilder { + if env.is_fast_try_build() { + // Skip things that cannot be skipped through `x ... --skip` + cmd.arg("--set") + .arg("rust.llvm-bitcode-linker=false") + // Skip wasm-component-ld. This also skips cargo, which we need to re-enable for dist + .arg("--set") + .arg("build.extended=false") + .arg("--set") + .arg("rust.codegen-backends=['llvm']") + .arg("--set") + .arg("rust.deny-warnings=false") + } else { + cmd + } } From 25dee4e56e0ad075044e7e465ae513086c78f45a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Tue, 24 Jun 2025 15:57:25 +0200 Subject: [PATCH 05/15] Skip more dist components --- src/tools/opt-dist/src/main.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/tools/opt-dist/src/main.rs b/src/tools/opt-dist/src/main.rs index d2827ec01ca7d..9c8a6637a3b10 100644 --- a/src/tools/opt-dist/src/main.rs +++ b/src/tools/opt-dist/src/main.rs @@ -407,13 +407,18 @@ fn main() -> anyhow::Result<()> { for target in [ "rust-docs", "rustc-docs", + "rustc-dev", + "rust-dev", "rust-docs-json", "rust-analyzer", "rustc-src", + "extended", "clippy", "miri", "rustfmt", "gcc", + "generate-copyright", + "bootstrap", ] { build_args.extend(["--skip".to_string(), target.to_string()]); } From 803415478cfc69d9e6c02b313560d6a2e433e0f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Tue, 24 Jun 2025 16:04:56 +0200 Subject: [PATCH 06/15] Do not build GCC in fast try builds --- src/ci/docker/host-x86_64/dist-x86_64-linux/dist.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/ci/docker/host-x86_64/dist-x86_64-linux/dist.sh b/src/ci/docker/host-x86_64/dist-x86_64-linux/dist.sh index 064ac5b0a5e42..924bdbc761505 100755 --- a/src/ci/docker/host-x86_64/dist-x86_64-linux/dist.sh +++ b/src/ci/docker/host-x86_64/dist-x86_64-linux/dist.sh @@ -10,4 +10,7 @@ python3 ../x.py build --set rust.debug=true opt-dist build-manifest bootstrap # Use GCC for building GCC, as it seems to behave badly when built with Clang -CC=/rustroot/bin/cc CXX=/rustroot/bin/c++ python3 ../x.py dist gcc +# Only build GCC on full builds, not try builds +if [ "${DIST_TRY_BUILD:-0}" == "0" ]; then + CC=/rustroot/bin/cc CXX=/rustroot/bin/c++ python3 ../x.py dist gcc +fi From 58bc1dcb73b75d8fd0117d76e9a9f61ff297cd4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Wed, 25 Jun 2025 16:24:30 +0200 Subject: [PATCH 07/15] Remove `mut` --- src/tools/opt-dist/src/exec.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tools/opt-dist/src/exec.rs b/src/tools/opt-dist/src/exec.rs index 75569eacacdea..0dc6e56b9d5f4 100644 --- a/src/tools/opt-dist/src/exec.rs +++ b/src/tools/opt-dist/src/exec.rs @@ -113,7 +113,7 @@ impl Bootstrap { "library/std", ]) .env("RUST_BACKTRACE", "full"); - let mut cmd = add_shared_x_flags(env, cmd); + let cmd = add_shared_x_flags(env, cmd); Self { cmd, metrics_path } } @@ -193,7 +193,7 @@ impl Bootstrap { } } -fn add_shared_x_flags(env: &Environment, mut cmd: CmdBuilder) -> CmdBuilder { +fn add_shared_x_flags(env: &Environment, cmd: CmdBuilder) -> CmdBuilder { if env.is_fast_try_build() { // Skip things that cannot be skipped through `x ... --skip` cmd.arg("--set") From 508021aa4320f1feb4c7a783ee16c2feebc9249a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Miku=C5=82a?= Date: Thu, 26 Jun 2025 01:31:12 +0200 Subject: [PATCH 08/15] Add windows-gnullvm hosts to the manifest --- src/tools/build-manifest/src/main.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs index 4c53ea42793cd..0520eff0fa277 100644 --- a/src/tools/build-manifest/src/main.rs +++ b/src/tools/build-manifest/src/main.rs @@ -14,6 +14,7 @@ use crate::versions::{PkgType, Versions}; static HOSTS: &[&str] = &[ "aarch64-apple-darwin", + "aarch64-pc-windows-gnullvm", "aarch64-pc-windows-msvc", "aarch64-unknown-linux-gnu", "aarch64-unknown-linux-musl", @@ -44,6 +45,7 @@ static HOSTS: &[&str] = &[ "x86_64-apple-darwin", "x86_64-pc-solaris", "x86_64-pc-windows-gnu", + "x86_64-pc-windows-gnullvm", "x86_64-pc-windows-msvc", "x86_64-unknown-freebsd", "x86_64-unknown-illumos", @@ -470,7 +472,7 @@ impl Builder { } // so is rust-mingw if it's available for the target PkgType::RustMingw => { - if host.contains("pc-windows-gnu") { + if host.ends_with("pc-windows-gnu") { components.push(host_component(pkg)); } } From b2be01c81567e89142577f9474a810e3a8676cfc Mon Sep 17 00:00:00 2001 From: binarycat Date: Tue, 24 Jun 2025 17:47:24 -0500 Subject: [PATCH 09/15] rustdoc: show attributes on enum variants mostly for #[non_exhaustive] --- src/librustdoc/html/render/print_item.rs | 1 + .../rustdoc/enum/enum-variant-non_exhaustive.rs | 17 +++++++++++++++++ ...-variant-non_exhaustive.type-alias-code.html | 4 ++++ .../enum-variant-non_exhaustive.type-code.html | 4 ++++ 4 files changed, 26 insertions(+) create mode 100644 tests/rustdoc/enum/enum-variant-non_exhaustive.rs create mode 100644 tests/rustdoc/enum/enum-variant-non_exhaustive.type-alias-code.html create mode 100644 tests/rustdoc/enum/enum-variant-non_exhaustive.type-code.html diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index 515424cbef19b..5456a09dce72c 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -1702,6 +1702,7 @@ fn render_enum_fields( if v.is_stripped() { continue; } + write!(w, "{}", render_attributes_in_pre(v, TAB, cx))?; w.write_str(TAB)?; match v.kind { clean::VariantItem(ref var) => match var.kind { diff --git a/tests/rustdoc/enum/enum-variant-non_exhaustive.rs b/tests/rustdoc/enum/enum-variant-non_exhaustive.rs new file mode 100644 index 0000000000000..ea0234a49f640 --- /dev/null +++ b/tests/rustdoc/enum/enum-variant-non_exhaustive.rs @@ -0,0 +1,17 @@ +// regression test for https://github.com/rust-lang/rust/issues/142599 + +#![crate_name = "foo"] + +//@ snapshot type-code 'foo/enum.Type.html' '//pre[@class="rust item-decl"]/code' +pub enum Type { + #[non_exhaustive] + // attribute that should not be shown + #[warn(unsafe_code)] + Variant, +} + +// we would love to use the `following-sibling::` axis +// (along with an `h2[@id="aliased-type"]` query), +// but unfortunately python doesn't implement that. +//@ snapshot type-alias-code 'foo/type.TypeAlias.html' '//pre[@class="rust item-decl"][2]/code' +pub type TypeAlias = Type; diff --git a/tests/rustdoc/enum/enum-variant-non_exhaustive.type-alias-code.html b/tests/rustdoc/enum/enum-variant-non_exhaustive.type-alias-code.html new file mode 100644 index 0000000000000..04eea709079d7 --- /dev/null +++ b/tests/rustdoc/enum/enum-variant-non_exhaustive.type-alias-code.html @@ -0,0 +1,4 @@ +pub enum TypeAlias { + #[non_exhaustive] + Variant, +} \ No newline at end of file diff --git a/tests/rustdoc/enum/enum-variant-non_exhaustive.type-code.html b/tests/rustdoc/enum/enum-variant-non_exhaustive.type-code.html new file mode 100644 index 0000000000000..6c8851ea5df47 --- /dev/null +++ b/tests/rustdoc/enum/enum-variant-non_exhaustive.type-code.html @@ -0,0 +1,4 @@ +pub enum Type { + #[non_exhaustive] + Variant, +} \ No newline at end of file From 7a79454de465774f8445a88640ffdc5792fc8a13 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Fri, 27 Jun 2025 18:24:42 +0800 Subject: [PATCH 10/15] update internal `send_signal` comment --- library/std/src/sys/process/unix/unix.rs | 4 ++-- library/std/src/sys/process/unix/vxworks.rs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/library/std/src/sys/process/unix/unix.rs b/library/std/src/sys/process/unix/unix.rs index 1fe80c13b81c8..bbd03e2b0c4e9 100644 --- a/library/std/src/sys/process/unix/unix.rs +++ b/library/std/src/sys/process/unix/unix.rs @@ -968,8 +968,8 @@ impl Process { } pub(crate) fn send_signal(&self, signal: i32) -> io::Result<()> { - // If we've already waited on this process then the pid can be recycled - // and used for another process, and we probably shouldn't be signaling + // If we've already waited on this process then the pid can be recycled and + // used for another process, and we probably shouldn't be sending signals to // random processes, so return Ok because the process has exited already. if self.status.is_some() { return Ok(()); diff --git a/library/std/src/sys/process/unix/vxworks.rs b/library/std/src/sys/process/unix/vxworks.rs index 51ae8c56bdb9b..2275cbb946a9c 100644 --- a/library/std/src/sys/process/unix/vxworks.rs +++ b/library/std/src/sys/process/unix/vxworks.rs @@ -151,8 +151,8 @@ impl Process { } pub fn send_signal(&self, signal: i32) -> io::Result<()> { - // If we've already waited on this process then the pid can be recycled - // and used for another process, and we probably shouldn't be killing + // If we've already waited on this process then the pid can be recycled and + // used for another process, and we probably shouldn't be sending signals to // random processes, so return Ok because the process has exited already. if self.status.is_some() { Ok(()) From cd1713ebba83a87e80a7366fdfe6fc28cabe6053 Mon Sep 17 00:00:00 2001 From: Cheng Xu Date: Fri, 27 Jun 2025 11:01:59 -0700 Subject: [PATCH 11/15] BTreeSet: remove duplicated code by reusing `from_sorted_iter` The method `BTreeSet::from_sorted_iter` was introduced in 49ccb7519f55bd117d2ab50b7a030637f380aec6, but it was not consistently used throughout the codebase. As a result, some code redundantly reimplemented its logic. This commit fixes the problem. --- library/alloc/src/collections/btree/set.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/library/alloc/src/collections/btree/set.rs b/library/alloc/src/collections/btree/set.rs index aa9e5fce1d4cc..d50ce02bda743 100644 --- a/library/alloc/src/collections/btree/set.rs +++ b/library/alloc/src/collections/btree/set.rs @@ -1517,9 +1517,7 @@ impl From<[T; N]> for BTreeSet { // use stable sort to preserve the insertion order. arr.sort(); - let iter = IntoIterator::into_iter(arr).map(|k| (k, SetValZST::default())); - let map = BTreeMap::bulk_build_from_sorted_iter(iter, Global); - BTreeSet { map } + BTreeSet::from_sorted_iter(IntoIterator::into_iter(arr), Global) } } From 9090199f49bf681aaf68322b3beedc37acea7b5f Mon Sep 17 00:00:00 2001 From: leopardracer <136604165+leopardracer@users.noreply.github.com> Date: Fri, 27 Jun 2025 22:38:52 +0300 Subject: [PATCH 12/15] Update ui.rs --- src/tools/test-float-parse/src/ui.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/test-float-parse/src/ui.rs b/src/tools/test-float-parse/src/ui.rs index 73473eef0bfdb..1a9ba0dc1d99c 100644 --- a/src/tools/test-float-parse/src/ui.rs +++ b/src/tools/test-float-parse/src/ui.rs @@ -118,7 +118,7 @@ pub fn finish_all(tests: &[TestInfo], total_elapsed: Duration, cfg: &Config) -> match result { Ok(FinishedAll) => (), Err(EarlyExit::Timeout) => { - println!(" exited early; exceded {:?} timeout", cfg.timeout) + println!(" exited early; exceeded {:?} timeout", cfg.timeout) } Err(EarlyExit::MaxFailures) => { println!(" exited early; exceeded {:?} max failures", cfg.max_failures) From 3a34dac6c36f4e725d7e16022d12c9f58ebc6c2a Mon Sep 17 00:00:00 2001 From: leopardracer <136604165+leopardracer@users.noreply.github.com> Date: Fri, 27 Jun 2025 22:39:12 +0300 Subject: [PATCH 13/15] Update README.md --- src/tools/miri/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/miri/README.md b/src/tools/miri/README.md index 5554c7975ff3b..3031d2c744a34 100644 --- a/src/tools/miri/README.md +++ b/src/tools/miri/README.md @@ -592,7 +592,7 @@ Definite bugs found: * [Occasional memory leak in `std::mpsc` channels](https://github.com/rust-lang/rust/issues/121582) (original code in [crossbeam](https://github.com/crossbeam-rs/crossbeam/pull/1084)) * [Weak-memory-induced memory leak in Windows thread-local storage](https://github.com/rust-lang/rust/pull/124281) * [A bug in the new `RwLock::downgrade` implementation](https://rust-lang.zulipchat.com/#narrow/channel/269128-miri/topic/Miri.20error.20library.20test) (caught by Miri before it landed in the Rust repo) -* [Mockall reading unintialized memory when mocking `std::io::Read::read`, even if all expectations are satisfied](https://github.com/asomers/mockall/issues/647) (caught by Miri running Tokio's test suite) +* [Mockall reading uninitialized memory when mocking `std::io::Read::read`, even if all expectations are satisfied](https://github.com/asomers/mockall/issues/647) (caught by Miri running Tokio's test suite) * [`ReentrantLock` not correctly dealing with reuse of addresses for TLS storage of different threads](https://github.com/rust-lang/rust/pull/141248) Violations of [Stacked Borrows] found that are likely bugs (but Stacked Borrows is currently just an experiment): From 39092cc10b1a9c9395b5876ad40999e1a1eda585 Mon Sep 17 00:00:00 2001 From: leopardracer <136604165+leopardracer@users.noreply.github.com> Date: Fri, 27 Jun 2025 22:39:40 +0300 Subject: [PATCH 14/15] Update dangling_pointer_to_raw_pointer.rs --- .../fail/dangling_pointers/dangling_pointer_to_raw_pointer.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_to_raw_pointer.rs b/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_to_raw_pointer.rs index c63e926376d45..9646cdb206591 100644 --- a/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_to_raw_pointer.rs +++ b/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_to_raw_pointer.rs @@ -6,7 +6,7 @@ fn direct_raw(x: *const (i32, i32)) -> *const i32 { // Ensure that if a raw pointer is created via an intermediate // reference, we catch that. (Just in case someone decides to -// desugar this differenly or so.) +// desugar this differently or so.) fn via_ref(x: *const (i32, i32)) -> *const i32 { unsafe { &(*x).0 as *const i32 } //~ERROR: dangling pointer } From 00b64f8851e9f56239a48e4306efd597d7be972c Mon Sep 17 00:00:00 2001 From: Yotam Ofek Date: Fri, 27 Jun 2025 17:58:36 +0000 Subject: [PATCH 15/15] Use tidy to sort `sym::*` items --- compiler/rustc_macros/src/symbols.rs | 12 -- compiler/rustc_macros/src/symbols/tests.rs | 15 --- compiler/rustc_span/src/symbol.rs | 131 ++++++++++----------- 3 files changed, 64 insertions(+), 94 deletions(-) diff --git a/compiler/rustc_macros/src/symbols.rs b/compiler/rustc_macros/src/symbols.rs index 2b00b7dd27aaf..78a4d47ca3346 100644 --- a/compiler/rustc_macros/src/symbols.rs +++ b/compiler/rustc_macros/src/symbols.rs @@ -190,17 +190,6 @@ fn symbols_with_errors(input: TokenStream) -> (TokenStream, Vec) { let mut symbols_stream = quote! {}; let mut prefill_stream = quote! {}; let mut entries = Entries::with_capacity(input.keywords.len() + input.symbols.len() + 10); - let mut prev_key: Option<(Span, String)> = None; - - let mut check_order = |span: Span, s: &str, errors: &mut Errors| { - if let Some((prev_span, ref prev_str)) = prev_key { - if s < prev_str { - errors.error(span, format!("Symbol `{s}` must precede `{prev_str}`")); - errors.error(prev_span, format!("location of previous symbol `{prev_str}`")); - } - } - prev_key = Some((span, s.to_string())); - }; // Generate the listed keywords. for keyword in input.keywords.iter() { @@ -219,7 +208,6 @@ fn symbols_with_errors(input: TokenStream) -> (TokenStream, Vec) { // Generate the listed symbols. for symbol in input.symbols.iter() { let name = &symbol.name; - check_order(symbol.name.span(), &name.to_string(), &mut errors); let value = match &symbol.value { Value::SameAsName => name.to_string(), diff --git a/compiler/rustc_macros/src/symbols/tests.rs b/compiler/rustc_macros/src/symbols/tests.rs index 9c53453df5b54..f0a7a2106be49 100644 --- a/compiler/rustc_macros/src/symbols/tests.rs +++ b/compiler/rustc_macros/src/symbols/tests.rs @@ -84,18 +84,3 @@ fn check_dup_symbol_and_keyword() { }; test_symbols_macro(input, &["Symbol `splat` is duplicated", "location of previous definition"]); } - -#[test] -fn check_symbol_order() { - let input = quote! { - Keywords {} - Symbols { - zebra, - aardvark, - } - }; - test_symbols_macro( - input, - &["Symbol `aardvark` must precede `zebra`", "location of previous symbol `zebra`"], - ); -} diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 4be7c7ba51093..c5bc8e85009b6 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -150,14 +150,10 @@ symbols! { // As well as the symbols listed, there are symbols for the strings // "0", "1", ..., "9", which are accessible via `sym::integer`. // - // The proc macro will abort if symbols are not in alphabetical order (as - // defined by `impl Ord for str`) or if any symbols are duplicated. Vim - // users can sort the list by selecting it and executing the command - // `:'<,'>!LC_ALL=C sort`. - // // There is currently no checking that all symbols are used; that would be // nice to have. Symbols { + // tidy-alphabetical-start Abi, AcqRel, Acquire, @@ -175,18 +171,18 @@ symbols! { AsyncGenPending, AsyncGenReady, AtomicBool, - AtomicI128, + AtomicI8, AtomicI16, AtomicI32, AtomicI64, - AtomicI8, + AtomicI128, AtomicIsize, AtomicPtr, - AtomicU128, + AtomicU8, AtomicU16, AtomicU32, AtomicU64, - AtomicU8, + AtomicU128, AtomicUsize, BTreeEntry, BTreeMap, @@ -607,10 +603,10 @@ symbols! { catch_unwind, cause, cdylib, - ceilf128, ceilf16, ceilf32, ceilf64, + ceilf128, cfg, cfg_accessible, cfg_attr, @@ -747,10 +743,10 @@ symbols! { copy, copy_closures, copy_nonoverlapping, - copysignf128, copysignf16, copysignf32, copysignf64, + copysignf128, core, core_panic, core_panic_2015_macro, @@ -763,10 +759,10 @@ symbols! { coroutine_state, coroutine_yield, coroutines, - cosf128, cosf16, cosf32, cosf64, + cosf128, count, coverage, coverage_attribute, @@ -874,8 +870,8 @@ symbols! { dotdot_in_tuple_patterns, dotdoteq_in_patterns, dreg, - dreg_low16, dreg_low8, + dreg_low16, drop, drop_in_place, drop_types_in_const, @@ -928,16 +924,16 @@ symbols! { exhaustive_integer_patterns, exhaustive_patterns, existential_type, - exp2f128, exp2f16, exp2f32, exp2f64, + exp2f128, expect, expected, - expf128, expf16, expf32, expf64, + expf128, explicit_extern_abis, explicit_generic_args_with_impl_trait, explicit_tail_calls, @@ -958,9 +954,6 @@ symbols! { external, external_doc, f, - f128, - f128_epsilon, - f128_nan, f16, f16_epsilon, f16_nan, @@ -999,10 +992,13 @@ symbols! { f64_legacy_const_neg_infinity, f64_legacy_const_radix, f64_nan, - fabsf128, + f128, + f128_epsilon, + f128_nan, fabsf16, fabsf32, fabsf64, + fabsf128, fadd_algebraic, fadd_fast, fake_variadic, @@ -1024,22 +1020,22 @@ symbols! { flags, float, float_to_int_unchecked, - floorf128, floorf16, floorf32, floorf64, - fmaf128, + floorf128, fmaf16, fmaf32, fmaf64, + fmaf128, fmt, fmt_debug, fmul_algebraic, fmul_fast, - fmuladdf128, fmuladdf16, fmuladdf32, fmuladdf64, + fmuladdf128, fn_align, fn_body, fn_delegation, @@ -1140,13 +1136,12 @@ symbols! { html_root_url, hwaddress, i, - i128, - i128_legacy_const_max, - i128_legacy_const_min, - i128_legacy_fn_max_value, - i128_legacy_fn_min_value, - i128_legacy_mod, - i128_type, + i8, + i8_legacy_const_max, + i8_legacy_const_min, + i8_legacy_fn_max_value, + i8_legacy_fn_min_value, + i8_legacy_mod, i16, i16_legacy_const_max, i16_legacy_const_min, @@ -1165,12 +1160,13 @@ symbols! { i64_legacy_fn_max_value, i64_legacy_fn_min_value, i64_legacy_mod, - i8, - i8_legacy_const_max, - i8_legacy_const_min, - i8_legacy_fn_max_value, - i8_legacy_fn_min_value, - i8_legacy_mod, + i128, + i128_legacy_const_max, + i128_legacy_const_min, + i128_legacy_fn_max_value, + i128_legacy_fn_min_value, + i128_legacy_mod, + i128_type, ident, if_let, if_let_guard, @@ -1292,19 +1288,19 @@ symbols! { loaded_from_disk, local, local_inner_macros, - log10f128, - log10f16, - log10f32, - log10f64, - log2f128, log2f16, log2f32, log2f64, + log2f128, + log10f16, + log10f32, + log10f64, + log10f128, log_syntax, - logf128, logf16, logf32, logf64, + logf128, loongarch_target_feature, loop_break_value, loop_match, @@ -1334,14 +1330,14 @@ symbols! { match_beginning_vert, match_default_bindings, matches_macro, - maximumf128, maximumf16, maximumf32, maximumf64, - maxnumf128, + maximumf128, maxnumf16, maxnumf32, maxnumf64, + maxnumf128, may_dangle, may_unwind, maybe_uninit, @@ -1372,14 +1368,14 @@ symbols! { min_generic_const_args, min_specialization, min_type_alias_impl_trait, - minimumf128, minimumf16, minimumf32, minimumf64, - minnumf128, + minimumf128, minnumf16, minnumf32, minnumf64, + minnumf128, mips_target_feature, mir_assume, mir_basic_block, @@ -1633,14 +1629,14 @@ symbols! { post_dash_lto: "post-lto", postfix_match, powerpc_target_feature, - powf128, powf16, powf32, powf64, - powif128, + powf128, powif16, powif32, powif64, + powif128, pre_dash_lto: "pre-lto", precise_capturing, precise_capturing_in_traits, @@ -1785,14 +1781,14 @@ symbols! { ropi_rwpi: "ropi-rwpi", rotate_left, rotate_right, - round_ties_even_f128, round_ties_even_f16, round_ties_even_f32, round_ties_even_f64, - roundf128, + round_ties_even_f128, roundf16, roundf32, roundf64, + roundf128, rt, rtm_target_feature, rust, @@ -1972,8 +1968,8 @@ symbols! { simd_fexp2, simd_ffi, simd_flog, - simd_flog10, simd_flog2, + simd_flog10, simd_floor, simd_fma, simd_fmax, @@ -2021,10 +2017,10 @@ symbols! { simd_with_exposed_provenance, simd_xor, since, - sinf128, sinf16, sinf32, sinf64, + sinf128, size, size_of, size_of_val, @@ -2046,10 +2042,10 @@ symbols! { specialization, speed, spotlight, - sqrtf128, sqrtf16, sqrtf32, sqrtf64, + sqrtf128, sreg, sreg_low16, sse, @@ -2127,10 +2123,10 @@ symbols! { target_has_atomic, target_has_atomic_equal_alignment, target_has_atomic_load_store, - target_has_reliable_f128, - target_has_reliable_f128_math, target_has_reliable_f16, target_has_reliable_f16_math, + target_has_reliable_f128, + target_has_reliable_f128_math, target_os, target_pointer_width, target_thread_local, @@ -2173,10 +2169,10 @@ symbols! { transparent_enums, transparent_unions, trivial_bounds, - truncf128, truncf16, truncf32, truncf64, + truncf128, try_blocks, try_capture, try_from, @@ -2205,12 +2201,12 @@ symbols! { type_name, type_privacy_lints, typed_swap_nonoverlapping, - u128, - u128_legacy_const_max, - u128_legacy_const_min, - u128_legacy_fn_max_value, - u128_legacy_fn_min_value, - u128_legacy_mod, + u8, + u8_legacy_const_max, + u8_legacy_const_min, + u8_legacy_fn_max_value, + u8_legacy_fn_min_value, + u8_legacy_mod, u16, u16_legacy_const_max, u16_legacy_const_min, @@ -2229,12 +2225,12 @@ symbols! { u64_legacy_fn_max_value, u64_legacy_fn_min_value, u64_legacy_mod, - u8, - u8_legacy_const_max, - u8_legacy_const_min, - u8_legacy_fn_max_value, - u8_legacy_fn_min_value, - u8_legacy_mod, + u128, + u128_legacy_const_max, + u128_legacy_const_min, + u128_legacy_fn_max_value, + u128_legacy_fn_min_value, + u128_legacy_mod, ub_checks, unaligned_volatile_load, unaligned_volatile_store, @@ -2387,6 +2383,7 @@ symbols! { zfh, zfhmin, zmm_reg, + // tidy-alphabetical-end } }