Skip to content

Commit c4b38a5

Browse files
committed
Auto merge of rust-lang#138653 - matthiaskrgr:rollup-fwwqmr7, r=matthiaskrgr
Rollup of 7 pull requests Successful merges: - rust-lang#136320 (exit: document interaction with C) - rust-lang#138080 (Leave a breadcrumb towards bootstrap config documentation in `bootstrap.toml`) - rust-lang#138301 (Implement `read_buf` for Hermit) - rust-lang#138569 (rustdoc-json: Add tests for `#[repr(...)]`) - rust-lang#138635 (Extract `for_each_immediate_subpat` from THIR pattern visitors) - rust-lang#138642 (Unvacation myself) - rust-lang#138644 (Add `#[cfg(test)]` for Transition in dfa in `rustc_transmute`) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 1370611 + f364f3e commit c4b38a5

File tree

16 files changed

+254
-59
lines changed

16 files changed

+254
-59
lines changed

compiler/rustc_middle/src/thir.rs

+2-21
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ use tracing::instrument;
2828
use crate::middle::region;
2929
use crate::mir::interpret::AllocId;
3030
use crate::mir::{self, BinOp, BorrowKind, FakeReadCause, UnOp};
31+
use crate::thir::visit::for_each_immediate_subpat;
3132
use crate::ty::adjustment::PointerCoercion;
3233
use crate::ty::layout::IntegerExt;
3334
use crate::ty::{
@@ -672,27 +673,7 @@ impl<'tcx> Pat<'tcx> {
672673
return;
673674
}
674675

675-
use PatKind::*;
676-
match &self.kind {
677-
Wild
678-
| Never
679-
| Range(..)
680-
| Binding { subpattern: None, .. }
681-
| Constant { .. }
682-
| Error(_) => {}
683-
AscribeUserType { subpattern, .. }
684-
| Binding { subpattern: Some(subpattern), .. }
685-
| Deref { subpattern }
686-
| DerefPattern { subpattern, .. }
687-
| ExpandedConstant { subpattern, .. } => subpattern.walk_(it),
688-
Leaf { subpatterns } | Variant { subpatterns, .. } => {
689-
subpatterns.iter().for_each(|field| field.pattern.walk_(it))
690-
}
691-
Or { pats } => pats.iter().for_each(|p| p.walk_(it)),
692-
Array { box prefix, slice, box suffix } | Slice { box prefix, slice, box suffix } => {
693-
prefix.iter().chain(slice.as_deref()).chain(suffix.iter()).for_each(|p| p.walk_(it))
694-
}
695-
}
676+
for_each_immediate_subpat(self, |p| p.walk_(it));
696677
}
697678

698679
/// Whether the pattern has a `PatKind::Error` nested within.

compiler/rustc_middle/src/thir/visit.rs

