extern_existential/
lib.rs

1#![no_std]
2
3#[macro_export]
4macro_rules! extern_existential {
5    ( $(#[$m:meta])* extern existential type $i:ident: $tr:path = $ty:path; ) => {
6        $(#[$m])*
7        #[no_mangle]
8        pub static $i: &(dyn $tr + Send + Sync + 'static) = &$ty;
9    };
10    ( $(#[$m:meta])* $v:vis extern existential type $i:ident: $tr:path; ) => {
11        $(#[$m])*
12        $v struct $i;
13
14        impl core::ops::Deref for $i {
15            type Target = dyn $tr + 'static;
16
17            // make sure the use of the extern symbol appears in another crate
18            // so the undefined symbol appears in the right place in the link
19            // order
20            #[inline(always)]
21            fn deref(&self) -> &(dyn $tr + 'static) {
22                #[allow(improper_ctypes)]
23                extern "Rust" {
24                    static $i: &'static (dyn $tr + Send + Sync + 'static);
25                }
26
27                unsafe { $i }
28            }
29        }
30    };
31}