Skip to content

Commit e3db390

Browse files
committed
Auto merge of #149975 - ChrisDenton:rollup-m8h7wuk, r=ChrisDenton
Rollup of 8 pull requests Successful merges: - #148755 (Constify `DropGuard::dismiss` and trait impls) - #148825 (Add SystemTime::{MIN, MAX}) - #149272 (Fix vec iter zst alignment) - #149417 (tidy: Detect outdated workspaces in workspace list) - #149437 (Fix trailing newline in JUnit formatter) - #149773 (fix va_list test by adding a llvmir signext check) - #149894 (Update to mdbook 0.5) - #149955 (Fix typo in armv7a-vex-v5 documentation) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 3f4dc1e + 56b6d13 commit e3db390

File tree

40 files changed

+761
-888
lines changed

40 files changed

+761
-888
lines changed

library/alloc/src/vec/into_iter.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -411,7 +411,12 @@ impl<T, A: Allocator> DoubleEndedIterator for IntoIter<T, A> {
411411
// SAFETY: same as for advance_by()
412412
self.end = unsafe { self.end.sub(step_size) };
413413
}
414-
let to_drop = ptr::slice_from_raw_parts_mut(self.end as *mut T, step_size);
414+
let to_drop = if T::IS_ZST {
415+
// ZST may cause unalignment
416+
ptr::slice_from_raw_parts_mut(ptr::NonNull::<T>::dangling().as_ptr(), step_size)
417+
} else {
418+
ptr::slice_from_raw_parts_mut(self.end as *mut T, step_size)
419+
};
415420
// SAFETY: same as for advance_by()
416421
unsafe {
417422
ptr::drop_in_place(to_drop);

library/alloctests/tests/vec.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2717,3 +2717,35 @@ fn vec_null_ptr_roundtrip() {
27172717
let new = roundtripped.with_addr(ptr.addr());
27182718
unsafe { new.read() };
27192719
}
2720+
2721+
// Regression test for Undefined Behavior (UB) caused by IntoIter::nth_back (#148682)
2722+
// when dealing with high-aligned Zero-Sized Types (ZSTs).
2723+
use std::collections::{BTreeMap, BinaryHeap, HashMap, LinkedList, VecDeque};
2724+
#[test]
2725+
fn zst_collections_iter_nth_back_regression() {
2726+
#[repr(align(8))]
2727+
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy)]
2728+
struct Thing;
2729+
let v = vec![Thing, Thing];
2730+
let _ = v.into_iter().nth_back(1);
2731+
let mut d = VecDeque::new();
2732+
d.push_back(Thing);
2733+
d.push_back(Thing);
2734+
let _ = d.into_iter().nth_back(1);
2735+
let mut map = BTreeMap::new();
2736+
map.insert(0, Thing);
2737+
map.insert(1, Thing);
2738+
let _ = map.into_values().nth_back(0);
2739+
let mut hash_map = HashMap::new();
2740+
hash_map.insert(1, Thing);
2741+
hash_map.insert(2, Thing);
2742+
let _ = hash_map.into_values().nth(1);
2743+
let mut heap = BinaryHeap::new();
2744+
heap.push(Thing);
2745+
heap.push(Thing);
2746+
let _ = heap.into_iter().nth_back(1);
2747+
let mut list = LinkedList::new();
2748+
list.push_back(Thing);
2749+
list.push_back(Thing);
2750+
let _ = list.into_iter().nth_back(1);
2751+
}

library/core/src/mem/drop_guard.rs

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use crate::fmt::{self, Debug};
2+
use crate::marker::Destruct;
23
use crate::mem::ManuallyDrop;
34
use crate::ops::{Deref, DerefMut};
45

