Is assigning a non-Drop type to variable that claims to be of its type but is actually uninitialized always OK?

Suppose I have Rust struct Foo that's not Drop and whose fields (recursively) are not Drop. If I get foo: *mut Foo from FFI and assign a Foo to *foo, is it guaranteed that new bits get written only and the operation causes no reads from *foo? I.e. it's OK if foo points to uninitialized memory obtained from malloc() in C (i.e. C provides memory to a Rust type)? (AFAICT, it's OK for C to just free() the memory when it's done, since a non-Drop Rust object needs no clean-up. AFAICT, malloc() guarantees enough alignment that the malloc()-returned pointer should be sufficiently aligned for everything.)

Is there a way to mark a type as not being Drop such that it fails to compile if (recursively) a Drop field is added?

Any reason not to use ptr::write? That would handle a Drop type as well.

I think if you impl Copy for Foo {}, the compiler will make sure that no part of it is Drop, since those two traits are exclusive.

1 Like

I was unaware of ptr::write. If the type is non-Drop, is there any benefit from using ptr::write over a plain assignment?

While the type should be disposable without any Drop cleanup (i.e. it should be disposable with just free() in C if written to memory provided by malloc()), it does have internal state, so on the Rust side it would be undesirable for it to behave like Copy. With Copy, an instance initially created using a factory method would be copied on each assignment with the snapshot of the internal state at the time of the copy remaining usable via the old variable binding. That would be a footgun on the Rust side. I want to retain move semantics on the Rust side.

(Concretely, what I'm pondering is if encoding_rs::Decoder can be stored in a "user data" void* in a C++ API that's misdesigned such that there's no public API for providing a custom clean-up function and the user data void* is free()ed by the internals of the C++ API. The not awesome C++ API is the Qt QTextCodec extension mechanism, FWIW. Internally, it does have the ability to set a custom clean-up function, but that part of the API is considered private to Qt!)

1 Like

Other than being able to grep/find usages of this a bit easier, there’s no other advantage that I can think of in this case.