Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rollup of 7 pull requests #138653

Merged
merged 15 commits into from
Mar 19, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 2 additions & 21 deletions compiler/rustc_middle/src/thir.rs
Original file line number Diff line number Diff line change
@@ -28,6 +28,7 @@ use tracing::instrument;
use crate::middle::region;
use crate::mir::interpret::AllocId;
use crate::mir::{self, BinOp, BorrowKind, FakeReadCause, UnOp};
use crate::thir::visit::for_each_immediate_subpat;
use crate::ty::adjustment::PointerCoercion;
use crate::ty::layout::IntegerExt;
use crate::ty::{
@@ -672,27 +673,7 @@ impl<'tcx> Pat<'tcx> {
return;
}

use PatKind::*;
match &self.kind {
Wild
| Never
| Range(..)
| Binding { subpattern: None, .. }
| Constant { .. }
| Error(_) => {}
AscribeUserType { subpattern, .. }
| Binding { subpattern: Some(subpattern), .. }
| Deref { subpattern }
| DerefPattern { subpattern, .. }
| ExpandedConstant { subpattern, .. } => subpattern.walk_(it),
Leaf { subpatterns } | Variant { subpatterns, .. } => {
subpatterns.iter().for_each(|field| field.pattern.walk_(it))
}
Or { pats } => pats.iter().for_each(|p| p.walk_(it)),
Array { box prefix, slice, box suffix } | Slice { box prefix, slice, box suffix } => {
prefix.iter().chain(slice.as_deref()).chain(suffix.iter()).for_each(|p| p.walk_(it))
}
}
for_each_immediate_subpat(self, |p| p.walk_(it));
}

/// Whether the pattern has a `PatKind::Error` nested within.
59 changes: 34 additions & 25 deletions compiler/rustc_middle/src/thir/visit.rs
Original file line number Diff line number Diff line change
@@ -240,36 +240,45 @@ pub fn walk_pat<'thir, 'tcx: 'thir, V: Visitor<'thir, 'tcx>>(
visitor: &mut V,
pat: &'thir Pat<'tcx>,
) {
use PatKind::*;
for_each_immediate_subpat(pat, |p| visitor.visit_pat(p));
}

