//! Thread local support for platforms with native TLS.
//!
//! To achieve the best performance, we choose from four different types for
//! the TLS variable, depending on the method of initialization used (`const`
//! or lazy) and the drop requirements of the stored type:
//!
//! |         | `Drop`               | `!Drop`             |
//! |--------:|:--------------------:|:-------------------:|
//! | `const` | `EagerStorage<T>`    | `T`                 |
//! | lazy    | `LazyStorage<T, ()>` | `LazyStorage<T, !>` |
//!
//! For `const` initialization and `!Drop` types, we simply use `T` directly,
//! but for other situations, we implement a state machine to handle
//! initialization of the variable and its destructor and destruction.
//! Upon accessing the TLS variable, the current state is compared:
//!
//! 1. If the state is `Initial`, initialize the storage, transition the state
//!    to `Alive` and (if applicable) register the destructor, and return a
//!    reference to the value.
//! 2. If the state is `Alive`, initialization was previously completed, so
//!    return a reference to the value.
//! 3. If the state is `Destroyed`, the destructor has been run already, so
//!    return [`None`].
//!
//! The TLS destructor sets the state to `Destroyed` and drops the current value.
//!
//! To simplify the code, we make `LazyStorage` generic over the destroyed state
//! and use the `!` type (never type) as type parameter for `!Drop` types. This
//! eliminates the `Destroyed` state for these values, which can allow more niche
//! optimizations to occur for the `State` enum. For `Drop` types, `()` is used.

use crate::cell::Cell;
use crate::ptr;

mod eager;
mod lazy;

pub use eager::Storage as EagerStorage;
pub use lazy::Storage as LazyStorage;

#[doc(hidden)]
#[allow_internal_unstable(
    thread_local_internals,
    cfg_target_thread_local,
    thread_local,
    never_type
)]
#[allow_internal_unsafe]
#[unstable(feature = "thread_local_internals", issue = "none")]
#[rustc_macro_transparency = "semitransparent"]
pub macro thread_local_inner {
    // NOTE: we cannot import `LocalKey`, `LazyStorage` or `EagerStorage` with a `use` because that
    // can shadow user provided type or type alias with a matching name. Please update the shadowing
    // test in `tests/thread.rs` if these types are renamed.

    // Used to generate the `LocalKey` value for const-initialized thread locals.
    (@key $t:ty, $(#[$align_attr:meta])*, const $init:expr) => {{
        const __RUST_STD_INTERNAL_INIT: $t = $init;

        unsafe {
            $crate::thread::LocalKey::new(const {
                if $crate::mem::needs_drop::<$t>() {
                    |_| {
                        #[thread_local]
                        $(#[$align_attr])*
                        static __RUST_STD_INTERNAL_VAL: $crate::thread::local_impl::EagerStorage<$t>
                            = $crate::thread::local_impl::EagerStorage::new(__RUST_STD_INTERNAL_INIT);
                        __RUST_STD_INTERNAL_VAL.get()
                    }
                } else {
                    |_| {
                        #[thread_local]
                        $(#[$align_attr])*
                        static __RUST_STD_INTERNAL_VAL: $t = __RUST_STD_INTERNAL_INIT;
                        &__RUST_STD_INTERNAL_VAL
                    }
                }
            })
        }
    }},

    // used to generate the `LocalKey` value for `thread_local!`
    (@key $t:ty, $(#[$align_attr:meta])*, $init:expr) => {{
        #[inline]
        fn __rust_std_internal_init_fn() -> $t {
            $init
        }

        unsafe {
            $crate::thread::LocalKey::new(const {
                if $crate::mem::needs_drop::<$t>() {
                    |__rust_std_internal_init| {
                        #[thread_local]
                        $(#[$align_attr])*
                        static __RUST_STD_INTERNAL_VAL: $crate::thread::local_impl::LazyStorage<$t, ()>
                            = $crate::thread::local_impl::LazyStorage::new();
                        __RUST_STD_INTERNAL_VAL.get_or_init(__rust_std_internal_init, __rust_std_internal_init_fn)
                    }
                } else {
                    |__rust_std_internal_init| {
                        #[thread_local]
                        $(#[$align_attr])*
                        static __RUST_STD_INTERNAL_VAL: $crate::thread::local_impl::LazyStorage<$t, !>
                            = $crate::thread::local_impl::LazyStorage::new();
                        __RUST_STD_INTERNAL_VAL.get_or_init(__rust_std_internal_init, __rust_std_internal_init_fn)
                    }
                }
            })
        }
    }},
}

#[rustc_macro_transparency = "semitransparent"]
pub(crate) macro local_pointer {
    () => {},
    ($vis:vis static $name:ident; $($rest:tt)*) => {
        #[thread_local]
        $vis static $name: $crate::sys::thread_local::LocalPointer = $crate::sys::thread_local::LocalPointer::__new();
        $crate::sys::thread_local::local_pointer! { $($rest)* }
    },
}

pub(crate) struct LocalPointer {
    p: Cell<*mut ()>,
}

impl LocalPointer {
    pub const fn __new() -> LocalPointer {
        LocalPointer { p: Cell::new(ptr::null_mut()) }
    }

    pub fn get(&self) -> *mut () {
        self.p.get()
    }

    pub fn set(&self, p: *mut ()) {
        self.p.set(p)
    }
}
