diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 6909d10dd08..c477743eba8 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -342,7 +342,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - run: rustup update --no-self-update 1.76.0 && rustup default 1.76.0 + - run: rustup update --no-self-update 1.78.0 && rustup default 1.78.0 - run: cargo test -p wasm-bindgen-macro - run: cargo test -p wasm-bindgen-test-macro @@ -569,6 +569,8 @@ jobs: - wasm32-unknown-unknown features: - --no-default-features + - --no-default-features --features std + - --no-default-features --features msrv - "" defaults: run: @@ -594,6 +596,8 @@ jobs: - wasm32-unknown-unknown features: - --no-default-features + - --no-default-features --features std + - --no-default-features --features msrv - "" defaults: run: diff --git a/CHANGELOG.md b/CHANGELOG.md index 17a86bbfdbd..95b8f96cbfa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,9 @@ * Optional parameters are now typed as `T | undefined | null` to reflect the actual JS behavior. [#4188](https://github.com/rustwasm/wasm-bindgen/pull/4188) +* Adding `getter`, `setter`, and `constructor` methods to enums now results in a compiler error. This was previously erroneously allowed and resulted in invalid JS code gen. + [#4278](https://github.com/rustwasm/wasm-bindgen/pull/4278) + ### Fixed - Fixed using [JavaScript keyword](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Lexical_grammar#keywords) as identifiers not being handled correctly. diff --git a/Cargo.toml b/Cargo.toml index 2b4ac7f3f3d..5956facd64a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,12 +22,19 @@ features = ["serde-serialize"] test = false [features] -default = ["std"] +default = ["std", "msrv"] enable-interning = ["std"] serde-serialize = ["serde", "serde_json", "std"] spans = [] std = ["wasm-bindgen-macro/std", "once_cell/std"] +# Opt-in for Rust language features that require a higher MSRV. +# +# The current rustc version is detected at compile-time, so enabling this +# feature for older compilers will NOT result in a compilation error. Instead, +# any unsupported language feature will not be used. +msrv = ["rustversion"] + # Whether or not the `#[wasm_bindgen]` macro is strict and generates an error on # all unused attributes strict-macro = ["wasm-bindgen-macro/strict-macro"] @@ -43,6 +50,7 @@ xxx_debug_only_print_generated_code = ["wasm-bindgen-macro/xxx_debug_only_print_ [dependencies] cfg-if = "1.0.0" 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 } diff --git a/crates/backend/src/codegen.rs b/crates/backend/src/codegen.rs index 23599fc87b0..63b9376e35d 100644 --- a/crates/backend/src/codegen.rs +++ b/crates/backend/src/codegen.rs @@ -224,6 +224,13 @@ impl ToTokens for ast::Struct { let unwrap_fn = Ident::new(&shared::unwrap_function(&name_str), Span::call_site()); let wasm_bindgen = &self.wasm_bindgen; (quote! { + #[automatically_derived] + impl #wasm_bindgen::__rt::marker::SupportsConstructor for #name {} + #[automatically_derived] + impl #wasm_bindgen::__rt::marker::SupportsInstanceProperty for #name {} + #[automatically_derived] + impl #wasm_bindgen::__rt::marker::SupportsStaticProperty for #name {} + #[automatically_derived] impl #wasm_bindgen::describe::WasmDescribe for #name { fn describe() { @@ -782,12 +789,41 @@ impl TryToTokens for ast::Export { let nargs = self.function.arguments.len() as u32; let attrs = &self.function.rust_attrs; - let start_check = if self.start { - quote! { const _ASSERT: fn() = || -> #projection::Abi { loop {} }; } - } else { - quote! {} + let mut checks = Vec::new(); + if self.start { + checks.push(quote! { const _ASSERT: fn() = || -> #projection::Abi { loop {} }; }); }; + if let Some(class) = self.rust_class.as_ref() { + // little helper function to make sure the check points to the + // location of the function causing the assert to fail + let mut add_check = |token_stream| { + checks.push(respan(token_stream, &self.rust_name)); + }; + + match &self.method_kind { + ast::MethodKind::Constructor => { + add_check(quote! { + let _: #wasm_bindgen::__rt::marker::CheckSupportsConstructor<#class>; + }); + } + ast::MethodKind::Operation(operation) => match operation.kind { + ast::OperationKind::Getter(_) | ast::OperationKind::Setter(_) => { + if operation.is_static { + add_check(quote! { + let _: #wasm_bindgen::__rt::marker::CheckSupportsStaticProperty<#class>; + }); + } else { + add_check(quote! { + let _: #wasm_bindgen::__rt::marker::CheckSupportsInstanceProperty<#class>; + }); + } + } + _ => {} + }, + } + } + (quote! { #[automatically_derived] const _: () = { @@ -798,7 +834,9 @@ impl TryToTokens for ast::Export { export_name = #export_name, )] pub unsafe extern "C" fn #generated_name(#(#args),*) -> #wasm_bindgen::convert::WasmRet<#projection::Abi> { - #start_check + const _: () = { + #(#checks)* + }; let #ret = #call; #convert_ret diff --git a/crates/macro/ui-tests/async-errors.stderr b/crates/macro/ui-tests/async-errors.stderr index 5526851f1d3..a13c8fceac8 100644 --- a/crates/macro/ui-tests/async-errors.stderr +++ b/crates/macro/ui-tests/async-errors.stderr @@ -22,7 +22,7 @@ error[E0277]: the trait bound `wasm_bindgen::JsValue: From` is not sati --> ui-tests/async-errors.rs:35:24 | 35 | pub async fn bad3() -> BadType { loop {} } - | ^^^^^^^ the trait `From` is not implemented for `wasm_bindgen::JsValue` + | ^^^^^^^ the trait `From` is not implemented for `wasm_bindgen::JsValue`, which is required by `BadType: IntoJsResult` | = help: the following other types implement trait `From`: > diff --git a/crates/macro/ui-tests/main-debug.rs b/crates/macro/ui-tests/main-debug.rs index 2fc9aa7ca6a..ba163e4cf18 100644 --- a/crates/macro/ui-tests/main-debug.rs +++ b/crates/macro/ui-tests/main-debug.rs @@ -9,7 +9,7 @@ fn main() -> Result<(), Test> { struct Test; impl fmt::Debug for Test { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result { unimplemented!() } } diff --git a/crates/macro/ui-tests/main-infallible.stderr b/crates/macro/ui-tests/main-infallible.stderr index fd8c9c99769..4487bdcfcf6 100644 --- a/crates/macro/ui-tests/main-infallible.stderr +++ b/crates/macro/ui-tests/main-infallible.stderr @@ -3,3 +3,20 @@ error: the main function has to be called main | 10 | fn fail() {} | ^^^^ + +warning: unreachable expression + --> ui-tests/main-infallible.rs:4:1 + | +4 | #[wasm_bindgen(main)] + | ^^^^^^^^^^^^^^^^^^^^^ + | | + | unreachable expression + | any code following this expression is unreachable + | +note: this expression has type `Infallible`, which is uninhabited + --> ui-tests/main-infallible.rs:4:1 + | +4 | #[wasm_bindgen(main)] + | ^^^^^^^^^^^^^^^^^^^^^ + = note: `#[warn(unreachable_code)]` on by default + = note: this warning originates in the attribute macro `wasm_bindgen` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/crates/macro/ui-tests/missing-catch.stderr b/crates/macro/ui-tests/missing-catch.stderr index 4fc6b3ed6de..b420b787da7 100644 --- a/crates/macro/ui-tests/missing-catch.stderr +++ b/crates/macro/ui-tests/missing-catch.stderr @@ -18,3 +18,38 @@ error[E0277]: the trait bound `Result: FromWasmAbi` is not satisfied + --> ui-tests/missing-catch.rs:3:1 + | +3 | #[wasm_bindgen] + | ^^^^^^^^^^^^^^^ the trait `FromWasmAbi` is not implemented for `Result` + | + = help: the following other types implement trait `FromWasmAbi`: + bool + char + isize + i8 + i16 + i32 + i64 + i128 + and $N others + = note: this error originates in the attribute macro `wasm_bindgen` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0277]: the trait bound `Result: FromWasmAbi` is not satisfied + --> ui-tests/missing-catch.rs:6:18 + | +6 | pub fn foo() -> Result; + | ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `FromWasmAbi` is not implemented for `Result` + | + = help: the following other types implement trait `FromWasmAbi`: + bool + char + isize + i8 + i16 + i32 + i64 + i128 + and $N others diff --git a/crates/macro/ui-tests/traits-not-implemented.stderr b/crates/macro/ui-tests/traits-not-implemented.stderr index 82aeb56b6fe..2f7e9887747 100644 --- a/crates/macro/ui-tests/traits-not-implemented.stderr +++ b/crates/macro/ui-tests/traits-not-implemented.stderr @@ -15,3 +15,41 @@ error[E0277]: the trait bound `A: IntoWasmAbi` is not satisfied i128 and $N others = note: this error originates in the attribute macro `wasm_bindgen` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0277]: the trait bound `A: IntoWasmAbi` is not satisfied + --> ui-tests/traits-not-implemented.rs:8:19 + | +8 | pub fn foo(a: A); + | ^ the trait `IntoWasmAbi` is not implemented for `A` + | + = help: the following other types implement trait `IntoWasmAbi`: + bool + char + isize + i8 + i16 + i32 + i64 + i128 + and $N others + +error[E0277]: the trait bound `A: IntoWasmAbi` is not satisfied + --> ui-tests/traits-not-implemented.rs:8:12 + | +5 | #[wasm_bindgen] + | --------------- in this procedural macro expansion +... +8 | pub fn foo(a: A); + | ^^^ the trait `IntoWasmAbi` is not implemented for `A` + | + = help: the following other types implement trait `IntoWasmAbi`: + bool + char + isize + i8 + i16 + i32 + i64 + i128 + and $N others + = note: this error originates in the attribute macro `wasm_bindgen` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/crates/macro/ui-tests/unsupported-options.rs b/crates/macro/ui-tests/unsupported-options.rs new file mode 100644 index 00000000000..1589027f30c --- /dev/null +++ b/crates/macro/ui-tests/unsupported-options.rs @@ -0,0 +1,82 @@ +use wasm_bindgen::prelude::*; + +#[wasm_bindgen] +pub struct RustStruct { + data: u32, +} + +#[wasm_bindgen] +impl RustStruct { + pub fn instance_method(&self) {} + fn priv_instance_method(&self) {} + pub fn static_method() {} + + #[wasm_bindgen(constructor)] + pub fn new() -> Self { + Self { data: 0 } + } + + #[wasm_bindgen(getter)] + pub fn prop(self) -> u32 { + 32 + } + #[wasm_bindgen(setter)] + pub fn set_prop(self, _value: u32) {} + + #[wasm_bindgen(getter)] + pub fn static_prop() -> u32 { + 32 + } + #[wasm_bindgen(setter)] + pub fn set_static_prop(_value: u32) {} + + #[wasm_bindgen(indexing_getter)] + pub fn indexing_getter(self) -> u32 { + 32 + } + #[wasm_bindgen(indexing_setter)] + pub fn indexing_setter(self, _value: u32) {} + #[wasm_bindgen(indexing_deleter)] + pub fn indexing_deleter(self, _value: u32) {} +} + +#[wasm_bindgen] +pub enum RustEnum { + A = 0, + B = 1, +} + +#[wasm_bindgen] +impl RustEnum { + pub fn instance_method(self) {} + fn priv_instance_method(self) {} + pub fn static_method() {} + + #[wasm_bindgen(constructor)] + pub fn new() -> Self { + Self::A + } + + #[wasm_bindgen(getter)] + pub fn prop(self) -> u32 { + 32 + } + #[wasm_bindgen(setter)] + pub fn set_prop(self, _value: u32) {} + + #[wasm_bindgen(getter)] + pub fn static_prop() -> u32 { + 32 + } + #[wasm_bindgen(setter)] + pub fn set_static_prop(_value: u32) {} +} + +pub struct NonWasmType; + +#[wasm_bindgen] +impl NonWasmType { + pub fn static_method() {} +} + +fn main() {} diff --git a/crates/macro/ui-tests/unsupported-options.stderr b/crates/macro/ui-tests/unsupported-options.stderr new file mode 100644 index 00000000000..7a6dcd70537 --- /dev/null +++ b/crates/macro/ui-tests/unsupported-options.stderr @@ -0,0 +1,95 @@ +error[E0277]: JavaScript constructors are not supported for `RustEnum` + --> ui-tests/unsupported-options.rs:56:12 + | +49 | #[wasm_bindgen] + | --------------- in this procedural macro expansion +... +56 | pub fn new() -> Self { + | ^^^ this function cannot be the constructor of `RustEnum` + | + = help: the trait `SupportsConstructor` is not implemented for `RustEnum` + = note: `#[wasm_bindgen(constructor)]` is only supported for `struct`s and cannot be used for `enum`s. + = note: Consider removing the `constructor` option and using a regular static method instead. + = help: the trait `SupportsConstructor` is implemented for `RustStruct` +note: required by a bound in `CheckSupportsConstructor` + --> $WORKSPACE/src/rt/marker.rs + | + | pub struct CheckSupportsConstructor(T); + | ^^^^^^^^^^^^^^^^^^^ required by this bound in `CheckSupportsConstructor` + = note: this error originates in the attribute macro `wasm_bindgen::prelude::__wasm_bindgen_class_marker` which comes from the expansion of the attribute macro `wasm_bindgen` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0277]: JavaScript instance getters and setters are not supported for `RustEnum` + --> ui-tests/unsupported-options.rs:61:12 + | +49 | #[wasm_bindgen] + | --------------- in this procedural macro expansion +... +61 | pub fn prop(self) -> u32 { + | ^^^^ this method cannot be a getter or setter for `RustEnum` + | + = help: the trait `SupportsInstanceProperty` is not implemented for `RustEnum` + = note: `#[wasm_bindgen(getter)]` and `#[wasm_bindgen(setter)]` are only supported for `struct`s and cannot be used for `enum`s. + = help: the trait `SupportsInstanceProperty` is implemented for `RustStruct` +note: required by a bound in `CheckSupportsInstanceProperty` + --> $WORKSPACE/src/rt/marker.rs + | + | pub struct CheckSupportsInstanceProperty(T); + | ^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `CheckSupportsInstanceProperty` + = note: this error originates in the attribute macro `wasm_bindgen::prelude::__wasm_bindgen_class_marker` which comes from the expansion of the attribute macro `wasm_bindgen` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0277]: JavaScript instance getters and setters are not supported for `RustEnum` + --> ui-tests/unsupported-options.rs:65:12 + | +49 | #[wasm_bindgen] + | --------------- in this procedural macro expansion +... +65 | pub fn set_prop(self, _value: u32) {} + | ^^^^^^^^ this method cannot be a getter or setter for `RustEnum` + | + = help: the trait `SupportsInstanceProperty` is not implemented for `RustEnum` + = note: `#[wasm_bindgen(getter)]` and `#[wasm_bindgen(setter)]` are only supported for `struct`s and cannot be used for `enum`s. + = help: the trait `SupportsInstanceProperty` is implemented for `RustStruct` +note: required by a bound in `CheckSupportsInstanceProperty` + --> $WORKSPACE/src/rt/marker.rs + | + | pub struct CheckSupportsInstanceProperty(T); + | ^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `CheckSupportsInstanceProperty` + = note: this error originates in the attribute macro `wasm_bindgen::prelude::__wasm_bindgen_class_marker` which comes from the expansion of the attribute macro `wasm_bindgen` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0277]: JavaScript static getters and setters are not supported for `RustEnum` + --> ui-tests/unsupported-options.rs:68:12 + | +49 | #[wasm_bindgen] + | --------------- in this procedural macro expansion +... +68 | pub fn static_prop() -> u32 { + | ^^^^^^^^^^^ this static function cannot be a static getter or setter on `RustEnum` + | + = help: the trait `SupportsStaticProperty` is not implemented for `RustEnum` + = note: `#[wasm_bindgen(getter)]` and `#[wasm_bindgen(setter)]` are only supported for `struct`s and cannot be used for `enum`s. + = help: the trait `SupportsStaticProperty` is implemented for `RustStruct` +note: required by a bound in `CheckSupportsStaticProperty` + --> $WORKSPACE/src/rt/marker.rs + | + | pub struct CheckSupportsStaticProperty(T); + | ^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `CheckSupportsStaticProperty` + = note: this error originates in the attribute macro `wasm_bindgen::prelude::__wasm_bindgen_class_marker` which comes from the expansion of the attribute macro `wasm_bindgen` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0277]: JavaScript static getters and setters are not supported for `RustEnum` + --> ui-tests/unsupported-options.rs:72:12 + | +49 | #[wasm_bindgen] + | --------------- in this procedural macro expansion +... +72 | pub fn set_static_prop(_value: u32) {} + | ^^^^^^^^^^^^^^^ this static function cannot be a static getter or setter on `RustEnum` + | + = help: the trait `SupportsStaticProperty` is not implemented for `RustEnum` + = note: `#[wasm_bindgen(getter)]` and `#[wasm_bindgen(setter)]` are only supported for `struct`s and cannot be used for `enum`s. + = help: the trait `SupportsStaticProperty` is implemented for `RustStruct` +note: required by a bound in `CheckSupportsStaticProperty` + --> $WORKSPACE/src/rt/marker.rs + | + | pub struct CheckSupportsStaticProperty(T); + | ^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `CheckSupportsStaticProperty` + = note: this error originates in the attribute macro `wasm_bindgen::prelude::__wasm_bindgen_class_marker` which comes from the expansion of the attribute macro `wasm_bindgen` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/crates/msrv/lib/Cargo.toml b/crates/msrv/lib/Cargo.toml index 7cf0a5d4bb5..98e95deff10 100644 --- a/crates/msrv/lib/Cargo.toml +++ b/crates/msrv/lib/Cargo.toml @@ -5,7 +5,14 @@ publish = false version = "0.0.0" [features] -default = ["std"] +default = [ + "wasm-bindgen/default", + "js-sys/default", + "wasm-bindgen-futures/default", + "web-sys/default", + "wasm-bindgen-test/default", +] +msrv = ["wasm-bindgen/msrv"] std = [ "wasm-bindgen/std", "js-sys/std", diff --git a/crates/msrv/resolver/Cargo.toml b/crates/msrv/resolver/Cargo.toml index 6c7eeffbfc5..842ce86ec82 100644 --- a/crates/msrv/resolver/Cargo.toml +++ b/crates/msrv/resolver/Cargo.toml @@ -6,7 +6,14 @@ resolver = "1" version = "0.0.0" [features] -default = ["std"] +default = [ + "wasm-bindgen/default", + "js-sys/default", + "wasm-bindgen-futures/default", + "web-sys/default", + "wasm-bindgen-test/default", +] +msrv = ["wasm-bindgen/msrv"] std = [ "wasm-bindgen/std", "js-sys/std", diff --git a/src/lib.rs b/src/lib.rs index 5c22b11b462..810197c3072 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -14,6 +14,14 @@ //! This feature currently enables the `std` feature, meaning that it is not //! compatible with `no_std` environments. //! +//! ### `msrv` (default) +//! +//! Enables Rust language features that require a higher MSRV. Enabling this +//! feature on older compilers will NOT result in a compilation error, the newer +//! language features will simply not be used. +//! +//! When compiling with Rust v1.78 or later, this feature enables better error messages for invalid methods on structs and enums. +//! //! ### `std` (default) //! //! Enabling this feature will make the crate depend on the Rust standard library. @@ -60,7 +68,7 @@ use alloc::boxed::Box; use alloc::string::String; use alloc::vec::Vec; use core::convert::TryFrom; -use core::marker; +use core::marker::PhantomData; use core::mem; use core::ops::{ Add, BitAnd, BitOr, BitXor, Deref, DerefMut, Div, Mul, Neg, Not, Rem, Shl, Shr, Sub, @@ -129,7 +137,7 @@ if_std! { } #[doc(hidden)] -#[path = "rt.rs"] +#[path = "rt/mod.rs"] pub mod __rt; /// Representation of an object owned by JS. @@ -140,7 +148,7 @@ pub mod __rt; /// but for now it may be slightly slow. pub struct JsValue { idx: u32, - _marker: marker::PhantomData<*mut u8>, // not at all threadsafe + _marker: PhantomData<*mut u8>, // not at all threadsafe } const JSIDX_OFFSET: u32 = 128; // keep in sync with js/mod.rs @@ -167,7 +175,7 @@ impl JsValue { const fn _new(idx: u32) -> JsValue { JsValue { idx, - _marker: marker::PhantomData, + _marker: PhantomData, } } diff --git a/src/rt/marker.rs b/src/rt/marker.rs new file mode 100644 index 00000000000..8d4641b6772 --- /dev/null +++ b/src/rt/marker.rs @@ -0,0 +1,47 @@ +/// Marker trait for types that support `#[wasm_bindgen(constructor)]`. +#[cfg_attr( + feature = "msrv", + rustversion::attr( + since(1.78), + diagnostic::on_unimplemented( + message = "JavaScript constructors are not supported for `{Self}`", + label = "this function cannot be the constructor of `{Self}`", + note = "`#[wasm_bindgen(constructor)]` is only supported for `struct`s and cannot be used for `enum`s.", + note = "Consider removing the `constructor` option and using a regular static method instead." + ) + ) +)] +pub trait SupportsConstructor {} +pub struct CheckSupportsConstructor(T); + +/// Marker trait for types that support `#[wasm_bindgen(getter)]` or +/// `#[wasm_bindgen(Setter)]` on instance methods. +#[cfg_attr( + feature = "msrv", + rustversion::attr( + since(1.78), + diagnostic::on_unimplemented( + message = "JavaScript instance getters and setters are not supported for `{Self}`", + label = "this method cannot be a getter or setter for `{Self}`", + note = "`#[wasm_bindgen(getter)]` and `#[wasm_bindgen(setter)]` are only supported for `struct`s and cannot be used for `enum`s.", + ) + ) +)] +pub trait SupportsInstanceProperty {} +pub struct CheckSupportsInstanceProperty(T); + +/// Marker trait for types that support `#[wasm_bindgen(getter)]` or +/// `#[wasm_bindgen(Setter)]` on static methods. +#[cfg_attr( + feature = "msrv", + rustversion::attr( + since(1.78), + diagnostic::on_unimplemented( + message = "JavaScript static getters and setters are not supported for `{Self}`", + label = "this static function cannot be a static getter or setter on `{Self}`", + note = "`#[wasm_bindgen(getter)]` and `#[wasm_bindgen(setter)]` are only supported for `struct`s and cannot be used for `enum`s.", + ) + ) +)] +pub trait SupportsStaticProperty {} +pub struct CheckSupportsStaticProperty(T); diff --git a/src/rt.rs b/src/rt/mod.rs similarity index 99% rename from src/rt.rs rename to src/rt/mod.rs index 2aac5ce3a41..82e97f691f5 100644 --- a/src/rt.rs +++ b/src/rt/mod.rs @@ -16,6 +16,8 @@ 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"))]