diff --git a/Cargo.toml b/Cargo.toml index 43affd2..141f11d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -38,10 +38,11 @@ luau-vector4 = ["luau", "ffi/luau-vector4"] vendored = ["ffi/vendored"] module = ["dep:mlua_derive", "ffi/module"] async = ["dep:futures-util"] -send = ["parking_lot/send_guard"] +send = ["parking_lot/send_guard", "error-send"] +error-send = [] serialize = ["dep:serde", "dep:erased-serde", "dep:serde-value"] macros = ["mlua_derive/macros"] -anyhow = ["dep:anyhow"] +anyhow = ["dep:anyhow", "error-send"] [dependencies] mlua_derive = { version = "=0.10.0-rc.1", optional = true, path = "mlua_derive" } diff --git a/README.md b/README.md index 3a0efe8..5bd0157 100644 --- a/README.md +++ b/README.md @@ -55,6 +55,7 @@ Below is a list of the available feature flags. By default `mlua` does not enabl * `module`: enable module mode (building loadable `cdylib` library for Lua) * `async`: enable async/await support (any executor can be used, eg. [tokio] or [async-std]) * `send`: make `mlua::Lua: Send + Sync` (adds [`Send`] requirement to `mlua::Function` and `mlua::UserData`) +* `error-send`: make `mlua:Error: Send + Sync` * `serialize`: add serialization and deserialization support to `mlua` types using [serde] framework * `macros`: enable procedural macros (such as `chunk!`) * `anyhow`: enable `anyhow::Error` conversion into Lua diff --git a/src/error.rs b/src/error.rs index fa61eda..1f24396 100644 --- a/src/error.rs +++ b/src/error.rs @@ -9,6 +9,12 @@ use std::sync::Arc; use crate::private::Sealed; +#[cfg(feature = "error-send")] +type DynStdError = dyn StdError + Send + Sync; + +#[cfg(not(feature = "error-send"))] +type DynStdError = dyn StdError; + /// Error type returned by `mlua` methods. #[derive(Debug, Clone)] #[non_exhaustive] @@ -191,7 +197,7 @@ pub enum Error { /// Returning `Err(ExternalError(...))` from a Rust callback will raise the error as a Lua /// error. The Rust code that originally invoked the Lua code then receives a `CallbackError`, /// from which the original error (and a stack traceback) can be recovered. - ExternalError(Arc), + ExternalError(Arc), /// An error with additional context. WithContext { /// A string containing additional context. @@ -345,7 +351,7 @@ impl Error { /// Wraps an external error object. #[inline] - pub fn external>>(err: T) -> Self { + pub fn external>>(err: T) -> Self { Error::ExternalError(err.into().into()) } @@ -406,7 +412,7 @@ pub trait ExternalError { fn into_lua_err(self) -> Error; } -impl>> ExternalError for E { +impl>> ExternalError for E { fn into_lua_err(self) -> Error { Error::external(self) } @@ -552,3 +558,13 @@ impl<'a> Iterator for Chain<'a> { } } } + +#[cfg(test)] +mod assertions { + use super::*; + + #[cfg(not(feature = "error-send"))] + static_assertions::assert_not_impl_any!(Error: Send, Sync); + #[cfg(feature = "send")] + static_assertions::assert_impl_all!(Error: Send, Sync); +}