@@ -78,32 +79,37 @@ where
7879
///
7980
/// let value = String::from("Nori likes chicken");
8081
/// let guard = DropGuard::new(value, |s| println!("{s}"));
81-
/// assert_eq!(guard.dismiss(), "Nori likes chicken");
82+
/// assert_eq!(DropGuard::dismiss(guard), "Nori likes chicken");
8283
/// ```
8384
#[unstable(feature = "drop_guard", issue = "144426")]
85+
#[rustc_const_unstable(feature = "const_drop_guard", issue = "none")]
8486
#[inline]
85-
pub fn dismiss(self) -> T {
87+
pub const fn dismiss(guard: Self) -> T
88+
where
89+
F: [const] Destruct,
90+
{
8691
// First we ensure that dropping the guard will not trigger
8792
// its destructor
88-
let mut this = ManuallyDrop::new(self);
93+
let mut guard = ManuallyDrop::new(guard);
8994

9095
// Next we manually read the stored value from the guard.
9196
//
9297
// SAFETY: this is safe because we've taken ownership of the guard.
93-
let value = unsafe { ManuallyDrop::take(&mut this.inner) };
98+
let value = unsafe { ManuallyDrop::take(&mut guard.inner) };
9499

95100
// Finally we drop the stored closure. We do this *after* having read
96101
// the value, so that even if the closure's `drop` function panics,
97102
// unwinding still tries to drop the value.
98103
//
99104
// SAFETY: this is safe because we've taken ownership of the guard.
100-
unsafe { ManuallyDrop::drop(&mut this.f) };
105+
unsafe { ManuallyDrop::drop(&mut guard.f) };
101106
value
102107
}
103108
}
104109

105110
#[unstable(feature = "drop_guard", issue = "144426")]
106-
impl<T, F> Deref for DropGuard<T, F>
111+
#[rustc_const_unstable(feature = "const_convert", issue = "143773")]
112+
impl<T, F> const Deref for DropGuard<T, F>
107113
where
108114
F: FnOnce(T),
109115
{
@@ -115,7 +121,8 @@ where
115121
}
116122

117123
#[unstable(feature = "drop_guard", issue = "144426")]
118-
impl<T, F> DerefMut for DropGuard<T, F>
124+
#[rustc_const_unstable(feature = "const_convert", issue = "143773")]
125+
impl<T, F> const DerefMut for DropGuard<T, F>
119126
where
120127
F: FnOnce(T),
121128
{
@@ -125,9 +132,10 @@ where
125132
}
126133

127134
#[unstable(feature = "drop_guard", issue = "144426")]
128-
impl<T, F> Drop for DropGuard<T, F>
135+
#[rustc_const_unstable(feature = "const_drop_guard", issue = "none")]
136+
impl<T, F> const Drop for DropGuard<T, F>
129137
where
130-
F: FnOnce(T),
138+
F: [const] FnOnce(T),
131139
{
132140
fn drop(&mut self) {
133141
// SAFETY: `DropGuard` is in the process of being dropped.

library/coretests/tests/mem.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -815,7 +815,7 @@ fn drop_guard_into_inner() {
815815
let dropped = Cell::new(false);
816816
let value = DropGuard::new(42, |_| dropped.set(true));
817817
let guard = DropGuard::new(value, |_| dropped.set(true));
818-
let inner = guard.dismiss();
818+
let inner = DropGuard::dismiss(guard);
819819
assert_eq!(dropped.get(), false);
820820
assert_eq!(*inner, 42);
821821
}
@@ -837,7 +837,7 @@ fn drop_guard_always_drops_value_if_closure_drop_unwinds() {
837837
// run the destructor of the value we passed, which we validate.
838838
let _ = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
839839
let guard = DropGuard::new(value_with_tracked_destruction, closure_that_panics_on_drop);
840-
guard.dismiss();
840+
DropGuard::dismiss(guard);
841841
}));
842842
assert!(value_was_dropped);
843843
}

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@ struct Timespec {
1515
}
1616

