# Error code E0802

The target of `derive(CoercePointee)` macro has inadmissible specification for a meaningful use.

Erroneous code examples:

The target data is not a `struct`.

    #![allow(unused)]
    #![feature(coerce_pointee)]
    fn main() {
    use std::marker::CoercePointee;
    #[derive(CoercePointee)]
    enum NotStruct<'a, T: ?Sized> {
        Variant(&'a T),
    }
    }

The target data has a layout that is not transparent, or `repr(transparent)` in other words.

    #![allow(unused)]
    #![feature(coerce_pointee)]
    fn main() {
    use std::marker::CoercePointee;
    #[derive(CoercePointee)]
    struct NotTransparent<'a, #[pointee] T: ?Sized> {
        ptr: &'a T,
    }
    }

The target data has no data field.

    #![allow(unused)]
    #![feature(coerce_pointee)]
    fn main() {
    use std::marker::CoercePointee;
    #[derive(CoercePointee)]
    #[repr(transparent)]
    struct NoField<'a, #[pointee] T: ?Sized> {}
    }

The target data is not generic over any data, or has no generic type parameter.

    #![allow(unused)]
    #![feature(coerce_pointee)]
    fn main() {
    use std::marker::CoercePointee;
    #[derive(CoercePointee)]
    #[repr(transparent)]
    struct NoGeneric<'a>(&'a u8);
    }

The target data has multiple generic type parameters, but none is designated as a pointee for coercion.

    #![allow(unused)]
    #![feature(coerce_pointee)]
    fn main() {
    use std::marker::CoercePointee;
    #[derive(CoercePointee)]
    #[repr(transparent)]
    struct AmbiguousPointee<'a, T1: ?Sized, T2: ?Sized> {
        a: (&'a T1, &'a T2),
    }
    }

The target data has multiple generic type parameters that are designated as pointees for coercion.

    #![allow(unused)]
    #![feature(coerce_pointee)]
    fn main() {
    use std::marker::CoercePointee;
    #[derive(CoercePointee)]
    #[repr(transparent)]
    struct TooManyPointees<
        'a,
        #[pointee] A: ?Sized,
        #[pointee] B: ?Sized>
    ((&'a A, &'a B));
    }

The type parameter that is designated as a pointee is not marked `?Sized`.

    #![allow(unused)]
    #![feature(coerce_pointee)]
    fn main() {
    use std::marker::CoercePointee;
    #[derive(CoercePointee)]
    #[repr(transparent)]
    struct NoMaybeSized<'a, #[pointee] T> {
        ptr: &'a T,
    }
    }

In summary, the `CoercePointee` macro demands the type to be a `struct` that is generic over at least one type or over more types, one of which is marked with `#[pointee]`, and has at least one data field and adopts a `repr(transparent)` layout. The only generic type or the type marked with `#[pointee]` has to be also marked as `?Sized`.