diff --git a/src/lib.rs b/src/lib.rs index cb15e1a..fb29bec 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -17,23 +17,27 @@ //! Actually making use of QADAPT is straight-forward. To set up the allocator, //! place the following snippet in either your program binaries (main.rs) or tests: //! -//! ```rust,no_run +//! ```rust //! use qadapt::QADAPT; //! //! #[global_allocator] //! static Q: QADAPT = QADAPT; //! //! fn main() { +//! # // Because `debug_assertions` are on for doctests in release mode +//! # // we have to add an extra guard. +//! # if qadapt::is_active() { //! if cfg!(debug_assertions) { //! assert!(qadapt::is_active()); //! } +//! # } //! } //! ``` //! //! After that, there are two ways of telling QADAPT that it should trigger a panic: //! //! 1. Annotate functions with the `#[no_alloc]` proc macro: -//! ```rust,no_run +//! ```rust //! use qadapt::no_alloc; //! use qadapt::QADAPT; //! use std::panic::catch_unwind; @@ -57,7 +61,9 @@ //! do_math(); //! //! let err = catch_unwind(|| does_panic()); +//! # if qadapt::is_active() { //! assert!(err.is_err()); +//! # } //! } //! ``` //! @@ -96,22 +102,27 @@ use std::thread; thread_local! { static PROTECTION_LEVEL: RwLock = RwLock::new(0); } +static IS_ACTIVE: RwLock = RwLock::new(false); +static INTERNAL_ALLOCATION: RwLock = RwLock::new(usize::max_value()); + /// The QADAPT allocator itself /// /// To make use of the allocator, include this code block in your program /// binaries/tests: /// -/// ```rust,no_run +/// ```rust /// use qadapt::QADAPT; /// /// #[global_allocator] /// static Q: QADAPT = QADAPT; /// /// fn main() { +/// # if qadapt::is_active() { /// if cfg!(debug_assertions) { /// assert!(qadapt::is_active()); /// } +/// # } /// } /// ``` pub struct QADAPT; @@ -228,7 +239,7 @@ pub fn exit_protected() { /// in code that was not intended to be allocation-free. The compiler will warn you /// that there is an unreachable statement if this happens. /// -/// ```rust,no_run +/// ```rust /// use qadapt::assert_no_alloc; /// use qadapt::QADAPT; /// use std::panic::catch_unwind; @@ -247,8 +258,10 @@ pub fn exit_protected() { /// // QADAPT allocation guards, this triggers a panic: /// // `Box::new` forces an allocation, and QADAPT still thinks /// // we're in a protected region because of the return in `early_return()` +/// # if qadapt::is_active() { /// let res = catch_unwind(|| Box::new(x)); /// assert!(res.is_err()); +/// # } /// } #[macro_export] macro_rules! assert_no_alloc { @@ -260,16 +273,13 @@ macro_rules! assert_no_alloc { }}; } -static IS_ACTIVE: RwLock = RwLock::new(false); -static INTERNAL_ALLOCATION: RwLock = RwLock::new(usize::max_value()); - /// Get the current "protection level" in QADAPT: calls to `enter_protected() - exit_protected()`. /// /// **Note**: For release builds, `protection_level()` will always return 0. /// /// **Example**: /// -/// ```rust,no_run +/// ```rust /// use qadapt::enter_protected; /// use qadapt::exit_protected; /// use qadapt::QADAPT; @@ -279,6 +289,7 @@ static INTERNAL_ALLOCATION: RwLock = RwLock::new(usize::max_value()); /// static Q: QADAPT = QADAPT; /// /// fn main() { +/// # if qadapt::is_active() { /// enter_protected(); /// // We're now in an allocation-protected code region /// assert_eq!(1, protection_level()); @@ -288,6 +299,7 @@ static INTERNAL_ALLOCATION: RwLock = RwLock::new(usize::max_value()); /// assert_eq!(2, protection_level()); /// exit_protected(); /// exit_protected(); +/// # } /// /// // It's now safe to allocate/drop /// } @@ -302,7 +314,7 @@ pub fn protection_level() -> usize { /// /// **Example**: /// -/// ```rust,no_run +/// ```rust /// use qadapt::is_active; /// use qadapt::QADAPT; /// @@ -310,9 +322,11 @@ pub fn protection_level() -> usize { /// static Q: QADAPT = QADAPT; /// /// pub fn main() { +/// # if qadapt::is_active() { /// if cfg!(debug_assertions) { /// assert!(is_active()); /// } +/// # } /// } /// ``` pub fn is_active() -> bool {