Move test_shrink_to_unwind
to its own file. · model-checking/verify-rust-std@d0c07aa (original) (raw)
1
``
`-
#![feature(alloc_error_hook)]
`
2
``
-
3
``
`-
use crate::alloc::{AllocError, Layout};
`
4
``
`-
use core::{iter::TrustedLen, ptr::NonNull};
`
5
``
`-
use std::{
`
6
``
`-
alloc::{set_alloc_error_hook, take_alloc_error_hook, System},
`
7
``
`-
panic::{catch_unwind, AssertUnwindSafe},
`
8
``
`-
};
`
``
1
`+
use core::iter::TrustedLen;
`
9
2
``
10
3
`use super::*;
`
11
4
``
`@@ -797,52 +790,6 @@ fn test_shrink_to() {
`
797
790
`}
`
798
791
`}
`
799
792
``
800
``
`-
#[test]
`
801
``
`-
fn test_shrink_to_unwind() {
`
802
``
`` -
// This tests that shrink_to
leaves the deque in a consistent state when
``
803
``
`` -
// the call to RawVec::shrink_to_fit
unwinds. The code is adapted from #123369
``
804
``
`-
// but changed to hopefully not have any UB even if the test fails.
`
805
``
-
806
``
`-
struct BadAlloc;
`
807
``
-
808
``
`-
unsafe impl Allocator for BadAlloc {
`
809
``
`-
fn allocate(&self, l: Layout) -> Result<NonNull<[u8]>, AllocError> {
`
810
``
`-
// We allocate zeroed here so that the whole buffer of the deque
`
811
``
`-
// is always initialized. That way, even if the deque is left in
`
812
``
`-
// an inconsistent state, no uninitialized memory should be accessed.
`
813
``
`-
System.allocate_zeroed(l)
`
814
``
`-
}
`
815
``
-
816
``
`-
unsafe fn deallocate(&self, ptr: NonNull, layout: Layout) {
`
817
``
`-
unsafe { System.deallocate(ptr, layout) }
`
818
``
`-
}
`
819
``
-
820
``
`-
unsafe fn shrink(
`
821
``
`-
&self,
`
822
``
`-
_ptr: NonNull,
`
823
``
`-
_old_layout: Layout,
`
824
``
`-
_new_layout: Layout,
`
825
``
`-
) -> Result<NonNull<[u8]>, AllocError> {
`
826
``
`-
Err(AllocError)
`
827
``
`-
}
`
828
``
`-
}
`
829
``
-
830
``
`-
// preserve the old error hook just in case.
`
831
``
`-
let old_error_hook = take_alloc_error_hook();
`
832
``
`-
set_alloc_error_hook(|_| panic!("alloc error"));
`
833
``
-
834
``
`-
let mut v = VecDeque::with_capacity_in(15, BadAlloc);
`
835
``
`-
v.push_back(1);
`
836
``
`-
v.push_front(2);
`
837
``
`` -
// This should unwind because it calls BadAlloc::shrink
and then handle_alloc_error
which unwinds.
``
838
``
`-
assert!(catch_unwind(AssertUnwindSafe(|| v.shrink_to_fit())).is_err());
`
839
``
`-
// This should only pass if the deque is left in a consistent state.
`
840
``
`-
assert_eq!(v, [2, 1]);
`
841
``
-
842
``
`-
// restore the old error hook.
`
843
``
`-
set_alloc_error_hook(old_error_hook);
`
844
``
`-
}
`
845
``
-
846
793
`#[test]
`
847
794
`fn test_shrink_to_fit() {
`
848
795
`// This test checks that every single combination of head and tail position,
`