From a308da1d1da7660a9577979c64bb30f0ed0700f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marvin=20L=C3=B6bel?= Date: Wed, 16 Nov 2016 20:39:59 +0100 Subject: [PATCH 1/4] Switch lazy_static over to mutable statics instead of UnsafeCell on nightly --- src/nightly_lazy.rs | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/nightly_lazy.rs b/src/nightly_lazy.rs index ee2c2bc..7011796 100644 --- a/src/nightly_lazy.rs +++ b/src/nightly_lazy.rs @@ -8,27 +8,28 @@ extern crate std; use self::std::prelude::v1::*; -use self::std::cell::UnsafeCell; use self::std::sync::{Once, ONCE_INIT}; -pub struct Lazy(UnsafeCell>, Once); +pub struct Lazy(Option, Once); impl Lazy { #[inline(always)] pub const fn new() -> Self { - Lazy(UnsafeCell::new(None), ONCE_INIT) + Lazy(None, ONCE_INIT) } #[inline(always)] - pub fn get(&'static self, f: F) -> &T + pub fn get(&'static mut self, f: F) -> &T where F: FnOnce() -> T { - unsafe { + { + let r = &mut self.0; self.1.call_once(|| { - *self.0.get() = Some(f()); + *r = Some(f()); }); - - match *self.0.get() { + } + unsafe { + match self.0 { Some(ref x) => x, None => std::intrinsics::unreachable(), } @@ -43,6 +44,6 @@ unsafe impl Sync for Lazy {} #[doc(hidden)] macro_rules! __lazy_static_create { ($NAME:ident, $T:ty) => { - static $NAME: $crate::lazy::Lazy<$T> = $crate::lazy::Lazy::new(); + static mut $NAME: $crate::lazy::Lazy<$T> = $crate::lazy::Lazy::new(); } } From 9b9f96c9fb2c4ba1e5423f630512479420b79630 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marvin=20L=C3=B6bel?= Date: Mon, 13 Nov 2017 17:25:28 +0100 Subject: [PATCH 2/4] Update and cleanup the code --- Cargo.toml | 2 +- src/core_lazy.rs | 2 -- src/lazy.rs | 5 ++--- src/lib.rs | 7 +++---- src/nightly_lazy.rs | 16 +++++----------- 5 files changed, 11 insertions(+), 21 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index b8b9149..dcea4c9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,7 +14,7 @@ keywords = ["macro", "lazy", "static"] categories = [ "no-std", "rust-patterns", "memory-management" ] [dependencies.spin] -version = "0.4" +version = "0.4.6" optional = true [dependencies.compiletest_rs] diff --git a/src/core_lazy.rs b/src/core_lazy.rs index 34a942c..90c7aaa 100644 --- a/src/core_lazy.rs +++ b/src/core_lazy.rs @@ -26,8 +26,6 @@ impl Lazy { } #[macro_export] -#[allow_internal_unstable] -#[doc(hidden)] macro_rules! __lazy_static_create { ($NAME:ident, $T:ty) => { static $NAME: $crate::lazy::Lazy<$T> = $crate::lazy::Lazy::new(); diff --git a/src/lazy.rs b/src/lazy.rs index 43b7b86..aab1e05 100644 --- a/src/lazy.rs +++ b/src/lazy.rs @@ -9,6 +9,7 @@ extern crate std; use self::std::prelude::v1::*; use self::std::sync::Once; +pub use self::std::sync::ONCE_INIT; pub struct Lazy(pub *const T, pub Once); @@ -31,10 +32,8 @@ impl Lazy { unsafe impl Sync for Lazy {} #[macro_export] -#[doc(hidden)] macro_rules! __lazy_static_create { ($NAME:ident, $T:ty) => { - use std::sync::ONCE_INIT; - static mut $NAME: $crate::lazy::Lazy<$T> = $crate::lazy::Lazy(0 as *const $T, ONCE_INIT); + static mut $NAME: $crate::lazy::Lazy<$T> = $crate::lazy::Lazy(0 as *const $T, $crate::lazy::ONCE_INIT); } } diff --git a/src/lib.rs b/src/lib.rs index f4eb0d3..b195662 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -90,9 +90,10 @@ The `Deref` implementation uses a hidden static variable that is guarded by a at */ -#![cfg_attr(feature="nightly", feature(const_fn, allow_internal_unstable, core_intrinsics, const_unsafe_cell_new))] +#![cfg_attr(feature="spin_no_std", feature(const_fn))] +#![cfg_attr(feature="nightly", feature(unreachable))] -#![doc(html_root_url = "https://docs.rs/lazy_static/0.2.8")] +#![doc(html_root_url = "https://docs.rs/lazy_static/0.2.10")] #![no_std] #[cfg(not(feature="nightly"))] @@ -113,7 +114,6 @@ pub mod lazy; pub use core::ops::Deref as __Deref; #[macro_export] -#[cfg_attr(feature="nightly", allow_internal_unstable)] #[doc(hidden)] macro_rules! __lazy_static_internal { // optional visibility restrictions are wrapped in `()` to allow for @@ -161,7 +161,6 @@ macro_rules! __lazy_static_internal { } #[macro_export] -#[cfg_attr(feature="nightly", allow_internal_unstable)] macro_rules! lazy_static { ($(#[$attr:meta])* static ref $N:ident : $T:ty = $e:expr; $($t:tt)*) => { // use `()` to explicitly forward the information about private items diff --git a/src/nightly_lazy.rs b/src/nightly_lazy.rs index 7011796..0ad0f66 100644 --- a/src/nightly_lazy.rs +++ b/src/nightly_lazy.rs @@ -8,16 +8,12 @@ extern crate std; use self::std::prelude::v1::*; -use self::std::sync::{Once, ONCE_INIT}; +use self::std::sync::Once; +pub use self::std::sync::ONCE_INIT; -pub struct Lazy(Option, Once); +pub struct Lazy(pub Option, pub Once); impl Lazy { - #[inline(always)] - pub const fn new() -> Self { - Lazy(None, ONCE_INIT) - } - #[inline(always)] pub fn get(&'static mut self, f: F) -> &T where F: FnOnce() -> T @@ -31,7 +27,7 @@ impl Lazy { unsafe { match self.0 { Some(ref x) => x, - None => std::intrinsics::unreachable(), + None => std::mem::unreachable(), } } } @@ -40,10 +36,8 @@ impl Lazy { unsafe impl Sync for Lazy {} #[macro_export] -#[allow_internal_unstable] -#[doc(hidden)] macro_rules! __lazy_static_create { ($NAME:ident, $T:ty) => { - static mut $NAME: $crate::lazy::Lazy<$T> = $crate::lazy::Lazy::new(); + static mut $NAME: $crate::lazy::Lazy<$T> = $crate::lazy::Lazy(None, $crate::lazy::ONCE_INIT); } } From e1f9b539c31a8552d21458af5f2479f5bb78c246 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marvin=20L=C3=B6bel?= Date: Mon, 13 Nov 2017 18:02:03 +0100 Subject: [PATCH 3/4] Check that statics are sized. Closes #26 --- tests/compile-fail/static_is_sized.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 tests/compile-fail/static_is_sized.rs diff --git a/tests/compile-fail/static_is_sized.rs b/tests/compile-fail/static_is_sized.rs new file mode 100644 index 0000000..3719f97 --- /dev/null +++ b/tests/compile-fail/static_is_sized.rs @@ -0,0 +1,10 @@ +#[macro_use] +extern crate lazy_static; + +lazy_static! { + pub static ref FOO: str = panic!(); +} +//^ ERROR `str` does not have a constant size known at compile-time + +fn main() { +} From 8fff063b97b43e399c56dbb6ca4a0efcbeeb4a0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marvin=20L=C3=B6bel?= Date: Mon, 13 Nov 2017 18:16:39 +0100 Subject: [PATCH 4/4] Fix error pattern --- tests/compile-fail/static_is_sized.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/compile-fail/static_is_sized.rs b/tests/compile-fail/static_is_sized.rs index 3719f97..3681ad7 100644 --- a/tests/compile-fail/static_is_sized.rs +++ b/tests/compile-fail/static_is_sized.rs @@ -1,10 +1,11 @@ +// error-pattern:the trait bound `str: std::marker::Sized` is not satisfied #[macro_use] extern crate lazy_static; lazy_static! { pub static ref FOO: str = panic!(); } -//^ ERROR `str` does not have a constant size known at compile-time + fn main() { }