Skip to content

Commit a8198dc

Browse files
author
The Miri Cronjob Bot
committed
Merge ref 'a015919e54c6' from rust-lang/rust
Pull recent changes from https://github.com/rust-lang/rust via Josh. Upstream ref: a015919 Filtered ref: 1867c5844dba22ac4d77d1ceb7d1624c14139c16 Upstream diff: rust-lang/rust@4ba1cf9...a015919 This merge was created using https://github.com/rust-lang/josh-sync.
2 parents 0c33b05 + c9a0ac1 commit a8198dc

File tree

20 files changed

+218
-213
lines changed

20 files changed

+218
-213
lines changed

alloc/src/collections/btree/map.rs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1433,7 +1433,6 @@ impl<K, V, A: Allocator + Clone> BTreeMap<K, V, A> {
14331433
/// # Examples
14341434
///
14351435
/// ```
1436-
/// #![feature(btree_extract_if)]
14371436
/// use std::collections::BTreeMap;
14381437
///
14391438
/// // Splitting a map into even and odd keys, reusing the original map:
@@ -1450,7 +1449,7 @@ impl<K, V, A: Allocator + Clone> BTreeMap<K, V, A> {
14501449
/// assert_eq!(low.keys().copied().collect::<Vec<_>>(), [0, 1, 2, 3]);
14511450
/// assert_eq!(high.keys().copied().collect::<Vec<_>>(), [4, 5, 6, 7]);
14521451
/// ```
1453-
#[unstable(feature = "btree_extract_if", issue = "70530")]
1452+
#[stable(feature = "btree_extract_if", since = "CURRENT_RUSTC_VERSION")]
14541453
pub fn extract_if<F, R>(&mut self, range: R, pred: F) -> ExtractIf<'_, K, V, R, F, A>
14551454
where
14561455
K: Ord,
@@ -1937,7 +1936,7 @@ impl<K, V> Default for Values<'_, K, V> {
19371936
}
19381937

19391938
/// An iterator produced by calling `extract_if` on BTreeMap.
1940-
#[unstable(feature = "btree_extract_if", issue = "70530")]
1939+
#[stable(feature = "btree_extract_if", since = "CURRENT_RUSTC_VERSION")]
19411940
#[must_use = "iterators are lazy and do nothing unless consumed"]
19421941
pub struct ExtractIf<
19431942
'a,
@@ -1970,7 +1969,7 @@ pub(super) struct ExtractIfInner<'a, K, V, R> {
19701969
range: R,
19711970
}
19721971

1973-
#[unstable(feature = "btree_extract_if", issue = "70530")]
1972+
#[stable(feature = "btree_extract_if", since = "CURRENT_RUSTC_VERSION")]
19741973
impl<K, V, R, F, A> fmt::Debug for ExtractIf<'_, K, V, R, F, A>
19751974
where
19761975
K: fmt::Debug,
@@ -1982,7 +1981,7 @@ where
19821981
}
19831982
}
19841983

1985-
#[unstable(feature = "btree_extract_if", issue = "70530")]
1984+
#[stable(feature = "btree_extract_if", since = "CURRENT_RUSTC_VERSION")]
19861985
impl<K, V, R, F, A: Allocator + Clone> Iterator for ExtractIf<'_, K, V, R, F, A>
19871986
where
19881987
K: PartialOrd,
@@ -2056,7 +2055,7 @@ impl<'a, K, V, R> ExtractIfInner<'a, K, V, R> {
20562055
}
20572056
}
20582057

2059-
#[unstable(feature = "btree_extract_if", issue = "70530")]
2058+
#[stable(feature = "btree_extract_if", since = "CURRENT_RUSTC_VERSION")]
20602059
impl<K, V, R, F> FusedIterator for ExtractIf<'_, K, V, R, F>
20612060
where
20622061
K: PartialOrd,

