From d0d4b9d3fb50721ce1a475ea8fb9c408ff1ad953 Mon Sep 17 00:00:00 2001 From: mejrs <59372212+mejrs@users.noreply.github.com> Date: Thu, 28 Sep 2023 12:26:09 +0200 Subject: [PATCH 1/2] Dont let auto trait syntax bleed through on stable --- src/marker.rs | 156 +++++++++++++++++++++++++++----------------------- 1 file changed, 83 insertions(+), 73 deletions(-) diff --git a/src/marker.rs b/src/marker.rs index 55b48119..7a4576c9 100644 --- a/src/marker.rs +++ b/src/marker.rs @@ -185,80 +185,90 @@ pub unsafe trait Ungil {} #[cfg(not(feature = "nightly"))] unsafe impl Ungil for T {} -/// Types that are safe to access while the GIL is not held. -/// -/// # Safety -/// -/// The type must not carry borrowed Python references or, if it does, not allow access to them if -/// the GIL is not held. -/// -/// See the [module-level documentation](self) for more information. -/// -/// # Examples -/// -/// Types which are `Ungil` cannot be used in contexts where the GIL was released, e.g. -/// -/// ```compile_fail -/// # use pyo3::prelude::*; -/// # use pyo3::types::PyString; -/// Python::with_gil(|py| { -/// let string = PyString::new(py, "foo"); -/// -/// py.allow_threads(|| { -/// println!("{:?}", string); -/// }); -/// }); -/// ``` -/// -/// This applies to the GIL token `Python` itself as well, e.g. -/// -/// ```compile_fail -/// # use pyo3::prelude::*; -/// Python::with_gil(|py| { -/// py.allow_threads(|| { -/// drop(py); -/// }); -/// }); -/// ``` -/// -/// On nightly Rust, this is not based on the [`Send`] auto trait and hence we are able -/// to prevent incorrectly circumventing it using e.g. the [`send_wrapper`](https://docs.rs/send_wrapper/) crate: -/// -/// ```compile_fail -/// # use pyo3::prelude::*; -/// # use pyo3::types::PyString; -/// use send_wrapper::SendWrapper; -/// -/// Python::with_gil(|py| { -/// let string = PyString::new(py, "foo"); -/// -/// let wrapped = SendWrapper::new(string); -/// -/// py.allow_threads(|| { -/// let sneaky: &PyString = *wrapped; -/// -/// println!("{:?}", sneaky); -/// }); -/// }); -/// ``` -/// -/// This also enables using non-[`Send`] types in `allow_threads`, -/// at least if they are not also bound to the GIL: -/// -/// ```rust -/// # use pyo3::prelude::*; -/// use std::rc::Rc; -/// -/// Python::with_gil(|py| { -/// let rc = Rc::new(42); -/// -/// py.allow_threads(|| { -/// println!("{:?}", rc); -/// }); -/// }); -/// ``` #[cfg(feature = "nightly")] -pub unsafe auto trait Ungil {} +macro_rules! define { + ($($tt:tt)*) => { $($tt)* } +} +#[cfg(not(feature = "nightly"))] +macro_rules! define { + ($($tt:tt)*) => {}; +} + +define! { + /// Types that are safe to access while the GIL is not held. + /// + /// # Safety + /// + /// The type must not carry borrowed Python references or, if it does, not allow access to them if + /// the GIL is not held. + /// + /// See the [module-level documentation](self) for more information. + /// + /// # Examples + /// + /// Types which are `Ungil` cannot be used in contexts where the GIL was released, e.g. + /// + /// ```compile_fail + /// # use pyo3::prelude::*; + /// # use pyo3::types::PyString; + /// Python::with_gil(|py| { + /// let string = PyString::new(py, "foo"); + /// + /// py.allow_threads(|| { + /// println!("{:?}", string); + /// }); + /// }); + /// ``` + /// + /// This applies to the GIL token `Python` itself as well, e.g. + /// + /// ```compile_fail + /// # use pyo3::prelude::*; + /// Python::with_gil(|py| { + /// py.allow_threads(|| { + /// drop(py); + /// }); + /// }); + /// ``` + /// + /// On nightly Rust, this is not based on the [`Send`] auto trait and hence we are able + /// to prevent incorrectly circumventing it using e.g. the [`send_wrapper`](https://docs.rs/send_wrapper/) crate: + /// + /// ```compile_fail + /// # use pyo3::prelude::*; + /// # use pyo3::types::PyString; + /// use send_wrapper::SendWrapper; + /// + /// Python::with_gil(|py| { + /// let string = PyString::new(py, "foo"); + /// + /// let wrapped = SendWrapper::new(string); + /// + /// py.allow_threads(|| { + /// let sneaky: &PyString = *wrapped; + /// + /// println!("{:?}", sneaky); + /// }); + /// }); + /// ``` + /// + /// This also enables using non-[`Send`] types in `allow_threads`, + /// at least if they are not also bound to the GIL: + /// + /// ```rust + /// # use pyo3::prelude::*; + /// use std::rc::Rc; + /// + /// Python::with_gil(|py| { + /// let rc = Rc::new(42); + /// + /// py.allow_threads(|| { + /// println!("{:?}", rc); + /// }); + /// }); + /// ``` + pub unsafe auto trait Ungil {} +} #[cfg(feature = "nightly")] mod negative_impls { From 0c8ab98760fda4d76133361a526c70e8aa644f32 Mon Sep 17 00:00:00 2001 From: mejrs <59372212+mejrs@users.noreply.github.com> Date: Fri, 29 Sep 2023 17:22:27 +0200 Subject: [PATCH 2/2] move it into the inline module. --- src/marker.rs | 168 ++++++++++++++++++++++++-------------------------- 1 file changed, 82 insertions(+), 86 deletions(-) diff --git a/src/marker.rs b/src/marker.rs index 7a4576c9..dfe876c8 100644 --- a/src/marker.rs +++ b/src/marker.rs @@ -186,93 +186,86 @@ pub unsafe trait Ungil {} unsafe impl Ungil for T {} #[cfg(feature = "nightly")] -macro_rules! define { - ($($tt:tt)*) => { $($tt)* } -} -#[cfg(not(feature = "nightly"))] -macro_rules! define { - ($($tt:tt)*) => {}; -} +mod nightly { + macro_rules! define { + ($($tt:tt)*) => { $($tt)* } + } -define! { - /// Types that are safe to access while the GIL is not held. - /// - /// # Safety - /// - /// The type must not carry borrowed Python references or, if it does, not allow access to them if - /// the GIL is not held. - /// - /// See the [module-level documentation](self) for more information. - /// - /// # Examples - /// - /// Types which are `Ungil` cannot be used in contexts where the GIL was released, e.g. - /// - /// ```compile_fail - /// # use pyo3::prelude::*; - /// # use pyo3::types::PyString; - /// Python::with_gil(|py| { - /// let string = PyString::new(py, "foo"); - /// - /// py.allow_threads(|| { - /// println!("{:?}", string); - /// }); - /// }); - /// ``` - /// - /// This applies to the GIL token `Python` itself as well, e.g. - /// - /// ```compile_fail - /// # use pyo3::prelude::*; - /// Python::with_gil(|py| { - /// py.allow_threads(|| { - /// drop(py); - /// }); - /// }); - /// ``` - /// - /// On nightly Rust, this is not based on the [`Send`] auto trait and hence we are able - /// to prevent incorrectly circumventing it using e.g. the [`send_wrapper`](https://docs.rs/send_wrapper/) crate: - /// - /// ```compile_fail - /// # use pyo3::prelude::*; - /// # use pyo3::types::PyString; - /// use send_wrapper::SendWrapper; - /// - /// Python::with_gil(|py| { - /// let string = PyString::new(py, "foo"); - /// - /// let wrapped = SendWrapper::new(string); - /// - /// py.allow_threads(|| { - /// let sneaky: &PyString = *wrapped; - /// - /// println!("{:?}", sneaky); - /// }); - /// }); - /// ``` - /// - /// This also enables using non-[`Send`] types in `allow_threads`, - /// at least if they are not also bound to the GIL: - /// - /// ```rust - /// # use pyo3::prelude::*; - /// use std::rc::Rc; - /// - /// Python::with_gil(|py| { - /// let rc = Rc::new(42); - /// - /// py.allow_threads(|| { - /// println!("{:?}", rc); - /// }); - /// }); - /// ``` - pub unsafe auto trait Ungil {} -} - -#[cfg(feature = "nightly")] -mod negative_impls { - use super::Ungil; + define! { + /// Types that are safe to access while the GIL is not held. + /// + /// # Safety + /// + /// The type must not carry borrowed Python references or, if it does, not allow access to them if + /// the GIL is not held. + /// + /// See the [module-level documentation](self) for more information. + /// + /// # Examples + /// + /// Types which are `Ungil` cannot be used in contexts where the GIL was released, e.g. + /// + /// ```compile_fail + /// # use pyo3::prelude::*; + /// # use pyo3::types::PyString; + /// Python::with_gil(|py| { + /// let string = PyString::new(py, "foo"); + /// + /// py.allow_threads(|| { + /// println!("{:?}", string); + /// }); + /// }); + /// ``` + /// + /// This applies to the GIL token `Python` itself as well, e.g. + /// + /// ```compile_fail + /// # use pyo3::prelude::*; + /// Python::with_gil(|py| { + /// py.allow_threads(|| { + /// drop(py); + /// }); + /// }); + /// ``` + /// + /// On nightly Rust, this is not based on the [`Send`] auto trait and hence we are able + /// to prevent incorrectly circumventing it using e.g. the [`send_wrapper`](https://docs.rs/send_wrapper/) crate: + /// + /// ```compile_fail + /// # use pyo3::prelude::*; + /// # use pyo3::types::PyString; + /// use send_wrapper::SendWrapper; + /// + /// Python::with_gil(|py| { + /// let string = PyString::new(py, "foo"); + /// + /// let wrapped = SendWrapper::new(string); + /// + /// py.allow_threads(|| { + /// let sneaky: &PyString = *wrapped; + /// + /// println!("{:?}", sneaky); + /// }); + /// }); + /// ``` + /// + /// This also enables using non-[`Send`] types in `allow_threads`, + /// at least if they are not also bound to the GIL: + /// + /// ```rust + /// # use pyo3::prelude::*; + /// use std::rc::Rc; + /// + /// Python::with_gil(|py| { + /// let rc = Rc::new(42); + /// + /// py.allow_threads(|| { + /// println!("{:?}", rc); + /// }); + /// }); + /// ``` + pub unsafe auto trait Ungil {} + } impl !Ungil for crate::Python<'_> {} @@ -299,6 +292,9 @@ mod negative_impls { impl !Ungil for crate::ffi::PyArena {} } +#[cfg(feature = "nightly")] +pub use nightly::Ungil; + /// A marker token that represents holding the GIL. /// /// It serves three main purposes: