Freeze is a lang-item marker auto-trait that indicates that a type does not contain any shared mutability (UnsafeCell) before indirection.
This property is observable on stable (and has been for a long while) even though the trait is unstable; it is only allowed to take a reference to a place in const context if that place was already behind a reference or has a Freeze type (feature(const_refs_to_cell)).
For a #[repr(packed)] type, the built-in #[derive] work by copying from the fields, since it's unsafe to reference an underaligned field. However, since the field is copied to the stack, if it were to contain any shared mutability, any writes from the delegated to trait implementation would get silently discarded.
This scenario is impossible so long as a type being Copy also requires it to be Freeze. UnsafeCell is not Copy, thus implementing Copy will indirectly require Freeze. However, I recall discussion saying that Cell<impl Copy> could potentially be made to impl Copy, it would just be a bit of a footgun similar to iterators, mutating a copy but expecting to change the original source as well.
I think it could be prudent to just make Freeze into a supertrait of Copy (and thus finalize that Cell must never be Copy). This turns an informal expectation into a stable guarantee that can then be relied upon.
A Copy + !Freeze field doesn't make packed derives unsound, since no unsafe is involved, but it would certainly be surprising; especially so if the derive ever chooses to bypass the copy for fields that are already guaranteed to be sufficiently aligned.