Description
According to the documentation of core::marker::Copy
,
Generally speaking, if your type can implement
Copy
, it should. Keep in mind, though, that implementingCopy
is part of the public API of your type. If the type might become non-Copy
in the future, it could be prudent to omit theCopy
implementation now, to avoid a breaking API change.
Zero-sized types in general are a bit tricky in that regard because they (just like core::marker::PhantomData
) can be used to represent ownership over values of types that non-trivially implement core::ops::Drop
.
However, zero-length arrays perhaps should implement Copy
because they can be bit-wise copied (assuming 0-bit/0-byte copy is permitted). It would allow implementing Copy
on overaligned types like the one below:
Is there anything that stops implementing Copy
on zero-length arrays aside from marker trait attribute dependency?
P.S. I would love to have a generic type where the first generic parameter would be the type of the stored value and the second parameter would be a generic constant of type usize
whose value would be used as a constraint for alignment, yet it is a story for discussion on Rust internals/another issue/RFC.
Activity
oli-obk commentedon Feb 24, 2022
cc @rust-lang/project-const-generics
lcnr commentedon Feb 24, 2022
pretty much, yeah. Though I am not sure we want it even once marker trait attributes, as it will be inconsistent with other traits which also rely on lattice specialization, e.g.
Clone
and so onJohnScience commentedon Feb 24, 2022
@lcnr Can you please explain the inconsistency?
lcnr commentedon Feb 24, 2022
We won't be able to implement
Clone
for zero-length arrays without having lattice specialization or by adding some hacks to the compiler.e.g. see
Default
which had the special-case for 0 length arrays and now can't be implemented using const generics https://doc.rust-lang.org/nightly/std/default/trait.Default.html#impl-Default-71.So if we add
impl<T> Copy for [T; 0]
once marker traits are stable, we still won't have these impls forClone
and so on, even though they are just as sensible.Additionally,
Clone
is a supertrait ofCopy
, so you wouldn't be able to add aCopy
impl without first implementingClone
.workingjubilee commentedon Feb 24, 2022
Using 0-length arrays to align things is a hack and should be replaced by an actually fluent interface to adjust layout computations based on various parameters.
JohnScience commentedon Feb 25, 2022
I suggest the following labels for the issue:
Since I can't account for everything and write a reasonable RFC, I think that this issue can remain open until someone finds it useful enough to implement.
Copy
trait implementation for zero-length arrays #94410JohnScience commentedon Feb 27, 2022
I want to do something terribly unsafe. I would like to have a struct implement
Copy
even though the field storing a zero-sized array doesn't. Any ideas which terrible hacks would help me achieve that?Note:
core::mem::ManuallyDrop<T>
implementsCopy
only ifT: Copy
zirconium-n commentedon Feb 28, 2022
Not really solving
[T; 0]
is non-Copy
, but for force alignment, it seemsgeneric_const_exprs
would suffice?lukas-code commentedon Jun 14, 2022
This would be another application of an
unsafe impl Copy
, as proposed in #62835 and #25053.