Skip to main content

link_section/
item.rs

1//! Item handling.
2
3use crate::{MovableRef, Ref};
4
5/// Argument to [`crate::TypedSection::offset_of`] and related section lookup APIs.
6pub trait SectionItemLocation<T: ?Sized> {
7    /// Address of the item's storage in the link section (not the wrapper).
8    fn item_ptr(&self) -> *const T;
9}
10
11impl<T: ?Sized> SectionItemLocation<T> for &T {
12    fn item_ptr(&self) -> *const T {
13        *self as *const T
14    }
15}
16
17impl<T> SectionItemLocation<T> for &Ref<T> {
18    fn item_ptr(&self) -> *const T {
19        Ref::as_ptr(self)
20    }
21}
22
23impl<T> SectionItemLocation<T> for &MovableRef<T> {
24    fn item_ptr(&self) -> *const T {
25        MovableRef::as_ptr(self)
26    }
27}
28
29/// Element type for this section handle ([`crate::TypedSection`], etc.).
30pub trait SectionItemType {
31    /// Item type stored or referenced in the section.
32    type Item;
33}
34
35// Waiting on Rust 1.78
36// #[diagnostic::on_unimplemented(message = "Incorrect section type for item")]
37/// Typed section compatibility for item `T`.
38pub trait SectionItemTyped<T> {
39    /// Item representation for this `T`.
40    type Item;
41}
42
43#[cfg(test)]
44mod tests {
45    use crate::item::SectionItemType;
46    use core::marker::PhantomData;
47
48    assert_type_eq!(<crate::TypedSection<u32> as SectionItemType>::Item, u32);
49    assert_type_eq!(
50        <crate::TypedSection<&'static u32> as SectionItemType>::Item,
51        &'static u32
52    );
53
54    macro_rules! assert_type_eq {
55        ($lhs:ty, $rhs:ty) => {
56            const _: () = {
57                struct __AssertTypeEq<T, U>(PhantomData<T>, PhantomData<U>);
58                trait __AssertTypeEqT {
59                    const CHECK: bool = true;
60                }
61                impl<T> __AssertTypeEqT for __AssertTypeEq<T, T> {}
62
63                _ = <__AssertTypeEq<$lhs, $rhs> as __AssertTypeEqT>::CHECK;
64            };
65        };
66    }
67    pub(crate) use assert_type_eq;
68}