+34-25
Original file line numberDiff line numberDiff line change
@@ -240,36 +240,45 @@ pub fn walk_pat<'thir, 'tcx: 'thir, V: Visitor<'thir, 'tcx>>(
240240
visitor: &mut V,
241241
pat: &'thir Pat<'tcx>,
242242
) {
243-
use PatKind::*;
243+
for_each_immediate_subpat(pat, |p| visitor.visit_pat(p));
244+
}
245+
246+
/// Invokes `callback` on each immediate subpattern of `pat`, if any.
247+
/// A building block for assembling THIR pattern visitors.
248+
pub(crate) fn for_each_immediate_subpat<'a, 'tcx>(
249+
pat: &'a Pat<'tcx>,
250+
mut callback: impl FnMut(&'a Pat<'tcx>),
251+
) {
244252
match &pat.kind {
245-
AscribeUserType { subpattern, ascription: _ }
246-
| Deref { subpattern }
247-
| DerefPattern { subpattern, .. }
248-
| Binding { subpattern: Some(subpattern), .. } => visitor.visit_pat(subpattern),
249-
Binding { .. } | Wild | Never | Error(_) => {}
250-
Variant { subpatterns, adt_def: _, args: _, variant_index: _ } | Leaf { subpatterns } => {
251-
for subpattern in subpatterns {
252-
visitor.visit_pat(&subpattern.pattern);
253+
PatKind::Wild
254+
| PatKind::Binding { subpattern: None, .. }
255+
| PatKind::Constant { value: _ }
256+
| PatKind::Range(_)
257+
| PatKind::Never
258+
| PatKind::Error(_) => {}
259+
260+
PatKind::AscribeUserType { subpattern, .. }
261+
| PatKind::Binding { subpattern: Some(subpattern), .. }
262+
| PatKind::Deref { subpattern }
263+
| PatKind::DerefPattern { subpattern, .. }
264+
| PatKind::ExpandedConstant { subpattern, .. } => callback(subpattern),
265+
266+
PatKind::Variant { subpatterns, .. } | PatKind::Leaf { subpatterns } => {
267+
for field_pat in subpatterns {
268+
callback(&field_pat.pattern);
253269
}
254270
}
255-
Constant { value: _ } => {}
256-
ExpandedConstant { def_id: _, is_inline: _, subpattern } => visitor.visit_pat(subpattern),
257-
Range(_) => {}
258-
Slice { prefix, slice, suffix } | Array { prefix, slice, suffix } => {
259-
for subpattern in prefix.iter() {
260-
visitor.visit_pat(subpattern);
261-
}
262-
if let Some(pat) = slice {
263-
visitor.visit_pat(pat);
264-
}
265-
for subpattern in suffix.iter() {
266-
visitor.visit_pat(subpattern);
271+
272+
PatKind::Slice { prefix, slice, suffix } | PatKind::Array { prefix, slice, suffix } => {
273+
for pat in prefix.iter().chain(slice.as_deref()).chain(suffix) {
274+
callback(pat);
267275
}
268276
}
269-
Or { pats } => {
270-
for pat in pats.iter() {
271-
visitor.visit_pat(pat);
277+
278+
PatKind::Or { pats } => {
279+
for pat in pats {
280+
callback(pat);
272281
}
273282
}
274-
};
283+
}
275284
}

compiler/rustc_transmute/src/layout/dfa.rs

+3
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ where
5555
#[derive(Hash, Eq, PartialEq, PartialOrd, Ord, Copy, Clone)]
5656
pub(crate) struct State(u32);
5757

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

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

171+
#[cfg(test)]
169172
impl<R> From<nfa::Transition<R>> for Transition<R>
170173
where
171174
R: Ref,

library/std/src/env.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -333,7 +333,7 @@ impl Error for VarError {
333333
///
334334
/// Discussion of this unsafety on Unix may be found in:
335335
///
336-
/// - [Austin Group Bugzilla](https://austingroupbugs.net/view.php?id=188)
336+
/// - [Austin Group Bugzilla (for POSIX)](https://austingroupbugs.net/view.php?id=188)
337337
/// - [GNU C library Bugzilla](https://sourceware.org/bugzilla/show_bug.cgi?id=15607#c2)
338338
///
339339
/// To pass an environment variable to a child process, you can instead use [`Command::env`].

library/std/src/process.rs

+30-3
Original file line numberDiff line numberDiff line change
@@ -2018,9 +2018,9 @@ impl ExitCode {
20182018
///
20192019
/// Note that this has the same caveats as [`process::exit()`][exit], namely that this function
20202020
/// terminates the process immediately, so no destructors on the current stack or any other
2021-
/// thread's stack will be run. If a clean shutdown is needed, it is recommended to simply
2022-
/// return this ExitCode from the `main` function, as demonstrated in the [type
2023-
/// documentation](#examples).
2021+
/// thread's stack will be run. Also see those docs for some important notes on interop with C
2022+
/// code. If a clean shutdown is needed, it is recommended to simply return this ExitCode from
2023+
/// the `main` function, as demonstrated in the [type documentation](#examples).
20242024
///
20252025
/// # Differences from `process::exit()`
20262026
///
@@ -2326,6 +2326,33 @@ impl Child {
23262326
///
23272327
/// process::exit(0x0100);
23282328
/// ```
2329+
///
2330+
/// ### Safe interop with C code
2331+
///
2332+
/// On Unix, this function is currently implemented using the `exit` C function [`exit`][C-exit]. As
2333+
/// of C23, the C standard does not permit multiple threads to call `exit` concurrently. Rust
2334+
/// mitigates this with a lock, but if C code calls `exit`, that can still cause undefined behavior.
2335+
/// Note that returning from `main` is equivalent to calling `exit`.
2336+
///
2337+
/// Therefore, it is undefined behavior to have two concurrent threads perform the following
2338+
/// without synchronization:
2339+
/// - One thread calls Rust's `exit` function or returns from Rust's `main` function
2340+
/// - Another thread calls the C function `exit` or `quick_exit`, or returns from C's `main` function
2341+
///
2342+
/// Note that if a binary contains multiple copies of the Rust runtime (e.g., when combining
2343+
/// multiple `cdylib` or `staticlib`), they each have their own separate lock, so from the
2344+
/// perspective of code running in one of the Rust runtimes, the "outside" Rust code is basically C
2345+
/// code, and concurrent `exit` again causes undefined behavior.
2346+
///
2347+
/// Individual C implementations might provide more guarantees than the standard and permit concurrent
2348+
/// calls to `exit`; consult the documentation of your C implementation for details.
2349+
///
2350+
/// For some of the on-going discussion to make `exit` thread-safe in C, see:
2351+
/// - [Rust issue #126600](https://github.com/rust-lang/rust/issues/126600)
2352+
/// - [Austin Group Bugzilla (for POSIX)](https://austingroupbugs.net/view.php?id=1845)
2353+
/// - [GNU C library Bugzilla](https://sourceware.org/bugzilla/show_bug.cgi?id=31997)
2354+
///
2355+
/// [C-exit]: https://en.cppreference.com/w/c/program/exit
23292356
#[stable(feature = "rust1", since = "1.0.0")]
23302357
#[cfg_attr(not(test), rustc_diagnostic_item = "process_exit")]
23312358
pub fn exit(code: i32) -> ! {

library/std/src/sys/fs/hermit.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -396,7 +396,7 @@ impl File {
396396
}
397397

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

402402
pub fn write(&self, buf: &[u8]) -> io::Result<usize> {

library/std/src/sys/pal/hermit/fd.rs

+16-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

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

26+
pub fn read_buf(&self, mut buf: BorrowedCursor<'_>) -> io::Result<()> {
27+
// SAFETY: The `read` syscall does not read from the buffer, so it is
28+
// safe to use `&mut [MaybeUninit<u8>]`.
29+
let result = cvt(unsafe {
30+
hermit_abi::read(
31+
self.fd.as_raw_fd(),
32+
buf.as_mut().as_mut_ptr() as *mut u8,
33+
buf.capacity(),
34+
)
35+
})?;
36+
// SAFETY: Exactly `result` bytes have been filled.
37+
unsafe { buf.advance_unchecked(result as usize) };
38+
Ok(())
39+
}
40+
2641
pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
2742
let ret = cvt(unsafe {
2843
hermit_abi::readv(

library/std/src/sys/stdio/unix.rs

+1-4
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,7 @@ use hermit_abi::{EBADF, STDERR_FILENO, STDIN_FILENO, STDOUT_FILENO};
33
#[cfg(target_family = "unix")]
44
use libc::{EBADF, STDERR_FILENO, STDIN_FILENO, STDOUT_FILENO};
55

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

31-
#[cfg(not(target_os = "hermit"))]
3229
fn read_buf(&mut self, buf: BorrowedCursor<'_>) -> io::Result<()> {
3330
unsafe { ManuallyDrop::new(FileDesc::from_raw_fd(STDIN_FILENO)).read_buf(buf) }
3431
}

src/bootstrap/src/core/build_steps/setup.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -214,8 +214,9 @@ fn setup_config_toml(path: &Path, profile: Profile, config: &Config) {
214214

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

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#![no_std]
2+
3+
//@ is "$.index[*][?(@.name=='Aligned')].attrs" '["#[attr = Repr([ReprAlign(Align(4 bytes))])]\n"]'
4+
#[repr(align(4))]
5+
pub struct Aligned {
6+
a: i8,
7+
b: i64,
8+
}

tests/rustdoc-json/attrs/repr_c.rs

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#![no_std]
2+
3+
//@ is "$.index[*][?(@.name=='ReprCStruct')].attrs" '["#[attr = Repr([ReprC])]\n"]'
4+
#[repr(C)]
5+
pub struct ReprCStruct(pub i64);
6+
7+
//@ is "$.index[*][?(@.name=='ReprCEnum')].attrs" '["#[attr = Repr([ReprC])]\n"]'
8+
#[repr(C)]
9+
pub enum ReprCEnum {
10+
First,
11+
}
12+
13+
//@ is "$.index[*][?(@.name=='ReprCUnion')].attrs" '["#[attr = Repr([ReprC])]\n"]'
14+
#[repr(C)]
15+
pub union ReprCUnion {
16+
pub left: i64,
17+
pub right: u64,
18+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
#![no_std]
2+
3+
// Combinations of `#[repr(..)]` attributes.
4+
5+
//@ is "$.index[*][?(@.name=='ReprCI8')].attrs" '["#[attr = Repr([ReprC, ReprInt(SignedInt(I8))])]\n"]'
6+
#[repr(C, i8)]
7+
pub enum ReprCI8 {
8+
First,
9+
}
10+
11+
//@ is "$.index[*][?(@.name=='SeparateReprCI16')].attrs" '["#[attr = Repr([ReprC, ReprInt(SignedInt(I16))])]\n"]'
12+
#[repr(C)]
13+
#[repr(i16)]
14+
pub enum SeparateReprCI16 {
15+
First,
16+
}
17+
18+
//@ is "$.index[*][?(@.name=='ReversedReprCUsize')].attrs" '["#[attr = Repr([ReprInt(UnsignedInt(Usize)), ReprC])]\n"]'
19+
#[repr(usize, C)]
20+
pub enum ReversedReprCUsize {
21+
First,
22+
}
23+
24+
//@ is "$.index[*][?(@.name=='ReprCPacked')].attrs" '["#[attr = Repr([ReprC, ReprPacked(Align(1 bytes))])]\n"]'
25+
#[repr(C, packed)]
26+
pub struct ReprCPacked {
27+
a: i8,
28+
b: i64,
29+
}
30+
31+
//@ is "$.index[*][?(@.name=='SeparateReprCPacked')].attrs" '["#[attr = Repr([ReprC, ReprPacked(Align(2 bytes))])]\n"]'
32+
#[repr(C)]
33+
#[repr(packed(2))]
34+
pub struct SeparateReprCPacked {
35+
a: i8,
36+
b: i64,
37+
}
38+
39+
//@ is "$.index[*][?(@.name=='ReversedReprCPacked')].attrs" '["#[attr = Repr([ReprPacked(Align(2 bytes)), ReprC])]\n"]'
40+
#[repr(packed(2), C)]
41+
pub struct ReversedReprCPacked {
42+
a: i8,
43+
b: i64,
44+
}
45+
46+
//@ is "$.index[*][?(@.name=='ReprCAlign')].attrs" '["#[attr = Repr([ReprC, ReprAlign(Align(16 bytes))])]\n"]'
47+
#[repr(C, align(16))]
48+
pub struct ReprCAlign {
49+
a: i8,
50+
b: i64,
51+
}
52+
53+
//@ is "$.index[*][?(@.name=='SeparateReprCAlign')].attrs" '["#[attr = Repr([ReprC, ReprAlign(Align(2 bytes))])]\n"]'
54+
#[repr(C)]
55+
#[repr(align(2))]
56+
pub struct SeparateReprCAlign {
57+
a: i8,
58+
b: i64,
59+
}
60+
61+
//@ is "$.index[*][?(@.name=='ReversedReprCAlign')].attrs" '["#[attr = Repr([ReprAlign(Align(2 bytes)), ReprC])]\n"]'
62+
#[repr(align(2), C)]
63+
pub struct ReversedReprCAlign {
64+
a: i8,
65+
b: i64,
66+
}
67+
68+
//@ is "$.index[*][?(@.name=='AlignedExplicitRepr')].attrs" '["#[attr = Repr([ReprC, ReprAlign(Align(16 bytes)), ReprInt(SignedInt(Isize))])]\n"]'
69+
#[repr(C, align(16), isize)]
70+
pub enum AlignedExplicitRepr {
71+
First,
72+
}
73+
74+
//@ is "$.index[*][?(@.name=='ReorderedAlignedExplicitRepr')].attrs" '["#[attr = Repr([ReprInt(SignedInt(Isize)), ReprC, ReprAlign(Align(16 bytes))])]\n"]'
75+
#[repr(isize, C, align(16))]
76+
pub enum ReorderedAlignedExplicitRepr {
77+
First,
78+
}
+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#![no_std]
2+
3+
//@ is "$.index[*][?(@.name=='I8')].attrs" '["#[attr = Repr([ReprInt(SignedInt(I8))])]\n"]'
4+
#[repr(i8)]
5+
pub enum I8 {
6+
First,
7+
}
8+
9+
//@ is "$.index[*][?(@.name=='I32')].attrs" '["#[attr = Repr([ReprInt(SignedInt(I32))])]\n"]'
10+
#[repr(i32)]
11+
pub enum I32 {
12+
First,
13+
}
14+
15+
//@ is "$.index[*][?(@.name=='Usize')].attrs" '["#[attr = Repr([ReprInt(UnsignedInt(Usize))])]\n"]'
16+
#[repr(usize)]
17+
pub enum Usize {
18+
First,
19+
}

0 commit comments

Comments
 (0)