1717
impl Timespec {
18+
const MAX: Timespec = Self::new(i64::MAX, 1_000_000_000 - 1);
19+
20+
const MIN: Timespec = Self::new(i64::MIN, 0);
21+
1822
const fn zero() -> Timespec {
1923
Timespec { t: timespec { tv_sec: 0, tv_nsec: 0 } }
2024
}
@@ -209,6 +213,10 @@ pub struct SystemTime(Timespec);
209213
pub const UNIX_EPOCH: SystemTime = SystemTime(Timespec::zero());
210214

211215
impl SystemTime {
216+
pub const MAX: SystemTime = SystemTime { t: Timespec::MAX };
217+
218+
pub const MIN: SystemTime = SystemTime { t: Timespec::MIN };
219+
212220
pub fn new(tv_sec: i64, tv_nsec: i32) -> SystemTime {
213221
SystemTime(Timespec::new(tv_sec, tv_nsec))
214222
}

library/std/src/sys/pal/sgx/time.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@ impl Instant {
2828
}
2929

3030
impl SystemTime {
31+
pub const MAX: SystemTime = SystemTime(Duration::MAX);
32+
33+
pub const MIN: SystemTime = SystemTime(Duration::ZERO);
34+
3135
pub fn now() -> SystemTime {
3236
SystemTime(usercalls::insecure_time())
3337
}

library/std/src/sys/pal/solid/time.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ pub struct SystemTime(abi::time_t);
1010
pub const UNIX_EPOCH: SystemTime = SystemTime(0);
1111

1212
impl SystemTime {
13+
pub const MAX: SystemTime = SystemTime(abi::time_t::MAX);
14+
15+
pub const MIN: SystemTime = SystemTime(abi::time_t::MIN);
16+
1317
pub fn now() -> SystemTime {
1418
let rtc = unsafe {
1519
let mut out = MaybeUninit::zeroed();

library/std/src/sys/pal/uefi/time.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,23 @@ impl Instant {
7070
}
7171

7272
impl SystemTime {
73+
pub const MAX: SystemTime = MAX_UEFI_TIME;
74+
75+
pub const MIN: SystemTime = SystemTime::from_uefi(r_efi::efi::Time {
76+
year: 1900,
77+
month: 1,
78+
day: 1,
79+
hour: 0,
80+
minute: 0,
81+
second: 0,
82+
nanosecond: 0,
83+
timezone: -1440,
84+
daylight: 0,
85+
pad1: 0,
86+
pad2: 0,
87+
})
88+
.unwrap();
89+
7390
pub(crate) const fn from_uefi(t: r_efi::efi::Time) -> Option<Self> {
7491
match system_time_internal::from_uefi(&t) {
7592
Some(x) => Some(Self(x)),

library/std/src/sys/pal/unix/time.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ pub(crate) struct Timespec {
3030
}
3131

3232
impl SystemTime {
33+
pub const MAX: SystemTime = SystemTime { t: Timespec::MAX };
34+
35+
pub const MIN: SystemTime = SystemTime { t: Timespec::MIN };
36+
3337
#[cfg_attr(any(target_os = "horizon", target_os = "hurd"), allow(unused))]
3438
pub fn new(tv_sec: i64, tv_nsec: i64) -> Result<SystemTime, io::Error> {
3539
Ok(SystemTime { t: Timespec::new(tv_sec, tv_nsec)? })
@@ -62,6 +66,13 @@ impl fmt::Debug for SystemTime {
6266
}
6367

6468
impl Timespec {
69+
const MAX: Timespec = unsafe { Self::new_unchecked(i64::MAX, 1_000_000_000 - 1) };
70+
71+
// As described below, on Apple OS, dates before epoch are represented differently.
72+
// This is not an issue here however, because we are using tv_sec = i64::MIN,
73+
// which will cause the compatibility wrapper to not be executed at all.
74+
const MIN: Timespec = unsafe { Self::new_unchecked(i64::MIN, 0) };
75+
6576
const unsafe fn new_unchecked(tv_sec: i64, tv_nsec: i64) -> Timespec {
6677
Timespec { tv_sec, tv_nsec: unsafe { Nanoseconds::new_unchecked(tv_nsec as u32) } }
6778
}

library/std/src/sys/pal/unsupported/time.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@ impl Instant {
2727
}
2828

2929
impl SystemTime {
30+
pub const MAX: SystemTime = SystemTime(Duration::MAX);
31+
32+
pub const MIN: SystemTime = SystemTime(Duration::ZERO);
33+
3034
pub fn now() -> SystemTime {
3135
panic!("time not implemented on this platform")
3236
}

0 commit comments

Comments
 (0)