-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ManuallyDrop
type gives precise control of dtors of inline data.
#197
Conversation
(Warning: thread hijack.) I've been thinking about a proposal which seems related and might subsume this one. I'm not at the point of writing an RFC for it, but I'll describe it briefly as food for thought:
And the connection to this proposal is that (With the respect to the built-in traits, this is an interesting question. Right now I'm thinking we should probably avoid unnecessary unsafety, and have |
👍 on |
Maybe only tangentially relevant, but we could really stand to have a more obviously in-place way to drop something than the |
@ben0x539 rust-lang/rust#16242 @glaebhoerl on a first reading, I think that idea isn't crazy.
It would literally just be an untyped chunk of bytes. If it did inform the compiler about the contained types, it seems like it is essentially identical to |
+1. Also, this means that the |
+1, this is definitely the right choice to sanely handle SmallVec-ish cases. The massive unsafety it introduces is in my mind acceptable, as it's not something you would use casually, but ideal for efficiently fiddling with fixed-size inline buffers. Ideally, this would only be used internally by libraries to expose an efficient mechanism with a safe interface. e.g. Small/Inline Vecs I have no strong opinion on more general mechanisms, as destructors are the only thing that I've found troubling. |
I'm "blocked" on this because I don't know if going with I'm inclined to think we should start simple, but I'm also inclined to think |
6357402
to
e0acdf4
Compare
+1, I think having a unsafe |
This could be done (except for static initialization) without adding a special case to the compiler if Rust had CTFE (at least for size_of.) struct ManuallyDrop<T> {
#[aligned(alignof(T))]
data: [u8, ..std::mem::size_of::<T>()],
_nocopy: std::kinds::marker::NoCopy,
}
impl<T> ManuallyDrop<T> {
pub unsafe fn new(t: T) -> ManuallyDrop<T> {
let ret = ManuallyDrop {
data: std::mem::transmute(t)
};
std::mem::forget(t);
ret
}
pub fn unwrap(self) -> T {
unsafe { std::mem::transmute(self.data); }
}
}
impl<T> Deref<T> for ManuallyDrop<T> {
fn deref(&self) -> &T {
unsafe { std::mem::transmute(&self.data) }
}
}
impl<T> DerefMut<T> for ManuallyDrop<T> {
fn deref_mut(&mut self) -> &mut T {
unsafe { std::mem::transmute(&mut self.data) }
}
} |
Along with CTFE, it also needs the alignment attribute (minor but it's not something we have in Rust now), and, @glaebhoerl's |
Off topic: I expect the aligned attribute to appear before 1.0 because, afaik, the only way to currently align a struct at a 16 bytes boundary is to add a |
I've really no idea how the special treatment for UnsafeCell works, but maybe the following would solve the problem? struct ManuallyDrop<T> {
#[aligned(alignof(T))]
data: [u8, ..std::mem::size_of::<T>()],
_ty: [T, ..0],
} Then (Furthermore this means that the struct is at least |
+1, this enables us to make pub struct Rc<T> {
_ptr: ManuallyDrop<Box<RcBox<T>>>,
_nosend: marker::NoSend,
_noshare: marker::NoSync
} |
It would be nice if the lang item could be specialcased so that implicitly dropping That plan doesn't seem to work so nicely with the hypothetical in-place drop facility though. You'd need to write |
I thought about this a bit more, and I do like @glaebhoerl @ben0x539 The impl<T> ManuallyDrop<T> {
unsafe fn run_destructor(&mut self) {
ptr::drop_in_place(self.get_mut())
}
unsafe fn discard(self) { mem::forget(self) }
} so your snippet becomes |
Still relevant. |
This PR is an implementation of [RFC 1974] which specifies a new method of defining a global allocator for a program. This obsoletes the old `#![allocator]` attribute and also removes support for it. [RFC 1974]: rust-lang/rfcs#197 The new `#[global_allocator]` attribute solves many issues encountered with the `#![allocator]` attribute such as composition and restrictions on the crate graph itself. The compiler now has much more control over the ABI of the allocator and how it's implemented, allowing much more freedom in terms of how this feature is implemented. cc rust-lang#27389
This PR is an implementation of [RFC 1974] which specifies a new method of defining a global allocator for a program. This obsoletes the old `#![allocator]` attribute and also removes support for it. [RFC 1974]: rust-lang/rfcs#197 The new `#[global_allocator]` attribute solves many issues encountered with the `#![allocator]` attribute such as composition and restrictions on the crate graph itself. The compiler now has much more control over the ABI of the allocator and how it's implemented, allowing much more freedom in terms of how this feature is implemented. cc rust-lang#27389
This PR is an implementation of [RFC 1974] which specifies a new method of defining a global allocator for a program. This obsoletes the old `#![allocator]` attribute and also removes support for it. [RFC 1974]: rust-lang/rfcs#197 The new `#[global_allocator]` attribute solves many issues encountered with the `#![allocator]` attribute such as composition and restrictions on the crate graph itself. The compiler now has much more control over the ABI of the allocator and how it's implemented, allowing much more freedom in terms of how this feature is implemented. cc rust-lang#27389
This PR is an implementation of [RFC 1974] which specifies a new method of defining a global allocator for a program. This obsoletes the old `#![allocator]` attribute and also removes support for it. [RFC 1974]: rust-lang/rfcs#197 The new `#[global_allocator]` attribute solves many issues encountered with the `#![allocator]` attribute such as composition and restrictions on the crate graph itself. The compiler now has much more control over the ABI of the allocator and how it's implemented, allowing much more freedom in terms of how this feature is implemented. cc #27389
This is a replacement for zeroing, acting like
*_ T
wrt destructors (i.e. they need to be run manually).