-
Notifications
You must be signed in to change notification settings - Fork 142
Open
Description
Many users ask for the ability to derive a zerocopy trait on their public type without allowing its methods to be called by users outside of the defining module - in other words, for the impl itself to be "private".
Rust doesn't support this natively, but we might be able to emulate it.
Some notes from a conversation with @kupiakos and @jswrenn discussion how to accomplish this.
#[derive(FromBytes)]
#[zerocopy(private)]
struct Foo { ... }pub unsafe trait FromBytes<Scope = ()> {
}
// my crate:
struct Private;
#[derive(FromBytes)]
#[zerocopy(FromBytes(scope = Private))]
// can still access in another crate with a private scope, breaking
// this entirely:
fn transmute<Scope, T: FromBytes<Scope>>(x: &[u8]) -> &T {
...
}
#[derive(FromBytes)]
#[derive(...)]
struct FooInner {
x: i32,
y: i32,
}
#[repr(transparent)]
struct Foo(FooInner);
transmute!(ref_to_foo_inner) -> &Foo
// assert size and align of Foo equals FooInner?
transmute!(ref_to_foo_inner) -> &Bar
&Foo: TransmuteFrom<&FooInner, Assume::SAFETY>
impl Foo {
fn from_inner(inner: &FooInner) -> &Foo {
// SAFETY: We're only assuming safety, and we're the authors
// of this abstraction, and we know that...
unsafe { TransmuteFrom::<_, Assume::SAFETY>::transmute(inner) }
}
}// Input
#[derive(FromBytes)]
#[zerocopy(private)]
pub struct Foo(...);
// Converted into:
#[derive(FromBytes)]
struct FooInner(...);
#[repr(transparent)]
pub struct Foo(FooInner);
impl Foo {
}// Input
#[derive(FromBytes)]
#[zerocopy(private)]
pub struct Foo(...);
// Converted into:
struct Foo(...);
// impls FromBytes on FooTransmute
#[repr(transparent)]
struct FooTransmute(Foo);
impl FooTransmute {
fn inner_ref(&self) -> &Foo {
}
}
#[repr(transparent)]
pub struct Foo(FooInner);
impl Foo {
fn from_bytes(x: &[u8]) -> &Foo {
&FooTransmute::ref_from(x).0
}
}Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels