Skip to content

Commit e292fec

Browse files
committed
Auto merge of #116742 - GuillaumeGomez:rollup-xjxs0mr, r=GuillaumeGomez
Rollup of 3 pull requests Successful merges: - #116540 (Implement `OnceCell/Lock::try_insert()`) - #116576 (const-eval: allow calling functions with targat features disabled at compile time in WASM) - #116661 (Make "request changes" reviews apply `S-waiting-on-author`) Failed merges: - #116643 (x.py zsh completion support) r? `@ghost` `@rustbot` modify labels: rollup
2 parents c543b6f + 31b86ea commit e292fec

File tree

7 files changed

+116
-18
lines changed

7 files changed

+116
-18
lines changed

Diff for: compiler/rustc_const_eval/src/interpret/terminator.rs

+6-4
Original file line numberDiff line numberDiff line change
@@ -890,11 +890,13 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
890890
}
891891

892892
fn check_fn_target_features(&self, instance: ty::Instance<'tcx>) -> InterpResult<'tcx, ()> {
893+
// Calling functions with `#[target_feature]` is not unsafe on WASM, see #84988
893894
let attrs = self.tcx.codegen_fn_attrs(instance.def_id());
894-
if attrs
895-
.target_features
896-
.iter()
897-
.any(|feature| !self.tcx.sess.target_features.contains(feature))
895+
if !self.tcx.sess.target.is_like_wasm
896+
&& attrs
897+
.target_features
898+
.iter()
899+
.any(|feature| !self.tcx.sess.target_features.contains(feature))
898900
{
899901
throw_ub_custom!(
900902
fluent::const_eval_unavailable_target_features_for_fn,

Diff for: library/core/src/cell/once.rs

+37-9
Original file line numberDiff line numberDiff line change
@@ -87,19 +87,48 @@ impl<T> OnceCell<T> {
8787
#[inline]
8888
#[stable(feature = "once_cell", since = "1.70.0")]
8989
pub fn set(&self, value: T) -> Result<(), T> {
90-
// SAFETY: Safe because we cannot have overlapping mutable borrows
91-
let slot = unsafe { &*self.inner.get() };
92-
if slot.is_some() {
93-
return Err(value);
90+
match self.try_insert(value) {
91+
Ok(_) => Ok(()),
92+
Err((_, value)) => Err(value),
93+
}
94+
}
95+
96+
/// Sets the contents of the cell to `value` if the cell was empty, then
97+
/// returns a reference to it.
98+
///
99+
/// # Errors
100+
///
101+
/// This method returns `Ok(&value)` if the cell was empty and
102+
/// `Err(&current_value, value)` if it was full.
103+
///
104+
/// # Examples
105+
///
106+
/// ```
107+
/// #![feature(once_cell_try_insert)]
108+
///
109+
/// use std::cell::OnceCell;
110+
///
111+
/// let cell = OnceCell::new();
112+
/// assert!(cell.get().is_none());
113+
///
114+
/// assert_eq!(cell.try_insert(92), Ok(&92));
115+
/// assert_eq!(cell.try_insert(62), Err((&92, 62)));
116+
///
117+
/// assert!(cell.get().is_some());
118+
/// ```
119+
#[inline]
120+
#[unstable(feature = "once_cell_try_insert", issue = "116693")]
121+
pub fn try_insert(&self, value: T) -> Result<&T, (&T, T)> {
122+
if let Some(old) = self.get() {
123+
return Err((old, value));
94124
}
95125

96126
// SAFETY: This is the only place where we set the slot, no races
97127
// due to reentrancy/concurrency are possible, and we've
98128
// checked that slot is currently `None`, so this write
99129
// maintains the `inner`'s invariant.
100130
let slot = unsafe { &mut *self.inner.get() };
101-
*slot = Some(value);
102-
Ok(())
131+
Ok(slot.insert(value))
103132
}
104133

105134
/// Gets the contents of the cell, initializing it with `f`
@@ -183,10 +212,9 @@ impl<T> OnceCell<T> {
183212
let val = outlined_call(f)?;
184213
// Note that *some* forms of reentrant initialization might lead to
185214
// UB (see `reentrant_init` test). I believe that just removing this
186-
// `assert`, while keeping `set/get` would be sound, but it seems
215+
// `panic`, while keeping `try_insert` would be sound, but it seems
187216
// better to panic, rather than to silently use an old value.
188-
assert!(self.set(val).is_ok(), "reentrant init");
189-
Ok(self.get().unwrap())
217+
if let Ok(val) = self.try_insert(val) { Ok(val) } else { panic!("reentrant init") }
190218
}
191219

192220
/// Consumes the cell, returning the wrapped value.

Diff for: library/std/src/sync/once_lock.rs

+40-3
Original file line numberDiff line numberDiff line change
@@ -126,11 +126,48 @@ impl<T> OnceLock<T> {
126126
#[inline]
127127
#[stable(feature = "once_cell", since = "1.70.0")]
128128
pub fn set(&self, value: T) -> Result<(), T> {
129+
match self.try_insert(value) {
130+
Ok(_) => Ok(()),
131+
Err((_, value)) => Err(value),
132+
}
133+
}
134+
135+
/// Sets the contents of this cell to `value` if the cell was empty, then
136+
/// returns a reference to it.
137+
///
138+
/// May block if another thread is currently attempting to initialize the cell. The cell is
139+
/// guaranteed to contain a value when set returns, though not necessarily the one provided.
140+
///
141+
/// Returns `Ok(&value)` if the cell was empty and `Err(&current_value, value)` if it was full.
142+
///
143+
/// # Examples
144+
///
145+
/// ```
146+
/// #![feature(once_cell_try_insert)]
147+
///
148+
/// use std::sync::OnceLock;
149+
///
150+
/// static CELL: OnceLock<i32> = OnceLock::new();
151+
///
152+
/// fn main() {
153+
/// assert!(CELL.get().is_none());
154+
///
155+
/// std::thread::spawn(|| {
156+
/// assert_eq!(CELL.try_insert(92), Ok(&92));
157+
/// }).join().unwrap();
158+
///
159+
/// assert_eq!(CELL.try_insert(62), Err((&92, 62)));
160+
/// assert_eq!(CELL.get(), Some(&92));
161+
/// }
162+
/// ```
163+
#[inline]
164+
#[unstable(feature = "once_cell_try_insert", issue = "116693")]
165+
pub fn try_insert(&self, value: T) -> Result<&T, (&T, T)> {
129166
let mut value = Some(value);
130-
self.get_or_init(|| value.take().unwrap());
167+
let res = self.get_or_init(|| value.take().unwrap());
131168
match value {
132-
None => Ok(()),
133-
Some(value) => Err(value),
169+
None => Ok(res),
170+
Some(value) => Err((res, value)),
134171
}
135172
}
136173

Diff for: src/tools/miri/ci.sh

+2-2
Original file line numberDiff line numberDiff line change
@@ -110,8 +110,8 @@ case $HOST_TARGET in
110110
MIRI_TEST_TARGET=i686-pc-windows-gnu run_tests
111111
MIRI_TEST_TARGET=x86_64-unknown-freebsd run_tests_minimal hello integer vec panic/panic concurrency/simple atomic data_race env/var
112112
MIRI_TEST_TARGET=aarch64-linux-android run_tests_minimal hello integer vec panic/panic
113-
MIRI_TEST_TARGET=wasm32-wasi run_tests_minimal no_std integer strings
114-
MIRI_TEST_TARGET=wasm32-unknown-unknown run_tests_minimal no_std integer strings
113+
MIRI_TEST_TARGET=wasm32-wasi run_tests_minimal no_std integer strings wasm
114+
MIRI_TEST_TARGET=wasm32-unknown-unknown run_tests_minimal no_std integer strings wasm
115115
MIRI_TEST_TARGET=thumbv7em-none-eabihf run_tests_minimal no_std # no_std embedded architecture
116116
MIRI_TEST_TARGET=tests/avr.json MIRI_NO_STD=1 run_tests_minimal no_std # JSON target file
117117
;;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
//@only-target-wasm32: tests WASM-specific behavior
2+
//@compile-flags: -C target-feature=-simd128
3+
4+
fn main() {
5+
// Calling functions with `#[target_feature]` is not unsound on WASM, see #84988
6+
assert!(!cfg!(target_feature = "simd128"));
7+
simd128_fn();
8+
}
9+
10+
#[target_feature(enable = "simd128")]
11+
fn simd128_fn() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// only-wasm32
2+
// compile-flags:-C target-feature=-simd128
3+
// build-pass
4+
5+
#![crate_type = "lib"]
6+
7+
#[cfg(target_feature = "simd128")]
8+
compile_error!("simd128 target feature should be disabled");
9+
10+
// Calling functions with `#[target_feature]` is not unsound on WASM, see #84988
11+
const A: () = simd128_fn();
12+
13+
#[target_feature(enable = "simd128")]
14+
const fn simd128_fn() {}

Diff for: triagebot.toml

+6
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,12 @@ allow-unauthenticated = [
2323
"needs-triage",
2424
]
2525

26+
[review-submitted]
27+
# This label is added when a "request changes" review is submitted.
28+
reviewed_label = "S-waiting-on-author"
29+
# These labels are removed when a "request changes" review is submitted.
30+
review_labels = ["S-waiting-on-review"]
31+
2632
[glacier]
2733

2834
[ping.icebreakers-llvm]

0 commit comments

Comments
 (0)