Auto merge of #132231 - lukas-code:rc-plug-leaks, r=tgross35 · qinheping/verify-rust-std@eb2e420 (original) (raw)

1

1

`use std::any::Any;

`

2

``

`-

use std::cell::RefCell;

`

``

2

`+

use std::cell::{Cell, RefCell};

`

3

3

`use std::iter::TrustedLen;

`

4

4

`use std::mem;

`

5

5

`use std::sync::{Arc, Weak};

`

`@@ -89,7 +89,7 @@ fn eq() {

`

89

89

``

90

90

`` // The test code below is identical to that in rc.rs.

``

91

91

`// For better maintainability we therefore define this type alias.

`

92

``

`-

type Rc = Arc;

`

``

92

`+

type Rc<T, A = std::alloc::Global> = Arc<T, A>;

`

93

93

``

94

94

`const SHARED_ITER_MAX: u16 = 100;

`

95

95

``

`@@ -210,6 +210,42 @@ fn weak_may_dangle() {

`

210

210

`` // borrow might be used here, when val is dropped and runs the Drop code for type std::sync::Weak

``

211

211

`}

`

212

212

``

``

213

`+

/// Test that a panic from a destructor does not leak the allocation.

`

``

214

`+

#[test]

`

``

215

`+

#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")]

`

``

216

`+

fn panic_no_leak() {

`

``

217

`+

use std::alloc::{AllocError, Allocator, Global, Layout};

`

``

218

`+

use std::panic::{AssertUnwindSafe, catch_unwind};

`

``

219

`+

use std::ptr::NonNull;

`

``

220

+

``

221

`+

struct AllocCount(Cell);

`

``

222

`+

unsafe impl Allocator for AllocCount {

`

``

223

`+

fn allocate(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError> {

`

``

224

`+

self.0.set(self.0.get() + 1);

`

``

225

`+

Global.allocate(layout)

`

``

226

`+

}

`

``

227

`+

unsafe fn deallocate(&self, ptr: NonNull, layout: Layout) {

`

``

228

`+

self.0.set(self.0.get() - 1);

`

``

229

`+

unsafe { Global.deallocate(ptr, layout) }

`

``

230

`+

}

`

``

231

`+

}

`

``

232

+

``

233

`+

struct PanicOnDrop;

`

``

234

`+

impl Drop for PanicOnDrop {

`

``

235

`+

fn drop(&mut self) {

`

``

236

`+

panic!("PanicOnDrop");

`

``

237

`+

}

`

``

238

`+

}

`

``

239

+

``

240

`+

let alloc = AllocCount(Cell::new(0));

`

``

241

`+

let rc = Rc::new_in(PanicOnDrop, &alloc);

`

``

242

`+

assert_eq!(alloc.0.get(), 1);

`

``

243

+

``

244

`+

let panic_message = catch_unwind(AssertUnwindSafe(|| drop(rc))).unwrap_err();

`

``

245

`+

assert_eq!(*panic_message.downcast_ref::<&'static str>().unwrap(), "PanicOnDrop");

`

``

246

`+

assert_eq!(alloc.0.get(), 0);

`

``

247

`+

}

`

``

248

+

213

249

`` /// This is similar to the doc-test for Arc::make_mut(), but on an unsized type (slice).

``

214

250

`#[test]

`

215

251

`fn make_mut_unsized() {

`