From 7d5ff2d76801cddb5272fd2750b802efa63d586a Mon Sep 17 00:00:00 2001 From: Georg Brandl Date: Sat, 12 Dec 2020 09:40:40 +0100 Subject: [PATCH] ffi: use recommended stable way to represent an opaque C struct After `extern { type ... }` has stabilized for a while, this can be replaced. For now, I used a macro since it is much easier to spot the locations to touch at that time. fixes #1311 --- CHANGELOG.md | 1 + src/ffi/code.rs | 2 +- src/ffi/mod.rs | 12 +++++++++++- src/ffi/object.rs | 2 +- src/ffi/pyarena.rs | 2 +- src/ffi/pythonrun.rs | 6 +++--- src/ffi/weakrefobject.rs | 2 +- 7 files changed, 19 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 39236e43..3edb5df9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -46,6 +46,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - Fix `#[text_signature]` interacting badly with rust `r#raw_identifiers`. [#1286](https://github.com/PyO3/pyo3/pull/1286) - Fix FFI definitions for `PyObject_Vectorcall` and `PyVectorcall_Call`. [#1287](https://github.com/PyO3/pyo3/pull/1285) - Fix building with Anaconda python inside a virtualenv. [#1290](https://github.com/PyO3/pyo3/pull/1290) +- Fix definition of opaque FFI types. [#1312](https://github.com/PyO3/pyo3/pull/1312) ## [0.12.4] - 2020-11-28 ### Fixed diff --git a/src/ffi/code.rs b/src/ffi/code.rs index 25c656eb..f516a0bd 100644 --- a/src/ffi/code.rs +++ b/src/ffi/code.rs @@ -3,7 +3,7 @@ use crate::ffi::pyport::Py_ssize_t; use std::os::raw::{c_char, c_int, c_uchar, c_void}; #[cfg(Py_3_8)] -pub enum _PyOpcache {} +opaque_struct!(_PyOpcache); #[repr(C)] #[derive(Copy, Clone)] diff --git a/src/ffi/mod.rs b/src/ffi/mod.rs index 2edb2768..98ce4ea3 100644 --- a/src/ffi/mod.rs +++ b/src/ffi/mod.rs @@ -2,6 +2,16 @@ #![cfg_attr(Py_LIMITED_API, allow(unused_imports))] #![cfg_attr(feature = "cargo-clippy", allow(clippy::inline_always))] +// Until `extern type` is stabilized, use the recommended approach to +// model opaque types: +// https://doc.rust-lang.org/nomicon/ffi.html#representing-opaque-structs +macro_rules! opaque_struct { + ($name:ident) => { + #[repr(C)] + pub struct $name([u8; 0]); + }; +} + pub use self::bltinmodule::*; pub use self::boolobject::*; pub use self::bytearrayobject::*; @@ -165,7 +175,7 @@ pub mod structmember; // TODO supports PEP-384 only; needs adjustment for Python pub mod frameobject; #[cfg(Py_LIMITED_API)] pub mod frameobject { - pub enum PyFrameObject {} + opaque_struct!(PyFrameObject); } pub(crate) mod datetime; diff --git a/src/ffi/object.rs b/src/ffi/object.rs index 99fc3798..5cd0aef6 100644 --- a/src/ffi/object.rs +++ b/src/ffi/object.rs @@ -262,7 +262,7 @@ pub type vectorcallfunc = unsafe extern "C" fn( #[cfg(Py_LIMITED_API)] mod typeobject { - pub enum PyTypeObject {} + opaque_struct!(PyTypeObject); } #[cfg(not(Py_LIMITED_API))] diff --git a/src/ffi/pyarena.rs b/src/ffi/pyarena.rs index bfe42fdb..87d5f28a 100644 --- a/src/ffi/pyarena.rs +++ b/src/ffi/pyarena.rs @@ -1 +1 @@ -pub enum PyArena {} +opaque_struct!(PyArena); diff --git a/src/ffi/pythonrun.rs b/src/ffi/pythonrun.rs index 51697581..e403bd02 100644 --- a/src/ffi/pythonrun.rs +++ b/src/ffi/pythonrun.rs @@ -15,7 +15,7 @@ pub struct PyCompilerFlags { } #[cfg(not(Py_LIMITED_API))] -pub enum _mod {} +opaque_struct!(_mod); #[cfg(not(Py_LIMITED_API))] extern "C" { @@ -90,8 +90,8 @@ extern "C" { ) -> *mut _mod; } -pub enum symtable {} -pub enum _node {} +opaque_struct!(symtable); +opaque_struct!(_node); #[inline] pub unsafe fn PyParser_SimpleParseString(s: *const c_char, b: c_int) -> *mut _node { diff --git a/src/ffi/weakrefobject.rs b/src/ffi/weakrefobject.rs index b1013152..65ef3562 100644 --- a/src/ffi/weakrefobject.rs +++ b/src/ffi/weakrefobject.rs @@ -1,7 +1,7 @@ use crate::ffi::object::*; use std::os::raw::c_int; -pub enum PyWeakReference {} +opaque_struct!(PyWeakReference); extern "C" { static mut _PyWeakref_RefType: PyTypeObject;