Derive/attribute macro that generates a function only if the type is Sized

Playground: Rust Playground

I'm trying to write a macro to derive a couple of functions, one of which should only be derived if the type is Sized. For instance,

struct A(i32);

should generate

impl A {
    fn get(self) -> i32 { self.0 }
    fn get_ref(&self) -> &i32 { &self.0 }
}

but for

struct B([u8]);

should only generate

impl B {
    fn get_ref(&self) -> &[u8] { &self.0 }
}

If the type is generic I can do something like

struct C<T>(T);

impl<T> C<T> {
    fn get(self) -> T where T: Sized { self.0 }
    fn get_ref(&self) -> &T { &self.0 }
}

and it should be fine. However writing the equivalent for a type that is unsized with no generics, that is

impl B {
    fn get(self) -> [u8] where [u8]: Sized { self.0 }
}

is immediately a compile error.

Is there a way around this?

EDIT: Adding this "indirection" also does not trick the compiler into accepting it x) Rust Playground

What you’re looking for is the “trivial bounds” feature, which isn’t yet fully supported or stable. I believe there is a workaround possible based on giving a bound that is sufficiently complex the compiler doesn’t determine that it never holds, but I don’t recall what approach can achieve that.

One merely needs to make the bound higher-ranked.

    //                         vvvvvvvvv
    fn get(self) -> [u8] where for<'__x> [u8]: Sized { self.0 }
3 Likes