From c9947a085a2927b15d7229fb1baa5a2fd0728bab Mon Sep 17 00:00:00 2001
From: daxpedda <daxpedda@gmail.com>
Date: Mon, 9 Dec 2024 11:50:36 +0100
Subject: [PATCH] Simplify `no_std` implementation

---
 .github/workflows/main.yml                    |   1 -
 Cargo.toml                                    |   5 +-
 crates/backend/Cargo.toml                     |   2 -
 crates/backend/src/codegen.rs                 |  14 +-
 .../tests/reference/anyref-import-catch.wat   |   4 +-
 crates/cli/tests/reference/echo.wat           |  94 +++++++-------
 crates/cli/tests/reference/import.wat         |   4 +-
 crates/cli/tests/reference/static.wat         |   4 +-
 crates/futures/Cargo.toml                     |   2 +-
 crates/futures/src/lib.rs                     |   5 +-
 crates/futures/src/queue.rs                   |  10 --
 .../futures/src/task/wait_async_polyfill.rs   |  42 ++----
 crates/js-sys/src/lib.rs                      |  31 ++---
 crates/macro-support/Cargo.toml               |   4 +-
 crates/macro/Cargo.toml                       |   4 +-
 crates/msrv/lib/Cargo.toml                    |   1 -
 crates/test/Cargo.toml                        |   3 +-
 crates/test/src/lib.rs                        |   2 -
 crates/test/src/rt/mod.rs                     |   1 -
 src/cache/intern.rs                           |   3 -
 src/externref.rs                              |   3 -
 src/lib.rs                                    |  65 +++-------
 src/rt/mod.rs                                 | 122 +++++-------------
 23 files changed, 136 insertions(+), 290 deletions(-)

diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index c477743eba8..d887cc699b7 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -582,7 +582,6 @@ jobs:
       run: |
         cargo update -p bumpalo --precise 3.12.0
         cargo update -p log --precise 0.4.18
-        cargo update -p scoped-tls --precise 1.0.0
     - run: cargo build --target ${{ matrix.target }} ${{ matrix.features }}
 
   msrv-lib:
diff --git a/Cargo.toml b/Cargo.toml
index 5956facd64a..57536ab1ce9 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -26,7 +26,7 @@ default = ["std", "msrv"]
 enable-interning = ["std"]
 serde-serialize = ["serde", "serde_json", "std"]
 spans = []
-std = ["wasm-bindgen-macro/std", "once_cell/std"]
+std = []
 
 # Opt-in for Rust language features that require a higher MSRV.
 #
@@ -53,9 +53,10 @@ once_cell = { version = "1.12", default-features = false }
 rustversion = { version = "1.0", optional = true }
 serde = { version = "1.0", optional = true }
 serde_json = { version = "1.0", optional = true }
-wasm-bindgen-macro = { path = "crates/macro", version = "=0.2.99", default-features = false }
+wasm-bindgen-macro = { path = "crates/macro", version = "=0.2.99" }
 
 [dev-dependencies]
+once_cell = "1"
 wasm-bindgen-test = { path = 'crates/test' }
 
 [target.'cfg(target_arch = "wasm32")'.dev-dependencies]
diff --git a/crates/backend/Cargo.toml b/crates/backend/Cargo.toml
index 04f9bcdc1e6..ab964ab8ec1 100644
--- a/crates/backend/Cargo.toml
+++ b/crates/backend/Cargo.toml
@@ -14,9 +14,7 @@ rust-version = "1.57"
 version = "0.2.99"
 
 [features]
-default = ["std"]
 extra-traits = ["syn/extra-traits"]
-std = []
 
 [dependencies]
 bumpalo = "3.0.0"
diff --git a/crates/backend/src/codegen.rs b/crates/backend/src/codegen.rs
index 63b9376e35d..c8decb4a136 100644
--- a/crates/backend/src/codegen.rs
+++ b/crates/backend/src/codegen.rs
@@ -1803,24 +1803,12 @@ fn thread_local_import(
             }
         },
         ast::ThreadLocal::V2 => {
-            #[cfg(feature = "std")]
-            let inner = quote! {
-                #wasm_bindgen::__rt::std::thread_local!(static _VAL: #actual_ty = init(););
-                #wasm_bindgen::JsThreadLocal {
-                    __inner: &_VAL,
-                }
-            };
-            #[cfg(not(feature = "std"))]
-            let inner = quote! {
-                #wasm_bindgen::__wbindgen_thread_local!(#wasm_bindgen, #actual_ty)
-            };
-
             quote! {
                 #vis static #name: #wasm_bindgen::JsThreadLocal<#actual_ty> = {
                     fn init() -> #actual_ty {
                         #init
                     }
-                    #inner
+                    #wasm_bindgen::__wbindgen_thread_local!(#wasm_bindgen, #actual_ty)
                 };
             }
         }
diff --git a/crates/cli/tests/reference/anyref-import-catch.wat b/crates/cli/tests/reference/anyref-import-catch.wat
index d5c8b26e7c0..506e67cca2b 100644
--- a/crates/cli/tests/reference/anyref-import-catch.wat
+++ b/crates/cli/tests/reference/anyref-import-catch.wat
@@ -6,8 +6,8 @@
   (import "./reference_test_bg.js" "__wbindgen_init_externref_table" (func (;0;) (type 0)))
   (func $__wbindgen_exn_store (;1;) (type 3) (param i32))
   (func $__externref_table_dealloc (;2;) (type 3) (param i32))
-  (func $__externref_table_alloc (;3;) (type 1) (result i32))
-  (func $"exported multivalue shim" (;4;) (type 2) (result i32 i32))
+  (func $"exported multivalue shim" (;3;) (type 2) (result i32 i32))
+  (func $__externref_table_alloc (;4;) (type 1) (result i32))
   (table (;0;) 128 externref)
   (memory (;0;) 17)
   (export "memory" (memory 0))
