about summary refs log tree commit diff
path: root/src/libstd/thread_local
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2015-03-06 05:20:11 +0000
committerbors <bors@rust-lang.org>2015-03-06 05:20:11 +0000
commit1fe8f221450bad3ffb1351c6549f67c18ce0b94e (patch)
tree475876888ff3be07f3b72e58bc3c7d3554107f1a /src/libstd/thread_local
parentb0746ff19b3bc204215f04bbb5756159f9bc5c92 (diff)
parentb5c6ab20b7d1f4d6b0cc31c2987b2e0f8ea43e0c (diff)
downloadrust-1fe8f221450bad3ffb1351c6549f67c18ce0b94e.tar.gz
rust-1fe8f221450bad3ffb1351c6549f67c18ce0b94e.zip
Auto merge of #22899 - huonw:macro-stability, r=alexcrichton
Unstable items used in a macro expansion will now always trigger
stability warnings, *unless* the unstable items are directly inside a
macro marked with `#[allow_internal_unstable]`. IOW, the compiler warns
unless the span of the unstable item is a subspan of the definition of a
macro marked with that attribute.

E.g.

    #[allow_internal_unstable]
    macro_rules! foo {
        ($e: expr) => {{
            $e;
            unstable(); // no warning
            only_called_by_foo!();
        }}
    }

    macro_rules! only_called_by_foo {
        () => { unstable() } // warning
    }

    foo!(unstable()) // warning

The unstable inside `foo` is fine, due to the attribute. But the
`unstable` inside `only_called_by_foo` is not, since that macro doesn't
have the attribute, and the `unstable` passed into `foo` is also not
fine since it isn't contained in the macro itself (that is, even though
it is only used directly in the macro).

In the process this makes the stability tracking much more precise,
e.g. previously `println!("{}", unstable())` got no warning, but now it
does. As such, this is a bug fix that may cause [breaking-change]s.

The attribute is definitely feature gated, since it explicitly allows
side-stepping the feature gating system.

---

This updates `thread_local!` macro to use the attribute, since it uses
unstable features internally (initialising a struct with unstable
fields).
Diffstat (limited to 'src/libstd/thread_local')
-rw-r--r--src/libstd/thread_local/mod.rs22
-rw-r--r--src/libstd/thread_local/scoped.rs2
2 files changed, 14 insertions, 10 deletions
diff --git a/src/libstd/thread_local/mod.rs b/src/libstd/thread_local/mod.rs
index 764c7d730cb..6bba73420d8 100644
--- a/src/libstd/thread_local/mod.rs
+++ b/src/libstd/thread_local/mod.rs
@@ -45,7 +45,7 @@ pub mod scoped;
 
 // Sure wish we had macro hygiene, no?
 #[doc(hidden)]
-#[stable(feature = "rust1", since = "1.0.0")]
+#[unstable(feature = "thread_local_internals")]
 pub mod __impl {
     pub use super::imp::Key as KeyInner;
     pub use super::imp::destroy_value;
@@ -117,6 +117,7 @@ pub struct Key<T> {
 /// Declare a new thread local storage key of type `std::thread_local::Key`.
 #[macro_export]
 #[stable(feature = "rust1", since = "1.0.0")]
+#[allow_internal_unstable]
 macro_rules! thread_local {
     (static $name:ident: $t:ty = $init:expr) => (
         static $name: ::std::thread_local::Key<$t> = {
@@ -176,6 +177,7 @@ macro_rules! thread_local {
 
 #[macro_export]
 #[doc(hidden)]
+#[allow_internal_unstable]
 macro_rules! __thread_local_inner {
     (static $name:ident: $t:ty = $init:expr) => (
         #[cfg_attr(all(any(target_os = "macos", target_os = "linux"),
@@ -337,7 +339,7 @@ mod imp {
     use ptr;
 
     #[doc(hidden)]
-    #[stable(since = "1.0.0", feature = "rust1")]
+    #[unstable(feature = "thread_local_internals")]
     pub struct Key<T> {
         // Place the inner bits in an `UnsafeCell` to currently get around the
         // "only Sync statics" restriction. This allows any type to be placed in
@@ -345,14 +347,14 @@ mod imp {
         //
         // Note that all access requires `T: 'static` so it can't be a type with
         // any borrowed pointers still.
-        #[stable(since = "1.0.0", feature = "rust1")]
+        #[unstable(feature = "thread_local_internals")]
         pub inner: UnsafeCell<T>,
 
         // Metadata to keep track of the state of the destructor. Remember that
         // these variables are thread-local, not global.
-        #[stable(since = "1.0.0", feature = "rust1")]
+        #[unstable(feature = "thread_local_internals")]
         pub dtor_registered: UnsafeCell<bool>, // should be Cell
-        #[stable(since = "1.0.0", feature = "rust1")]
+        #[unstable(feature = "thread_local_internals")]
         pub dtor_running: UnsafeCell<bool>, // should be Cell
     }
 
@@ -455,7 +457,7 @@ mod imp {
     }
 
     #[doc(hidden)]
-    #[stable(feature = "rust1", since = "1.0.0")]
+    #[unstable(feature = "thread_local_internals")]
     pub unsafe extern fn destroy_value<T>(ptr: *mut u8) {
         let ptr = ptr as *mut Key<T>;
         // Right before we run the user destructor be sure to flag the
@@ -477,15 +479,15 @@ mod imp {
     use sys_common::thread_local::StaticKey as OsStaticKey;
 
     #[doc(hidden)]
-    #[stable(since = "1.0.0", feature = "rust1")]
+    #[unstable(feature = "thread_local_internals")]
     pub struct Key<T> {
         // Statically allocated initialization expression, using an `UnsafeCell`
         // for the same reasons as above.
-        #[stable(since = "1.0.0", feature = "rust1")]
+        #[unstable(feature = "thread_local_internals")]
         pub inner: UnsafeCell<T>,
 
         // OS-TLS key that we'll use to key off.
-        #[stable(since = "1.0.0", feature = "rust1")]
+        #[unstable(feature = "thread_local_internals")]
         pub os: OsStaticKey,
     }
 
@@ -528,7 +530,7 @@ mod imp {
     }
 
     #[doc(hidden)]
-    #[stable(feature = "rust1", since = "1.0.0")]
+    #[unstable(feature = "thread_local_internals")]
     pub unsafe extern fn destroy_value<T: 'static>(ptr: *mut u8) {
         // The OS TLS ensures that this key contains a NULL value when this
         // destructor starts to run. We set it back to a sentinel value of 1 to
diff --git a/src/libstd/thread_local/scoped.rs b/src/libstd/thread_local/scoped.rs
index d89d69e9497..a5339568e9e 100644
--- a/src/libstd/thread_local/scoped.rs
+++ b/src/libstd/thread_local/scoped.rs
@@ -65,6 +65,7 @@ pub struct Key<T> { #[doc(hidden)] pub inner: __impl::KeyInner<T> }
 /// This macro declares a `static` item on which methods are used to get and
 /// set the value stored within.
 #[macro_export]
+#[allow_internal_unstable]
 macro_rules! scoped_thread_local {
     (static $name:ident: $t:ty) => (
         __scoped_thread_local_inner!(static $name: $t);
@@ -76,6 +77,7 @@ macro_rules! scoped_thread_local {
 
 #[macro_export]
 #[doc(hidden)]
+#[allow_internal_unstable]
 macro_rules! __scoped_thread_local_inner {
     (static $name:ident: $t:ty) => (
         #[cfg_attr(not(any(windows,