Skip to content

Commit b9e9859

Browse files
authored
Merge pull request #3478 from mejrs/auto
Don't let auto trait syntax bleed through on stable Rust
2 parents 50cb41d + 0c8ab98 commit b9e9859

File tree

1 file changed

+82
-76
lines changed

1 file changed

+82
-76
lines changed

src/marker.rs

Lines changed: 82 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -185,84 +185,87 @@ pub unsafe trait Ungil {}
185185
#[cfg(not(feature = "nightly"))]
186186
unsafe impl<T: Send> Ungil for T {}
187187

188-
/// Types that are safe to access while the GIL is not held.
189-
///
190-
/// # Safety
191-
///
192-
/// The type must not carry borrowed Python references or, if it does, not allow access to them if
193-
/// the GIL is not held.
194-
///
195-
/// See the [module-level documentation](self) for more information.
196-
///
197-
/// # Examples
198-
///
199-
/// Types which are `Ungil` cannot be used in contexts where the GIL was released, e.g.
200-
///
201-
/// ```compile_fail
202-
/// # use pyo3::prelude::*;
203-
/// # use pyo3::types::PyString;
204-
/// Python::with_gil(|py| {
205-
/// let string = PyString::new(py, "foo");
206-
///
207-
/// py.allow_threads(|| {
208-
/// println!("{:?}", string);
209-
/// });
210-
/// });
211-
/// ```
212-
///
213-
/// This applies to the GIL token `Python` itself as well, e.g.
214-
///
215-
/// ```compile_fail
216-
/// # use pyo3::prelude::*;
217-
/// Python::with_gil(|py| {
218-
/// py.allow_threads(|| {
219-
/// drop(py);
220-
/// });
221-
/// });
222-
/// ```
223-
///
224-
/// On nightly Rust, this is not based on the [`Send`] auto trait and hence we are able
225-
/// to prevent incorrectly circumventing it using e.g. the [`send_wrapper`](https://docs.rs/send_wrapper/) crate:
226-
///
227-
/// ```compile_fail
228-
/// # use pyo3::prelude::*;
229-
/// # use pyo3::types::PyString;
230-
/// use send_wrapper::SendWrapper;
231-
///
232-
/// Python::with_gil(|py| {
233-
/// let string = PyString::new(py, "foo");
234-
///
235-
/// let wrapped = SendWrapper::new(string);
236-
///
237-
/// py.allow_threads(|| {
238-
/// let sneaky: &PyString = *wrapped;
239-
///
240-
/// println!("{:?}", sneaky);
241-
/// });
242-
/// });
243-
/// ```
244-
///
245-
/// This also enables using non-[`Send`] types in `allow_threads`,
246-
/// at least if they are not also bound to the GIL:
247-
///
248-
/// ```rust
249-
/// # use pyo3::prelude::*;
250-
/// use std::rc::Rc;
251-
///
252-
/// Python::with_gil(|py| {
253-
/// let rc = Rc::new(42);
254-
///
255-
/// py.allow_threads(|| {
256-
/// println!("{:?}", rc);
257-
/// });
258-
/// });
259-
/// ```
260188
#[cfg(feature = "nightly")]
261-
pub unsafe auto trait Ungil {}
189+
mod nightly {
190+
macro_rules! define {
191+
($($tt:tt)*) => { $($tt)* }
192+
}
262193

263-
#[cfg(feature = "nightly")]
264-
mod negative_impls {
265-
use super::Ungil;
194+
define! {
195+
/// Types that are safe to access while the GIL is not held.
196+
///
197+
/// # Safety
198+
///
199+
/// The type must not carry borrowed Python references or, if it does, not allow access to them if
200+
/// the GIL is not held.
201+
///
202+
/// See the [module-level documentation](self) for more information.
203+
///
204+
/// # Examples
205+
///
206+
/// Types which are `Ungil` cannot be used in contexts where the GIL was released, e.g.
207+
///
208+
/// ```compile_fail
209+
/// # use pyo3::prelude::*;
210+
/// # use pyo3::types::PyString;
211+
/// Python::with_gil(|py| {
212+
/// let string = PyString::new(py, "foo");
213+
///
214+
/// py.allow_threads(|| {
215+
/// println!("{:?}", string);
216+
/// });
217+
/// });
218+
/// ```
219+
///
220+
/// This applies to the GIL token `Python` itself as well, e.g.
221+
///
222+
/// ```compile_fail
223+
/// # use pyo3::prelude::*;
224+
/// Python::with_gil(|py| {
225+
/// py.allow_threads(|| {
226+
/// drop(py);
227+
/// });
228+
/// });
229+
/// ```
230+
///
231+
/// On nightly Rust, this is not based on the [`Send`] auto trait and hence we are able
232+
/// to prevent incorrectly circumventing it using e.g. the [`send_wrapper`](https://docs.rs/send_wrapper/) crate:
233+
///
234+
/// ```compile_fail
235+
/// # use pyo3::prelude::*;
236+
/// # use pyo3::types::PyString;
237+
/// use send_wrapper::SendWrapper;
238+
///
239+
/// Python::with_gil(|py| {
240+
/// let string = PyString::new(py, "foo");
241+
///
242+
/// let wrapped = SendWrapper::new(string);
243+
///
244+
/// py.allow_threads(|| {
245+
/// let sneaky: &PyString = *wrapped;
246+
///
247+
/// println!("{:?}", sneaky);
248+
/// });
249+
/// });
250+
/// ```
251+
///
252+
/// This also enables using non-[`Send`] types in `allow_threads`,
253+
/// at least if they are not also bound to the GIL:
254+
///
255+
/// ```rust
256+
/// # use pyo3::prelude::*;
257+
/// use std::rc::Rc;
258+
///
259+
/// Python::with_gil(|py| {
260+
/// let rc = Rc::new(42);
261+
///
262+
/// py.allow_threads(|| {
263+
/// println!("{:?}", rc);
264+
/// });
265+
/// });
266+
/// ```
267+
pub unsafe auto trait Ungil {}
268+
}
266269

267270
impl !Ungil for crate::Python<'_> {}
268271

@@ -289,6 +292,9 @@ mod negative_impls {
289292
impl !Ungil for crate::ffi::PyArena {}
290293
}
291294

295+
#[cfg(feature = "nightly")]
296+
pub use nightly::Ungil;
297+
292298
/// A marker token that represents holding the GIL.
293299
///
294300
/// It serves three main purposes:

0 commit comments

Comments
 (0)