diff --git a/crates/cli/tests/reference/echo.wat b/crates/cli/tests/reference/echo.wat
index aff42b9dcdc..4504528bcc9 100644
--- a/crates/cli/tests/reference/echo.wat
+++ b/crates/cli/tests/reference/echo.wat
@@ -46,53 +46,53 @@
   (func $echo_i64 (;29;) (type 11) (param i64) (result i64))
   (func $echo_f64 (;30;) (type 14) (param f64) (result f64))
   (func $__wbindgen_free (;31;) (type 6) (param i32 i32 i32))
-  (func $__externref_table_alloc (;32;) (type 1) (result i32))
-  (func $__wbg_foo_free (;33;) (type 3) (param i32 i32))
-  (func $"echo_option_u128 multivalue shim" (;34;) (type 9) (param i32 i64 i64) (result i32 i64 i64))
-  (func $"echo_option_i128 multivalue shim" (;35;) (type 9) (param i32 i64 i64) (result i32 i64 i64))
-  (func $"echo_u128 multivalue shim" (;36;) (type 12) (param i64 i64) (result i64 i64))
-  (func $"echo_i128 multivalue shim" (;37;) (type 12) (param i64 i64) (result i64 i64))
-  (func $"echo_string multivalue shim" (;38;) (type 5) (param i32 i32) (result i32 i32))
-  (func $"echo_vec_u8 multivalue shim" (;39;) (type 5) (param i32 i32) (result i32 i32))
-  (func $"echo_vec_i8 multivalue shim" (;40;) (type 5) (param i32 i32) (result i32 i32))
-  (func $"echo_vec_u16 multivalue shim" (;41;) (type 5) (param i32 i32) (result i32 i32))
-  (func $"echo_vec_i16 multivalue shim" (;42;) (type 5) (param i32 i32) (result i32 i32))
-  (func $"echo_vec_u32 multivalue shim" (;43;) (type 5) (param i32 i32) (result i32 i32))
-  (func $"echo_vec_i32 multivalue shim" (;44;) (type 5) (param i32 i32) (result i32 i32))
-  (func $"echo_vec_u64 multivalue shim" (;45;) (type 5) (param i32 i32) (result i32 i32))
-  (func $"echo_vec_i64 multivalue shim" (;46;) (type 5) (param i32 i32) (result i32 i32))
-  (func $"echo_vec_uninit_u8 multivalue shim" (;47;) (type 5) (param i32 i32) (result i32 i32))
-  (func $"echo_vec_uninit_i8 multivalue shim" (;48;) (type 5) (param i32 i32) (result i32 i32))
-  (func $"echo_vec_uninit_u16 multivalue shim" (;49;) (type 5) (param i32 i32) (result i32 i32))
-  (func $"echo_vec_uninit_i16 multivalue shim" (;50;) (type 5) (param i32 i32) (result i32 i32))
-  (func $"echo_vec_uninit_u32 multivalue shim" (;51;) (type 5) (param i32 i32) (result i32 i32))
-  (func $"echo_vec_uninit_i32 multivalue shim" (;52;) (type 5) (param i32 i32) (result i32 i32))
-  (func $"echo_vec_uninit_u64 multivalue shim" (;53;) (type 5) (param i32 i32) (result i32 i32))
-  (func $"echo_vec_uninit_i64 multivalue shim" (;54;) (type 5) (param i32 i32) (result i32 i32))
-  (func $"echo_vec_string multivalue shim" (;55;) (type 5) (param i32 i32) (result i32 i32))
-  (func $"echo_vec_struct multivalue shim" (;56;) (type 5) (param i32 i32) (result i32 i32))
-  (func $"echo_option_u64 multivalue shim" (;57;) (type 8) (param i32 i64) (result i32 i64))
-  (func $"echo_option_i64 multivalue shim" (;58;) (type 8) (param i32 i64) (result i32 i64))
-  (func $"echo_option_f64 multivalue shim" (;59;) (type 10) (param i32 f64) (result i32 f64))
-  (func $"echo_option_string multivalue shim" (;60;) (type 5) (param i32 i32) (result i32 i32))
-  (func $"echo_option_vec_u8 multivalue shim" (;61;) (type 5) (param i32 i32) (result i32 i32))
-  (func $"echo_option_vec_i8 multivalue shim" (;62;) (type 5) (param i32 i32) (result i32 i32))
-  (func $"echo_option_vec_u16 multivalue shim" (;63;) (type 5) (param i32 i32) (result i32 i32))
-  (func $"echo_option_vec_i16 multivalue shim" (;64;) (type 5) (param i32 i32) (result i32 i32))
-  (func $"echo_option_vec_u32 multivalue shim" (;65;) (type 5) (param i32 i32) (result i32 i32))
-  (func $"echo_option_vec_i32 multivalue shim" (;66;) (type 5) (param i32 i32) (result i32 i32))
-  (func $"echo_option_vec_u64 multivalue shim" (;67;) (type 5) (param i32 i32) (result i32 i32))
-  (func $"echo_option_vec_i64 multivalue shim" (;68;) (type 5) (param i32 i32) (result i32 i32))
-  (func $"echo_option_vec_uninit_u8 multivalue shim" (;69;) (type 5) (param i32 i32) (result i32 i32))
-  (func $"echo_option_vec_uninit_i8 multivalue shim" (;70;) (type 5) (param i32 i32) (result i32 i32))
-  (func $"echo_option_vec_uninit_u16 multivalue shim" (;71;) (type 5) (param i32 i32) (result i32 i32))
-  (func $"echo_option_vec_uninit_i16 multivalue shim" (;72;) (type 5) (param i32 i32) (result i32 i32))
-  (func $"echo_option_vec_uninit_u32 multivalue shim" (;73;) (type 5) (param i32 i32) (result i32 i32))
-  (func $"echo_option_vec_uninit_i32 multivalue shim" (;74;) (type 5) (param i32 i32) (result i32 i32))
-  (func $"echo_option_vec_uninit_u64 multivalue shim" (;75;) (type 5) (param i32 i32) (result i32 i32))
-  (func $"echo_option_vec_uninit_i64 multivalue shim" (;76;) (type 5) (param i32 i32) (result i32 i32))
-  (func $"echo_option_vec_string multivalue shim" (;77;) (type 5) (param i32 i32) (result i32 i32))
-  (func $"echo_option_vec_struct multivalue shim" (;78;) (type 5) (param i32 i32) (result i32 i32))
+  (func $__wbg_foo_free (;32;) (type 3) (param i32 i32))
+  (func $"echo_option_u128 multivalue shim" (;33;) (type 9) (param i32 i64 i64) (result i32 i64 i64))
+  (func $"echo_option_i128 multivalue shim" (;34;) (type 9) (param i32 i64 i64) (result i32 i64 i64))
+  (func $"echo_u128 multivalue shim" (;35;) (type 12) (param i64 i64) (result i64 i64))
+  (func $"echo_i128 multivalue shim" (;36;) (type 12) (param i64 i64) (result i64 i64))
+  (func $"echo_string multivalue shim" (;37;) (type 5) (param i32 i32) (result i32 i32))
+  (func $"echo_vec_u8 multivalue shim" (;38;) (type 5) (param i32 i32) (result i32 i32))
+  (func $"echo_vec_i8 multivalue shim" (;39;) (type 5) (param i32 i32) (result i32 i32))
+  (func $"echo_vec_u16 multivalue shim" (;40;) (type 5) (param i32 i32) (result i32 i32))
+  (func $"echo_vec_i16 multivalue shim" (;41;) (type 5) (param i32 i32) (result i32 i32))
+  (func $"echo_vec_u32 multivalue shim" (;42;) (type 5) (param i32 i32) (result i32 i32))
+  (func $"echo_vec_i32 multivalue shim" (;43;) (type 5) (param i32 i32) (result i32 i32))
+  (func $"echo_vec_u64 multivalue shim" (;44;) (type 5) (param i32 i32) (result i32 i32))
+  (func $"echo_vec_i64 multivalue shim" (;45;) (type 5) (param i32 i32) (result i32 i32))
+  (func $"echo_vec_uninit_u8 multivalue shim" (;46;) (type 5) (param i32 i32) (result i32 i32))
+  (func $"echo_vec_uninit_i8 multivalue shim" (;47;) (type 5) (param i32 i32) (result i32 i32))
+  (func $"echo_vec_uninit_u16 multivalue shim" (;48;) (type 5) (param i32 i32) (result i32 i32))
+  (func $"echo_vec_uninit_i16 multivalue shim" (;49;) (type 5) (param i32 i32) (result i32 i32))
+  (func $"echo_vec_uninit_u32 multivalue shim" (;50;) (type 5) (param i32 i32) (result i32 i32))
+  (func $"echo_vec_uninit_i32 multivalue shim" (;51;) (type 5) (param i32 i32) (result i32 i32))
+  (func $"echo_vec_uninit_u64 multivalue shim" (;52;) (type 5) (param i32 i32) (result i32 i32))
+  (func $"echo_vec_uninit_i64 multivalue shim" (;53;) (type 5) (param i32 i32) (result i32 i32))
+  (func $"echo_vec_string multivalue shim" (;54;) (type 5) (param i32 i32) (result i32 i32))
+  (func $"echo_vec_struct multivalue shim" (;55;) (type 5) (param i32 i32) (result i32 i32))
+  (func $"echo_option_u64 multivalue shim" (;56;) (type 8) (param i32 i64) (result i32 i64))
+  (func $"echo_option_i64 multivalue shim" (;57;) (type 8) (param i32 i64) (result i32 i64))
+  (func $"echo_option_f64 multivalue shim" (;58;) (type 10) (param i32 f64) (result i32 f64))
+  (func $"echo_option_string multivalue shim" (;59;) (type 5) (param i32 i32) (result i32 i32))
+  (func $"echo_option_vec_u8 multivalue shim" (;60;) (type 5) (param i32 i32) (result i32 i32))
+  (func $"echo_option_vec_i8 multivalue shim" (;61;) (type 5) (param i32 i32) (result i32 i32))
+  (func $"echo_option_vec_u16 multivalue shim" (;62;) (type 5) (param i32 i32) (result i32 i32))
+  (func $"echo_option_vec_i16 multivalue shim" (;63;) (type 5) (param i32 i32) (result i32 i32))
+  (func $"echo_option_vec_u32 multivalue shim" (;64;) (type 5) (param i32 i32) (result i32 i32))
+  (func $"echo_option_vec_i32 multivalue shim" (;65;) (type 5) (param i32 i32) (result i32 i32))
+  (func $"echo_option_vec_u64 multivalue shim" (;66;) (type 5) (param i32 i32) (result i32 i32))
+  (func $"echo_option_vec_i64 multivalue shim" (;67;) (type 5) (param i32 i32) (result i32 i32))
+  (func $"echo_option_vec_uninit_u8 multivalue shim" (;68;) (type 5) (param i32 i32) (result i32 i32))
+  (func $"echo_option_vec_uninit_i8 multivalue shim" (;69;) (type 5) (param i32 i32) (result i32 i32))
+  (func $"echo_option_vec_uninit_u16 multivalue shim" (;70;) (type 5) (param i32 i32) (result i32 i32))
+  (func $"echo_option_vec_uninit_i16 multivalue shim" (;71;) (type 5) (param i32 i32) (result i32 i32))
+  (func $"echo_option_vec_uninit_u32 multivalue shim" (;72;) (type 5) (param i32 i32) (result i32 i32))
+  (func $"echo_option_vec_uninit_i32 multivalue shim" (;73;) (type 5) (param i32 i32) (result i32 i32))
+  (func $"echo_option_vec_uninit_u64 multivalue shim" (;74;) (type 5) (param i32 i32) (result i32 i32))
+  (func $"echo_option_vec_uninit_i64 multivalue shim" (;75;) (type 5) (param i32 i32) (result i32 i32))
+  (func $"echo_option_vec_string multivalue shim" (;76;) (type 5) (param i32 i32) (result i32 i32))
+  (func $"echo_option_vec_struct multivalue shim" (;77;) (type 5) (param i32 i32) (result i32 i32))
+  (func $__externref_table_alloc (;78;) (type 1) (result i32))
   (table (;0;) 128 externref)
   (memory (;0;) 17)
   (export "memory" (memory 0))
