Macro kernel::assert_pinned

source ·
macro_rules! assert_pinned {
    ($ty:ty, $field:ident, $field_ty:ty, inline) => { ... };
    ($ty:ty, $field:ident, $field_ty:ty) => { ... };
}
Expand description

Asserts that a field on a struct using #[pin_data] is marked with #[pin] ie. that it is structurally pinned.

§Example

This will succeed:

use kernel::assert_pinned;
#[pin_data]
struct MyStruct {
    #[pin]
    some_field: u64,
}

assert_pinned!(MyStruct, some_field, u64);

This will fail:

use kernel::assert_pinned;
#[pin_data]
struct MyStruct {
    some_field: u64,
}

assert_pinned!(MyStruct, some_field, u64);

Some uses of the macro may trigger the can't use generic parameters from outer item error. To work around this, you may pass the inline parameter to the macro. The inline parameter can only be used when the macro is invoked from a function body.

use kernel::assert_pinned;
#[pin_data]
struct Foo<T> {
    #[pin]
    elem: T,
}

impl<T> Foo<T> {
    fn project(self: Pin<&mut Self>) -> Pin<&mut T> {
        assert_pinned!(Foo<T>, elem, T, inline);

        // SAFETY: The field is structurally pinned.
        unsafe { self.map_unchecked_mut(|me| &mut me.elem) }
    }
}