alloc/src/collections/btree/set.rs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1202,7 +1202,6 @@ impl<T, A: Allocator + Clone> BTreeSet<T, A> {
12021202
/// # Examples
12031203
///
12041204
/// ```
1205-
/// #![feature(btree_extract_if)]
12061205
/// use std::collections::BTreeSet;
12071206
///
12081207
/// // Splitting a set into even and odd values, reusing the original set:
@@ -1219,7 +1218,7 @@ impl<T, A: Allocator + Clone> BTreeSet<T, A> {
12191218
/// assert_eq!(low.into_iter().collect::<Vec<_>>(), [0, 1, 2, 3]);
12201219
/// assert_eq!(high.into_iter().collect::<Vec<_>>(), [4, 5, 6, 7]);
12211220
/// ```
1222-
#[unstable(feature = "btree_extract_if", issue = "70530")]
1221+
#[stable(feature = "btree_extract_if", since = "CURRENT_RUSTC_VERSION")]
12231222
pub fn extract_if<F, R>(&mut self, range: R, pred: F) -> ExtractIf<'_, T, R, F, A>
12241223
where
12251224
T: Ord,
@@ -1554,7 +1553,7 @@ impl<'a, T, A: Allocator + Clone> IntoIterator for &'a BTreeSet<T, A> {
15541553
}
15551554

15561555
/// An iterator produced by calling `extract_if` on BTreeSet.
1557-
#[unstable(feature = "btree_extract_if", issue = "70530")]
1556+
#[stable(feature = "btree_extract_if", since = "CURRENT_RUSTC_VERSION")]
15581557
#[must_use = "iterators are lazy and do nothing unless consumed"]
15591558
pub struct ExtractIf<
15601559
'a,
@@ -1569,7 +1568,7 @@ pub struct ExtractIf<
15691568
alloc: A,
15701569
}
15711570

1572-
#[unstable(feature = "btree_extract_if", issue = "70530")]
1571+
#[stable(feature = "btree_extract_if", since = "CURRENT_RUSTC_VERSION")]
15731572
impl<T, R, F, A> fmt::Debug for ExtractIf<'_, T, R, F, A>
15741573
where
15751574
T: fmt::Debug,
@@ -1582,7 +1581,7 @@ where
15821581
}
15831582
}
15841583

1585-
#[unstable(feature = "btree_extract_if", issue = "70530")]
1584+
#[stable(feature = "btree_extract_if", since = "CURRENT_RUSTC_VERSION")]
15861585
impl<T, R, F, A: Allocator + Clone> Iterator for ExtractIf<'_, T, R, F, A>
15871586
where
15881587
T: PartialOrd,
@@ -1602,7 +1601,7 @@ where
16021601
}
16031602
}
16041603

1605-
#[unstable(feature = "btree_extract_if", issue = "70530")]
1604+
#[stable(feature = "btree_extract_if", since = "CURRENT_RUSTC_VERSION")]
16061605
impl<T, R, F, A: Allocator + Clone> FusedIterator for ExtractIf<'_, T, R, F, A>
16071606
where
16081607
T: PartialOrd,

alloctests/benches/lib.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
// Disabling in Miri as these would take too long.
22
#![cfg(not(miri))]
3-
#![feature(btree_extract_if)]
43
#![feature(iter_next_chunk)]
54
#![feature(repr_simd)]
65
#![feature(slice_partition_dedup)]

alloctests/tests/lib.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
#![feature(alloc_layout_extra)]
33
#![feature(iter_array_chunks)]
44
#![feature(assert_matches)]
5-
#![feature(btree_extract_if)]
65
#![feature(wtf8_internals)]
76
#![feature(char_max_len)]
87
#![feature(cow_is_borrowed)]

core/src/ffi/va_list.rs

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -202,18 +202,23 @@ mod sealed {
202202
impl<T> Sealed for *const T {}
203203
}
204204

205-
/// Trait which permits the allowed types to be used with [`VaListImpl::arg`].
205+
/// Types that are valid to read using [`VaListImpl::arg`].
206206
///
207207
/// # Safety
208208
///
209-
/// This trait must only be implemented for types that C passes as varargs without implicit promotion.
209+
/// The standard library implements this trait for primitive types that are
210+
/// expected to have a variable argument application-binary interface (ABI) on all
211+
/// platforms.
210212
///
211-
/// In C varargs, integers smaller than [`c_int`] and floats smaller than [`c_double`]
212-
/// are implicitly promoted to [`c_int`] and [`c_double`] respectively. Implementing this trait for
213-
/// types that are subject to this promotion rule is invalid.
213+
/// When C passes variable arguments, integers smaller than [`c_int`] and floats smaller
214+
/// than [`c_double`] are implicitly promoted to [`c_int`] and [`c_double`] respectively.
215+
/// Implementing this trait for types that are subject to this promotion rule is invalid.
214216
///
215217
/// [`c_int`]: core::ffi::c_int
216218
/// [`c_double`]: core::ffi::c_double
219+
// We may unseal this trait in the future, but currently our `va_arg` implementations don't support
220+
// types with an alignment larger than 8, or with a non-scalar layout. Inline assembly can be used
221+
// to accept unsupported types in the meantime.
217222
pub unsafe trait VaArgSafe: sealed::Sealed {}
218223