diff --git a/crates/cli/tests/reference/import.wat b/crates/cli/tests/reference/import.wat
index d5c8b26e7c0..506e67cca2b 100644
--- a/crates/cli/tests/reference/import.wat
+++ b/crates/cli/tests/reference/import.wat
@@ -6,8 +6,8 @@
   (import "./reference_test_bg.js" "__wbindgen_init_externref_table" (func (;0;) (type 0)))
   (func $__wbindgen_exn_store (;1;) (type 3) (param i32))
   (func $__externref_table_dealloc (;2;) (type 3) (param i32))
-  (func $__externref_table_alloc (;3;) (type 1) (result i32))
-  (func $"exported multivalue shim" (;4;) (type 2) (result i32 i32))
+  (func $"exported multivalue shim" (;3;) (type 2) (result i32 i32))
+  (func $__externref_table_alloc (;4;) (type 1) (result i32))
   (table (;0;) 128 externref)
   (memory (;0;) 17)
   (export "memory" (memory 0))
diff --git a/crates/cli/tests/reference/static.wat b/crates/cli/tests/reference/static.wat
index b4ea3e1c9e8..35b905ffffe 100644
--- a/crates/cli/tests/reference/static.wat
+++ b/crates/cli/tests/reference/static.wat
@@ -2,8 +2,8 @@
   (type (;0;) (func))
   (type (;1;) (func (result i32)))
   (import "./reference_test_bg.js" "__wbindgen_init_externref_table" (func (;0;) (type 0)))
