I'm not really sure what you mean by "cleaned up". Memory on the stack will just be reused. The next time that memory location is used as part of a stack value, the old memory will simply be overwritten with a new value.
Copy types definitionally don't need additional logic to clean up after them, since they can't implement Drop and can't contain other types that aren't Copy.
I'm sorry, I'm trying to make my statement more precise:
As I understand it, the compiler inserts drop glue in the program for certain types in order to make the used memory available again for other purposes but I've read (eg here) that the compiler won't add any drop glue for types which are Copy. So my question is: Which mechanism(s) ensures that the used memory of such types, which are Copy, gets freed again?
The drop glue is responsible for calling the Drop impls to free resources held by the value. The memory containing the value itself is not freed up by the drop glue. As a Copy type can't have any associated resources by the virtue of not being able to implement Drop and by being freely copyable, there is no drop glue to run. If the value is held on the stack, the memory is reused either when the function returns or in some cases if the value becomes dead and the compiler reused the place on the stack for another value. If the value is on the heap, the drop glue of the value owning the heap location (eg Box or Vec) is responsible for freeing the memory, not the value that is stored on the heap itself.
The compiler will always make the memory free for other purposes, regardless of whether the type is Copy or not. Some types need to do more than just have their memory freed when they go out of scope - for this purpose, Rust has the Drop::drop trait method, which you implement to have the compiler run code when your type goes out of scope, just before the compiler inserts code that frees the memory for your instance.
"Drop glue" is the code the compiler inserts to run Drop::drop methods when you let a value go out of scope. This allows for (e.g.) a std::fs::File to close the file it has open just before you free up the memory that tells the std::fs::File code which file you have open.
Well, a simple example is that String does not implement Drop itself, but it definitely has drop glue for its Vec field. But a type can only implement Copy if all of its fields do as well, so there can't be any drop glue at all.
Of course, to be more precise, fields that don't implement Drop but merely have Drop glue are also causing their parent type to have Drop glue. I. e. it's a recursively defined thing, considering fields, and fields of fields, and fields of fields of fields, and so on.
(Also as a special case, types like MaybeUninit or ManuallyDrop never have drop glue.)
Of course, I fully agree with this. On the other hand, I think it's also useful that one can understand MaybeUninit without considering (or even knowing) that it's implemented using a union.
Regarding the documentation distinguishing struct from union, AFAIR that's a point that has existing discussions as to whether that's something rustdoc should maybe not call out for opaque types.
I get it, abstraction boundary and all, but I need to look behind the curtain often enough I get annoyed when rustdoc omits information... much less intentionally obscures it.