| //@ run-pass | |
| #![feature(allocator_api)] | |
| // Regression test for #131082. | |
| // Testing that the allocator of a Box is dropped in conditional drops | |
| use std::alloc::{AllocError, Allocator, Global, Layout}; | |
| use std::cell::Cell; | |
| use std::ptr::NonNull; | |
| struct DropCheckingAllocator<'a>(&'a Cell<bool>); | |
| unsafe impl Allocator for DropCheckingAllocator<'_> { | |
| fn allocate(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError> { | |
| Global.allocate(layout) | |
| } | |
| unsafe fn deallocate(&self, ptr: NonNull<u8>, layout: Layout) { | |
| Global.deallocate(ptr, layout); | |
| } | |
| } | |
| impl Drop for DropCheckingAllocator<'_> { | |
| fn drop(&mut self) { | |
| self.0.set(true); | |
| } | |
| } | |
| struct HasDrop; | |
| impl Drop for HasDrop { | |
| fn drop(&mut self) {} | |
| } | |
| fn main() { | |
| let dropped = Cell::new(false); | |
| { | |
| let b = Box::new_in(HasDrop, DropCheckingAllocator(&dropped)); | |
| if true { | |
| drop(*b); | |
| } else { | |
| drop(b); | |
| } | |
| } | |
| assert!(dropped.get()); | |
| } |