-  (func $__externref_table_alloc (;1;) (type 1) (result i32))
-  (func $exported (;2;) (type 0))
+  (func $exported (;1;) (type 0))
+  (func $__externref_table_alloc (;2;) (type 1) (result i32))
   (table (;0;) 128 externref)
   (memory (;0;) 17)
   (export "memory" (memory 0))
diff --git a/crates/futures/Cargo.toml b/crates/futures/Cargo.toml
index 3f35dfc300f..6c1f9dcdacf 100644
--- a/crates/futures/Cargo.toml
+++ b/crates/futures/Cargo.toml
@@ -26,7 +26,7 @@ wasm-bindgen = { path = "../..", version = '=0.2.99', default-features = false }
 [features]
 default = ["std"]
 futures-core-03-stream = ['futures-core']
-std = ["wasm-bindgen/std", "js-sys/std", "web-sys/std", "once_cell/std"]
+std = ["wasm-bindgen/std", "js-sys/std", "web-sys/std"]
 
 [target.'cfg(target_feature = "atomics")'.dependencies]
 web-sys = { path = "../web-sys", version = "=0.3.76", default-features = false, features = [
diff --git a/crates/futures/src/lib.rs b/crates/futures/src/lib.rs
index 6b6ba72e86e..633e023867b 100644
--- a/crates/futures/src/lib.rs
+++ b/crates/futures/src/lib.rs
@@ -31,10 +31,9 @@
 //! asynchronous and I/O work.
 
 #![cfg_attr(not(feature = "std"), no_std)]
-#![cfg_attr(target_feature = "atomics", feature(stdarch_wasm_atomic_wait))]
 #![cfg_attr(
-    all(not(feature = "std"), target_feature = "atomics"),
-    feature(thread_local)
+    target_feature = "atomics",
+    feature(thread_local, stdarch_wasm_atomic_wait)
 )]
 #![deny(missing_docs)]
 #![cfg_attr(docsrs, feature(doc_cfg))]
diff --git a/crates/futures/src/queue.rs b/crates/futures/src/queue.rs
index e0eb9e0de8f..b7d9c89fb4a 100644
--- a/crates/futures/src/queue.rs
+++ b/crates/futures/src/queue.rs
@@ -107,16 +107,6 @@ impl Queue {
         }
     }
 
-    #[cfg(feature = "std")]
-    pub(crate) fn with<R>(f: impl FnOnce(&Self) -> R) -> R {
-        thread_local! {
-            static QUEUE: Queue = Queue::new();
-        }
-
-        QUEUE.with(f)
-    }
-
-    #[cfg(not(feature = "std"))]
     pub(crate) fn with<R>(f: impl FnOnce(&Self) -> R) -> R {
         use once_cell::unsync::Lazy;
 
diff --git a/crates/futures/src/task/wait_async_polyfill.rs b/crates/futures/src/task/wait_async_polyfill.rs
index 757b5d56106..eed90c7ba6d 100644
--- a/crates/futures/src/task/wait_async_polyfill.rs
+++ b/crates/futures/src/task/wait_async_polyfill.rs
@@ -46,44 +46,22 @@ use js_sys::{Array, Promise};
 use wasm_bindgen::prelude::*;
 use web_sys::{MessageEvent, Worker};
 
-struct Helpers;
-
-impl Helpers {
-    #[cfg(feature = "std")]
-    pub(crate) fn with<R>(f: impl FnOnce(&RefCell<Vec<Worker>>) -> R) -> R {
-        thread_local! {
-            static HELPERS: RefCell<Vec<Worker>> = RefCell::new(vec![]);
-        }
-
-        HELPERS.with(f)
-    }
-
-    #[cfg(not(feature = "std"))]
-    pub(crate) fn with<R>(f: impl FnOnce(&RefCell<Vec<Worker>>) -> R) -> R {
-        #[thread_local]
-        static HELPERS: RefCell<Vec<Worker>> = RefCell::new(vec![]);
-
-        f(&HELPERS)
-    }
-}
+#[thread_local]
+static HELPERS: RefCell<Vec<Worker>> = RefCell::new(vec![]);
 
 fn alloc_helper() -> Worker {
-    Helpers::with(|helpers| {
-        if let Some(helper) = helpers.borrow_mut().pop() {
-            return helper;
-        }
+    if let Some(helper) = HELPERS.borrow_mut().pop() {
+        return helper;
+    }
 
-        let worker_url = wasm_bindgen::link_to!(module = "/src/task/worker.js");
-        Worker::new(&worker_url).unwrap_or_else(|js| wasm_bindgen::throw_val(js))
-    })
+    let worker_url = wasm_bindgen::link_to!(module = "/src/task/worker.js");
+    Worker::new(&worker_url).unwrap_or_else(|js| wasm_bindgen::throw_val(js))
 }
 
 fn free_helper(helper: Worker) {
-    Helpers::with(move |helpers| {
-        let mut helpers = helpers.borrow_mut();
-        helpers.push(helper.clone());
-        helpers.truncate(10); // random arbitrary limit chosen here
-    });
+    let mut helpers = HELPERS.borrow_mut();
+    helpers.push(helper.clone());
+    helpers.truncate(10); // random arbitrary limit chosen here
 }
 
 pub fn wait_async(ptr: &AtomicI32, value: i32) -> Promise {
diff --git a/crates/js-sys/src/lib.rs b/crates/js-sys/src/lib.rs
index e8588bdc24a..459e4d93953 100644
--- a/crates/js-sys/src/lib.rs
+++ b/crates/js-sys/src/lib.rs
@@ -18,10 +18,7 @@
 
 #![doc(html_root_url = "https://docs.rs/js-sys/0.2")]
 #![cfg_attr(not(feature = "std"), no_std)]
-#![cfg_attr(
-    all(not(feature = "std"), target_feature = "atomics"),
-    feature(thread_local)
-)]
+#![cfg_attr(target_feature = "atomics", feature(thread_local))]
 
 extern crate alloc;
 
