Skip to content

Commit 83d0a94

Browse files
committed
Auto merge of rust-lang#123545 - matthiaskrgr:rollup-vyx8cfv, r=matthiaskrgr
Rollup of 4 pull requests Successful merges: - rust-lang#114788 (impl get_mut_or_init and get_mut_or_try_init for OnceCell and OnceLock) - rust-lang#122291 (Stabilize `const_caller_location` and `const_location_fields`) - rust-lang#123357 (CI: Redirect stderr to stdout to order GHA logs) - rust-lang#123504 (bootstrap: split cargo-miri test into separate Step) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 01f7f3a + d9727d1 commit 83d0a94

File tree

13 files changed

+221
-37
lines changed

13 files changed

+221
-37
lines changed

.github/workflows/ci.yml

+3-3
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ jobs:
156156
run: src/ci/scripts/verify-stable-version-number.sh
157157
if: success() && !env.SKIP_JOB
158158
- name: run the build
159-
run: src/ci/scripts/run-build-from-ci.sh
159+
run: src/ci/scripts/run-build-from-ci.sh 2>&1
160160
env:
161161
AWS_ACCESS_KEY_ID: "${{ env.CACHES_AWS_ACCESS_KEY_ID }}"
162162
AWS_SECRET_ACCESS_KEY: "${{ secrets[format('AWS_SECRET_ACCESS_KEY_{0}', env.CACHES_AWS_ACCESS_KEY_ID)] }}"
@@ -566,7 +566,7 @@ jobs:
566566
run: src/ci/scripts/verify-stable-version-number.sh
567567
if: success() && !env.SKIP_JOB
568568
- name: run the build
569-
run: src/ci/scripts/run-build-from-ci.sh
569+
run: src/ci/scripts/run-build-from-ci.sh 2>&1
570570
env:
571571
AWS_ACCESS_KEY_ID: "${{ env.CACHES_AWS_ACCESS_KEY_ID }}"
572572
AWS_SECRET_ACCESS_KEY: "${{ secrets[format('AWS_SECRET_ACCESS_KEY_{0}', env.CACHES_AWS_ACCESS_KEY_ID)] }}"
@@ -705,7 +705,7 @@ jobs:
705705
run: src/ci/scripts/verify-stable-version-number.sh
706706
if: success() && !env.SKIP_JOB
707707
- name: run the build
708-
run: src/ci/scripts/run-build-from-ci.sh
708+
run: src/ci/scripts/run-build-from-ci.sh 2>&1
709709
env:
710710
AWS_ACCESS_KEY_ID: "${{ env.CACHES_AWS_ACCESS_KEY_ID }}"
711711
AWS_SECRET_ACCESS_KEY: "${{ secrets[format('AWS_SECRET_ACCESS_KEY_{0}', env.CACHES_AWS_ACCESS_KEY_ID)] }}"

library/core/src/cell/once.rs

+84-9
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,42 @@ impl<T> OnceCell<T> {
164164
}
165165
}
166166

