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() {
`