Skip to content

Commit 78bc0a5

Browse files
committedApr 14, 2024·
Auto merge of #123913 - matthiaskrgr:rollup-w8stnwl, r=matthiaskrgr
Rollup of 8 pull requests Successful merges: - #123651 (Thread local updates for idiomatic examples) - #123699 (run-make-support: tidy up support library) - #123779 (OpenBSD fix long socket addresses) - #123875 (Doc: replace x with y for hexa-decimal fmt) - #123879 (Add missing `unsafe` to some internal `std` functions) - #123889 (reduce tidy overheads in run-make checks) - #123898 (Generic associated consts: Check regions earlier when comparing impl with trait item def) - #123902 (compiletest: Update rustfix to 0.8.1) r? `@ghost` `@rustbot` modify labels: rollup
2 parents a3269e9 + ab65c68 commit 78bc0a5

File tree

17 files changed

+289
-206
lines changed

17 files changed

+289
-206
lines changed
 

‎Cargo.lock

+15-3
Original file line numberDiff line numberDiff line change
@@ -766,7 +766,7 @@ dependencies = [
766766
"miropt-test-tools",
767767
"once_cell",
768768
"regex",
769-
"rustfix",
769+
"rustfix 0.8.1",
770770
"serde",
771771
"serde_json",
772772
"tracing",
@@ -4855,6 +4855,18 @@ dependencies = [
48554855
"serde_json",
48564856
]
48574857

4858+
[[package]]
4859+
name = "rustfix"
4860+
version = "0.8.1"
4861+
source = "registry+https://github.com/rust-lang/crates.io-index"
4862+
checksum = "81864b097046da5df3758fdc6e4822bbb70afa06317e8ca45ea1b51cb8c5e5a4"
4863+
dependencies = [
4864+
"serde",
4865+
"serde_json",
4866+
"thiserror",
4867+
"tracing",
4868+
]
4869+
48584870
[[package]]
48594871
name = "rustfmt-config_proc_macro"
48604872
version = "0.3.0"
@@ -5896,7 +5908,7 @@ dependencies = [
58965908
"prettydiff",
58975909
"regex",
58985910
"rustc_version",
5899-
"rustfix",
5911+
"rustfix 0.6.1",
59005912
"serde",
59015913
"serde_json",
59025914
"tempfile",
@@ -5923,7 +5935,7 @@ dependencies = [
59235935
"prettydiff",
59245936
"regex",
59255937
"rustc_version",
5926-
"rustfix",
5938+
"rustfix 0.6.1",
59275939
"serde",
59285940
"serde_json",
59295941
"spanned",

‎compiler/rustc_hir_analysis/src/check/compare_impl_item.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -1723,6 +1723,7 @@ pub(super) fn compare_impl_const_raw(
17231723

17241724
compare_number_of_generics(tcx, impl_const_item, trait_const_item, false)?;
17251725
compare_generic_param_kinds(tcx, impl_const_item, trait_const_item, false)?;
1726+
check_region_bounds_on_impl_item(tcx, impl_const_item, trait_const_item, false)?;
17261727
compare_const_predicate_entailment(tcx, impl_const_item, trait_const_item, impl_trait_ref)
17271728
}
17281729

@@ -1763,8 +1764,6 @@ fn compare_const_predicate_entailment<'tcx>(
17631764
let impl_ct_predicates = tcx.predicates_of(impl_ct.def_id);
17641765
let trait_ct_predicates = tcx.predicates_of(trait_ct.def_id);
17651766

1766-
check_region_bounds_on_impl_item(tcx, impl_ct, trait_ct, false)?;
1767-
17681767
// The predicates declared by the impl definition, the trait and the
17691768
// associated const in the trait are assumed.
17701769
let impl_predicates = tcx.predicates_of(impl_ct_predicates.parent.unwrap());
@@ -1866,6 +1865,7 @@ pub(super) fn compare_impl_ty<'tcx>(
18661865
let _: Result<(), ErrorGuaranteed> = try {
18671866
compare_number_of_generics(tcx, impl_ty, trait_ty, false)?;
18681867
compare_generic_param_kinds(tcx, impl_ty, trait_ty, false)?;
1868+
check_region_bounds_on_impl_item(tcx, impl_ty, trait_ty, false)?;
18691869
compare_type_predicate_entailment(tcx, impl_ty, trait_ty, impl_trait_ref)?;
18701870
check_type_bounds(tcx, trait_ty, impl_ty, impl_trait_ref)?;
18711871
};
@@ -1886,8 +1886,6 @@ fn compare_type_predicate_entailment<'tcx>(
18861886
let impl_ty_predicates = tcx.predicates_of(impl_ty.def_id);
18871887
let trait_ty_predicates = tcx.predicates_of(trait_ty.def_id);
18881888

1889-
check_region_bounds_on_impl_item(tcx, impl_ty, trait_ty, false)?;
1890-
18911889
let impl_ty_own_bounds = impl_ty_predicates.instantiate_own(tcx, impl_args);
18921890
if impl_ty_own_bounds.len() == 0 {
18931891
// Nothing to check.

‎library/core/src/fmt/mod.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -860,10 +860,10 @@ pub trait Binary {
860860
/// Basic usage with `i32`:
861861
///
862862
/// ```
863-
/// let x = 42; // 42 is '2a' in hex
863+
/// let y = 42; // 42 is '2a' in hex
864864
///
865-
/// assert_eq!(format!("{x:x}"), "2a");
866-
/// assert_eq!(format!("{x:#x}"), "0x2a");
865+
/// assert_eq!(format!("{y:x}"), "2a");
866+
/// assert_eq!(format!("{y:#x}"), "0x2a");
867867
///
868868
/// assert_eq!(format!("{:x}", -16), "fffffff0");
869869
/// ```
@@ -915,10 +915,10 @@ pub trait LowerHex {
915915
/// Basic usage with `i32`:
916916
///
917917
/// ```
918-
/// let x = 42; // 42 is '2A' in hex
918+
/// let y = 42; // 42 is '2A' in hex
919919
///
920-
/// assert_eq!(format!("{x:X}"), "2A");
921-
/// assert_eq!(format!("{x:#X}"), "0x2A");
920+
/// assert_eq!(format!("{y:X}"), "2A");
921+
/// assert_eq!(format!("{y:#X}"), "0x2A");
922922
///
923923
/// assert_eq!(format!("{:X}", -16), "FFFFFFF0");
924924
/// ```

‎library/std/src/os/unix/net/addr.rs

+10
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,16 @@ impl SocketAddr {
107107
addr: libc::sockaddr_un,
108108
mut len: libc::socklen_t,
109109
) -> io::Result<SocketAddr> {
110+
if cfg!(target_os = "openbsd") {
111+
// on OpenBSD, getsockname(2) returns the actual size of the socket address,
112+
// and not the len of the content. Figure out the length for ourselves.
113+
// https://marc.info/?l=openbsd-bugs&m=170105481926736&w=2
114+
let sun_path: &[u8] =
115+
unsafe { mem::transmute::<&[libc::c_char], &[u8]>(&addr.sun_path) };
116+
len = core::slice::memchr::memchr(0, sun_path)
117+
.map_or(len, |new_len| (new_len + sun_path_offset(&addr)) as libc::socklen_t);
118+
}
119+
110120
if len == 0 {
111121
// When there is a datagram from unnamed unix socket
112122
// linux returns zero bytes of address

‎library/std/src/sys/pal/unix/thread.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -709,7 +709,7 @@ mod cgroups {
709709
// is created in an application with big thread-local storage requirements.
710710
// See #6233 for rationale and details.
711711
#[cfg(all(target_os = "linux", target_env = "gnu"))]
712-
fn min_stack_size(attr: *const libc::pthread_attr_t) -> usize {
712+
unsafe fn min_stack_size(attr: *const libc::pthread_attr_t) -> usize {
713713
// We use dlsym to avoid an ELF version dependency on GLIBC_PRIVATE. (#23628)
714714
// We shouldn't really be using such an internal symbol, but there's currently
715715
// no other way to account for the TLS size.
@@ -723,11 +723,11 @@ fn min_stack_size(attr: *const libc::pthread_attr_t) -> usize {
723723

724724
// No point in looking up __pthread_get_minstack() on non-glibc platforms.
725725
#[cfg(all(not(all(target_os = "linux", target_env = "gnu")), not(target_os = "netbsd")))]
726-
fn min_stack_size(_: *const libc::pthread_attr_t) -> usize {
726+
unsafe fn min_stack_size(_: *const libc::pthread_attr_t) -> usize {
727727
libc::PTHREAD_STACK_MIN
728728
}
729729

730730
#[cfg(target_os = "netbsd")]
731-
fn min_stack_size(_: *const libc::pthread_attr_t) -> usize {
731+
unsafe fn min_stack_size(_: *const libc::pthread_attr_t) -> usize {
732732
2048 // just a guess
733733
}

‎library/std/src/sys/sync/rwlock/queue.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@ impl Node {
202202
fn prepare(&mut self) {
203203
// Fall back to creating an unnamed `Thread` handle to allow locking in
204204
// TLS destructors.
205-
self.thread.get_or_init(|| thread::try_current().unwrap_or_else(|| Thread::new(None)));
205+
self.thread.get_or_init(|| thread::try_current().unwrap_or_else(Thread::new_unnamed));
206206
self.completed = AtomicBool::new(false);
207207
}
208208

‎library/std/src/thread/local.rs

+32-28
Original file line numberDiff line numberDiff line change
@@ -53,25 +53,25 @@ use crate::fmt;
5353
/// # Examples
5454
///
5555
/// ```
56-
/// use std::cell::RefCell;
56+
/// use std::cell::Cell;
5757
/// use std::thread;
5858
///
59-
/// thread_local!(static FOO: RefCell<u32> = RefCell::new(1));
59+
/// thread_local!(static FOO: Cell<u32> = Cell::new(1));
6060
///
61-
/// FOO.with_borrow(|v| assert_eq!(*v, 1));
62-
/// FOO.with_borrow_mut(|v| *v = 2);
61+
/// assert_eq!(FOO.get(), 1);
62+
/// FOO.set(2);
6363
///
6464
/// // each thread starts out with the initial value of 1
6565
/// let t = thread::spawn(move|| {
66-
/// FOO.with_borrow(|v| assert_eq!(*v, 1));
67-
/// FOO.with_borrow_mut(|v| *v = 3);
66+
/// assert_eq!(FOO.get(), 1);
67+
/// FOO.set(3);
6868
/// });
6969
///
7070
/// // wait for the thread to complete and bail out on panic
7171
/// t.join().unwrap();
7272
///
7373
/// // we retain our original value of 2 despite the child thread
74-
/// FOO.with_borrow(|v| assert_eq!(*v, 2));
74+
/// assert_eq!(FOO.get(), 2);
7575
/// ```
7676
///
7777
/// # Platform-specific behavior
@@ -141,15 +141,16 @@ impl<T: 'static> fmt::Debug for LocalKey<T> {
141141
/// Publicity and attributes for each static are allowed. Example:
142142
///
143143
/// ```
144-
/// use std::cell::RefCell;
144+
/// use std::cell::{Cell, RefCell};
145+
///
145146
/// thread_local! {
146-
/// pub static FOO: RefCell<u32> = RefCell::new(1);
147+
/// pub static FOO: Cell<u32> = Cell::new(1);
147148
///
148-
/// static BAR: RefCell<f32> = RefCell::new(1.0);
149+
/// static BAR: RefCell<Vec<f32>> = RefCell::new(vec![1.0, 2.0]);
149150
/// }
150151
///
151-
/// FOO.with_borrow(|v| assert_eq!(*v, 1));
152-
/// BAR.with_borrow(|v| assert_eq!(*v, 1.0));
152+
/// assert_eq!(FOO.get(), 1);
153+
/// BAR.with_borrow(|v| assert_eq!(v[1], 2.0));
153154
/// ```
154155
///
155156
/// Note that only shared references (`&T`) to the inner data may be obtained, so a
@@ -164,12 +165,13 @@ impl<T: 'static> fmt::Debug for LocalKey<T> {
164165
/// track any additional state.
165166
///
166167
/// ```
167-
/// use std::cell::Cell;
168+
/// use std::cell::RefCell;
169+
///
168170
/// thread_local! {
169-
/// pub static FOO: Cell<u32> = const { Cell::new(1) };
171+
/// pub static FOO: RefCell<Vec<u32>> = const { RefCell::new(Vec::new()) };
170172
/// }
171173
///
172-
/// assert_eq!(FOO.get(), 1);
174+
/// FOO.with_borrow(|v| assert_eq!(v.len(), 0));
173175
/// ```
174176
///
175177
/// See [`LocalKey` documentation][`std::thread::LocalKey`] for more
@@ -279,10 +281,9 @@ impl<T: 'static> LocalKey<T> {
279281
where
280282
F: FnOnce(&T) -> R,
281283
{
282-
unsafe {
283-
let thread_local = (self.inner)(None).ok_or(AccessError)?;
284-
Ok(f(thread_local))
285-
}
284+
// SAFETY: `inner` is safe to call within the lifetime of the thread
285+
let thread_local = unsafe { (self.inner)(None).ok_or(AccessError)? };
286+
Ok(f(thread_local))
286287
}
287288

288289
/// Acquires a reference to the value in this TLS key, initializing it with
@@ -301,14 +302,17 @@ impl<T: 'static> LocalKey<T> {
301302
where
302303
F: FnOnce(Option<T>, &T) -> R,
303304
{
304-
unsafe {
305-
let mut init = Some(init);
306-
let reference = (self.inner)(Some(&mut init)).expect(
305+
let mut init = Some(init);
306+
307+
// SAFETY: `inner` is safe to call within the lifetime of the thread
308+
let reference = unsafe {
309+
(self.inner)(Some(&mut init)).expect(
307310
"cannot access a Thread Local Storage value \
308311
during or after destruction",
309-
);
310-
f(init, reference)
311-
}
312+
)
313+
};
314+
315+
f(init, reference)
312316
}
313317
}
314318

@@ -377,7 +381,7 @@ impl<T: 'static> LocalKey<Cell<T>> {
377381
where
378382
T: Copy,
379383
{
380-
self.with(|cell| cell.get())
384+
self.with(Cell::get)
381385
}
382386

383387
/// Takes the contained value, leaving `Default::default()` in its place.
@@ -407,7 +411,7 @@ impl<T: 'static> LocalKey<Cell<T>> {
407411
where
408412
T: Default,
409413
{
410-
self.with(|cell| cell.take())
414+
self.with(Cell::take)
411415
}
412416

413417
/// Replaces the contained value, returning the old value.
@@ -578,7 +582,7 @@ impl<T: 'static> LocalKey<RefCell<T>> {
578582
where
579583
T: Default,
580584
{
581-
self.with(|cell| cell.take())
585+
self.with(RefCell::take)
582586
}
583587

584588
/// Replaces the contained value, returning the old value.

‎library/std/src/thread/mod.rs

+20-13
Original file line numberDiff line numberDiff line change
@@ -487,9 +487,11 @@ impl Builder {
487487
amt
488488
});
489489

490-
let my_thread = Thread::new(name.map(|name| {
491-
CString::new(name).expect("thread name may not contain interior null bytes")
492-
}));
490+
let my_thread = name.map_or_else(Thread::new_unnamed, |name| unsafe {
491+
Thread::new(
492+
CString::new(name).expect("thread name may not contain interior null bytes"),
493+
)
494+
});
493495
let their_thread = my_thread.clone();
494496

495497
let my_packet: Arc<Packet<'scope, T>> = Arc::new(Packet {
@@ -711,7 +713,7 @@ pub(crate) fn set_current(thread: Thread) {
711713
/// In contrast to the public `current` function, this will not panic if called
712714
/// from inside a TLS destructor.
713715
pub(crate) fn try_current() -> Option<Thread> {
714-
CURRENT.try_with(|current| current.get_or_init(|| Thread::new(None)).clone()).ok()
716+
CURRENT.try_with(|current| current.get_or_init(|| Thread::new_unnamed()).clone()).ok()
715717
}
716718

717719
/// Gets a handle to the thread that invokes it.
@@ -1307,21 +1309,26 @@ pub struct Thread {
13071309
}
13081310

13091311
impl Thread {
1310-
// Used only internally to construct a thread object without spawning
1311-
pub(crate) fn new(name: Option<CString>) -> Thread {
1312-
if let Some(name) = name {
1313-
Self::new_inner(ThreadName::Other(name))
1314-
} else {
1315-
Self::new_inner(ThreadName::Unnamed)
1316-
}
1312+
/// Used only internally to construct a thread object without spawning.
1313+
///
1314+
/// # Safety
1315+
/// `name` must be valid UTF-8.
1316+
pub(crate) unsafe fn new(name: CString) -> Thread {
1317+
unsafe { Self::new_inner(ThreadName::Other(name)) }
1318+
}
1319+
1320+
pub(crate) fn new_unnamed() -> Thread {
1321+
unsafe { Self::new_inner(ThreadName::Unnamed) }
13171322
}
13181323

13191324
// Used in runtime to construct main thread
13201325
pub(crate) fn new_main() -> Thread {
1321-
Self::new_inner(ThreadName::Main)
1326+
unsafe { Self::new_inner(ThreadName::Main) }
13221327
}
13231328

1324-
fn new_inner(name: ThreadName) -> Thread {
1329+
/// # Safety
1330+
/// If `name` is `ThreadName::Other(_)`, the contained string must be valid UTF-8.
1331+
unsafe fn new_inner(name: ThreadName) -> Thread {
13251332
// We have to use `unsafe` here to construct the `Parker` in-place,
13261333
// which is required for the UNIX implementation.
13271334
//

‎src/tools/compiletest/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ tracing-subscriber = { version = "0.3.3", default-features = false, features = [
2020
regex = "1.0"
2121
serde = { version = "1.0", features = ["derive"] }
2222
serde_json = "1.0"
23-
rustfix = "0.6.0"
23+
rustfix = "0.8.1"
2424
once_cell = "1.16.0"
2525
walkdir = "2"
2626
glob = "0.3.0"

‎src/tools/run-make-support/src/cc.rs

+3-36
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use std::env;
22
use std::path::Path;
3-
use std::process::{Command, Output};
3+
use std::process::Command;
44

55
use crate::{bin_name, cygpath_windows, handle_failed_output, is_msvc, is_windows, tmp_dir, uname};
66

@@ -19,6 +19,8 @@ pub struct Cc {
1919
cmd: Command,
2020
}
2121

22+
crate::impl_common_helpers!(Cc);
23+
2224
impl Cc {
2325
/// Construct a new platform-specific C compiler invocation.
2426
///
@@ -43,22 +45,6 @@ impl Cc {
4345
self
4446
}
4547

46-
/// Add a *platform-and-compiler-specific* argument. Please consult the docs for the various
47-
/// possible C compilers on the various platforms to check which arguments are legal for
48-
/// which compiler.
49-
pub fn arg(&mut self, flag: &str) -> &mut Self {
50-
self.cmd.arg(flag);
51-
self
52-
}
53-
54-
/// Add multiple *platform-and-compiler-specific* arguments. Please consult the docs for the
55-
/// various possible C compilers on the various platforms to check which arguments are legal
56-
/// for which compiler.
57-
pub fn args(&mut self, args: &[&str]) -> &mut Self {
58-
self.cmd.args(args);
59-
self
60-
}
61-
6248
/// Specify `-o` or `-Fe`/`-Fo` depending on platform/compiler. This assumes that the executable
6349
/// is under `$TMPDIR`.
6450
pub fn out_exe(&mut self, name: &str) -> &mut Self {
@@ -85,25 +71,6 @@ impl Cc {
8571

8672
self
8773
}
88-
89-
/// Run the constructed C invocation command and assert that it is successfully run.
90-
#[track_caller]
91-
pub fn run(&mut self) -> Output {
92-
let caller_location = std::panic::Location::caller();
93-
let caller_line_number = caller_location.line();
94-
95-
let output = self.cmd.output().unwrap();
96-
if !output.status.success() {
97-
handle_failed_output(&format!("{:#?}", self.cmd), output, caller_line_number);
98-
}
99-
output
100-
}
101-
102-
/// Inspect what the underlying [`Command`] is up to the current construction.
103-
pub fn inspect(&mut self, f: impl FnOnce(&Command)) -> &mut Self {
104-
f(&self.cmd);
105-
self
106-
}
10774
}
10875

10976
/// `EXTRACFLAGS`

‎src/tools/run-make-support/src/lib.rs

+134-5
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
//! `run-make-support` is a support library for run-make tests. It provides command wrappers and
2+
//! convenience utility functions to help test writers reduce duplication. The support library
3+
//! notably is built via cargo: this means that if your test wants some non-trivial utility, such
4+
//! as `object` or `wasmparser`, they can be re-exported and be made available through this library.
5+
16
pub mod cc;
27
pub mod run;
38
pub mod rustc;
@@ -82,7 +87,7 @@ pub fn cygpath_windows<P: AsRef<Path>>(path: P) -> String {
8287
cygpath.arg(path.as_ref());
8388
let output = cygpath.output().unwrap();
8489
if !output.status.success() {
85-
handle_failed_output(&format!("{:#?}", cygpath), output, caller_line_number);
90+
handle_failed_output(&cygpath, output, caller_line_number);
8691
}
8792
let s = String::from_utf8(output.stdout).unwrap();
8893
// cygpath -w can attach a newline
@@ -98,18 +103,18 @@ pub fn uname() -> String {
98103
let mut uname = Command::new("uname");
99104
let output = uname.output().unwrap();
100105
if !output.status.success() {
101-
handle_failed_output(&format!("{:#?}", uname), output, caller_line_number);
106+
handle_failed_output(&uname, output, caller_line_number);
102107
}
103108
String::from_utf8(output.stdout).unwrap()
104109
}
105110

106-
fn handle_failed_output(cmd: &str, output: Output, caller_line_number: u32) -> ! {
111+
fn handle_failed_output(cmd: &Command, output: Output, caller_line_number: u32) -> ! {
107112
if output.status.success() {
108-
eprintln!("command incorrectly succeeded at line {caller_line_number}");
113+
eprintln!("command unexpectedly succeeded at line {caller_line_number}");
109114
} else {
110115
eprintln!("command failed at line {caller_line_number}");
111116
}
112-
eprintln!("{cmd}");
117+
eprintln!("{cmd:?}");
113118
eprintln!("output status: `{}`", output.status);
114119
eprintln!("=== STDOUT ===\n{}\n\n", String::from_utf8(output.stdout).unwrap());
115120
eprintln!("=== STDERR ===\n{}\n\n", String::from_utf8(output.stderr).unwrap());
@@ -129,3 +134,127 @@ pub fn set_host_rpath(cmd: &mut Command) {
129134
env::join_paths(paths.iter()).unwrap()
130135
});
131136
}
137+
138+
/// Implement common helpers for command wrappers. This assumes that the command wrapper is a struct
139+
/// containing a `cmd: Command` field. The provided helpers are:
140+
///
141+
/// 1. Generic argument acceptors: `arg` and `args` (delegated to [`Command`]). These are intended
142+
/// to be *fallback* argument acceptors, when specific helpers don't make sense. Prefer to add
143+
/// new specific helper methods over relying on these generic argument providers.
144+
/// 2. Environment manipulation methods: `env`, `env_remove` and `env_clear`: these delegate to
145+
/// methods of the same name on [`Command`].
146+
/// 3. Output and execution: `output`, `run` and `run_fail` are provided. `output` waits for the
147+
/// command to finish running and returns the process's [`Output`]. `run` and `run_fail` are
148+
/// higher-level convenience methods which waits for the command to finish running and assert
149+
/// that the command successfully ran or failed as expected. Prefer `run` and `run_fail` when
150+
/// possible.
151+
///
152+
/// Example usage:
153+
///
154+
/// ```ignore (illustrative)
155+
/// struct CommandWrapper { cmd: Command }
156+
///
157+
/// crate::impl_common_helpers!(CommandWrapper);
158+
///
159+
/// impl CommandWrapper {
160+
/// // ... additional specific helper methods
161+
/// }
162+
/// ```
163+
///
164+
/// [`Command`]: ::std::process::Command
165+
/// [`Output`]: ::std::process::Output
166+
macro_rules! impl_common_helpers {
167+
($wrapper: ident) => {
168+
impl $wrapper {
169+
/// Specify an environment variable.
170+
pub fn env<K, V>(&mut self, key: K, value: V) -> &mut Self
171+
where
172+
K: AsRef<::std::ffi::OsStr>,
173+
V: AsRef<::std::ffi::OsStr>,
174+
{
175+
self.cmd.env(key, value);
176+
self
177+
}
178+
179+
/// Remove an environmental variable.
180+
pub fn env_remove<K>(&mut self, key: K) -> &mut Self
181+
where
182+
K: AsRef<::std::ffi::OsStr>,
183+
{
184+
self.cmd.env_remove(key);
185+
self
186+
}
187+
188+
/// Clear all environmental variables.
189+
pub fn env_var(&mut self) -> &mut Self {
190+
self.cmd.env_clear();
191+
self
192+
}
193+
194+
/// Generic command argument provider. Prefer specific helper methods if possible.
195+
/// Note that for some executables, arguments might be platform specific. For C/C++
196+
/// compilers, arguments might be platform *and* compiler specific.
197+
pub fn arg<S>(&mut self, arg: S) -> &mut Self
198+
where
199+
S: AsRef<::std::ffi::OsStr>,
200+
{
201+
self.cmd.arg(arg);
202+
self
203+
}
204+
205+
/// Generic command arguments provider. Prefer specific helper methods if possible.
206+
/// Note that for some executables, arguments might be platform specific. For C/C++
207+
/// compilers, arguments might be platform *and* compiler specific.
208+
pub fn args<S>(&mut self, args: &[S]) -> &mut Self
209+
where
210+
S: AsRef<::std::ffi::OsStr>,
211+
{
212+
self.cmd.args(args);
213+
self
214+
}
215+
216+
/// Inspect what the underlying [`Command`][::std::process::Command] is up to the
217+
/// current construction.
218+
pub fn inspect<I>(&mut self, inspector: I) -> &mut Self
219+
where
220+
I: FnOnce(&::std::process::Command),
221+
{
222+
inspector(&self.cmd);
223+
self
224+
}
225+
226+
/// Get the [`Output`][::std::process::Output] of the finished process.
227+
pub fn output(&mut self) -> ::std::process::Output {
228+
self.cmd.output().expect("failed to get output of finished process")
229+
}
230+
231+
/// Run the constructed command and assert that it is successfully run.
232+
#[track_caller]
233+
pub fn run(&mut self) -> ::std::process::Output {
234+
let caller_location = ::std::panic::Location::caller();
235+
let caller_line_number = caller_location.line();
236+
237+
let output = self.cmd.output().unwrap();
238+
if !output.status.success() {
239+
handle_failed_output(&self.cmd, output, caller_line_number);
240+
}
241+
output
242+
}
243+
244+
/// Run the constructed command and assert that it does not successfully run.
245+
#[track_caller]
246+
pub fn run_fail(&mut self) -> ::std::process::Output {
247+
let caller_location = ::std::panic::Location::caller();
248+
let caller_line_number = caller_location.line();
249+
250+
let output = self.cmd.output().unwrap();
251+
if output.status.success() {
252+
handle_failed_output(&self.cmd, output, caller_line_number);
253+
}
254+
output
255+
}
256+
}
257+
};
258+
}
259+
260+
pub(crate) use impl_common_helpers;

‎src/tools/run-make-support/src/run.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ pub fn run(name: &str) -> Output {
4545

4646
let (cmd, output) = run_common(name);
4747
if !output.status.success() {
48-
handle_failed_output(&format!("{:#?}", cmd), output, caller_line_number);
48+
handle_failed_output(&cmd, output, caller_line_number);
4949
}
5050
output
5151
}
@@ -58,7 +58,7 @@ pub fn run_fail(name: &str) -> Output {
5858

5959
let (cmd, output) = run_common(name);
6060
if output.status.success() {
61-
handle_failed_output(&format!("{:#?}", cmd), output, caller_line_number);
61+
handle_failed_output(&cmd, output, caller_line_number);
6262
}
6363
output
6464
}

‎src/tools/run-make-support/src/rustc.rs

+4-57
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use std::env;
2-
use std::ffi::{OsStr, OsString};
2+
use std::ffi::OsString;
33
use std::path::Path;
44
use std::process::{Command, Output};
55

@@ -21,6 +21,8 @@ pub struct Rustc {
2121
cmd: Command,
2222
}
2323

24+
crate::impl_common_helpers!(Rustc);
25+
2426
fn setup_common() -> Command {
2527
let rustc = env::var("RUSTC").unwrap();
2628
let mut cmd = Command::new(rustc);
@@ -133,12 +135,6 @@ impl Rustc {
133135
self
134136
}
135137

136-
/// Generic command argument provider. Use `.arg("-Zname")` over `.arg("-Z").arg("arg")`.
137-
pub fn arg<S: AsRef<OsStr>>(&mut self, arg: S) -> &mut Self {
138-
self.cmd.arg(arg);
139-
self
140-
}
141-
142138
/// Specify the crate type.
143139
pub fn crate_type(&mut self, crate_type: &str) -> &mut Self {
144140
self.cmd.arg("--crate-type");
@@ -153,64 +149,15 @@ impl Rustc {
153149
self
154150
}
155151

156-
/// Generic command arguments provider. Use `.arg("-Zname")` over `.arg("-Z").arg("arg")`.
157-
pub fn args<S: AsRef<OsStr>>(&mut self, args: &[S]) -> &mut Self {
158-
self.cmd.args(args);
159-
self
160-
}
161-
162-
pub fn env(&mut self, name: impl AsRef<OsStr>, value: impl AsRef<OsStr>) -> &mut Self {
163-
self.cmd.env(name, value);
164-
self
165-
}
166-
167-
// Command inspection, output and running helper methods
168-
169-
/// Get the [`Output`][std::process::Output] of the finished `rustc` process.
170-
pub fn output(&mut self) -> Output {
171-
self.cmd.output().unwrap()
172-
}
173-
174-
/// Run the constructed `rustc` command and assert that it is successfully run.
175-
#[track_caller]
176-
pub fn run(&mut self) -> Output {
177-
let caller_location = std::panic::Location::caller();
178-
let caller_line_number = caller_location.line();
179-
180-
let output = self.cmd.output().unwrap();
181-
if !output.status.success() {
182-
handle_failed_output(&format!("{:#?}", self.cmd), output, caller_line_number);
183-
}
184-
output
185-
}
186-
187-
#[track_caller]
188-
pub fn run_fail(&mut self) -> Output {
189-
let caller_location = std::panic::Location::caller();
190-
let caller_line_number = caller_location.line();
191-
192-
let output = self.cmd.output().unwrap();
193-
if output.status.success() {
194-
handle_failed_output(&format!("{:#?}", self.cmd), output, caller_line_number);
195-
}
196-
output
197-
}
198-
199152
#[track_caller]
200153
pub fn run_fail_assert_exit_code(&mut self, code: i32) -> Output {
201154
let caller_location = std::panic::Location::caller();
202155
let caller_line_number = caller_location.line();
203156

204157
let output = self.cmd.output().unwrap();
205158
if output.status.code().unwrap() != code {
206-
handle_failed_output(&format!("{:#?}", self.cmd), output, caller_line_number);
159+
handle_failed_output(&self.cmd, output, caller_line_number);
207160
}
208161
output
209162
}
210-
211-
/// Inspect what the underlying [`Command`] is up to the current construction.
212-
pub fn inspect(&mut self, f: impl FnOnce(&Command)) -> &mut Self {
213-
f(&self.cmd);
214-
self
215-
}
216163
}

‎src/tools/run-make-support/src/rustdoc.rs

+3-21
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
use std::env;
2-
use std::ffi::OsStr;
32
use std::path::Path;
43
use std::process::{Command, Output};
54

@@ -20,6 +19,8 @@ pub struct Rustdoc {
2019
cmd: Command,
2120
}
2221

22+
crate::impl_common_helpers!(Rustdoc);
23+
2324
fn setup_common() -> Command {
2425
let rustdoc = env::var("RUSTDOC").unwrap();
2526
let mut cmd = Command::new(rustdoc);
@@ -61,33 +62,14 @@ impl Rustdoc {
6162
self
6263
}
6364

64-
/// Generic command argument provider. Use `.arg("-Zname")` over `.arg("-Z").arg("arg")`.
65-
pub fn arg<S: AsRef<OsStr>>(&mut self, arg: S) -> &mut Self {
66-
self.cmd.arg(arg);
67-
self
68-
}
69-
70-
/// Run the build `rustdoc` command and assert that the run is successful.
71-
#[track_caller]
72-
pub fn run(&mut self) -> Output {
73-
let caller_location = std::panic::Location::caller();
74-
let caller_line_number = caller_location.line();
75-
76-
let output = self.cmd.output().unwrap();
77-
if !output.status.success() {
78-
handle_failed_output(&format!("{:#?}", self.cmd), output, caller_line_number);
79-
}
80-
output
81-
}
82-
8365
#[track_caller]
8466
pub fn run_fail_assert_exit_code(&mut self, code: i32) -> Output {
8567
let caller_location = std::panic::Location::caller();
8668
let caller_line_number = caller_location.line();
8769

8870
let output = self.cmd.output().unwrap();
8971
if output.status.code().unwrap() != code {
90-
handle_failed_output(&format!("{:#?}", self.cmd), output, caller_line_number);
72+
handle_failed_output(&self.cmd, output, caller_line_number);
9173
}
9274
output
9375
}

‎src/tools/tidy/src/run_make_tests.rs

+24-9
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,26 @@ use std::io::Write;
66
use std::path::{Path, PathBuf};
77

88
pub fn check(tests_path: &Path, src_path: &Path, bless: bool, bad: &mut bool) {
9+
let mut is_sorted = true;
10+
911
let allowed_makefiles = {
10-
let allowed_makefiles = include_str!("allowed_run_make_makefiles.txt");
11-
let allowed_makefiles = allowed_makefiles.lines().collect::<Vec<_>>();
12-
let is_sorted = allowed_makefiles.windows(2).all(|w| w[0] < w[1]);
12+
let mut total_lines = 0;
13+
let mut prev_line = "";
14+
let allowed_makefiles: BTreeSet<&str> = include_str!("allowed_run_make_makefiles.txt")
15+
.lines()
16+
.map(|line| {
17+
total_lines += 1;
18+
19+
if prev_line > line {
20+
is_sorted = false;
21+
}
22+
23+
prev_line = line;
24+
25+
line
26+
})
27+
.collect();
28+
1329
if !is_sorted && !bless {
1430
tidy_error!(
1531
bad,
@@ -18,17 +34,16 @@ pub fn check(tests_path: &Path, src_path: &Path, bless: bool, bad: &mut bool) {
1834
`x test tidy --bless`"
1935
);
2036
}
21-
let allowed_makefiles_unique =
22-
allowed_makefiles.iter().map(ToString::to_string).collect::<BTreeSet<String>>();
23-
if allowed_makefiles_unique.len() != allowed_makefiles.len() {
37+
if allowed_makefiles.len() != total_lines {
2438
tidy_error!(
2539
bad,
2640
"`src/tools/tidy/src/allowed_run_make_makefiles.txt` contains duplicate entries, \
2741
likely because you modified it manually, please only update it with command \
2842
`x test tidy --bless`"
2943
);
3044
}
31-
allowed_makefiles_unique
45+
46+
allowed_makefiles
3247
};
3348

3449
let mut remaining_makefiles = allowed_makefiles.clone();
@@ -48,7 +63,7 @@ pub fn check(tests_path: &Path, src_path: &Path, bless: bool, bad: &mut bool) {
4863
let makefile_path = entry.path().strip_prefix(&tests_path).unwrap();
4964
let makefile_path = makefile_path.to_str().unwrap().replace('\\', "/");
5065

51-
if !remaining_makefiles.remove(&makefile_path) {
66+
if !remaining_makefiles.remove(makefile_path.as_str()) {
5267
tidy_error!(
5368
bad,
5469
"found run-make Makefile not permitted in \
@@ -64,7 +79,7 @@ pub fn check(tests_path: &Path, src_path: &Path, bless: bool, bad: &mut bool) {
6479
// Our data must remain up to date, so they must be removed from
6580
// `src/tools/tidy/src/allowed_run_make_makefiles.txt`.
6681
// This can be done automatically on --bless, or else a tidy error will be issued.
67-
if bless && !remaining_makefiles.is_empty() {
82+
if bless && (!remaining_makefiles.is_empty() || !is_sorted) {
6883
let tidy_src = src_path.join("tools").join("tidy").join("src");
6984
let org_file_path = tidy_src.join("allowed_run_make_makefiles.txt");
7085
let temp_file_path = tidy_src.join("blessed_allowed_run_make_makefiles.txt");

‎tests/ui/generic-const-items/compare-impl-item.rs

+7-4
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,10 @@ trait Trait<P> {
66
const B<const K: u64, const Q: u64>: u64;
77
const C<T>: T;
88
const D<const N: usize>: usize;
9+
const E<'a>: &'a ();
910

10-
const E: usize;
11-
const F<T: PartialEq>: ();
11+
const F: usize;
12+
const G<T: PartialEq>: ();
1213
}
1314

1415
impl<P> Trait<P> for () {
@@ -20,11 +21,13 @@ impl<P> Trait<P> for () {
2021
//~^ ERROR const `C` has 0 type parameters but its trait declaration has 1 type parameter
2122
const D<const N: u16>: u16 = N;
2223
//~^ ERROR const `D` has an incompatible generic parameter for trait `Trait`
24+
const E: &'static () = &();
25+
//~^ ERROR lifetime parameters or bounds on const `E` do not match the trait declaration
2326

24-
const E: usize = 1024
27+
const F: usize = 1024
2528
where
2629
P: Copy; //~ ERROR impl has stricter requirements than trait
27-
const F<T: Eq>: () = (); //~ ERROR impl has stricter requirements than trait
30+
const G<T: Eq>: () = (); //~ ERROR impl has stricter requirements than trait
2831
}
2932

3033
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error[E0049]: const `A` has 1 type parameter but its trait declaration has 0 type parameters
2-
--> $DIR/compare-impl-item.rs:15:13
2+
--> $DIR/compare-impl-item.rs:16:13
33
|
44
LL | const A: ();
55
| - expected 0 type parameters
@@ -8,7 +8,7 @@ LL | const A<T>: () = ();
88
| ^ found 1 type parameter
99

1010
error[E0049]: const `B` has 1 const parameter but its trait declaration has 2 const parameters
11-
--> $DIR/compare-impl-item.rs:17:13
11+
--> $DIR/compare-impl-item.rs:18:13
1212
|
1313
LL | const B<const K: u64, const Q: u64>: u64;
1414
| ------------ ------------
@@ -19,7 +19,7 @@ LL | const B<const K: u64>: u64 = 0;
1919
| ^^^^^^^^^^^^ found 1 const parameter
2020

2121
error[E0049]: const `C` has 0 type parameters but its trait declaration has 1 type parameter
22-
--> $DIR/compare-impl-item.rs:19:13
22+
--> $DIR/compare-impl-item.rs:20:13
2323
|
2424
LL | const C<T>: T;
2525
| - expected 1 type parameter
@@ -28,7 +28,7 @@ LL | const C<'a>: &'a str = "";
2828
| ^^ found 0 type parameters
2929

3030
error[E0053]: const `D` has an incompatible generic parameter for trait `Trait`
31-
--> $DIR/compare-impl-item.rs:21:13
31+
--> $DIR/compare-impl-item.rs:22:13
3232
|
3333
LL | trait Trait<P> {
3434
| -----
@@ -42,25 +42,34 @@ LL | impl<P> Trait<P> for () {
4242
LL | const D<const N: u16>: u16 = N;
4343
| ^^^^^^^^^^^^ found const parameter of type `u16`
4444

45+
error[E0195]: lifetime parameters or bounds on const `E` do not match the trait declaration
46+
--> $DIR/compare-impl-item.rs:24:12
47+
|
48+
LL | const E<'a>: &'a ();
49+
| ---- lifetimes in impl do not match this const in trait
50+
...
51+
LL | const E: &'static () = &();
52+
| ^ lifetimes do not match const in trait
53+
4554
error[E0276]: impl has stricter requirements than trait
46-
--> $DIR/compare-impl-item.rs:26:12
55+
--> $DIR/compare-impl-item.rs:29:12
4756
|
48-
LL | const E: usize;
49-
| -------------- definition of `E` from trait
57+
LL | const F: usize;
58+
| -------------- definition of `F` from trait
5059
...
5160
LL | P: Copy;
5261
| ^^^^ impl has extra requirement `P: Copy`
5362

5463
error[E0276]: impl has stricter requirements than trait
55-
--> $DIR/compare-impl-item.rs:27:16
64+
--> $DIR/compare-impl-item.rs:30:16
5665
|
57-
LL | const F<T: PartialEq>: ();
58-
| ------------------------- definition of `F` from trait
66+
LL | const G<T: PartialEq>: ();
67+
| ------------------------- definition of `G` from trait
5968
...
60-
LL | const F<T: Eq>: () = ();
69+
LL | const G<T: Eq>: () = ();
6170
| ^^ impl has extra requirement `T: Eq`
6271

63-
error: aborting due to 6 previous errors
72+
error: aborting due to 7 previous errors
6473

65-
Some errors have detailed explanations: E0049, E0053, E0276.
74+
Some errors have detailed explanations: E0049, E0053, E0195, E0276.
6675
For more information about an error, try `rustc --explain E0049`.

0 commit comments

Comments
 (0)
Please sign in to comment.