167+
/// Gets the mutable reference of the contents of the cell,
168+
/// initializing it with `f` if the cell was empty.
169+
///
170+
/// # Panics
171+
///
172+
/// If `f` panics, the panic is propagated to the caller, and the cell
173+
/// remains uninitialized.
174+
///
175+
/// # Examples
176+
///
177+
/// ```
178+
/// #![feature(once_cell_get_mut)]
179+
///
180+
/// use std::cell::OnceCell;
181+
///
182+
/// let mut cell = OnceCell::new();
183+
/// let value = cell.get_mut_or_init(|| 92);
184+
/// assert_eq!(*value, 92);
185+
///
186+
/// *value += 2;
187+
/// assert_eq!(*value, 94);
188+
///
189+
/// let value = cell.get_mut_or_init(|| unreachable!());
190+
/// assert_eq!(*value, 94);
191+
/// ```
192+
#[inline]
193+
#[unstable(feature = "once_cell_get_mut", issue = "121641")]
194+
pub fn get_mut_or_init<F>(&mut self, f: F) -> &mut T
195+
where
196+
F: FnOnce() -> T,
197+
{
198+
match self.get_mut_or_try_init(|| Ok::<T, !>(f())) {
199+
Ok(val) => val,
200+
}
201+
}
202+
167203
/// Gets the contents of the cell, initializing it with `f` if
168204
/// the cell was empty. If the cell was empty and `f` failed, an
169205
/// error is returned.
@@ -200,16 +236,55 @@ impl<T> OnceCell<T> {
200236
if let Some(val) = self.get() {
201237
return Ok(val);
202238
}
203-
/// Avoid inlining the initialization closure into the common path that fetches
204-
/// the already initialized value
205-
#[cold]
206-
fn outlined_call<F, T, E>(f: F) -> Result<T, E>
207-
where
208-
F: FnOnce() -> Result<T, E>,
209-
{
210-
f()
239+
self.try_init(f)
240+
}
241+
242+
/// Gets the mutable reference of the contents of the cell, initializing
243+
/// it with `f` if the cell was empty. If the cell was empty and `f` failed,
244+
/// an error is returned.
245+
///
246+
/// # Panics
247+
///
248+
/// If `f` panics, the panic is propagated to the caller, and the cell
249+
/// remains uninitialized.
250+
///
251+
/// # Examples
252+
///
253+
/// ```
254+
/// #![feature(once_cell_get_mut)]
255+
///
256+
/// use std::cell::OnceCell;
257+
///
258+
/// let mut cell: OnceCell<u32> = OnceCell::new();
259+
///
260+
/// // Failed initializers do not change the value
261+
/// assert!(cell.get_mut_or_try_init(|| "not a number!".parse()).is_err());
262+
/// assert!(cell.get().is_none());
263+
///
264+
/// let value = cell.get_mut_or_try_init(|| "1234".parse());
265+
/// assert_eq!(value, Ok(&mut 1234));
266+
/// *value.unwrap() += 2;
267+
/// assert_eq!(cell.get(), Some(&1236))
268+
/// ```
269+
#[unstable(feature = "once_cell_get_mut", issue = "121641")]
270+
pub fn get_mut_or_try_init<F, E>(&mut self, f: F) -> Result<&mut T, E>
271+
where
272+
F: FnOnce() -> Result<T, E>,
273+
{
274+
if self.get().is_none() {
275+
self.try_init(f)?;
211276
}
212-
let val = outlined_call(f)?;
277+
Ok(self.get_mut().unwrap())
278+
}
279+
280+
// Avoid inlining the initialization closure into the common path that fetches
281+
// the already initialized value
282+
#[cold]
283+
fn try_init<F, E>(&self, f: F) -> Result<&T, E>
284+
where
285+
F: FnOnce() -> Result<T, E>,
286+
{
287+
let val = f()?;
213288
// Note that *some* forms of reentrant initialization might lead to
214289
// UB (see `reentrant_init` test). I believe that just removing this
215290
// `panic`, while keeping `try_insert` would be sound, but it seems

library/core/src/intrinsics.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1128,7 +1128,7 @@ extern "rust-intrinsic" {
11281128
/// any safety invariants.
11291129
///
11301130
/// Consider using [`core::panic::Location::caller`] instead.
1131-
#[rustc_const_unstable(feature = "const_caller_location", issue = "76156")]
1131+
#[rustc_const_stable(feature = "const_caller_location", since = "CURRENT_RUSTC_VERSION")]
11321132
#[rustc_safe_intrinsic]
11331133
#[rustc_nounwind]
11341134
pub fn caller_location() -> &'static crate::panic::Location<'static>;

library/core/src/lib.rs

-1
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,6 @@
125125
#![feature(const_array_into_iter_constructors)]
126126
#![feature(const_bigint_helper_methods)]
127127
#![feature(const_black_box)]
128-
#![feature(const_caller_location)]
129128
#![feature(const_cell_into_inner)]
130129
#![feature(const_char_from_u32_unchecked)]
131130
#![feature(const_eval_select)]

library/core/src/panic/location.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ impl<'a> Location<'a> {
8181
/// ```
8282
#[must_use]
8383
#[stable(feature = "track_caller", since = "1.46.0")]
84-
#[rustc_const_unstable(feature = "const_caller_location", issue = "76156")]
84+
#[rustc_const_stable(feature = "const_caller_location", since = "CURRENT_RUSTC_VERSION")]
8585
#[track_caller]
8686
#[inline]
8787
pub const fn caller() -> &'static Location<'static> {
@@ -123,7 +123,7 @@ impl<'a> Location<'a> {
123123
/// ```
124124
#[must_use]
125125
#[stable(feature = "panic_hooks", since = "1.10.0")]
126-
#[rustc_const_unstable(feature = "const_location_fields", issue = "102911")]
126+
#[rustc_const_stable(feature = "const_location_fields", since = "CURRENT_RUSTC_VERSION")]
127127
#[inline]
128128
pub const fn file(&self) -> &str {
129129
self.file
@@ -148,7 +148,7 @@ impl<'a> Location<'a> {
148148
/// ```
149149
#[must_use]
150150
#[stable(feature = "panic_hooks", since = "1.10.0")]
151-
#[rustc_const_unstable(feature = "const_location_fields", issue = "102911")]
151+
#[rustc_const_stable(feature = "const_location_fields", since = "CURRENT_RUSTC_VERSION")]
152152
#[inline]
153153
pub const fn line(&self) -> u32 {
154154
self.line
@@ -173,7 +173,7 @@ impl<'a> Location<'a> {
173173
/// ```
174174
#[must_use]
175175
#[stable(feature = "panic_col", since = "1.25.0")]
176-
#[rustc_const_unstable(feature = "const_location_fields", issue = "102911")]
176+
#[rustc_const_stable(feature = "const_location_fields", since = "CURRENT_RUSTC_VERSION")]
177177
#[inline]
178178
pub const fn column(&self) -> u32 {
179179
self.col

library/core/tests/lib.rs

-2
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
#![feature(const_align_offset)]
1212
#![feature(const_align_of_val_raw)]
1313
#![feature(const_black_box)]
14-
#![feature(const_caller_location)]
1514
#![feature(const_cell_into_inner)]
1615
#![feature(const_hash)]
1716
#![feature(const_heap)]
@@ -25,7 +24,6 @@
2524
#![cfg_attr(not(bootstrap), feature(const_three_way_compare))]
2625
#![feature(const_trait_impl)]
2726
#![feature(const_likely)]
28-
#![feature(const_location_fields)]
2927
#![feature(core_intrinsics)]
3028
#![feature(core_io_borrowed_buf)]
3129
#![feature(core_private_bignum)]

library/std/src/sync/once_lock.rs

+81
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,46 @@ impl<T> OnceLock<T> {
252252
}
253253
}
254254

255+
/// Gets the mutable reference of the contents of the cell, initializing
256+
/// it with `f` if the cell was empty.
257+
///
258+
/// Many threads may call `get_mut_or_init` concurrently with different
259+
/// initializing functions, but it is guaranteed that only one function
260+
/// will be executed.
261+
///
262+
/// # Panics
263+
///
264+
/// If `f` panics, the panic is propagated to the caller, and the cell
265+
/// remains uninitialized.
266+
///
267+
/// # Examples
268+
///
269+
/// ```
270+
/// #![feature(once_cell_get_mut)]
271+
///
272+
/// use std::sync::OnceLock;
273+
///
274+
/// let mut cell = OnceLock::new();
275+
/// let value = cell.get_mut_or_init(|| 92);
276+
/// assert_eq!(*value, 92);
277+
///
278+
/// *value += 2;
279+
/// assert_eq!(*value, 94);
280+
///
281+
/// let value = cell.get_mut_or_init(|| unreachable!());
282+
/// assert_eq!(*value, 94);
283+
/// ```
284+
#[inline]
285+
#[unstable(feature = "once_cell_get_mut", issue = "121641")]
286+
pub fn get_mut_or_init<F>(&mut self, f: F) -> &mut T
287+
where
288+
F: FnOnce() -> T,
289+
{
290+
match self.get_mut_or_try_init(|| Ok::<T, !>(f())) {
291+
Ok(val) => val,
292+
}
293+
}
294+
255295
/// Gets the contents of the cell, initializing it with `f` if
256296
/// the cell was empty. If the cell was empty and `f` failed, an
257297
/// error is returned.
@@ -303,6 +343,47 @@ impl<T> OnceLock<T> {
303343
Ok(unsafe { self.get_unchecked() })
304344
}
305345

346+
/// Gets the mutable reference of the contents of the cell, initializing
347+
/// it with `f` if the cell was empty. If the cell was empty and `f` failed,
348+
/// an error is returned.
349+
///
350+
/// # Panics
351+
///
352+
/// If `f` panics, the panic is propagated to the caller, and
353+
/// the cell remains uninitialized.
354+
///
355+
/// # Examples
356+
///
357+
/// ```
358+
/// #![feature(once_cell_get_mut)]
359+
///
360+
/// use std::sync::OnceLock;
361+
///
362+
/// let mut cell: OnceLock<u32> = OnceLock::new();
363+
///
364+
/// // Failed initializers do not change the value
365+
/// assert!(cell.get_mut_or_try_init(|| "not a number!".parse()).is_err());
366+
/// assert!(cell.get().is_none());
367+
///
368+
/// let value = cell.get_mut_or_try_init(|| "1234".parse());
369+
/// assert_eq!(value, Ok(&mut 1234));
370+
/// *value.unwrap() += 2;
371+
/// assert_eq!(cell.get(), Some(&1236))
372+
/// ```
373+
#[inline]
374+
#[unstable(feature = "once_cell_get_mut", issue = "121641")]
375+
pub fn get_mut_or_try_init<F, E>(&mut self, f: F) -> Result<&mut T, E>
376+
where
377+
F: FnOnce() -> Result<T, E>,
378+
{
379+
if self.get().is_none() {
380+
self.initialize(f)?;
381+
}
382+
debug_assert!(self.is_initialized());
383+
// SAFETY: The inner value has been initialized
384+
Ok(unsafe { self.get_unchecked_mut() })
385+
}
386+
306387
/// Consumes the `OnceLock`, returning the wrapped value. Returns
307388
/// `None` if the cell was empty.
308389
///

src/bootstrap/src/core/build_steps/test.rs

+35-4
Original file line numberDiff line numberDiff line change
@@ -597,7 +597,7 @@ impl Step for Miri {
597597
builder.ensure(compile::Std::new(target_compiler, host));
598598
let host_sysroot = builder.sysroot(target_compiler);
599599

600-
// # Run `cargo test`.
600+
// Run `cargo test`.
601601
// This is with the Miri crate, so it uses the host compiler.
602602
let mut cargo = tool::prepare_tool_cargo(
603603
builder,
@@ -652,15 +652,46 @@ impl Step for Miri {
652652
builder.run(&mut cargo);
653653
}
654654
}
655+
}
656+
}
657+
658+
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
659+
pub struct CargoMiri {
660+
target: TargetSelection,
661+
}
662+
663+
impl Step for CargoMiri {
664+
type Output = ();
665+
const ONLY_HOSTS: bool = false;
655666

656-
// # Run `cargo miri test`.
667+
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
668+
run.path("src/tools/miri/cargo-miri")
669+
}
670+
671+
fn make_run(run: RunConfig<'_>) {
672+
run.builder.ensure(CargoMiri { target: run.target });
673+
}
674+
675+
/// Tests `cargo miri test`.
676+
fn run(self, builder: &Builder<'_>) {
677+
let host = builder.build.build;
678+
let target = self.target;
679+
let stage = builder.top_stage;
680+
if stage == 0 {
681+
eprintln!("cargo-miri cannot be tested at stage 0");
682+
std::process::exit(1);
683+
}
684+
685+
// This compiler runs on the host, we'll just use it for the target.
686+
let compiler = builder.compiler(stage, host);
687+
688+
// Run `cargo miri test`.
657689
// This is just a smoke test (Miri's own CI invokes this in a bunch of different ways and ensures
658690
// that we get the desired output), but that is sufficient to make sure that the libtest harness
659691
// itself executes properly under Miri, and that all the logic in `cargo-miri` does not explode.
660-
// This is running the build `cargo-miri` for the given target, so we need the target compiler.
661692
let mut cargo = tool::prepare_tool_cargo(
662693
builder,
663-
target_compiler,
694+
compiler,
664695
Mode::ToolStd, // it's unclear what to use here, we're not building anything just doing a smoke test!
665696
target,
666697
"miri-test",

src/bootstrap/src/core/builder.rs

+1
Original file line numberDiff line numberDiff line change
@@ -808,6 +808,7 @@ impl<'a> Builder<'a> {
808808
test::EditionGuide,
809809
test::Rustfmt,
810810
test::Miri,
811+
test::CargoMiri,
811812
test::Clippy,
812813
test::RustDemangler,
813814
test::CompiletestTest,

src/ci/docker/host-x86_64/x86_64-gnu-tools/checktools.sh

+4-4
Original file line numberDiff line numberDiff line change
@@ -32,18 +32,18 @@ python3 "$X_PY" test --stage 2 src/tools/rustfmt
3232
# that bugs which only surface when the GC runs at a specific time are more likely to cause CI to fail.
3333
# This significantly increases the runtime of our test suite, or we'd do this in PR CI too.
3434
if [ -z "${PR_CI_JOB:-}" ]; then
35-
MIRIFLAGS=-Zmiri-provenance-gc=1 python3 "$X_PY" test --stage 2 src/tools/miri
35+
MIRIFLAGS=-Zmiri-provenance-gc=1 python3 "$X_PY" test --stage 2 src/tools/miri src/tools/miri/cargo-miri
3636
else
37-
python3 "$X_PY" test --stage 2 src/tools/miri
37+
python3 "$X_PY" test --stage 2 src/tools/miri src/tools/miri/cargo-miri
3838
fi
3939
# We natively run this script on x86_64-unknown-linux-gnu and x86_64-pc-windows-msvc.
4040
# Also cover some other targets via cross-testing, in particular all tier 1 targets.
4141
case $HOST_TARGET in
4242
x86_64-unknown-linux-gnu)
4343
# Only this branch runs in PR CI.
4444
# Fully test all main OSes, including a 32bit target.
45-
python3 "$X_PY" test --stage 2 src/tools/miri --target x86_64-apple-darwin
46-
python3 "$X_PY" test --stage 2 src/tools/miri --target i686-pc-windows-msvc
45+
python3 "$X_PY" test --stage 2 src/tools/miri src/tools/miri/cargo-miri --target x86_64-apple-darwin
46+
python3 "$X_PY" test --stage 2 src/tools/miri src/tools/miri/cargo-miri --target i686-pc-windows-msvc
4747
# Only run "pass" tests for the remaining targets, which is quite a bit faster.
4848
python3 "$X_PY" test --stage 2 src/tools/miri --target x86_64-pc-windows-gnu --test-args pass
4949
python3 "$X_PY" test --stage 2 src/tools/miri --target i686-unknown-linux-gnu --test-args pass

src/ci/github-actions/ci.yml

+2-1
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,8 @@ x--expand-yaml-anchors--remove:
249249
<<: *step
250250

251251
- name: run the build
252-
run: src/ci/scripts/run-build-from-ci.sh
252+
# Redirect stderr to stdout to avoid reordering the two streams in the GHA logs.
253+
run: src/ci/scripts/run-build-from-ci.sh 2>&1
253254
env:
254255
AWS_ACCESS_KEY_ID: ${{ env.CACHES_AWS_ACCESS_KEY_ID }}
255256
AWS_SECRET_ACCESS_KEY: ${{ secrets[format('AWS_SECRET_ACCESS_KEY_{0}', env.CACHES_AWS_ACCESS_KEY_ID)] }}

0 commit comments

Comments
 (0)