/// Invokes `callback` on each immediate subpattern of `pat`, if any.
/// A building block for assembling THIR pattern visitors.
pub(crate) fn for_each_immediate_subpat<'a, 'tcx>(
pat: &'a Pat<'tcx>,
mut callback: impl FnMut(&'a Pat<'tcx>),
) {
match &pat.kind {
AscribeUserType { subpattern, ascription: _ }
| Deref { subpattern }
| DerefPattern { subpattern, .. }
| Binding { subpattern: Some(subpattern), .. } => visitor.visit_pat(subpattern),
Binding { .. } | Wild | Never | Error(_) => {}
Variant { subpatterns, adt_def: _, args: _, variant_index: _ } | Leaf { subpatterns } => {
for subpattern in subpatterns {
visitor.visit_pat(&subpattern.pattern);
PatKind::Wild
| PatKind::Binding { subpattern: None, .. }
| PatKind::Constant { value: _ }
| PatKind::Range(_)
| PatKind::Never
| PatKind::Error(_) => {}

PatKind::AscribeUserType { subpattern, .. }
| PatKind::Binding { subpattern: Some(subpattern), .. }
| PatKind::Deref { subpattern }
| PatKind::DerefPattern { subpattern, .. }
| PatKind::ExpandedConstant { subpattern, .. } => callback(subpattern),

PatKind::Variant { subpatterns, .. } | PatKind::Leaf { subpatterns } => {
for field_pat in subpatterns {
callback(&field_pat.pattern);
}
}
Constant { value: _ } => {}
ExpandedConstant { def_id: _, is_inline: _, subpattern } => visitor.visit_pat(subpattern),
Range(_) => {}
Slice { prefix, slice, suffix } | Array { prefix, slice, suffix } => {
for subpattern in prefix.iter() {
visitor.visit_pat(subpattern);
}
if let Some(pat) = slice {
visitor.visit_pat(pat);
}
for subpattern in suffix.iter() {
visitor.visit_pat(subpattern);

PatKind::Slice { prefix, slice, suffix } | PatKind::Array { prefix, slice, suffix } => {
for pat in prefix.iter().chain(slice.as_deref()).chain(suffix) {
callback(pat);
}
}
Or { pats } => {
for pat in pats.iter() {
visitor.visit_pat(pat);

PatKind::Or { pats } => {
for pat in pats {
callback(pat);
}
}
};
}
}
3 changes: 3 additions & 0 deletions compiler/rustc_transmute/src/layout/dfa.rs
Original file line number Diff line number Diff line change
@@ -55,6 +55,7 @@ where
#[derive(Hash, Eq, PartialEq, PartialOrd, Ord, Copy, Clone)]
pub(crate) struct State(u32);

#[cfg(test)]
#[derive(Hash, Eq, PartialEq, Clone, Copy)]
pub(crate) enum Transition<R>
where
@@ -70,6 +71,7 @@ impl fmt::Debug for State {
}
}

#[cfg(test)]
impl<R> fmt::Debug for Transition<R>
where
R: Ref,
@@ -166,6 +168,7 @@ impl State {
}
}

#[cfg(test)]
impl<R> From<nfa::Transition<R>> for Transition<R>
where
R: Ref,
2 changes: 1 addition & 1 deletion library/std/src/env.rs
Original file line number Diff line number Diff line change
@@ -333,7 +333,7 @@ impl Error for VarError {
///
/// Discussion of this unsafety on Unix may be found in:
///
/// - [Austin Group Bugzilla](https://austingroupbugs.net/view.php?id=188)
/// - [Austin Group Bugzilla (for POSIX)](https://austingroupbugs.net/view.php?id=188)
/// - [GNU C library Bugzilla](https://sourceware.org/bugzilla/show_bug.cgi?id=15607#c2)
///
/// To pass an environment variable to a child process, you can instead use [`Command::env`].
33 changes: 30 additions & 3 deletions library/std/src/process.rs
Original file line number Diff line number Diff line change
@@ -2018,9 +2018,9 @@ impl ExitCode {
///
/// Note that this has the same caveats as [`process::exit()`][exit], namely that this function
/// terminates the process immediately, so no destructors on the current stack or any other
/// thread's stack will be run. If a clean shutdown is needed, it is recommended to simply
/// return this ExitCode from the `main` function, as demonstrated in the [type
/// documentation](#examples).
/// thread's stack will be run. Also see those docs for some important notes on interop with C
/// code. If a clean shutdown is needed, it is recommended to simply return this ExitCode from
/// the `main` function, as demonstrated in the [type documentation](#examples).
///
/// # Differences from `process::exit()`
///
@@ -2326,6 +2326,33 @@ impl Child {
///
/// process::exit(0x0100);
/// ```
///
/// ### Safe interop with C code
///
/// On Unix, this function is currently implemented using the `exit` C function [`exit`][C-exit]. As
/// of C23, the C standard does not permit multiple threads to call `exit` concurrently. Rust
/// mitigates this with a lock, but if C code calls `exit`, that can still cause undefined behavior.
/// Note that returning from `main` is equivalent to calling `exit`.
///
/// Therefore, it is undefined behavior to have two concurrent threads perform the following
/// without synchronization:
/// - One thread calls Rust's `exit` function or returns from Rust's `main` function
/// - Another thread calls the C function `exit` or `quick_exit`, or returns from C's `main` function
///
/// Note that if a binary contains multiple copies of the Rust runtime (e.g., when combining
/// multiple `cdylib` or `staticlib`), they each have their own separate lock, so from the
/// perspective of code running in one of the Rust runtimes, the "outside" Rust code is basically C
/// code, and concurrent `exit` again causes undefined behavior.
///
/// Individual C implementations might provide more guarantees than the standard and permit concurrent
/// calls to `exit`; consult the documentation of your C implementation for details.
///
/// For some of the on-going discussion to make `exit` thread-safe in C, see:
/// - [Rust issue #126600](https://github.com/rust-lang/rust/issues/126600)
/// - [Austin Group Bugzilla (for POSIX)](https://austingroupbugs.net/view.php?id=1845)
/// - [GNU C library Bugzilla](https://sourceware.org/bugzilla/show_bug.cgi?id=31997)
///
/// [C-exit]: https://en.cppreference.com/w/c/program/exit
#[stable(feature = "rust1", since = "1.0.0")]
#[cfg_attr(not(test), rustc_diagnostic_item = "process_exit")]
pub fn exit(code: i32) -> ! {
2 changes: 1 addition & 1 deletion library/std/src/sys/fs/hermit.rs
Original file line number Diff line number Diff line change
@@ -396,7 +396,7 @@ impl File {
}

pub fn read_buf(&self, cursor: BorrowedCursor<'_>) -> io::Result<()> {
crate::io::default_read_buf(|buf| self.read(buf), cursor)
self.0.read_buf(cursor)
}

pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
17 changes: 16 additions & 1 deletion library/std/src/sys/pal/hermit/fd.rs
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@

use super::hermit_abi;
use crate::cmp;
use crate::io::{self, IoSlice, IoSliceMut, Read, SeekFrom};
use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut, Read, SeekFrom};
use crate::os::hermit::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd};
use crate::sys::{cvt, unsupported};
use crate::sys_common::{AsInner, FromInner, IntoInner};
@@ -23,6 +23,21 @@ impl FileDesc {
Ok(result as usize)
}

pub fn read_buf(&self, mut buf: BorrowedCursor<'_>) -> io::Result<()> {
// SAFETY: The `read` syscall does not read from the buffer, so it is
// safe to use `&mut [MaybeUninit<u8>]`.
let result = cvt(unsafe {
hermit_abi::read(
self.fd.as_raw_fd(),
buf.as_mut().as_mut_ptr() as *mut u8,
buf.capacity(),
)
})?;
// SAFETY: Exactly `result` bytes have been filled.
unsafe { buf.advance_unchecked(result as usize) };
Ok(())
}

pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
let ret = cvt(unsafe {
hermit_abi::readv(
5 changes: 1 addition & 4 deletions library/std/src/sys/stdio/unix.rs
Original file line number Diff line number Diff line change
@@ -3,9 +3,7 @@ use hermit_abi::{EBADF, STDERR_FILENO, STDIN_FILENO, STDOUT_FILENO};
#[cfg(target_family = "unix")]
use libc::{EBADF, STDERR_FILENO, STDIN_FILENO, STDOUT_FILENO};

#[cfg(target_family = "unix")]
use crate::io::BorrowedCursor;
use crate::io::{self, IoSlice, IoSliceMut};
use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut};
use crate::mem::ManuallyDrop;
#[cfg(target_os = "hermit")]
use crate::os::hermit::io::FromRawFd;
@@ -28,7 +26,6 @@ impl io::Read for Stdin {
unsafe { ManuallyDrop::new(FileDesc::from_raw_fd(STDIN_FILENO)).read(buf) }
}

#[cfg(not(target_os = "hermit"))]
fn read_buf(&mut self, buf: BorrowedCursor<'_>) -> io::Result<()> {
unsafe { ManuallyDrop::new(FileDesc::from_raw_fd(STDIN_FILENO)).read_buf(buf) }
}
5 changes: 3 additions & 2 deletions src/bootstrap/src/core/build_steps/setup.rs
Original file line number Diff line number Diff line change
@@ -214,8 +214,9 @@ fn setup_config_toml(path: &Path, profile: Profile, config: &Config) {

let latest_change_id = CONFIG_CHANGE_HISTORY.last().unwrap().change_id;
let settings = format!(
"# Includes one of the default files in {PROFILE_DIR}\n\
profile = \"{profile}\"\n\
"# See bootstrap.example.toml for documentation of available options\n\
#\n\
profile = \"{profile}\" # Includes one of the default files in {PROFILE_DIR}\n\
change-id = {latest_change_id}\n"
);

8 changes: 8 additions & 0 deletions tests/rustdoc-json/attrs/repr_align.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#![no_std]

//@ is "$.index[*][?(@.name=='Aligned')].attrs" '["#[attr = Repr([ReprAlign(Align(4 bytes))])]\n"]'
#[repr(align(4))]
pub struct Aligned {
a: i8,
b: i64,
}
18 changes: 18 additions & 0 deletions tests/rustdoc-json/attrs/repr_c.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#![no_std]

//@ is "$.index[*][?(@.name=='ReprCStruct')].attrs" '["#[attr = Repr([ReprC])]\n"]'
#[repr(C)]
pub struct ReprCStruct(pub i64);

//@ is "$.index[*][?(@.name=='ReprCEnum')].attrs" '["#[attr = Repr([ReprC])]\n"]'
#[repr(C)]
pub enum ReprCEnum {
First,
}

//@ is "$.index[*][?(@.name=='ReprCUnion')].attrs" '["#[attr = Repr([ReprC])]\n"]'
#[repr(C)]
pub union ReprCUnion {
pub left: i64,
pub right: u64,
}
78 changes: 78 additions & 0 deletions tests/rustdoc-json/attrs/repr_combination.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
#![no_std]

// Combinations of `#[repr(..)]` attributes.

//@ is "$.index[*][?(@.name=='ReprCI8')].attrs" '["#[attr = Repr([ReprC, ReprInt(SignedInt(I8))])]\n"]'
#[repr(C, i8)]
pub enum ReprCI8 {
First,
}

//@ is "$.index[*][?(@.name=='SeparateReprCI16')].attrs" '["#[attr = Repr([ReprC, ReprInt(SignedInt(I16))])]\n"]'
#[repr(C)]
#[repr(i16)]
pub enum SeparateReprCI16 {
First,
}

//@ is "$.index[*][?(@.name=='ReversedReprCUsize')].attrs" '["#[attr = Repr([ReprInt(UnsignedInt(Usize)), ReprC])]\n"]'
#[repr(usize, C)]
pub enum ReversedReprCUsize {
First,
}

//@ is "$.index[*][?(@.name=='ReprCPacked')].attrs" '["#[attr = Repr([ReprC, ReprPacked(Align(1 bytes))])]\n"]'
#[repr(C, packed)]
pub struct ReprCPacked {
a: i8,
b: i64,
}

//@ is "$.index[*][?(@.name=='SeparateReprCPacked')].attrs" '["#[attr = Repr([ReprC, ReprPacked(Align(2 bytes))])]\n"]'
#[repr(C)]
#[repr(packed(2))]
pub struct SeparateReprCPacked {
a: i8,
b: i64,
}

//@ is "$.index[*][?(@.name=='ReversedReprCPacked')].attrs" '["#[attr = Repr([ReprPacked(Align(2 bytes)), ReprC])]\n"]'
#[repr(packed(2), C)]
pub struct ReversedReprCPacked {
a: i8,
b: i64,
}

//@ is "$.index[*][?(@.name=='ReprCAlign')].attrs" '["#[attr = Repr([ReprC, ReprAlign(Align(16 bytes))])]\n"]'
#[repr(C, align(16))]
pub struct ReprCAlign {
a: i8,
b: i64,
}

//@ is "$.index[*][?(@.name=='SeparateReprCAlign')].attrs" '["#[attr = Repr([ReprC, ReprAlign(Align(2 bytes))])]\n"]'
#[repr(C)]
#[repr(align(2))]
pub struct SeparateReprCAlign {
a: i8,
b: i64,
}

//@ is "$.index[*][?(@.name=='ReversedReprCAlign')].attrs" '["#[attr = Repr([ReprAlign(Align(2 bytes)), ReprC])]\n"]'
#[repr(align(2), C)]
pub struct ReversedReprCAlign {
a: i8,
b: i64,
}

//@ is "$.index[*][?(@.name=='AlignedExplicitRepr')].attrs" '["#[attr = Repr([ReprC, ReprAlign(Align(16 bytes)), ReprInt(SignedInt(Isize))])]\n"]'
#[repr(C, align(16), isize)]
pub enum AlignedExplicitRepr {
First,
}

//@ is "$.index[*][?(@.name=='ReorderedAlignedExplicitRepr')].attrs" '["#[attr = Repr([ReprInt(SignedInt(Isize)), ReprC, ReprAlign(Align(16 bytes))])]\n"]'
#[repr(isize, C, align(16))]
pub enum ReorderedAlignedExplicitRepr {
First,
}
19 changes: 19 additions & 0 deletions tests/rustdoc-json/attrs/repr_int_enum.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#![no_std]

//@ is "$.index[*][?(@.name=='I8')].attrs" '["#[attr = Repr([ReprInt(SignedInt(I8))])]\n"]'
#[repr(i8)]
pub enum I8 {
First,
}

//@ is "$.index[*][?(@.name=='I32')].attrs" '["#[attr = Repr([ReprInt(SignedInt(I32))])]\n"]'
#[repr(i32)]
pub enum I32 {
First,
}

//@ is "$.index[*][?(@.name=='Usize')].attrs" '["#[attr = Repr([ReprInt(UnsignedInt(Usize))])]\n"]'
#[repr(usize)]
pub enum Usize {
First,
}
Loading
Loading