@@ -6031,28 +6028,20 @@ extern "C" {
 /// This allows access to the global properties and global names by accessing
 /// the `Object` returned.
 pub fn global() -> Object {
-    #[cfg(feature = "std")]
-    {
-        thread_local!(static GLOBAL: Object = get_global_object());
-        return GLOBAL.with(|g| g.clone());
-    }
-    #[cfg(not(feature = "std"))]
-    {
-        use once_cell::unsync::Lazy;
+    use once_cell::unsync::Lazy;
 
-        struct Wrapper<T>(Lazy<T>);
+    struct Wrapper<T>(Lazy<T>);
 
-        #[cfg(not(target_feature = "atomics"))]
-        unsafe impl<T> Sync for Wrapper<T> {}
+    #[cfg(not(target_feature = "atomics"))]
+    unsafe impl<T> Sync for Wrapper<T> {}
 
-        #[cfg(not(target_feature = "atomics"))]
-        unsafe impl<T> Send for Wrapper<T> {}
+    #[cfg(not(target_feature = "atomics"))]
+    unsafe impl<T> Send for Wrapper<T> {}
 
-        #[cfg_attr(target_feature = "atomics", thread_local)]
-        static GLOBAL: Wrapper<Object> = Wrapper(Lazy::new(get_global_object));
+    #[cfg_attr(target_feature = "atomics", thread_local)]
+    static GLOBAL: Wrapper<Object> = Wrapper(Lazy::new(get_global_object));
 
-        return GLOBAL.0.clone();
-    }
+    return GLOBAL.0.clone();
 
     fn get_global_object() -> Object {
         // Accessing the global object is not an easy thing to do, and what we
diff --git a/crates/macro-support/Cargo.toml b/crates/macro-support/Cargo.toml
index 19978c98d41..75eab654bd5 100644
--- a/crates/macro-support/Cargo.toml
+++ b/crates/macro-support/Cargo.toml
@@ -14,16 +14,14 @@ rust-version = "1.57"
 version = "0.2.99"
 
 [features]
-default = ["std"]
 extra-traits = ["syn/extra-traits"]
-std = ["wasm-bindgen-backend/std"]
 strict-macro = []
 
 [dependencies]
 proc-macro2 = "1.0"
 quote = '1.0'
 syn = { version = '2.0', features = ['visit', 'visit-mut', 'full'] }
-wasm-bindgen-backend = { path = "../backend", version = "=0.2.99", default-features = false }
+wasm-bindgen-backend = { path = "../backend", version = "=0.2.99" }
 wasm-bindgen-shared = { path = "../shared", version = "=0.2.99" }
 
 [lints]
diff --git a/crates/macro/Cargo.toml b/crates/macro/Cargo.toml
index 0c7cfcd0709..1a194c6dcab 100644
--- a/crates/macro/Cargo.toml
+++ b/crates/macro/Cargo.toml
@@ -17,14 +17,12 @@ version = "0.2.99"
 proc-macro = true
 
 [features]
-default = ["std"]
-std = ["wasm-bindgen-macro-support/std"]
 strict-macro = ["wasm-bindgen-macro-support/strict-macro"]
 xxx_debug_only_print_generated_code = []
 
 [dependencies]
 quote = "1.0"
-wasm-bindgen-macro-support = { path = "../macro-support", version = "=0.2.99", default-features = false }
+wasm-bindgen-macro-support = { path = "../macro-support", version = "=0.2.99" }
 
 [dev-dependencies]
 js-sys = { path = "../js-sys" }
diff --git a/crates/msrv/lib/Cargo.toml b/crates/msrv/lib/Cargo.toml
index 98e95deff10..8bff4349dd4 100644
--- a/crates/msrv/lib/Cargo.toml
+++ b/crates/msrv/lib/Cargo.toml
@@ -31,4 +31,3 @@ web-sys = { path = "../../web-sys", default-features = false }
 # Pinned sub-dependencies for MSRV
 bumpalo = "=3.12.0"
 log = "=0.4.18"
-scoped-tls = { version = "=1.0.0", optional = false }
diff --git a/crates/test/Cargo.toml b/crates/test/Cargo.toml
index 7303e635a54..004e990cac7 100644
--- a/crates/test/Cargo.toml
+++ b/crates/test/Cargo.toml
@@ -11,12 +11,11 @@ version = "0.3.49"
 
 [features]
 default = ["std"]
-std = ["wasm-bindgen/std", "js-sys/std", "wasm-bindgen-futures/std", "scoped-tls"]
+std = ["wasm-bindgen/std", "js-sys/std", "wasm-bindgen-futures/std"]
 
 [dependencies]
 gg-alloc = { version = "1.0", optional = true }
 js-sys = { path = '../js-sys', version = '=0.3.76', default-features = false }
-scoped-tls = { version = "1.0", optional = true }
 wasm-bindgen = { path = '../..', version = '=0.2.99', default-features = false }
 wasm-bindgen-futures = { path = '../futures', version = '=0.4.49', default-features = false }
 wasm-bindgen-test-macro = { path = '../test-macro', version = '=0.3.49' }
diff --git a/crates/test/src/lib.rs b/crates/test/src/lib.rs
index f20ca2d82e3..36ee18248c9 100644
--- a/crates/test/src/lib.rs
+++ b/crates/test/src/lib.rs
@@ -7,8 +7,6 @@
 
 extern crate alloc;
 
-#[cfg(feature = "std")]
-use scoped_tls::scoped_thread_local;
 pub use wasm_bindgen_test_macro::wasm_bindgen_test;
 
 // Custom allocator that only returns pointers in the 2GB-4GB range
diff --git a/crates/test/src/rt/mod.rs b/crates/test/src/rt/mod.rs
index 0c28b1344d1..6b35c145b56 100644
--- a/crates/test/src/rt/mod.rs
+++ b/crates/test/src/rt/mod.rs
@@ -114,7 +114,6 @@ const CONCURRENCY: usize = 1;
 pub mod browser;
 pub mod detect;
 pub mod node;
-#[cfg(not(feature = "std"))]
 mod scoped_tls;
 pub mod worker;
 
diff --git a/src/cache/intern.rs b/src/cache/intern.rs
index c8aa51b2caa..b9559a2d213 100644
--- a/src/cache/intern.rs
+++ b/src/cache/intern.rs
@@ -1,6 +1,5 @@
 use cfg_if::cfg_if;
 
-
 cfg_if! {
     if #[cfg(feature = "enable-interning")] {
         use std::thread_local;
@@ -51,7 +50,6 @@ cfg_if! {
     }
 }
 
-
 /// Interns Rust strings so that it's much faster to send them to JS.
 ///
 /// Sending strings from Rust to JS is slow, because it has to do a full `O(n)`
@@ -89,7 +87,6 @@ pub fn intern(s: &str) -> &str {
     s
 }
 
-
 /// Removes a Rust string from the intern cache.
 ///
 /// This does the opposite of the [`intern`](fn.intern.html) function.
diff --git a/src/externref.rs b/src/externref.rs
index a708dc5adc2..e575c12a537 100644
--- a/src/externref.rs
+++ b/src/externref.rs
@@ -117,9 +117,6 @@ fn internal_error(msg: &str) -> ! {
 
 // Management of `externref` is always thread local since an `externref` value
 // can't cross threads in wasm. Indices as a result are always thread-local.
-#[cfg(feature = "std")]
-std::thread_local!(static HEAP_SLAB: Cell<Slab> = Cell::new(Slab::new()));
-#[cfg(not(feature = "std"))]
 #[cfg_attr(target_feature = "atomics", thread_local)]
 static HEAP_SLAB: crate::__rt::LazyCell<Cell<Slab>> =
     crate::__rt::LazyCell::new(|| Cell::new(Slab::new()));
diff --git a/src/lib.rs b/src/lib.rs
index 810197c3072..0c81941bc39 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -48,21 +48,17 @@
 
 #![no_std]
 #![cfg_attr(wasm_bindgen_unstable_test_coverage, feature(coverage_attribute))]
+#![cfg_attr(target_feature = "atomics", feature(thread_local))]
 #![cfg_attr(
-    all(not(feature = "std"), target_feature = "atomics"),
-    feature(thread_local)
-)]
-#![cfg_attr(
-    any(
-        all(not(feature = "std"), target_feature = "atomics"),
-        wasm_bindgen_unstable_test_coverage
-    ),
+    any(target_feature = "atomics", wasm_bindgen_unstable_test_coverage),
     feature(allow_internal_unstable),
     allow(internal_features)
 )]
 #![doc(html_root_url = "https://docs.rs/wasm-bindgen/0.2")]
 
 extern crate alloc;