219224
// i8 and i16 are implicitly promoted to c_int in C, and cannot implement `VaArgSafe`.
@@ -233,7 +238,19 @@ unsafe impl<T> VaArgSafe for *mut T {}
233238
unsafe impl<T> VaArgSafe for *const T {}
234239

235240
impl<'f> VaListImpl<'f> {
236-
/// Advance to the next arg.
241+
/// Advance to and read the next variable argument.
242+
///
243+
/// # Safety
244+
///
245+
/// This function is only sound to call when the next variable argument:
246+
///
247+
/// - has a type that is ABI-compatible with the type `T`
248+
/// - has a value that is a properly initialized value of type `T`
249+
///
250+
/// Calling this function with an incompatible type, an invalid value, or when there
251+
/// are no more variable arguments, is unsound.
252+
///
253+
/// [valid]: https://doc.rust-lang.org/nightly/nomicon/what-unsafe-does.html
237254
#[inline]
238255
pub unsafe fn arg<T: VaArgSafe>(&mut self) -> T {
239256
// SAFETY: the caller must uphold the safety contract for `va_arg`.

std/src/keyword_docs.rs

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1257,6 +1257,108 @@ mod ref_keyword {}
12571257
/// [`async`]: ../std/keyword.async.html
12581258
mod return_keyword {}
12591259

1260+
#[doc(keyword = "become")]
1261+
//
1262+
/// Perform a tail-call of a function.
1263+
///
1264+
/// <div class="warning">
1265+
///
1266+
/// `feature(explicit_tail_calls)` is currently incomplete and may not work properly.
1267+
/// </div>
1268+
///
1269+
/// When tail calling a function, instead of its stack frame being added to the
1270+
/// stack, the stack frame of the caller is directly replaced with the callee's.
1271+
/// This means that as long as a loop in a call graph only uses tail calls, the
1272+
/// stack growth will be bounded.
1273+
///
1274+
/// This is useful for writing functional-style code (since it prevents recursion
1275+
/// from exhausting resources) or for code optimization (since a tail call
1276+
/// *might* be cheaper than a normal call, tail calls can be used in a similar
1277+
/// manner to computed goto).
1278+
///
1279+
/// Example of using `become` to implement functional-style `fold`:
1280+
/// ```
1281+
/// #![feature(explicit_tail_calls)]
1282+
/// #![expect(incomplete_features)]
1283+
///
1284+
/// fn fold<T: Copy, S>(slice: &[T], init: S, f: impl Fn(S, T) -> S) -> S {
1285+
/// match slice {
1286+
/// // without `become`, on big inputs this could easily overflow the
1287+
/// // stack. using a tail call guarantees that the stack will not grow unboundedly
1288+
/// [first, rest @ ..] => become fold(rest, f(init, *first), f),
1289+
/// [] => init,
1290+
/// }
1291+
/// }
1292+
/// ```
1293+
///
1294+
/// Compilers can already perform "tail call optimization" -- they can replace normal
1295+
/// calls with tail calls, although there are no guarantees that this will be done.
1296+
/// However, to perform TCO, the call needs to be the last thing that happens
1297+
/// in the functions and be returned from it. This requirement is often broken
1298+
/// by drop code for locals, which is run after computing the return expression:
1299+
///
1300+
/// ```
1301+
/// fn example() {
1302+
/// let string = "meow".to_owned();
1303+
/// println!("{string}");
1304+
/// return help(); // this is *not* the last thing that happens in `example`...
1305+
/// }
1306+
///
1307+
/// // ... because it is desugared to this:
1308+
/// fn example_desugared() {
1309+
/// let string = "meow".to_owned();
1310+
/// println!("{string}");
1311+
/// let tmp = help();
1312+
/// drop(string);
1313+
/// return tmp;
1314+
/// }
1315+
///
1316+
/// fn help() {}
1317+
/// ```
1318+
///
1319+
/// For this reason, `become` also changes the drop order, such that locals are
1320+
/// dropped *before* evaluating the call.
1321+
///
1322+
/// In order to guarantee that the compiler can perform a tail call, `become`
1323+
/// currently has these requirements:
1324+
/// 1. callee and caller must have the same ABI, arguments, and return type
1325+
/// 2. callee and caller must not have varargs
1326+
/// 3. caller must not be marked with `#[track_caller]`
1327+
/// - callee is allowed to be marked with `#[track_caller]` as otherwise
1328+
/// adding `#[track_caller]` would be a breaking change. if callee is
1329+
/// marked with `#[track_caller]` a tail call is not guaranteed.
1330+
/// 4. callee and caller cannot be a closure
1331+
/// (unless it's coerced to a function pointer)
1332+
///
1333+
/// It is possible to tail-call a function pointer:
1334+
/// ```
1335+
/// #![feature(explicit_tail_calls)]
1336+
/// #![expect(incomplete_features)]
1337+
///
1338+
/// #[derive(Copy, Clone)]
1339+
/// enum Inst { Inc, Dec }
1340+
///
1341+
/// fn dispatch(stream: &[Inst], state: u32) -> u32 {
1342+
/// const TABLE: &[fn(&[Inst], u32) -> u32] = &[increment, decrement];
1343+
/// match stream {
1344+
/// [inst, rest @ ..] => become TABLE[*inst as usize](rest, state),
1345+
/// [] => state,
1346+
/// }
1347+
/// }
1348+
///
1349+
/// fn increment(stream: &[Inst], state: u32) -> u32 {
1350+
/// become dispatch(stream, state + 1)
1351+
/// }
1352+
///
1353+
/// fn decrement(stream: &[Inst], state: u32) -> u32 {
1354+
/// become dispatch(stream, state - 1)
1355+
/// }
1356+
///
1357+
/// let program = &[Inst::Inc, Inst::Inc, Inst::Dec, Inst::Inc];
1358+
/// assert_eq!(dispatch(program, 0), 2);
1359+
/// ```
1360+
mod become_keyword {}
1361+
12601362
#[doc(keyword = "self")]
12611363
//
12621364
/// The receiver of a method, or the current module.

std/src/lib.rs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,6 @@
284284
#![feature(core_float_math)]
285285
#![feature(decl_macro)]
286286
#![feature(deprecated_suggestion)]
287-
#![feature(derive_const)]
288287
#![feature(doc_cfg)]
289288
#![feature(doc_cfg_hide)]
290289
#![feature(doc_masked)]
@@ -332,11 +331,7 @@
332331
#![feature(cfg_select)]
333332
#![feature(char_internals)]
334333
#![feature(clone_to_uninit)]
335-
#![feature(const_cmp)]
336334
#![feature(const_convert)]
337-
#![feature(const_ops)]
338-
#![feature(const_option_ops)]
339-
#![feature(const_try)]
340335
#![feature(core_intrinsics)]
341336
#![feature(core_io_borrowed_buf)]
342337
#![feature(drop_guard)]

std/src/sync/nonpoison/condvar.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -198,11 +198,10 @@ impl Condvar {
198198
/// the system time. This function is susceptible to spurious wakeups.
199199
/// Condition variables normally have a boolean predicate associated with
200200
/// them, and the predicate must always be checked each time this function
201-
/// returns to protect against spurious wakeups. Additionally, it is
202-
/// typically desirable for the timeout to not exceed some duration in
203-
/// spite of spurious wakes, thus the sleep-duration is decremented by the
204-
/// amount slept. Alternatively, use the `wait_timeout_while` method
205-
/// to wait with a timeout while a predicate is true.
201+
/// returns to protect against spurious wakeups. Furthermore, since the timeout
202+
/// is given relative to the moment this function is called, it needs to be adjusted
203+
/// when this function is called in a loop. The [`wait_timeout_while`] method
204+
/// lets you wait with a timeout while a predicate is true, taking care of all these concerns.
206205
///
207206
/// The returned [`WaitTimeoutResult`] value indicates if the timeout is
208207
/// known to have elapsed.

std/src/sync/poison/condvar.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -269,11 +269,10 @@ impl Condvar {
269269
/// the system time. This function is susceptible to spurious wakeups.
270270
/// Condition variables normally have a boolean predicate associated with
271271
/// them, and the predicate must always be checked each time this function
272-
/// returns to protect against spurious wakeups. Additionally, it is
273-
/// typically desirable for the timeout to not exceed some duration in
274-
/// spite of spurious wakes, thus the sleep-duration is decremented by the
275-
/// amount slept. Alternatively, use the `wait_timeout_while` method
276-
/// to wait with a timeout while a predicate is true.
272+
/// returns to protect against spurious wakeups. Furthermore, since the timeout
273+
/// is given relative to the moment this function is called, it needs to be adjusted
274+
/// when this function is called in a loop. The [`wait_timeout_while`] method
275+
/// lets you wait with a timeout while a predicate is true, taking care of all these concerns.
277276
///
278277
/// The returned [`WaitTimeoutResult`] value indicates if the timeout is
279278
/// known to have elapsed.

std/src/sys/pal/hermit/time.rs

Lines changed: 10 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,8 @@ impl Timespec {
2525
Timespec { t: timespec { tv_sec, tv_nsec } }
2626
}
2727

28-
#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
29-
const fn sub_timespec(&self, other: &Timespec) -> Result<Duration, Duration> {
30-
// FIXME: const PartialOrd
31-
let mut cmp = self.t.tv_sec - other.t.tv_sec;
32-
if cmp == 0 {
33-
cmp = self.t.tv_nsec as i64 - other.t.tv_nsec as i64;
34-
}
35-
36-
if cmp >= 0 {
28+
fn sub_timespec(&self, other: &Timespec) -> Result<Duration, Duration> {
29+
if self >= other {
3730
Ok(if self.t.tv_nsec >= other.t.tv_nsec {
3831
Duration::new(
3932
(self.t.tv_sec - other.t.tv_sec) as u64,
@@ -53,22 +46,20 @@ impl Timespec {
5346
}
5447
}
5548

56-
#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
57-
const fn checked_add_duration(&self, other: &Duration) -> Option<Timespec> {
49+
fn checked_add_duration(&self, other: &Duration) -> Option<Timespec> {
5850
let mut secs = self.t.tv_sec.checked_add_unsigned(other.as_secs())?;
5951

6052
// Nano calculations can't overflow because nanos are <1B which fit
6153
// in a u32.
62-
let mut nsec = other.subsec_nanos() + self.t.tv_nsec as u32;
63-
if nsec >= NSEC_PER_SEC as u32 {
64-
nsec -= NSEC_PER_SEC as u32;
54+
let mut nsec = other.subsec_nanos() + u32::try_from(self.t.tv_nsec).unwrap();
55+
if nsec >= NSEC_PER_SEC.try_into().unwrap() {
56+
nsec -= u32::try_from(NSEC_PER_SEC).unwrap();
6557
secs = secs.checked_add(1)?;
6658
}
6759
Some(Timespec { t: timespec { tv_sec: secs, tv_nsec: nsec as _ } })
6860
}
6961

70-
#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
71-
const fn checked_sub_duration(&self, other: &Duration) -> Option<Timespec> {
62+
fn checked_sub_duration(&self, other: &Duration) -> Option<Timespec> {
7263
let mut secs = self.t.tv_sec.checked_sub_unsigned(other.as_secs())?;
7364

7465
// Similar to above, nanos can't overflow.
@@ -222,18 +213,15 @@ impl SystemTime {
222213
SystemTime(time)
223214
}
224215

225-
#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
226-
pub const fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
216+
pub fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
227217
self.0.sub_timespec(&other.0)
228218
}
229219

230-
#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
231-
pub const fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
220+
pub fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
232221
Some(SystemTime(self.0.checked_add_duration(other)?))
233222
}
234223

235-
#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
236-
pub const fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
224+
pub fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
237225
Some(SystemTime(self.0.checked_sub_duration(other)?))
238226
}
239227
}

0 commit comments

Comments
 (0)