aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/lib.rs2
-rw-r--r--src/macros.rs52
2 files changed, 49 insertions, 5 deletions
diff --git a/src/lib.rs b/src/lib.rs
index 694d1b2..6af60d7 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -15,6 +15,7 @@
extern crate aligned;
extern crate bare_metal;
+extern crate untagged_option;
extern crate volatile_register;
#[macro_use]
@@ -31,3 +32,4 @@ pub mod peripheral;
pub mod register;
pub use peripheral::Peripherals;
+pub use untagged_option::UntaggedOption;
diff --git a/src/macros.rs b/src/macros.rs
index c9a32c2..7d2cf6a 100644
--- a/src/macros.rs
+++ b/src/macros.rs
@@ -52,17 +52,59 @@ macro_rules! iprintln {
#[macro_export]
macro_rules! singleton {
(: $ty:ty = $expr:expr) => {
- $crate::interrupt::free(|_| unsafe {
+ $crate::interrupt::free(|_| {
static mut USED: bool = false;
- static mut VAR: $ty = $expr;
+ static mut VAR: $crate::UntaggedOption<$ty> = $crate::UntaggedOption { none: () };
- if USED {
+
+ #[allow(unsafe_code)]
+ let used = unsafe { USED };
+ if used {
None
} else {
- USED = true;
- let var: &'static mut _ = &mut VAR;
+ #[allow(unsafe_code)]
+ unsafe { USED = true }
+
+ let expr = $expr;
+
+ #[allow(unsafe_code)]
+ unsafe { VAR.some = expr }
+
+ #[allow(unsafe_code)]
+ let var: &'static mut _ = unsafe { &mut VAR.some };
+
Some(var)
}
})
}
}
+
+
+/// ``` compile_fail
+/// #[macro_use(singleton)]
+/// extern crate cortex_m;
+///
+/// fn main() {}
+///
+/// fn foo() {
+/// // check that the call to `uninitialized` requires unsafe
+/// singleton!(: u8 = std::mem::uninitialized());
+/// }
+/// ```
+#[allow(dead_code)]
+const CFAIL: () = ();
+
+/// ```
+/// #![deny(unsafe_code)]
+/// #[macro_use(singleton)]
+/// extern crate cortex_m;
+///
+/// fn main() {}
+///
+/// fn foo() {
+/// // check that calls to `singleton!` don't trip the `unsafe_code` lint
+/// singleton!(: u8 = 0);
+/// }
+/// ```
+#[allow(dead_code)]
+const CPASS: () = ();