+#[cfg(feature = "std")]
+extern crate std;
 
 use alloc::boxed::Box;
 use alloc::string::String;
@@ -77,12 +73,6 @@ use core::ptr::NonNull;
 
 use crate::convert::{FromWasmAbi, TryFromJsValue, WasmRet, WasmSlice};
 
-macro_rules! if_std {
-    ($($i:item)*) => ($(
-        #[cfg(feature = "std")] $i
-    )*)
-}
-
 macro_rules! externs {
     ($(#[$attr:meta])* extern "C" { $(fn $name:ident($($args:tt)*) -> $ret:ty;)* }) => (
         #[cfg(all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")))]
@@ -129,12 +119,8 @@ mod link;
 mod cast;
 pub use crate::cast::{JsCast, JsObject};
 
-if_std! {
-    extern crate std;
-    use std::prelude::v1::*;
-    mod cache;
-    pub use cache::intern::{intern, unintern};
-}
+mod cache;
+pub use cache::intern::{intern, unintern};
 
 #[doc(hidden)]
 #[path = "rt/mod.rs"]
@@ -447,7 +433,6 @@ impl JsValue {
     }
 
     /// Get a string representation of the JavaScript object for debugging.
-    #[cfg(feature = "std")]
     fn as_debug_string(&self) -> String {
         unsafe {
             let mut ret = [0; 2];
@@ -1184,20 +1169,12 @@ impl Clone for JsValue {
     }
 }
 
-#[cfg(feature = "std")]
 impl core::fmt::Debug for JsValue {
     fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
         write!(f, "JsValue({})", self.as_debug_string())
     }
 }
 
-#[cfg(not(feature = "std"))]
-impl core::fmt::Debug for JsValue {
-    fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
-        f.write_str("JsValue")
-    }
-}
-
 impl Drop for JsValue {
     #[inline]
     fn drop(&mut self) {
@@ -1278,13 +1255,10 @@ impl<T: FromWasmAbi + 'static> Deref for JsStatic<T> {
 /// ```
 pub struct JsThreadLocal<T: 'static> {
     #[doc(hidden)]
-    #[cfg(feature = "std")]
-    pub __inner: &'static std::thread::LocalKey<T>,
-    #[doc(hidden)]
-    #[cfg(all(not(feature = "std"), not(target_feature = "atomics")))]
+    #[cfg(not(target_feature = "atomics"))]
     pub __inner: &'static __rt::LazyCell<T>,
     #[doc(hidden)]
-    #[cfg(all(not(feature = "std"), target_feature = "atomics"))]
+    #[cfg(target_feature = "atomics")]
     pub __inner: fn() -> *const T,
 }
 
@@ -1293,11 +1267,9 @@ impl<T> JsThreadLocal<T> {
     where
         F: FnOnce(&T) -> R,
     {
-        #[cfg(feature = "std")]
-        return self.__inner.with(f);
-        #[cfg(all(not(feature = "std"), not(target_feature = "atomics")))]
+        #[cfg(not(target_feature = "atomics"))]
         return f(self.__inner);
-        #[cfg(all(not(feature = "std"), target_feature = "atomics"))]
+        #[cfg(target_feature = "atomics")]
         f(unsafe { &*(self.__inner)() })
     }
 }
@@ -1716,14 +1688,15 @@ impl JsError {
     }
 }
 
-if_std! {
-    impl<E> From<E> for JsError
-    where
-        E: std::error::Error,
-    {
-        fn from(error: E) -> Self {
-            JsError::new(&error.to_string())
-        }
+#[cfg(feature = "std")]
+impl<E> From<E> for JsError
+where
+    E: std::error::Error,
+{
+    fn from(error: E) -> Self {
+        use std::string::ToString;
+
+        JsError::new(&error.to_string())
     }
 }
 
diff --git a/src/rt/mod.rs b/src/rt/mod.rs
index 82e97f691f5..c4b104abf4d 100644
--- a/src/rt/mod.rs
+++ b/src/rt/mod.rs
@@ -4,86 +4,73 @@ use core::cell::{Cell, UnsafeCell};
 use core::convert::Infallible;
 use core::mem;
 use core::ops::{Deref, DerefMut};
-#[cfg(all(target_feature = "atomics", not(feature = "std")))]
+#[cfg(target_feature = "atomics")]
 use core::sync::atomic::{AtomicU8, Ordering};
 
+use alloc::alloc::{alloc, dealloc, realloc, Layout};
+use alloc::boxed::Box;
+use alloc::rc::Rc;
+use once_cell::unsync::Lazy;
+
 pub extern crate alloc;
 pub extern crate core;
 #[cfg(feature = "std")]
 pub extern crate std;
 
-use alloc::alloc::{alloc, dealloc, realloc, Layout};
-use alloc::boxed::Box;
-use alloc::rc::Rc;
-
 pub mod marker;
 
-/// Wrapper around [`::once_cell::unsync::Lazy`] adding some compatibility methods with
-/// [`std::thread::LocalKey`] and adding `Send + Sync` when `atomics` is not enabled.
-#[cfg(not(feature = "std"))]
-pub struct LazyCell<T, F = fn() -> T>(::once_cell::unsync::Lazy<T, F>);
+/// Wrapper around [`Lazy`] adding `Send + Sync` when `atomics` is not enabled.
+pub struct LazyCell<T, F = fn() -> T>(Wrapper<Lazy<T, F>>);
 
-#[cfg(all(not(target_feature = "atomics"), not(feature = "std")))]
-unsafe impl<T, F> Sync for LazyCell<T, F> {}
+struct Wrapper<T>(T);
 
-#[cfg(all(not(target_feature = "atomics"), not(feature = "std")))]
-unsafe impl<T, F> Send for LazyCell<T, F> {}
+unsafe impl<T> Sync for Wrapper<T> {}
+
+unsafe impl<T> Send for Wrapper<T> {}
 
-#[cfg(not(feature = "std"))]
 impl<T, F> LazyCell<T, F> {
     pub const fn new(init: F) -> LazyCell<T, F> {
-        Self(::once_cell::unsync::Lazy::new(init))
+        Self(Wrapper(Lazy::new(init)))
     }
 }
 
-#[cfg(not(feature = "std"))]
 impl<T, F: FnOnce() -> T> LazyCell<T, F> {
     pub(crate) fn try_with<R>(
         &self,
         f: impl FnOnce(&T) -> R,
     ) -> Result<R, core::convert::Infallible> {
-        Ok(f(&self.0))
+        Ok(f(&self.0 .0))
     }
 
     pub fn force(this: &Self) -> &T {
-        &this.0
+        &this.0 .0
     }
 }
 
-#[cfg(not(feature = "std"))]
 impl<T> Deref for LazyCell<T> {
     type Target = T;
 
     fn deref(&self) -> &T {
-        ::once_cell::unsync::Lazy::force(&self.0)
+        ::once_cell::unsync::Lazy::force(&self.0 .0)
     }
 }
 
-#[cfg(feature = "std")]
-pub use once_cell::sync::Lazy as LazyLock;
-
-#[cfg(all(not(target_feature = "atomics"), not(feature = "std")))]
+#[cfg(not(target_feature = "atomics"))]
 pub use LazyCell as LazyLock;
 
-#[cfg(all(target_feature = "atomics", not(feature = "std")))]
+#[cfg(target_feature = "atomics")]
 pub struct LazyLock<T, F = fn() -> T> {
     state: AtomicU8,
-    data: UnsafeCell<Data<T, F>>,
+    data: Wrapper<UnsafeCell<Data<T, F>>>,
 }
 
-#[cfg(all(target_feature = "atomics", not(feature = "std")))]
+#[cfg(target_feature = "atomics")]
 enum Data<T, F> {
     Value(T),
     Init(F),
 }
 
-#[cfg(all(target_feature = "atomics", not(feature = "std")))]
-unsafe impl<T, F> Sync for LazyLock<T, F> {}
-
-#[cfg(all(target_feature = "atomics", not(feature = "std")))]
-unsafe impl<T, F> Send for LazyLock<T, F> {}
-
-#[cfg(all(target_feature = "atomics", not(feature = "std")))]
+#[cfg(target_feature = "atomics")]
 impl<T, F> LazyLock<T, F> {
     const STATE_UNINIT: u8 = 0;
     const STATE_INITIALIZING: u8 = 1;
@@ -92,12 +79,12 @@ impl<T, F> LazyLock<T, F> {
     pub const fn new(init: F) -> LazyLock<T, F> {
         Self {
             state: AtomicU8::new(Self::STATE_UNINIT),
-            data: UnsafeCell::new(Data::Init(init)),
+            data: Wrapper(UnsafeCell::new(Data::Init(init))),
         }
     }
 }
 
-#[cfg(all(target_feature = "atomics", not(feature = "std")))]
+#[cfg(target_feature = "atomics")]
 impl<T> Deref for LazyLock<T> {
     type Target = T;
 
@@ -107,7 +94,7 @@ impl<T> Deref for LazyLock<T> {
         loop {
             match state {
                 Self::STATE_INIT => {
-                    let Data::Value(value) = (unsafe { &*self.data.get() }) else {
+                    let Data::Value(value) = (unsafe { &*self.data.0.get() }) else {
                         unreachable!()
                     };
                     return value;
@@ -123,7 +110,7 @@ impl<T> Deref for LazyLock<T> {
                         continue;
                     }
 
-                    let data = unsafe { &mut *self.data.get() };
+                    let data = unsafe { &mut *self.data.0.get() };
                     let Data::Init(init) = data else {
                         unreachable!()
                     };
@@ -144,7 +131,7 @@ impl<T> Deref for LazyLock<T> {
 
 #[macro_export]
 #[doc(hidden)]
-#[cfg(all(not(feature = "std"), not(target_feature = "atomics")))]
+#[cfg(not(target_feature = "atomics"))]
 macro_rules! __wbindgen_thread_local {
     ($wasm_bindgen:tt, $actual_ty:ty) => {{
         static _VAL: $wasm_bindgen::__rt::LazyCell<$actual_ty> =
@@ -155,7 +142,7 @@ macro_rules! __wbindgen_thread_local {
 
 #[macro_export]
 #[doc(hidden)]
-#[cfg(all(not(feature = "std"), target_feature = "atomics"))]
+#[cfg(target_feature = "atomics")]
 #[allow_internal_unstable(thread_local)]
 macro_rules! __wbindgen_thread_local {
     ($wasm_bindgen:tt, $actual_ty:ty) => {{
@@ -538,63 +525,22 @@ pub fn link_mem_intrinsics() {
     crate::link::link_intrinsics();
 }
 
-#[cfg(feature = "std")]
-std::thread_local! {
-    static GLOBAL_EXNDATA: Cell<[u32; 2]> = Cell::new([0; 2]);
-}
-#[cfg(all(not(feature = "std"), not(target_feature = "atomics")))]
-static mut GLOBAL_EXNDATA: [u32; 2] = [0; 2];
-#[cfg(all(not(feature = "std"), target_feature = "atomics"))]
-#[thread_local]
-static GLOBAL_EXNDATA: Cell<[u32; 2]> = Cell::new([0; 2]);
-
-struct GlobalExndata;
-
-impl GlobalExndata {
-    #[cfg(feature = "std")]
-    fn get() -> [u32; 2] {
-        GLOBAL_EXNDATA.with(Cell::get)
-    }
-
-    #[cfg(all(not(feature = "std"), not(target_feature = "atomics")))]
-    fn get() -> [u32; 2] {
-        unsafe { GLOBAL_EXNDATA }
-    }
-
-    #[cfg(all(not(feature = "std"), target_feature = "atomics"))]
-    fn get() -> [u32; 2] {
-        GLOBAL_EXNDATA.get()
-    }
-
-    #[cfg(feature = "std")]
-    fn set(data: [u32; 2]) {
-        GLOBAL_EXNDATA.with(|d| d.set(data))
-    }
-
-    #[cfg(all(not(feature = "std"), not(target_feature = "atomics")))]
-    fn set(data: [u32; 2]) {
-        unsafe { GLOBAL_EXNDATA = data };
-    }
-
-    #[cfg(all(not(feature = "std"), target_feature = "atomics"))]
-    fn set(data: [u32; 2]) {
-        GLOBAL_EXNDATA.set(data);
-    }
-}
+#[cfg_attr(target_feature = "atomics", thread_local)]
+static GLOBAL_EXNDATA: Wrapper<Cell<[u32; 2]>> = Wrapper(Cell::new([0; 2]));
 
 #[no_mangle]
 pub unsafe extern "C" fn __wbindgen_exn_store(idx: u32) {
-    debug_assert_eq!(GlobalExndata::get()[0], 0);
-    GlobalExndata::set([1, idx]);
+    debug_assert_eq!(GLOBAL_EXNDATA.0.get()[0], 0);
+    GLOBAL_EXNDATA.0.set([1, idx]);
 }
 
 pub fn take_last_exception() -> Result<(), super::JsValue> {
-    let ret = if GlobalExndata::get()[0] == 1 {
-        Err(super::JsValue::_new(GlobalExndata::get()[1]))
+    let ret = if GLOBAL_EXNDATA.0.get()[0] == 1 {
+        Err(super::JsValue::_new(GLOBAL_EXNDATA.0.get()[1]))
     } else {
         Ok(())
     };
-    GlobalExndata::set([0, 0]);
+    GLOBAL_EXNDATA.0.set([0, 0]);
     ret
 }