1use core::ptr::NonNull;
2
3macro_rules! feature {
4 (
5 #![$meta:meta]
6 $($item:item)*
7 ) => {
8 $(
9 #[cfg($meta)]
10 #[cfg_attr(docsrs, doc(cfg($meta)))]
11 $item
12 )*
13 }
14}
15
16macro_rules! loom_const_fn {
17 (
18 $(#[$meta:meta])*
19 $vis:vis unsafe fn $name:ident($($arg:ident: $T:ty),*) -> $Ret:ty $body:block
20 ) => {
21 $(#[$meta])*
22 #[cfg(not(loom))]
23 $vis const unsafe fn $name($($arg: $T),*) -> $Ret $body
24
25 $(#[$meta])*
26 #[cfg(loom)]
27 $vis unsafe fn $name($($arg: $T),*) -> $Ret $body
28 };
29 (
30 $(#[$meta:meta])*
31 $vis:vis fn $name:ident($($arg:ident: $T:ty),*) -> $Ret:ty $body:block
32 ) => {
33 $(#[$meta])*
34 #[cfg(not(loom))]
35 $vis const fn $name($($arg: $T),*) -> $Ret $body
36
37 $(#[$meta])*
38 #[cfg(loom)]
39 $vis fn $name($($arg: $T),*) -> $Ret $body
40 }
41}
42
43#[cfg(debug_assertions)]
46#[track_caller]
47#[inline(always)]
48pub(crate) unsafe fn non_null<T>(ptr: *mut T) -> NonNull<T> {
49 NonNull::new(ptr).expect(
50 "/!\\ constructed a `NonNull` from a null pointer! /!\\ \n\
51 in release mode, this would have called `NonNull::new_unchecked`, \
52 violating the `NonNull` invariant! this is a bug in `cordyceps!`.",
53 )
54}
55
56#[cfg(not(debug_assertions))]
61#[inline(always)]
62pub(crate) unsafe fn non_null<T>(ptr: *mut T) -> NonNull<T> {
63 NonNull::new_unchecked(ptr)
64}
65
66#[cfg(test)]
67pub(crate) use self::test::trace_init;
68
69pub(crate) fn expect_display<T, E: core::fmt::Display>(result: Result<T, E>, msg: &str) -> T {
70 match result {
71 Ok(t) => t,
72 Err(error) => panic!("{msg}: {error}"),
73 }
74}
75
76#[cfg(test)]
77pub(crate) mod test {
78 #[must_use]
85 pub struct TestGuard {
86 #[cfg(not(loom))]
87 _x2: tracing_02::collect::DefaultGuard,
88 #[cfg(loom)]
89 _x1: tracing_01::subscriber::DefaultGuard,
90 }
91
92 pub(crate) fn trace_init() -> TestGuard {
97 trace_init_with_default("maitake=debug,cordyceps=debug")
98 }
99
100 #[cfg(not(loom))]
105 pub(crate) fn trace_init_with_default(default: &str) -> TestGuard {
106 use tracing_subscriber::filter::{EnvFilter, LevelFilter};
107 let env = std::env::var("RUST_LOG").unwrap_or_default();
108 let builder = EnvFilter::builder().with_default_directive(LevelFilter::INFO.into());
109 let filter = if env.is_empty() {
110 builder.parse(default).unwrap()
111 } else {
112 builder.parse_lossy(env)
113 };
114 let filter = filter.add_directive("maitake::alloc=trace".parse().unwrap());
116 let collector = tracing_subscriber::fmt()
117 .with_env_filter(filter)
118 .with_test_writer()
119 .without_time()
120 .finish();
121
122 TestGuard {
123 _x2: tracing_02::collect::set_default(collector),
124 }
125 }
126
127 #[cfg(loom)]
132 pub(crate) fn trace_init_with_default(default: &str) -> TestGuard {
133 use tracing_subscriber_03::filter::{EnvFilter, LevelFilter};
134 let env = std::env::var("LOOM_LOG").unwrap_or_default();
135 let builder = EnvFilter::builder().with_default_directive(LevelFilter::INFO.into());
136 let filter = if env.is_empty() {
137 builder
138 .parse(default)
139 .unwrap()
140 .add_directive("loom=info".parse().unwrap())
143 } else {
144 builder.parse_lossy(env)
145 };
146 let collector = tracing_subscriber_03::fmt()
147 .with_env_filter(filter)
148 .with_test_writer()
149 .without_time()
150 .finish();
151
152 use tracing_subscriber_03::util::SubscriberInitExt;
153 TestGuard {
154 _x1: collector.set_default(),
155 }
156 }
157}