From 88078e7770a2beda072ac37f89e2a81e5a9cb243 Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Fri, 15 Feb 2019 19:52:25 +0100 Subject: add "nightly" feature --- src/export.rs | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++++---- src/lib.rs | 1 + 2 files changed, 62 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/export.rs b/src/export.rs index 6eae65f..f8fc815 100644 --- a/src/export.rs +++ b/src/export.rs @@ -1,8 +1,10 @@ //! IMPLEMENTATION DETAILS. DO NOT USE ANYTHING IN THIS MODULE -#[cfg(not(debug_assertions))] +#[cfg(all(not(feature = "nightly"), not(debug_assertions)))] use core::hint; -use core::{cell::Cell, ptr, u8}; +#[cfg(not(feature = "nightly"))] +use core::ptr; +use core::{cell::Cell, u8}; #[cfg(armv7m)] use cortex_m::register::basepri; @@ -64,17 +66,72 @@ impl Priority { } } -// TODO(MaybeUninit) Until core::mem::MaybeUninit is stabilized we use our own (inefficient) -// implementation +#[cfg(feature = "nightly")] +pub struct MaybeUninit { + // we newtype so the end-user doesn't need `#![feature(maybe_uninit)]` in their code + inner: core::mem::MaybeUninit, +} + +#[cfg(feature = "nightly")] +impl MaybeUninit { + pub const fn uninitialized() -> Self { + MaybeUninit { + inner: core::mem::MaybeUninit::uninitialized(), + } + } + + pub fn as_ptr(&self) -> *const T { + self.inner.as_ptr() + } + + pub fn as_mut_ptr(&mut self) -> *mut T { + self.inner.as_mut_ptr() + } + + pub fn set(&mut self, value: T) -> &mut T { + self.inner.set(value) + } +} + +#[cfg(not(feature = "nightly"))] pub struct MaybeUninit { value: Option, } +#[cfg(not(feature = "nightly"))] impl MaybeUninit { pub const fn uninitialized() -> Self { MaybeUninit { value: None } } + pub fn as_ptr(&self) -> *const T { + if let Some(x) = self.value.as_ref() { + x + } else { + match () { + // Try to catch UB when compiling in release with debug assertions enabled + #[cfg(debug_assertions)] + () => unreachable!(), + #[cfg(not(debug_assertions))] + () => unsafe { hint::unreachable_unchecked() }, + } + } + } + + pub fn as_mut_ptr(&mut self) -> *mut T { + if let Some(x) = self.value.as_mut() { + x + } else { + match () { + // Try to catch UB when compiling in release with debug assertions enabled + #[cfg(debug_assertions)] + () => unreachable!(), + #[cfg(not(debug_assertions))] + () => unsafe { hint::unreachable_unchecked() }, + } + } + } + pub unsafe fn get_ref(&self) -> &T { if let Some(x) = self.value.as_ref() { x diff --git a/src/lib.rs b/src/lib.rs index 9914aaf..6c79f6c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -36,6 +36,7 @@ //! [`Instant`]: struct.Instant.html //! [`Duration`]: struct.Duration.html +#![cfg_attr(feature = "nightly", feature(maybe_uninit))] #![deny(missing_docs)] #![deny(warnings)] #![no_std] -- cgit v1.2.3 From 16821c8315fc5e0f9bfbc6ddd7ca79cc2b1d5d40 Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Fri, 15 Feb 2019 20:20:38 +0100 Subject: document the nightly feature --- src/lib.rs | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src') diff --git a/src/lib.rs b/src/lib.rs index 6c79f6c..4c2fd9e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -35,6 +35,11 @@ //! //! [`Instant`]: struct.Instant.html //! [`Duration`]: struct.Duration.html +//! +//! - `nightly`. Enabling this opt-in feature makes RTFM internally use the unstable +//! `core::mem::MaybeUninit` API and unstable `const_fn` language feature to reduce static memory +//! usage, runtime overhead and initialization overhead. This feature requires a nightly compiler +//! and may stop working at any time! #![cfg_attr(feature = "nightly", feature(maybe_uninit))] #![deny(missing_docs)] -- cgit v1.2.3 From 28ee83dfdd76ffad0487bad83636fa600084c834 Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Fri, 15 Feb 2019 20:23:32 +0100 Subject: turn all potential UB into panics --- src/export.rs | 38 ++++++++------------------------------ 1 file changed, 8 insertions(+), 30 deletions(-) (limited to 'src') diff --git a/src/export.rs b/src/export.rs index f8fc815..495468e 100644 --- a/src/export.rs +++ b/src/export.rs @@ -1,7 +1,5 @@ //! IMPLEMENTATION DETAILS. DO NOT USE ANYTHING IN THIS MODULE -#[cfg(all(not(feature = "nightly"), not(debug_assertions)))] -use core::hint; #[cfg(not(feature = "nightly"))] use core::ptr; use core::{cell::Cell, u8}; @@ -98,6 +96,10 @@ pub struct MaybeUninit { value: Option, } +#[cfg(not(feature = "nightly"))] +const MSG: &str = + "you have hit a bug (UB) in RTFM implementation; try enabling this crate 'nightly' feature"; + #[cfg(not(feature = "nightly"))] impl MaybeUninit { pub const fn uninitialized() -> Self { @@ -108,13 +110,7 @@ impl MaybeUninit { if let Some(x) = self.value.as_ref() { x } else { - match () { - // Try to catch UB when compiling in release with debug assertions enabled - #[cfg(debug_assertions)] - () => unreachable!(), - #[cfg(not(debug_assertions))] - () => unsafe { hint::unreachable_unchecked() }, - } + unreachable!(MSG) } } @@ -122,13 +118,7 @@ impl MaybeUninit { if let Some(x) = self.value.as_mut() { x } else { - match () { - // Try to catch UB when compiling in release with debug assertions enabled - #[cfg(debug_assertions)] - () => unreachable!(), - #[cfg(not(debug_assertions))] - () => unsafe { hint::unreachable_unchecked() }, - } + unreachable!(MSG) } } @@ -136,13 +126,7 @@ impl MaybeUninit { if let Some(x) = self.value.as_ref() { x } else { - match () { - // Try to catch UB when compiling in release with debug assertions enabled - #[cfg(debug_assertions)] - () => unreachable!(), - #[cfg(not(debug_assertions))] - () => hint::unreachable_unchecked(), - } + unreachable!(MSG) } } @@ -150,13 +134,7 @@ impl MaybeUninit { if let Some(x) = self.value.as_mut() { x } else { - match () { - // Try to catch UB when compiling in release with debug assertions enabled - #[cfg(debug_assertions)] - () => unreachable!(), - #[cfg(not(debug_assertions))] - () => hint::unreachable_unchecked(), - } + unreachable!(MSG) } } -- cgit v1.2.3