From 70915126eef06588dbded844da205301df06f57b Mon Sep 17 00:00:00 2001 From: David Hewitt <1939362+davidhewitt@users.noreply.github.com> Date: Fri, 3 Dec 2021 23:29:02 +0000 Subject: [PATCH] rust: support 1.57 --- pyo3-macros-backend/src/params.rs | 1 + src/buffer.rs | 4 ++++ src/conversion.rs | 4 ++++ src/instance.rs | 4 ++++ src/type_object.rs | 11 +++++++++++ tests/test_compile_error.rs | 19 +++++++++++++++++-- tests/ui/static_ref.stderr | 2 +- tests/ui/wrong_aspyref_lifetimes.stderr | 4 ++-- 8 files changed, 44 insertions(+), 5 deletions(-) diff --git a/pyo3-macros-backend/src/params.rs b/pyo3-macros-backend/src/params.rs index 1bbbb4727d8..e781a1d3ec9 100644 --- a/pyo3-macros-backend/src/params.rs +++ b/pyo3-macros-backend/src/params.rs @@ -292,6 +292,7 @@ fn impl_arg_param( Ok(quote_arg_span! { let #mut_ _tmp: #target_ty = #arg_value_or_default; + #[allow(clippy::needless_option_as_deref)] let #arg_name = #borrow_tmp; }) } else { diff --git a/src/buffer.rs b/src/buffer.rs index f155bb11162..1f4f57fb4b8 100644 --- a/src/buffer.rs +++ b/src/buffer.rs @@ -163,6 +163,10 @@ fn is_matching_endian(c: u8) -> bool { } /// Trait implemented for possible element types of `PyBuffer`. +/// +/// # Safety +/// +/// This trait must only be implemented for types which represent valid elements of Python buffers. pub unsafe trait Element: Copy { /// Gets whether the element specified in the format string is potentially compatible. /// Alignment and size are checked separately from this function. diff --git a/src/conversion.rs b/src/conversion.rs index e1238edc80e..ccd690bee15 100644 --- a/src/conversion.rs +++ b/src/conversion.rs @@ -463,6 +463,10 @@ impl IntoPy> for () { } /// Raw level conversion between `*mut ffi::PyObject` and PyO3 types. +/// +/// # Safety +/// +/// See safety notes on individual functions. pub unsafe trait FromPyPointer<'p>: Sized { /// Convert from an arbitrary `PyObject`. /// diff --git a/src/instance.rs b/src/instance.rs index b8f7ab69b81..0037abb8158 100644 --- a/src/instance.rs +++ b/src/instance.rs @@ -17,6 +17,10 @@ use std::ptr::NonNull; /// PyO3 is designed in a way that all references to those types are bound /// to the GIL, which is why you can get a token from all references of those /// types. +/// +/// # Safety +/// +/// This trait must only be implemented for types which cannot be accessed without the GIL. pub unsafe trait PyNativeType: Sized { /// Returns a GIL marker constrained to the lifetime of this type. #[inline] diff --git a/src/type_object.rs b/src/type_object.rs index 0f16f566f99..bf60d18f037 100644 --- a/src/type_object.rs +++ b/src/type_object.rs @@ -16,6 +16,10 @@ use std::thread::{self, ThreadId}; /// is of `PyAny`. /// /// This trait is intended to be used internally. +/// +/// # Safety +/// +/// This trait must only be implemented for types which represent valid layouts of Python objects. pub unsafe trait PyLayout {} /// `T: PySizedLayout` represents that `T` is not a instance of @@ -31,6 +35,11 @@ pub trait PySizedLayout: PyLayout + Sized {} /// - the return value of type_object must always point to the same PyTypeObject instance /// /// It is safely implemented by the `pyclass` macro. +/// +/// # Safety +/// +/// Implementations must provide an implementation for `type_object_raw` which infallibly produces a +/// non-null pointer to the corresponding Python type object. pub unsafe trait PyTypeInfo: Sized { /// Class name. const NAME: &'static str; @@ -57,6 +66,8 @@ pub unsafe trait PyTypeInfo: Sized { /// Python object types that have a corresponding type object. /// +/// # Safety +/// /// This trait is marked unsafe because not fulfilling the contract for type_object /// leads to UB. /// diff --git a/tests/test_compile_error.rs b/tests/test_compile_error.rs index 9631b2a129b..61eb5dc897f 100644 --- a/tests/test_compile_error.rs +++ b/tests/test_compile_error.rs @@ -28,12 +28,12 @@ fn _test_compile_errors() { t.compile_fail("tests/ui/invalid_argument_attributes.rs"); t.compile_fail("tests/ui/missing_clone.rs"); t.compile_fail("tests/ui/reject_generics.rs"); - t.compile_fail("tests/ui/wrong_aspyref_lifetimes.rs"); tests_rust_1_49(&t); tests_rust_1_54(&t); tests_rust_1_55(&t); tests_rust_1_56(&t); + tests_rust_1_57(&t); #[rustversion::since(1.49)] fn tests_rust_1_49(t: &trybuild::TestCases) { @@ -45,7 +45,6 @@ fn _test_compile_errors() { #[rustversion::since(1.54)] fn tests_rust_1_54(t: &trybuild::TestCases) { t.compile_fail("tests/ui/invalid_frompy_derive.rs"); - t.compile_fail("tests/ui/static_ref.rs"); } #[rustversion::before(1.54)] fn tests_rust_1_54(_t: &trybuild::TestCases) {} @@ -70,4 +69,20 @@ fn _test_compile_errors() { #[rustversion::before(1.56)] fn tests_rust_1_56(_t: &trybuild::TestCases) {} + + #[rustversion::since(1.57)] + fn tests_rust_1_57(t: &trybuild::TestCases) { + t.compile_fail("tests/ui/invalid_closure.rs"); + t.compile_fail("tests/ui/invalid_result_conversion.rs"); + t.compile_fail("tests/ui/pyclass_send.rs"); + + #[cfg(Py_LIMITED_API)] + t.compile_fail("tests/ui/abi3_nativetype_inheritance.rs"); + } + + #[rustversion::before(1.57)] + fn tests_rust_1_56(_t: &trybuild::TestCases) { + t.compile_fail("tests/ui/static_ref.rs"); + t.compile_fail("tests/ui/wrong_aspyref_lifetimes.rs"); + } } diff --git a/tests/ui/static_ref.stderr b/tests/ui/static_ref.stderr index 58fc6a532ec..9165f63a03f 100644 --- a/tests/ui/static_ref.stderr +++ b/tests/ui/static_ref.stderr @@ -4,7 +4,7 @@ error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'py` 4 | #[pyfunction] | ^^^^^^^^^^^^^ | -note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the body at 4:1... +note: first, the lifetime cannot outlive the anonymous lifetime #1 defined here... --> tests/ui/static_ref.rs:4:1 | 4 | #[pyfunction] diff --git a/tests/ui/wrong_aspyref_lifetimes.stderr b/tests/ui/wrong_aspyref_lifetimes.stderr index 319f4ee5f3a..0042bc6b9fd 100644 --- a/tests/ui/wrong_aspyref_lifetimes.stderr +++ b/tests/ui/wrong_aspyref_lifetimes.stderr @@ -2,9 +2,9 @@ error[E0505]: cannot move out of `gil` because it is borrowed --> tests/ui/wrong_aspyref_lifetimes.rs:7:10 | 6 | let dict: &PyDict = dict.as_ref(gil.python()); - | --- borrow of `gil` occurs here + | ------------ borrow of `gil` occurs here 7 | drop(gil); | ^^^ move out of `gil` occurs here 8 | 9 | let _py: Python = dict.py(); // Obtain a Python<'p> without GIL. - | ---- borrow later used here + | --------- borrow later used here