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,

`