Lokathor/bytemuck

Split `Pod` into two traits

zakarumych opened this issue · 13 comments

Traits NoPadding and AnyBitPattern that would allow "casting" like this

fn cast<T, U>(T) -> U
where
    T: NoPadding,
    U: AnyBitPattern,
{
   ...
}

Then Pod is simply both.

As a simple use-case, this will enable us to reinterpret structures with bool as bytes.

When the 1.0 of this crate was being developed, no one considered the ability to view a &bool as a &u8 very valuable, so this particular trait split was skipped on.

I think this would be a breaking change to fit in to the existing crate.

Because of the safe transmute project, any work on a 2.0 is being held off until that project is done and stabilized. However, at that time we might be able to split up the traits like this.

Would it be a breaking change though?
Relaxing requirements on functions doesn't seem to break anything.

If we add blanket impls like this

instead of the other way around then all existing implementation would still work.

The downside of blanket impls in this direction is that implementing both NoPadding and AnyBitPattern won't make type a Pod automagically.

I admit I'm not a trait expert, so with careful design it might be done I suppose.

I'll point some of the trait folks I know at this topic and maybe they can weigh in.

Once again I'd really like this feature, as I want to cast bytes to other types which can have padding but accept any bit pattern.

We could have a NoPadding trait that lets you turn &A into &[u8], and just have it as a separate thing from Pod. That wouldn't be a breaking change.

And currently I need the reverse. Turning &[u8] into A: AnyBitPattern.
Although NoPadding has its use cases as well.
Do you still think proposed solution above may be a breaking change?

Yeah. No one I spoke to thought that it was possible to insert and extra trait into the trait tree.

I'm curious. Did they provide a counterexample?

BTW. This change below is not even required.

trait Pod: NoPadding + AnyBitPattern {}

Pod may stay separate. Only functions bounds should be relaxed.
Given impls for any Pod type, generic code with T: Pod bound should be able to call function that would require T: AnyBitPattern or T: NoPadding.

No one showed that it couldn't be done, but no one definitely showed it can be done with absolutely no chance of breaks.

I'd rather just have a separate trait, which is assured to not break any existing code.

Do you mean that you want separate functions as well?

Yes, we should add this as just a separate group of traits and functions. No breakage that way.

This has been done as much as will happen in version 1.

Version 2 of the crate will be largely defined by how the safe-transmute project works out, so it's hard to say precisely, but this is expected to be possible at that time.

For now I'm gonna close it.