From 270d33b9a5147272571ffc4c04d882d0e3391e43 Mon Sep 17 00:00:00 2001 From: David Hewitt Date: Fri, 6 Mar 2026 13:44:12 +0000 Subject: [PATCH 01/21] try out `ui-test` instead of `trybuild` --- Cargo.toml | 3 + tests/test_compile_error.rs | 260 +++++++---- tests/ui/abi3_dict.rs | 2 +- tests/ui/abi3_dict.stderr | 8 +- tests/ui/abi3_inheritance.rs | 2 + tests/ui/abi3_inheritance.stderr | 62 +-- tests/ui/abi3_nativetype_inheritance.rs | 2 + tests/ui/abi3_nativetype_inheritance.stderr | 62 +-- tests/ui/abi3_weakref.rs | 2 +- tests/ui/abi3_weakref.stderr | 8 +- tests/ui/ambiguous_associated_items.rs | 1 + tests/ui/ambiguous_associated_items.stderr | 16 + tests/ui/base/Cargo.toml | 10 + tests/ui/base/src/lib.rs | 2 + tests/ui/deprecated_pyfn.rs | 1 + tests/ui/deprecated_pyfn.stderr | 3 + tests/ui/duplicate_pymodule_submodule.rs | 2 + tests/ui/duplicate_pymodule_submodule.stderr | 10 +- tests/ui/empty.rs | 1 + tests/ui/forbid_unsafe.stderr | 80 ++++ tests/ui/get_set_all.rs | 4 + tests/ui/get_set_all.stderr | 15 +- tests/ui/immutable_type.rs | 13 +- tests/ui/immutable_type.stderr | 4 + tests/ui/invalid_annotation.rs | 1 + tests/ui/invalid_annotation.stderr | 3 + tests/ui/invalid_annotation_return.rs | 1 + tests/ui/invalid_annotation_return.stderr | 3 + tests/ui/invalid_argument_attributes.rs | 6 + tests/ui/invalid_argument_attributes.stderr | 24 +- tests/ui/invalid_async.rs | 5 +- tests/ui/invalid_async.stderr | 11 +- tests/ui/invalid_base_class.rs | 2 + tests/ui/invalid_base_class.stderr | 74 ++- tests/ui/invalid_cancel_handle.rs | 8 + tests/ui/invalid_cancel_handle.stderr | 126 ++--- tests/ui/invalid_closure.rs | 1 + tests/ui/invalid_closure.stderr | 12 +- tests/ui/invalid_frompy_derive.rs | 44 ++ tests/ui/invalid_frompy_derive.stderr | 212 +++++---- tests/ui/invalid_frozen_pyclass_borrow.rs | 7 + tests/ui/invalid_frozen_pyclass_borrow.stderr | 200 ++++---- tests/ui/invalid_intern_arg.rs | 2 + tests/ui/invalid_intern_arg.stderr | 24 +- tests/ui/invalid_intopy_derive.rs | 29 ++ tests/ui/invalid_intopy_derive.stderr | 141 +++--- tests/ui/invalid_intopy_with.rs | 2 + tests/ui/invalid_intopy_with.stderr | 12 +- tests/ui/invalid_property_args.rs | 9 + tests/ui/invalid_property_args.stderr | 80 ++-- tests/ui/invalid_proto_pymethods.rs | 7 + tests/ui/invalid_proto_pymethods.stderr | 45 +- tests/ui/invalid_pycallargs.rs | 17 +- tests/ui/invalid_pycallargs.stderr | 64 +-- tests/ui/invalid_pyclass_args.rs | 50 ++ tests/ui/invalid_pyclass_args.stderr | 438 ++++++++---------- tests/ui/invalid_pyclass_doc.rs | 1 + tests/ui/invalid_pyclass_doc.stderr | 3 + tests/ui/invalid_pyclass_enum.rs | 22 + tests/ui/invalid_pyclass_enum.stderr | 225 ++++----- tests/ui/invalid_pyclass_generic.rs | 6 + tests/ui/invalid_pyclass_generic.stderr | 151 +++--- tests/ui/invalid_pyclass_init.rs | 27 +- tests/ui/invalid_pyclass_init.stderr | 26 +- tests/ui/invalid_pyclass_item.rs | 1 + tests/ui/invalid_pyclass_item.stderr | 3 + tests/ui/invalid_pyfunction_argument.rs | 4 + tests/ui/invalid_pyfunction_argument.stderr | 220 ++++----- tests/ui/invalid_pyfunction_definition.rs | 1 + tests/ui/invalid_pyfunction_definition.stderr | 3 + tests/ui/invalid_pyfunction_signatures.rs | 11 + tests/ui/invalid_pyfunction_signatures.stderr | 47 +- tests/ui/invalid_pyfunction_warn.rs | 8 + tests/ui/invalid_pyfunction_warn.stderr | 31 +- tests/ui/invalid_pyfunctions.rs | 8 + tests/ui/invalid_pyfunctions.stderr | 32 +- tests/ui/invalid_pymethod_enum.rs | 4 + tests/ui/invalid_pymethod_enum.stderr | 116 ++--- tests/ui/invalid_pymethod_names.rs | 5 + tests/ui/invalid_pymethod_names.stderr | 19 +- tests/ui/invalid_pymethod_receiver.rs | 1 + tests/ui/invalid_pymethod_receiver.stderr | 4 + tests/ui/invalid_pymethods.rs | 33 ++ tests/ui/invalid_pymethods.stderr | 144 +++--- tests/ui/invalid_pymethods_buffer.rs | 2 + tests/ui/invalid_pymethods_buffer.stderr | 20 +- tests/ui/invalid_pymethods_duplicates.rs | 3 + tests/ui/invalid_pymethods_duplicates.stderr | 9 +- tests/ui/invalid_pymethods_warn.rs | 2 + tests/ui/invalid_pymethods_warn.stderr | 7 +- tests/ui/invalid_pymodule_args.rs | 5 + tests/ui/invalid_pymodule_args.stderr | 19 +- tests/ui/invalid_pymodule_glob.rs | 1 + tests/ui/invalid_pymodule_glob.stderr | 3 + tests/ui/invalid_pymodule_in_root.rs | 2 + tests/ui/invalid_pymodule_in_root.stderr | 4 + tests/ui/invalid_pymodule_trait.rs | 2 + tests/ui/invalid_pymodule_trait.stderr | 3 + .../ui/invalid_pymodule_two_pymodule_init.rs | 1 + .../invalid_pymodule_two_pymodule_init.stderr | 3 + tests/ui/invalid_result_conversion.rs | 1 + tests/ui/invalid_result_conversion.stderr | 6 +- tests/ui/missing_intopy.rs | 2 + tests/ui/missing_intopy.stderr | 63 +-- tests/ui/not_send.rs | 1 + tests/ui/not_send.stderr | 78 ++-- tests/ui/not_send2.rs | 1 + tests/ui/not_send2.stderr | 93 ++-- tests/ui/pyclass_generic_enum.rs | 2 + tests/ui/pyclass_generic_enum.stderr | 11 +- tests/ui/pyclass_probe.rs | 105 ++--- tests/ui/pyclass_send.rs | 4 + tests/ui/pyclass_send.stderr | 70 +-- tests/ui/pymodule_missing_docs.rs | 1 + tests/ui/reject_generics.rs | 2 + tests/ui/reject_generics.stderr | 11 +- tests/ui/static_ref.rs | 3 + tests/ui/static_ref.stderr | 27 +- tests/ui/traverse.rs | 5 + tests/ui/traverse.stderr | 19 +- tests/ui/wrong_aspyref_lifetimes.rs | 1 + tests/ui/wrong_aspyref_lifetimes.stderr | 3 + 122 files changed, 2322 insertions(+), 1662 deletions(-) create mode 100644 tests/ui/ambiguous_associated_items.stderr create mode 100644 tests/ui/base/Cargo.toml create mode 100644 tests/ui/base/src/lib.rs create mode 100644 tests/ui/forbid_unsafe.stderr diff --git a/Cargo.toml b/Cargo.toml index f67a157f32c..6c9ebecb054 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -80,6 +80,8 @@ tempfile = "3.12.0" static_assertions = "1.1.0" uuid = { version = "1.10.0", features = ["v4"] } parking_lot = { version = "0.12.3", features = ["arc_lock"] } +ui_test = "0.30.4" +ctrlc = "3.5.2" [build-dependencies] pyo3-build-config = { path = "pyo3-build-config", version = "=0.28.2", features = ["resolve-config"] } @@ -181,6 +183,7 @@ members = [ "pyo3-macros", "pyo3-macros-backend", "pyo3-introspection", + "tests/ui/base", "pytests", "examples", ] diff --git a/tests/test_compile_error.rs b/tests/test_compile_error.rs index 423f0dd5cea..de171070a07 100644 --- a/tests/test_compile_error.rs +++ b/tests/test_compile_error.rs @@ -3,96 +3,172 @@ #[cfg(not(target_arch = "wasm32"))] // Not possible to invoke compiler from wasm #[test] fn test_compile_errors() { - let t = trybuild::TestCases::new(); - - t.compile_fail("tests/ui/deprecated_pyfn.rs"); - #[cfg(not(feature = "experimental-inspect"))] - t.compile_fail("tests/ui/invalid_property_args.rs"); - t.compile_fail("tests/ui/invalid_proto_pymethods.rs"); - #[cfg(not(all(Py_LIMITED_API, not(Py_3_10))))] // to avoid PyFunctionArgument for &str - t.compile_fail("tests/ui/invalid_pyclass_args.rs"); - t.compile_fail("tests/ui/invalid_pyclass_doc.rs"); - t.compile_fail("tests/ui/invalid_pyclass_enum.rs"); - t.compile_fail("tests/ui/invalid_pyclass_init.rs"); - t.compile_fail("tests/ui/invalid_pyclass_item.rs"); - #[cfg(Py_3_9)] - t.compile_fail("tests/ui/invalid_pyclass_generic.rs"); - #[cfg(Py_3_9)] - t.compile_fail("tests/ui/pyclass_generic_enum.rs"); - #[cfg(not(feature = "experimental-inspect"))] - #[cfg(not(all(Py_LIMITED_API, not(Py_3_10))))] // to avoid PyFunctionArgument for &str - t.compile_fail("tests/ui/invalid_pyfunction_argument.rs"); - t.compile_fail("tests/ui/invalid_pyfunction_definition.rs"); - t.compile_fail("tests/ui/invalid_pyfunction_signatures.rs"); - #[cfg(any(not(Py_LIMITED_API), Py_3_11))] - t.compile_fail("tests/ui/invalid_pymethods_buffer.rs"); - // The output is not stable across abi3 / not abi3 and features - #[cfg(all(not(Py_LIMITED_API), feature = "full"))] - t.compile_fail("tests/ui/invalid_pymethods_duplicates.rs"); - t.compile_fail("tests/ui/invalid_pymethod_enum.rs"); - t.compile_fail("tests/ui/invalid_pymethod_names.rs"); - t.compile_fail("tests/ui/invalid_pymodule_args.rs"); - t.compile_fail("tests/ui/invalid_pycallargs.rs"); - t.compile_fail("tests/ui/reject_generics.rs"); - t.compile_fail("tests/ui/invalid_closure.rs"); - t.compile_fail("tests/ui/pyclass_send.rs"); - #[cfg(not(feature = "experimental-inspect"))] - t.compile_fail("tests/ui/invalid_annotation.rs"); - #[cfg(not(feature = "experimental-inspect"))] - t.compile_fail("tests/ui/invalid_annotation_return.rs"); - t.compile_fail("tests/ui/invalid_argument_attributes.rs"); - t.compile_fail("tests/ui/invalid_intopy_derive.rs"); - #[cfg(not(windows))] - t.compile_fail("tests/ui/invalid_intopy_with.rs"); - t.compile_fail("tests/ui/invalid_frompy_derive.rs"); - t.compile_fail("tests/ui/static_ref.rs"); - t.compile_fail("tests/ui/wrong_aspyref_lifetimes.rs"); - #[cfg(not(feature = "uuid"))] - t.compile_fail("tests/ui/invalid_pyfunctions.rs"); - t.compile_fail("tests/ui/invalid_pymethods.rs"); - // output changes with async feature - #[cfg(all(not(Py_3_12), Py_LIMITED_API, feature = "experimental-async"))] - t.compile_fail("tests/ui/abi3_nativetype_inheritance.rs"); - #[cfg(not(feature = "experimental-async"))] - t.compile_fail("tests/ui/invalid_async.rs"); - t.compile_fail("tests/ui/invalid_intern_arg.rs"); - t.compile_fail("tests/ui/invalid_frozen_pyclass_borrow.rs"); - #[cfg(not(any(feature = "hashbrown", feature = "indexmap")))] - t.compile_fail("tests/ui/invalid_pymethod_receiver.rs"); - #[cfg(not(feature = "experimental-inspect"))] - t.compile_fail("tests/ui/missing_intopy.rs"); - // adding extra error conversion impls changes the output - #[cfg(not(any(windows, feature = "eyre", feature = "anyhow", Py_LIMITED_API)))] - t.compile_fail("tests/ui/invalid_result_conversion.rs"); - t.compile_fail("tests/ui/not_send.rs"); - t.compile_fail("tests/ui/not_send2.rs"); - t.compile_fail("tests/ui/get_set_all.rs"); - t.compile_fail("tests/ui/traverse.rs"); - t.compile_fail("tests/ui/invalid_pymodule_in_root.rs"); - t.compile_fail("tests/ui/invalid_pymodule_glob.rs"); - t.compile_fail("tests/ui/invalid_pymodule_trait.rs"); - t.compile_fail("tests/ui/invalid_pymodule_two_pymodule_init.rs"); - #[cfg(all(feature = "experimental-async", not(feature = "experimental-inspect")))] - #[cfg(any(not(Py_LIMITED_API), Py_3_10))] // to avoid PyFunctionArgument for &str - t.compile_fail("tests/ui/invalid_cancel_handle.rs"); - t.pass("tests/ui/pymodule_missing_docs.rs"); - #[cfg(not(any(Py_LIMITED_API, feature = "experimental-inspect")))] - t.pass("tests/ui/forbid_unsafe.rs"); - #[cfg(all(Py_LIMITED_API, not(feature = "experimental-async")))] - // output changes with async feature - t.compile_fail("tests/ui/abi3_inheritance.rs"); - #[cfg(all(Py_LIMITED_API, not(Py_3_9)))] - t.compile_fail("tests/ui/abi3_weakref.rs"); - #[cfg(all(Py_LIMITED_API, not(Py_3_9)))] - t.compile_fail("tests/ui/abi3_dict.rs"); - #[cfg(not(feature = "experimental-inspect"))] - t.compile_fail("tests/ui/duplicate_pymodule_submodule.rs"); - #[cfg(all(not(Py_LIMITED_API), Py_3_11))] - t.compile_fail("tests/ui/invalid_base_class.rs"); - #[cfg(any(not(Py_3_10), all(not(Py_3_14), Py_LIMITED_API)))] - t.compile_fail("tests/ui/immutable_type.rs"); - t.pass("tests/ui/ambiguous_associated_items.rs"); - t.pass("tests/ui/pyclass_probe.rs"); - t.compile_fail("tests/ui/invalid_pyfunction_warn.rs"); - t.compile_fail("tests/ui/invalid_pymethods_warn.rs"); + // let t = trybuild::TestCases::new(); + + // t.compile_fail("tests/ui/deprecated_pyfn.rs"); + // #[cfg(not(feature = "experimental-inspect"))] + // t.compile_fail("tests/ui/invalid_property_args.rs"); + // t.compile_fail("tests/ui/invalid_proto_pymethods.rs"); + // #[cfg(not(all(Py_LIMITED_API, not(Py_3_10))))] // to avoid PyFunctionArgument for &str + // t.compile_fail("tests/ui/invalid_pyclass_args.rs"); + // t.compile_fail("tests/ui/invalid_pyclass_doc.rs"); + // t.compile_fail("tests/ui/invalid_pyclass_enum.rs"); + // t.compile_fail("tests/ui/invalid_pyclass_init.rs"); + // t.compile_fail("tests/ui/invalid_pyclass_item.rs"); + // #[cfg(Py_3_9)] + // t.compile_fail("tests/ui/invalid_pyclass_generic.rs"); + // #[cfg(Py_3_9)] + // t.compile_fail("tests/ui/pyclass_generic_enum.rs"); + // #[cfg(not(feature = "experimental-inspect"))] + // #[cfg(not(all(Py_LIMITED_API, not(Py_3_10))))] // to avoid PyFunctionArgument for &str + // t.compile_fail("tests/ui/invalid_pyfunction_argument.rs"); + // t.compile_fail("tests/ui/invalid_pyfunction_definition.rs"); + // t.compile_fail("tests/ui/invalid_pyfunction_signatures.rs"); + // #[cfg(any(not(Py_LIMITED_API), Py_3_11))] + // t.compile_fail("tests/ui/invalid_pymethods_buffer.rs"); + // // The output is not stable across abi3 / not abi3 and features + // #[cfg(all(not(Py_LIMITED_API), feature = "full"))] + // t.compile_fail("tests/ui/invalid_pymethods_duplicates.rs"); + // t.compile_fail("tests/ui/invalid_pymethod_enum.rs"); + // t.compile_fail("tests/ui/invalid_pymethod_names.rs"); + // t.compile_fail("tests/ui/invalid_pymodule_args.rs"); + // t.compile_fail("tests/ui/invalid_pycallargs.rs"); + // t.compile_fail("tests/ui/reject_generics.rs"); + // t.compile_fail("tests/ui/invalid_closure.rs"); + // t.compile_fail("tests/ui/pyclass_send.rs"); + // #[cfg(not(feature = "experimental-inspect"))] + // t.compile_fail("tests/ui/invalid_annotation.rs"); + // #[cfg(not(feature = "experimental-inspect"))] + // t.compile_fail("tests/ui/invalid_annotation_return.rs"); + // t.compile_fail("tests/ui/invalid_argument_attributes.rs"); + // t.compile_fail("tests/ui/invalid_intopy_derive.rs"); + // #[cfg(not(windows))] + // t.compile_fail("tests/ui/invalid_intopy_with.rs"); + // t.compile_fail("tests/ui/invalid_frompy_derive.rs"); + // t.compile_fail("tests/ui/static_ref.rs"); + // t.compile_fail("tests/ui/wrong_aspyref_lifetimes.rs"); + // #[cfg(not(feature = "uuid"))] + // t.compile_fail("tests/ui/invalid_pyfunctions.rs"); + // t.compile_fail("tests/ui/invalid_pymethods.rs"); + // // output changes with async feature + // #[cfg(all(not(Py_3_12), Py_LIMITED_API, feature = "experimental-async"))] + // t.compile_fail("tests/ui/abi3_nativetype_inheritance.rs"); + // #[cfg(not(feature = "experimental-async"))] + // t.compile_fail("tests/ui/invalid_async.rs"); + // t.compile_fail("tests/ui/invalid_intern_arg.rs"); + // t.compile_fail("tests/ui/invalid_frozen_pyclass_borrow.rs"); + // #[cfg(not(any(feature = "hashbrown", feature = "indexmap")))] + // t.compile_fail("tests/ui/invalid_pymethod_receiver.rs"); + // #[cfg(not(feature = "experimental-inspect"))] + // t.compile_fail("tests/ui/missing_intopy.rs"); + // // adding extra error conversion impls changes the output + // #[cfg(not(any(windows, feature = "eyre", feature = "anyhow", Py_LIMITED_API)))] + // t.compile_fail("tests/ui/invalid_result_conversion.rs"); + // t.compile_fail("tests/ui/not_send.rs"); + // t.compile_fail("tests/ui/not_send2.rs"); + // t.compile_fail("tests/ui/get_set_all.rs"); + // t.compile_fail("tests/ui/traverse.rs"); + // t.compile_fail("tests/ui/invalid_pymodule_in_root.rs"); + // t.compile_fail("tests/ui/invalid_pymodule_glob.rs"); + // t.compile_fail("tests/ui/invalid_pymodule_trait.rs"); + // t.compile_fail("tests/ui/invalid_pymodule_two_pymodule_init.rs"); + // #[cfg(all(feature = "experimental-async", not(feature = "experimental-inspect")))] + // #[cfg(any(not(Py_LIMITED_API), Py_3_10))] // to avoid PyFunctionArgument for &str + // t.compile_fail("tests/ui/invalid_cancel_handle.rs"); + // t.pass("tests/ui/pymodule_missing_docs.rs"); + // #[cfg(not(any(Py_LIMITED_API, feature = "experimental-inspect")))] + // t.pass("tests/ui/forbid_unsafe.rs"); + // #[cfg(all(Py_LIMITED_API, not(feature = "experimental-async")))] + // // output changes with async feature + // t.compile_fail("tests/ui/abi3_inheritance.rs"); + // #[cfg(all(Py_LIMITED_API, not(Py_3_9)))] + // t.compile_fail("tests/ui/abi3_weakref.rs"); + // #[cfg(all(Py_LIMITED_API, not(Py_3_9)))] + // t.compile_fail("tests/ui/abi3_dict.rs"); + // #[cfg(not(feature = "experimental-inspect"))] + // t.compile_fail("tests/ui/duplicate_pymodule_submodule.rs"); + // #[cfg(all(not(Py_LIMITED_API), Py_3_11))] + // t.compile_fail("tests/ui/invalid_base_class.rs"); + // #[cfg(any(not(Py_3_10), all(not(Py_3_14), Py_LIMITED_API)))] + // t.compile_fail("tests/ui/immutable_type.rs"); + // t.pass("tests/ui/ambiguous_associated_items.rs"); + // t.pass("tests/ui/pyclass_probe.rs"); + // t.compile_fail("tests/ui/invalid_pyfunction_warn.rs"); + // t.compile_fail("tests/ui/invalid_pymethods_warn.rs"); + + use std::path::PathBuf; + + use ui_test::{run_tests, Config}; + + let mut config = Config::rustc("tests/ui"); + + let deps_features = vec![ + #[cfg(feature = "macros")] + "pyo3/macros".to_string(), + #[cfg(feature = "abi3")] + "pyo3/abi3".to_string(), + #[cfg(feature = "abi3-py37")] + "pyo3/abi3-py37".to_string(), + #[cfg(feature = "abi3-py38")] + "pyo3/abi3-py38".to_string(), + #[cfg(feature = "abi3-py39")] + "pyo3/abi3-py39".to_string(), + #[cfg(feature = "abi3-py310")] + "pyo3/abi3-py310".to_string(), + #[cfg(feature = "abi3-py311")] + "pyo3/abi3-py311".to_string(), + #[cfg(feature = "abi3-py312")] + "pyo3/abi3-py312".to_string(), + #[cfg(feature = "abi3-py313")] + "pyo3/abi3-py313".to_string(), + #[cfg(feature = "abi3-py314")] + "pyo3/abi3-py314".to_string(), + ]; + + let mut deps_cargo = ui_test::CommandBuilder::cargo(); + deps_cargo.args.push("--features".into()); + deps_cargo.args.push(deps_features.join(",").into()); + + config.comment_defaults.base().set_custom( + "dependencies", + ui_test::dependencies::DependencyBuilder { + crate_manifest_path: PathBuf::from( + env!("CARGO_MANIFEST_DIR").to_owned() + "/tests/ui/base/Cargo.toml", + ), + program: deps_cargo, + ..Default::default() + }, + ); + + config + .comment_defaults + .base() + .compile_flags + .push("--diagnostic-width=140".into()); + + // not a test file, used to configure dependencies for the tests + config.skip_files.push("base/src/lib.rs".into()); + + // don't run abi3-only tests when not testing abi3 features + #[cfg(not(Py_LIMITED_API))] + config.skip_files.push("abi3".into()); + + #[cfg(Py_LIMITED_API)] + config.skip_files.push("forbid_unsafe.rs".into()); + + #[cfg(all(Py_LIMITED_API, not(Py_3_11)))] + config.skip_files.push("buffer".into()); + + #[cfg(any(Py_3_14, all(Py_3_10, not(Py_LIMITED_API))))] + config.skip_files.push("immutable_type.rs".into()); + + #[cfg(not(Py_3_9))] + config.skip_files.push("invalid_pyclass_generic.rs".into()); + + config.output_conflict_handling = ui_test::bless_output_files; + + let abort_check = config.abort_check.clone(); + ctrlc::set_handler(move || abort_check.abort()).unwrap(); + + run_tests(config).unwrap(); } diff --git a/tests/ui/abi3_dict.rs b/tests/ui/abi3_dict.rs index 764a4d415a7..ac2c2daf0e3 100644 --- a/tests/ui/abi3_dict.rs +++ b/tests/ui/abi3_dict.rs @@ -1,7 +1,7 @@ -//! With abi3, dict not supported until python 3.9 or greater use pyo3::prelude::*; #[pyclass(dict)] +//~^ ERROR: `dict` requires Python >= 3.9 when using the `abi3` feature struct TestClass {} fn main() {} diff --git a/tests/ui/abi3_dict.stderr b/tests/ui/abi3_dict.stderr index 0bf4a04ae77..794260dee78 100644 --- a/tests/ui/abi3_dict.stderr +++ b/tests/ui/abi3_dict.stderr @@ -1,7 +1,11 @@ error[E0080]: evaluation panicked: `dict` requires Python >= 3.9 when using the `abi3` feature - --> tests/ui/abi3_dict.rs:4:11 + --> tests/ui/abi3_dict.rs:3:11 | -4 | #[pyclass(dict)] +3 | #[pyclass(dict)] | ^^^^ evaluation of `_::ASSERT_DICT_SUPPORTED` failed here | = note: this error originates in the attribute macro `pyclass` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/abi3_inheritance.rs b/tests/ui/abi3_inheritance.rs index 60972e4cf7a..e91303c31f6 100644 --- a/tests/ui/abi3_inheritance.rs +++ b/tests/ui/abi3_inheritance.rs @@ -2,6 +2,8 @@ use pyo3::exceptions::PyException; use pyo3::prelude::*; #[pyclass(extends=PyException)] +//~^ error: `PyException` cannot be subclassed +//~| error: `PyException` cannot be subclassed #[derive(Clone)] struct MyException { code: u32, diff --git a/tests/ui/abi3_inheritance.stderr b/tests/ui/abi3_inheritance.stderr index f3b2e3a8fc2..cff56caa423 100644 --- a/tests/ui/abi3_inheritance.stderr +++ b/tests/ui/abi3_inheritance.stderr @@ -1,38 +1,38 @@ error[E0277]: pyclass `PyException` cannot be subclassed - --> tests/ui/abi3_inheritance.rs:4:1 - | -4 | #[pyclass(extends=PyException)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required for `#[pyclass(extends=PyException)]` - | - = help: the trait `PyClassBaseType` is not implemented for `PyException` - = note: `PyException` must have `#[pyclass(subclass)]` to be eligible for subclassing - = note: with the `abi3` feature enabled, PyO3 does not support subclassing native types + --> tests/ui/abi3_inheritance.rs:4:1 + | + 4 | #[pyclass(extends=PyException)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required for `#[pyclass(extends=PyException)]` + | + = help: the trait `PyClassBaseType` is not implemented for `PyException` + = note: `PyException` must have `#[pyclass(subclass)]` to be eligible for subclassing + = note: with the `abi3` feature enabled, PyO3 does not support subclassing native types help: the trait `PyClassBaseType` is implemented for `PyAny` - --> src/types/any.rs - | - | impl crate::impl_::pyclass::PyClassBaseType for PyAny { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: this error originates in the attribute macro `pyclass` (in Nightly builds, run with -Z macro-backtrace for more info) + --> src/types/any.rs:55:1 + | +55 | impl crate::impl_::pyclass::PyClassBaseType for PyAny { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: this error originates in the attribute macro `pyclass` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: pyclass `PyException` cannot be subclassed - --> tests/ui/abi3_inheritance.rs:4:19 - | -4 | #[pyclass(extends=PyException)] - | ^^^^^^^^^^^ required for `#[pyclass(extends=PyException)]` - | - = help: the trait `PyClassBaseType` is not implemented for `PyException` - = note: `PyException` must have `#[pyclass(subclass)]` to be eligible for subclassing - = note: with the `abi3` feature enabled, PyO3 does not support subclassing native types + --> tests/ui/abi3_inheritance.rs:4:19 + | + 4 | #[pyclass(extends=PyException)] + | ^^^^^^^^^^^ required for `#[pyclass(extends=PyException)]` + | + = help: the trait `PyClassBaseType` is not implemented for `PyException` + = note: `PyException` must have `#[pyclass(subclass)]` to be eligible for subclassing + = note: with the `abi3` feature enabled, PyO3 does not support subclassing native types help: the trait `PyClassBaseType` is implemented for `PyAny` - --> src/types/any.rs - | - | impl crate::impl_::pyclass::PyClassBaseType for PyAny { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + --> src/types/any.rs:55:1 + | + 55 | impl crate::impl_::pyclass::PyClassBaseType for PyAny { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: required by a bound in `PyClassImpl::BaseType` - --> src/impl_/pyclass.rs - | - | type BaseType: PyTypeInfo + PyClassBaseType; - | ^^^^^^^^^^^^^^^ required by this bound in `PyClassImpl::BaseType` + --> src/impl_/pyclass.rs:184:33 + | +184 | type BaseType: PyTypeInfo + PyClassBaseType; + | ^^^^^^^^^^^^^^^ required by this bound in `PyClassImpl::BaseType` warning: use of deprecated associated constant `pyo3::impl_::deprecated::HasAutomaticFromPyObject::::MSG`: The `FromPyObject` implementation for `#[pyclass]` types which implement `Clone` is changing to an opt-in option. Use `#[pyclass(from_py_object)]` to opt-in to the `FromPyObject` derive now, or `#[pyclass(skip_from_py_object)]` to skip the `FromPyObject` implementation. --> tests/ui/abi3_inheritance.rs:4:1 @@ -42,3 +42,7 @@ warning: use of deprecated associated constant `pyo3::impl_::deprecated::HasAuto | = note: `#[warn(deprecated)]` on by default = note: this warning originates in the attribute macro `pyclass` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 2 previous errors; 1 warning emitted + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/abi3_nativetype_inheritance.rs b/tests/ui/abi3_nativetype_inheritance.rs index 80faff1b739..41db05ffef3 100644 --- a/tests/ui/abi3_nativetype_inheritance.rs +++ b/tests/ui/abi3_nativetype_inheritance.rs @@ -3,6 +3,8 @@ use pyo3::prelude::*; use pyo3::types::PyDict; #[pyclass(extends=PyDict)] +//~^ error: `PyDict` cannot be subclassed +//~| error: `PyDict` cannot be subclassed struct TestClass {} fn main() {} diff --git a/tests/ui/abi3_nativetype_inheritance.stderr b/tests/ui/abi3_nativetype_inheritance.stderr index 3e9e4544467..977375e47c4 100644 --- a/tests/ui/abi3_nativetype_inheritance.stderr +++ b/tests/ui/abi3_nativetype_inheritance.stderr @@ -1,35 +1,39 @@ error[E0277]: pyclass `PyDict` cannot be subclassed - --> tests/ui/abi3_nativetype_inheritance.rs:5:1 - | -5 | #[pyclass(extends=PyDict)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ required for `#[pyclass(extends=PyDict)]` - | - = help: the trait `PyClassBaseType` is not implemented for `PyDict` - = note: `PyDict` must have `#[pyclass(subclass)]` to be eligible for subclassing - = note: with the `abi3` feature enabled, PyO3 does not support subclassing native types + --> tests/ui/abi3_nativetype_inheritance.rs:5:1 + | + 5 | #[pyclass(extends=PyDict)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ required for `#[pyclass(extends=PyDict)]` + | + = help: the trait `PyClassBaseType` is not implemented for `PyDict` + = note: `PyDict` must have `#[pyclass(subclass)]` to be eligible for subclassing + = note: with the `abi3` feature enabled, PyO3 does not support subclassing native types help: the trait `PyClassBaseType` is implemented for `PyAny` - --> src/types/any.rs - | - | impl crate::impl_::pyclass::PyClassBaseType for PyAny { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: this error originates in the attribute macro `pyclass` (in Nightly builds, run with -Z macro-backtrace for more info) + --> src/types/any.rs:55:1 + | +55 | impl crate::impl_::pyclass::PyClassBaseType for PyAny { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: this error originates in the attribute macro `pyclass` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: pyclass `PyDict` cannot be subclassed - --> tests/ui/abi3_nativetype_inheritance.rs:5:19 - | -5 | #[pyclass(extends=PyDict)] - | ^^^^^^ required for `#[pyclass(extends=PyDict)]` - | - = help: the trait `PyClassBaseType` is not implemented for `PyDict` - = note: `PyDict` must have `#[pyclass(subclass)]` to be eligible for subclassing - = note: with the `abi3` feature enabled, PyO3 does not support subclassing native types + --> tests/ui/abi3_nativetype_inheritance.rs:5:19 + | + 5 | #[pyclass(extends=PyDict)] + | ^^^^^^ required for `#[pyclass(extends=PyDict)]` + | + = help: the trait `PyClassBaseType` is not implemented for `PyDict` + = note: `PyDict` must have `#[pyclass(subclass)]` to be eligible for subclassing + = note: with the `abi3` feature enabled, PyO3 does not support subclassing native types help: the trait `PyClassBaseType` is implemented for `PyAny` - --> src/types/any.rs - | - | impl crate::impl_::pyclass::PyClassBaseType for PyAny { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + --> src/types/any.rs:55:1 + | + 55 | impl crate::impl_::pyclass::PyClassBaseType for PyAny { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: required by a bound in `PyClassImpl::BaseType` - --> src/impl_/pyclass.rs - | - | type BaseType: PyTypeInfo + PyClassBaseType; - | ^^^^^^^^^^^^^^^ required by this bound in `PyClassImpl::BaseType` + --> src/impl_/pyclass.rs:184:33 + | +184 | type BaseType: PyTypeInfo + PyClassBaseType; + | ^^^^^^^^^^^^^^^ required by this bound in `PyClassImpl::BaseType` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/abi3_weakref.rs b/tests/ui/abi3_weakref.rs index f45b2258c96..0e0d8c736ce 100644 --- a/tests/ui/abi3_weakref.rs +++ b/tests/ui/abi3_weakref.rs @@ -1,7 +1,7 @@ -//! With abi3, weakref not supported until python 3.9 or greater use pyo3::prelude::*; #[pyclass(weakref)] +//~^ ERROR: `weakref` requires Python >= 3.9 when using the `abi3` feature struct TestClass {} fn main() {} diff --git a/tests/ui/abi3_weakref.stderr b/tests/ui/abi3_weakref.stderr index ff2e2222105..71e3ecd8ac5 100644 --- a/tests/ui/abi3_weakref.stderr +++ b/tests/ui/abi3_weakref.stderr @@ -1,7 +1,11 @@ error[E0080]: evaluation panicked: `weakref` requires Python >= 3.9 when using the `abi3` feature - --> tests/ui/abi3_weakref.rs:4:11 + --> tests/ui/abi3_weakref.rs:3:11 | -4 | #[pyclass(weakref)] +3 | #[pyclass(weakref)] | ^^^^^^^ evaluation of `_::ASSERT_WEAKREF_SUPPORTED` failed here | = note: this error originates in the attribute macro `pyclass` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/ambiguous_associated_items.rs b/tests/ui/ambiguous_associated_items.rs index e0e5075124a..3c9f4b0039f 100644 --- a/tests/ui/ambiguous_associated_items.rs +++ b/tests/ui/ambiguous_associated_items.rs @@ -1,3 +1,4 @@ +//@check-pass use pyo3::prelude::*; #[pyclass(eq)] diff --git a/tests/ui/ambiguous_associated_items.stderr b/tests/ui/ambiguous_associated_items.stderr new file mode 100644 index 00000000000..20008d42b9b --- /dev/null +++ b/tests/ui/ambiguous_associated_items.stderr @@ -0,0 +1,16 @@ +warning: enum `DeriveItems` is never used + --> tests/ui/ambiguous_associated_items.rs:20:6 + | +20 | enum DeriveItems { + | ^^^^^^^^^^^ + | + = note: `#[warn(dead_code)]` (part of `#[warn(unused)]`) on by default + +warning: enum `DeriveItemsFromPyObject` is never used + --> tests/ui/ambiguous_associated_items.rs:43:6 + | +43 | enum DeriveItemsFromPyObject { + | ^^^^^^^^^^^^^^^^^^^^^^^ + +warning: 2 warnings emitted + diff --git a/tests/ui/base/Cargo.toml b/tests/ui/base/Cargo.toml new file mode 100644 index 00000000000..5eb03c07487 --- /dev/null +++ b/tests/ui/base/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "pyo3_ui_tests" +version = "0.1.0" +edition = "2021" + +[dependencies] +pyo3 = { version = "0.28.2", default-features = false, path = "../../../" } + +[features] +macros = ["pyo3/macros"] diff --git a/tests/ui/base/src/lib.rs b/tests/ui/base/src/lib.rs new file mode 100644 index 00000000000..606adc062a2 --- /dev/null +++ b/tests/ui/base/src/lib.rs @@ -0,0 +1,2 @@ +// Causes `ui-test` to build pyo3 as a dependency of the ui tests +extern crate pyo3; diff --git a/tests/ui/deprecated_pyfn.rs b/tests/ui/deprecated_pyfn.rs index 1c5edbafd31..fa0446c159f 100644 --- a/tests/ui/deprecated_pyfn.rs +++ b/tests/ui/deprecated_pyfn.rs @@ -5,6 +5,7 @@ use pyo3::prelude::*; #[pymodule] fn module_with_pyfn(m: &Bound<'_, PyModule>) -> PyResult<()> { #[pyfn(m)] +//~^ ERROR: use of deprecated constant `module_with_pyfn::PYFN_ATTRIBUTE`: `pyfn` will be removed in a future PyO3 version, use declarative `#[pymodule]` with `mod` instead fn foo() {} Ok(()) diff --git a/tests/ui/deprecated_pyfn.stderr b/tests/ui/deprecated_pyfn.stderr index c5dd0b3b4ac..16bf82f6451 100644 --- a/tests/ui/deprecated_pyfn.stderr +++ b/tests/ui/deprecated_pyfn.stderr @@ -9,3 +9,6 @@ note: the lint level is defined here | 1 | #![deny(deprecated)] | ^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/duplicate_pymodule_submodule.rs b/tests/ui/duplicate_pymodule_submodule.rs index 774d3819645..eb910722f0f 100644 --- a/tests/ui/duplicate_pymodule_submodule.rs +++ b/tests/ui/duplicate_pymodule_submodule.rs @@ -1,7 +1,9 @@ #[pyo3::pymodule] +//~^ ERROR: cannot find value `_PYO3_DEF` in module `submod` mod mymodule { #[pyo3::pymodule(submodule)] mod submod {} +//~^ ERROR: `submodule` may only be specified once (it is implicitly always specified for nested modules) } fn main() {} diff --git a/tests/ui/duplicate_pymodule_submodule.stderr b/tests/ui/duplicate_pymodule_submodule.stderr index a2141b0dcd3..ba4a6cf92b8 100644 --- a/tests/ui/duplicate_pymodule_submodule.stderr +++ b/tests/ui/duplicate_pymodule_submodule.stderr @@ -1,7 +1,7 @@ error: `submodule` may only be specified once (it is implicitly always specified for nested modules) - --> tests/ui/duplicate_pymodule_submodule.rs:4:2 + --> tests/ui/duplicate_pymodule_submodule.rs:5:2 | -4 | mod submod {} +5 | mod submod {} | ^^^ error[E0425]: cannot find value `_PYO3_DEF` in module `submod` @@ -13,5 +13,9 @@ error[E0425]: cannot find value `_PYO3_DEF` in module `submod` = note: this error originates in the attribute macro `pyo3::pymodule` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider importing this static | -3 + use crate::mymodule::_PYO3_DEF; +4 + use crate::mymodule::_PYO3_DEF; | + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0425`. diff --git a/tests/ui/empty.rs b/tests/ui/empty.rs index be89c636426..4fc5b5a031a 100644 --- a/tests/ui/empty.rs +++ b/tests/ui/empty.rs @@ -1 +1,2 @@ +//@check-pass // see invalid_pymodule_in_root.rs diff --git a/tests/ui/forbid_unsafe.stderr b/tests/ui/forbid_unsafe.stderr new file mode 100644 index 00000000000..b51b989da09 --- /dev/null +++ b/tests/ui/forbid_unsafe.stderr @@ -0,0 +1,80 @@ +error[E0277]: pyclass `PyWarning` cannot be subclassed + --> tests/ui/../../src/tests/hygiene/pymethods.rs:462:1 + | +462 | #[crate::pyclass(crate = "crate", extends=crate::exceptions::PyWarning)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required for `#[pyclass(extends=PyWarning)]` + | + = help: the trait `PyClassBaseType` is not implemented for `PyWarning` + = note: `PyWarning` must have `#[pyclass(subclass)]` to be eligible for subclassing + = note: with the `abi3` feature enabled, PyO3 does not support subclassing native types + = help: the following other types implement trait `PyClassBaseType`: + Bar + ComplexEnumEqOrd + ComplexEnumManyVariantFields + TupleEnumEqOrd + pyo3::PyAny + = note: this error originates in the attribute macro `crate::pyclass` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0277]: pyclass `PyWarning` cannot be subclassed + --> tests/ui/../../src/tests/hygiene/pymethods.rs:462:43 + | +462 | #[crate::pyclass(crate = "crate", extends=crate::exceptions::PyWarning)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required for `#[pyclass(extends=PyWarning)]` + | + = help: the trait `PyClassBaseType` is not implemented for `PyWarning` + = note: `PyWarning` must have `#[pyclass(subclass)]` to be eligible for subclassing + = note: with the `abi3` feature enabled, PyO3 does not support subclassing native types + = help: the following other types implement trait `PyClassBaseType`: + Bar + ComplexEnumEqOrd + ComplexEnumManyVariantFields + TupleEnumEqOrd + pyo3::PyAny +note: required by a bound in `PyClassImpl::BaseType` + --> src/impl_/pyclass.rs:184:33 + | +184 | type BaseType: PyTypeInfo + PyClassBaseType; + | ^^^^^^^^^^^^^^^ required by this bound in `PyClassImpl::BaseType` + +error[E0080]: evaluation panicked: `dict` requires Python >= 3.9 when using the `abi3` feature + --> tests/ui/../../src/tests/hygiene/pyclass.rs:18:5 + | +18 | dict + | ^^^^ evaluation of `hygiene::pyclass::_::ASSERT_DICT_SUPPORTED` failed here + +error[E0080]: evaluation panicked: `weakref` requires Python >= 3.9 when using the `abi3` feature + --> tests/ui/../../src/tests/hygiene/pyclass.rs:17:5 + | +17 | weakref, + | ^^^^^^^ evaluation of `hygiene::pyclass::_::ASSERT_WEAKREF_SUPPORTED` failed here + +error[E0277]: pyclass `PyWarning` cannot be subclassed + --> tests/ui/../../src/tests/hygiene/pymethods.rs:466:1 + | +466 | #[crate::pymethods(crate = "crate")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required for `#[pyclass(extends=PyWarning)]` + | + = help: the trait `PyClassBaseType` is not implemented for `PyWarning` + = note: `PyWarning` must have `#[pyclass(subclass)]` to be eligible for subclassing + = note: with the `abi3` feature enabled, PyO3 does not support subclassing native types + = help: the following other types implement trait `PyClassBaseType`: + Bar + ComplexEnumEqOrd + ComplexEnumManyVariantFields + TupleEnumEqOrd + pyo3::PyAny + = note: required for `UserDefinedWarning` to implement `PyClassInit<'_, true, false>` +note: required by a bound in `tp_new_impl` + --> src/impl_/pymethods.rs:825:8 + | +819 | pub unsafe fn tp_new_impl<'py, T, const IS_PYCLASS: bool, const IS_INITIALIZER_TUPLE: bool>( + | ----------- required by a bound in this function +... +825 | T: super::pyclass_init::PyClassInit<'py, IS_PYCLASS, IS_INITIALIZER_TUPLE>, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `tp_new_impl` + = note: this error originates in the attribute macro `crate::pymethods` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 5 previous errors + +Some errors have detailed explanations: E0080, E0277. +For more information about an error, try `rustc --explain E0080`. diff --git a/tests/ui/get_set_all.rs b/tests/ui/get_set_all.rs index 20a5eca07bf..64723857d58 100644 --- a/tests/ui/get_set_all.rs +++ b/tests/ui/get_set_all.rs @@ -1,20 +1,24 @@ use pyo3::prelude::*; #[pyclass(set_all)] +//~^ ERROR: `set_all` on an unit struct does nothing, because unit structs have no fields struct Foo; #[pyclass(set_all)] struct Foo2{ #[pyo3(set)] +//~^ ERROR: useless `set` - the struct is already annotated with `set_all` field: u8, } #[pyclass(get_all)] +//~^ ERROR: `get_all` on an unit struct does nothing, because unit structs have no fields struct Foo3; #[pyclass(get_all)] struct Foo4{ #[pyo3(get)] +//~^ ERROR: useless `get` - the struct is already annotated with `get_all` field: u8, } diff --git a/tests/ui/get_set_all.stderr b/tests/ui/get_set_all.stderr index 607d5f96597..33b47e1c7cb 100644 --- a/tests/ui/get_set_all.stderr +++ b/tests/ui/get_set_all.stderr @@ -5,19 +5,22 @@ error: `set_all` on an unit struct does nothing, because unit structs have no fi | ^^^^^^^ error: useless `set` - the struct is already annotated with `set_all` - --> tests/ui/get_set_all.rs:8:12 + --> tests/ui/get_set_all.rs:9:12 | -8 | #[pyo3(set)] +9 | #[pyo3(set)] | ^^^ error: `get_all` on an unit struct does nothing, because unit structs have no fields - --> tests/ui/get_set_all.rs:12:11 + --> tests/ui/get_set_all.rs:14:11 | -12 | #[pyclass(get_all)] +14 | #[pyclass(get_all)] | ^^^^^^^ error: useless `get` - the struct is already annotated with `get_all` - --> tests/ui/get_set_all.rs:17:12 + --> tests/ui/get_set_all.rs:20:12 | -17 | #[pyo3(get)] +20 | #[pyo3(get)] | ^^^ + +error: aborting due to 4 previous errors + diff --git a/tests/ui/immutable_type.rs b/tests/ui/immutable_type.rs index a311eb5b249..b8c5abc4f1c 100644 --- a/tests/ui/immutable_type.rs +++ b/tests/ui/immutable_type.rs @@ -1,6 +1,7 @@ -use pyo3::prelude::*; - -#[pyclass(immutable_type)] -struct ImmutableType {} - -fn main() {} +use pyo3::prelude::*; + +#[pyclass(immutable_type)] +//~^ ERROR: `immutable_type` requires Python >= 3.10 (or >= 3.14 when using the `abi3` feature) +struct ImmutableType {} + +fn main() {} diff --git a/tests/ui/immutable_type.stderr b/tests/ui/immutable_type.stderr index 04f09cbcdaf..6eba994c031 100644 --- a/tests/ui/immutable_type.stderr +++ b/tests/ui/immutable_type.stderr @@ -5,3 +5,7 @@ error[E0080]: evaluation panicked: `immutable_type` requires Python >= 3.10 (or | ^^^^^^^^^^^^^^ evaluation of `_::ASSERT_IMMUTABLE_SUPPORTED` failed here | = note: this error originates in the attribute macro `pyclass` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/invalid_annotation.rs b/tests/ui/invalid_annotation.rs index d8b803550ca..58b4c3b6520 100644 --- a/tests/ui/invalid_annotation.rs +++ b/tests/ui/invalid_annotation.rs @@ -2,6 +2,7 @@ use pyo3::prelude::*; #[pyfunction] #[pyo3(signature = (a: "int"))] +//~^ ERROR: Type annotations in the signature is only supported with the `experimental-inspect` feature fn check(a: usize) -> usize { a } diff --git a/tests/ui/invalid_annotation.stderr b/tests/ui/invalid_annotation.stderr index ff2981b4818..4f62a7554bb 100644 --- a/tests/ui/invalid_annotation.stderr +++ b/tests/ui/invalid_annotation.stderr @@ -3,3 +3,6 @@ error: Type annotations in the signature is only supported with the `experimenta | 4 | #[pyo3(signature = (a: "int"))] | ^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/invalid_annotation_return.rs b/tests/ui/invalid_annotation_return.rs index 5cb4298ec8b..c335ca31a0f 100644 --- a/tests/ui/invalid_annotation_return.rs +++ b/tests/ui/invalid_annotation_return.rs @@ -2,6 +2,7 @@ use pyo3::prelude::*; #[pyfunction] #[pyo3(signature = (a) -> "int")] +//~^ ERROR: Return type annotation in the signature is only supported with the `experimental-inspect` feature fn check(a: usize) -> usize { a } diff --git a/tests/ui/invalid_annotation_return.stderr b/tests/ui/invalid_annotation_return.stderr index 2a70079f82d..37ae25d81f6 100644 --- a/tests/ui/invalid_annotation_return.stderr +++ b/tests/ui/invalid_annotation_return.stderr @@ -3,3 +3,6 @@ error: Return type annotation in the signature is only supported with the `exper | 4 | #[pyo3(signature = (a) -> "int")] | ^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/invalid_argument_attributes.rs b/tests/ui/invalid_argument_attributes.rs index e4066e5fd9c..e70f9d16199 100644 --- a/tests/ui/invalid_argument_attributes.rs +++ b/tests/ui/invalid_argument_attributes.rs @@ -2,18 +2,23 @@ use pyo3::prelude::*; #[pyfunction] fn invalid_attribute(#[pyo3(get)] _param: String) {} +//~^ ERROR: expected `cancel_handle` or `from_py_with` #[pyfunction] fn from_py_with_no_value(#[pyo3(from_py_with)] _param: String) {} +//~^ ERROR: expected `=` #[pyfunction] fn from_py_with_string(#[pyo3("from_py_with")] _param: String) {} +//~^ ERROR: expected `cancel_handle` or `from_py_with` #[pyfunction] fn from_py_with_value_not_found(#[pyo3(from_py_with = func)] _param: String) {} +//~^ ERROR: cannot find value `func` in this scope #[pyfunction] fn from_py_with_repeated(#[pyo3(from_py_with = func, from_py_with = func)] _param: String) {} +//~^ ERROR: `from_py_with` may only be specified once per argument fn bytes_from_py(bytes: &Bound<'_, pyo3::types::PyBytes>) -> Vec { bytes.as_bytes().to_vec() @@ -21,5 +26,6 @@ fn bytes_from_py(bytes: &Bound<'_, pyo3::types::PyBytes>) -> Vec { #[pyfunction] fn f(#[pyo3(from_py_with = "bytes_from_py")] _bytes: Vec) {} +//~^ ERROR: expected identifier fn main() {} diff --git a/tests/ui/invalid_argument_attributes.stderr b/tests/ui/invalid_argument_attributes.stderr index d59558c16b9..6ecccd5b471 100644 --- a/tests/ui/invalid_argument_attributes.stderr +++ b/tests/ui/invalid_argument_attributes.stderr @@ -5,31 +5,35 @@ error: expected `cancel_handle` or `from_py_with` | ^^^ error: expected `=` - --> tests/ui/invalid_argument_attributes.rs:7:45 + --> tests/ui/invalid_argument_attributes.rs:8:45 | -7 | fn from_py_with_no_value(#[pyo3(from_py_with)] _param: String) {} +8 | fn from_py_with_no_value(#[pyo3(from_py_with)] _param: String) {} | ^ error: expected `cancel_handle` or `from_py_with` - --> tests/ui/invalid_argument_attributes.rs:10:31 + --> tests/ui/invalid_argument_attributes.rs:12:31 | -10 | fn from_py_with_string(#[pyo3("from_py_with")] _param: String) {} +12 | fn from_py_with_string(#[pyo3("from_py_with")] _param: String) {} | ^^^^^^^^^^^^^^ error: `from_py_with` may only be specified once per argument - --> tests/ui/invalid_argument_attributes.rs:16:54 + --> tests/ui/invalid_argument_attributes.rs:20:54 | -16 | fn from_py_with_repeated(#[pyo3(from_py_with = func, from_py_with = func)] _param: String) {} +20 | fn from_py_with_repeated(#[pyo3(from_py_with = func, from_py_with = func)] _param: String) {} | ^^^^^^^^^^^^ error: expected identifier - --> tests/ui/invalid_argument_attributes.rs:23:28 + --> tests/ui/invalid_argument_attributes.rs:28:28 | -23 | fn f(#[pyo3(from_py_with = "bytes_from_py")] _bytes: Vec) {} +28 | fn f(#[pyo3(from_py_with = "bytes_from_py")] _bytes: Vec) {} | ^^^^^^^^^^^^^^^ error[E0425]: cannot find value `func` in this scope - --> tests/ui/invalid_argument_attributes.rs:13:55 + --> tests/ui/invalid_argument_attributes.rs:16:55 | -13 | fn from_py_with_value_not_found(#[pyo3(from_py_with = func)] _param: String) {} +16 | fn from_py_with_value_not_found(#[pyo3(from_py_with = func)] _param: String) {} | ^^^^ not found in this scope + +error: aborting due to 6 previous errors + +For more information about this error, try `rustc --explain E0425`. diff --git a/tests/ui/invalid_async.rs b/tests/ui/invalid_async.rs index 2c7375fd2f9..915f30e35f1 100644 --- a/tests/ui/invalid_async.rs +++ b/tests/ui/invalid_async.rs @@ -2,6 +2,7 @@ use pyo3::prelude::*; #[pyfunction] async fn check(){} +//~^ ERROR: async functions are only supported with the `experimental-async` feature #[pyclass] pub(crate) struct AsyncRange { @@ -11,10 +12,12 @@ pub(crate) struct AsyncRange { #[pymethods] impl AsyncRange { async fn __anext__(mut _pyself: PyRefMut<'_, Self>) -> PyResult { +//~^ ERROR: async functions are only supported with the `experimental-async` feature Ok(0) } async fn foo(&self) {} +//~^ ERROR: async functions are only supported with the `experimental-async` feature } -fn main() {} \ No newline at end of file +fn main() {} diff --git a/tests/ui/invalid_async.stderr b/tests/ui/invalid_async.stderr index 0bf9f53f8c3..533684075a9 100644 --- a/tests/ui/invalid_async.stderr +++ b/tests/ui/invalid_async.stderr @@ -5,13 +5,16 @@ error: async functions are only supported with the `experimental-async` feature | ^^^^^ error: async functions are only supported with the `experimental-async` feature - --> tests/ui/invalid_async.rs:13:5 + --> tests/ui/invalid_async.rs:14:5 | -13 | async fn __anext__(mut _pyself: PyRefMut<'_, Self>) -> PyResult { +14 | async fn __anext__(mut _pyself: PyRefMut<'_, Self>) -> PyResult { | ^^^^^ error: async functions are only supported with the `experimental-async` feature - --> tests/ui/invalid_async.rs:17:5 + --> tests/ui/invalid_async.rs:19:5 | -17 | async fn foo(&self) {} +19 | async fn foo(&self) {} | ^^^^^ + +error: aborting due to 3 previous errors + diff --git a/tests/ui/invalid_base_class.rs b/tests/ui/invalid_base_class.rs index 7433dcb2b96..560e7639706 100644 --- a/tests/ui/invalid_base_class.rs +++ b/tests/ui/invalid_base_class.rs @@ -2,6 +2,8 @@ use pyo3::prelude::*; use pyo3::types::PyBool; #[pyclass(extends=PyBool)] +//~^ ERROR: pyclass `PyBool` cannot be subclassed +//~| ERROR: pyclass `PyBool` cannot be subclassed struct ExtendsBool; fn main() {} diff --git a/tests/ui/invalid_base_class.stderr b/tests/ui/invalid_base_class.stderr index a9262564cec..5463942de95 100644 --- a/tests/ui/invalid_base_class.stderr +++ b/tests/ui/invalid_base_class.stderr @@ -1,43 +1,39 @@ error[E0277]: pyclass `PyBool` cannot be subclassed - --> tests/ui/invalid_base_class.rs:4:1 - | -4 | #[pyclass(extends=PyBool)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ required for `#[pyclass(extends=PyBool)]` - | - = help: the trait `PyClassBaseType` is not implemented for `PyBool` - = note: `PyBool` must have `#[pyclass(subclass)]` to be eligible for subclassing - = help: the following other types implement trait `PyClassBaseType`: - PyAny - PyArithmeticError - PyAssertionError - PyAttributeError - PyBaseException - PyBaseExceptionGroup - PyBlockingIOError - PyBrokenPipeError - and $N others - = note: this error originates in the attribute macro `pyclass` (in Nightly builds, run with -Z macro-backtrace for more info) + --> tests/ui/invalid_base_class.rs:4:1 + | + 4 | #[pyclass(extends=PyBool)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ required for `#[pyclass(extends=PyBool)]` + | + = help: the trait `PyClassBaseType` is not implemented for `PyBool` + = note: `PyBool` must have `#[pyclass(subclass)]` to be eligible for subclassing + = note: with the `abi3` feature enabled, PyO3 does not support subclassing native types +help: the trait `PyClassBaseType` is implemented for `PyAny` + --> src/types/any.rs:55:1 + | +55 | impl crate::impl_::pyclass::PyClassBaseType for PyAny { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: this error originates in the attribute macro `pyclass` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: pyclass `PyBool` cannot be subclassed - --> tests/ui/invalid_base_class.rs:4:19 - | -4 | #[pyclass(extends=PyBool)] - | ^^^^^^ required for `#[pyclass(extends=PyBool)]` - | - = help: the trait `PyClassBaseType` is not implemented for `PyBool` - = note: `PyBool` must have `#[pyclass(subclass)]` to be eligible for subclassing - = help: the following other types implement trait `PyClassBaseType`: - PyAny - PyArithmeticError - PyAssertionError - PyAttributeError - PyBaseException - PyBaseExceptionGroup - PyBlockingIOError - PyBrokenPipeError - and $N others + --> tests/ui/invalid_base_class.rs:4:19 + | + 4 | #[pyclass(extends=PyBool)] + | ^^^^^^ required for `#[pyclass(extends=PyBool)]` + | + = help: the trait `PyClassBaseType` is not implemented for `PyBool` + = note: `PyBool` must have `#[pyclass(subclass)]` to be eligible for subclassing + = note: with the `abi3` feature enabled, PyO3 does not support subclassing native types +help: the trait `PyClassBaseType` is implemented for `PyAny` + --> src/types/any.rs:55:1 + | + 55 | impl crate::impl_::pyclass::PyClassBaseType for PyAny { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: required by a bound in `PyClassImpl::BaseType` - --> src/impl_/pyclass.rs - | - | type BaseType: PyTypeInfo + PyClassBaseType; - | ^^^^^^^^^^^^^^^ required by this bound in `PyClassImpl::BaseType` + --> src/impl_/pyclass.rs:184:33 + | +184 | type BaseType: PyTypeInfo + PyClassBaseType; + | ^^^^^^^^^^^^^^^ required by this bound in `PyClassImpl::BaseType` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/invalid_cancel_handle.rs b/tests/ui/invalid_cancel_handle.rs index b61397d4161..6287eccdad4 100644 --- a/tests/ui/invalid_cancel_handle.rs +++ b/tests/ui/invalid_cancel_handle.rs @@ -2,9 +2,11 @@ use pyo3::prelude::*; #[pyfunction] async fn cancel_handle_repeated(#[pyo3(cancel_handle, cancel_handle)] _param: String) {} +//~^ ERROR: `cancel_handle` may only be specified once per argument #[pyfunction] async fn cancel_handle_repeated2( +//~^ ERROR: async functions are only supported with the `experimental-async` feature #[pyo3(cancel_handle)] _param: String, #[pyo3(cancel_handle)] _param2: String, ) { @@ -12,16 +14,22 @@ async fn cancel_handle_repeated2( #[pyfunction] fn cancel_handle_synchronous(#[pyo3(cancel_handle)] _param: String) {} +//~^ ERROR: `cancel_handle` attribute can only be used with `async fn` #[pyfunction] async fn cancel_handle_wrong_type(#[pyo3(cancel_handle)] _param: String) {} +//~^ ERROR: async functions are only supported with the `experimental-async` feature #[pyfunction] async fn missing_cancel_handle_attribute(_param: pyo3::coroutine::CancelHandle) {} +//~^ ERROR: failed to resolve: could not find `coroutine` in `pyo3` +//~| ERROR: async functions are only supported with the `experimental-async` feature #[pyfunction] async fn cancel_handle_and_from_py_with( #[pyo3(cancel_handle, from_py_with = cancel_handle)] _param: pyo3::coroutine::CancelHandle, +//~^ ERROR: failed to resolve: could not find `coroutine` in `pyo3` +//~| ERROR: `from_py_with` and `cancel_handle` cannot be specified together ) { } diff --git a/tests/ui/invalid_cancel_handle.stderr b/tests/ui/invalid_cancel_handle.stderr index 8fdea4c951a..8936e97fab8 100644 --- a/tests/ui/invalid_cancel_handle.stderr +++ b/tests/ui/invalid_cancel_handle.stderr @@ -4,94 +4,64 @@ error: `cancel_handle` may only be specified once per argument 4 | async fn cancel_handle_repeated(#[pyo3(cancel_handle, cancel_handle)] _param: String) {} | ^^^^^^^^^^^^^ -error: `cancel_handle` may only be specified once - --> tests/ui/invalid_cancel_handle.rs:9:28 +error: async functions are only supported with the `experimental-async` feature + --> tests/ui/invalid_cancel_handle.rs:8:1 | -9 | #[pyo3(cancel_handle)] _param2: String, - | ^^^^^^^ +8 | async fn cancel_handle_repeated2( + | ^^^^^ error: `cancel_handle` attribute can only be used with `async fn` - --> tests/ui/invalid_cancel_handle.rs:14:53 + --> tests/ui/invalid_cancel_handle.rs:16:53 | -14 | fn cancel_handle_synchronous(#[pyo3(cancel_handle)] _param: String) {} +16 | fn cancel_handle_synchronous(#[pyo3(cancel_handle)] _param: String) {} | ^^^^^^ -error: `from_py_with` and `cancel_handle` cannot be specified together - --> tests/ui/invalid_cancel_handle.rs:24:12 +error: async functions are only supported with the `experimental-async` feature + --> tests/ui/invalid_cancel_handle.rs:20:1 | -24 | #[pyo3(cancel_handle, from_py_with = cancel_handle)] _param: pyo3::coroutine::CancelHandle, - | ^^^^^^^^^^^^^ +20 | async fn cancel_handle_wrong_type(#[pyo3(cancel_handle)] _param: String) {} + | ^^^^^ -error[E0308]: mismatched types - --> tests/ui/invalid_cancel_handle.rs:16:1 - | -16 | #[pyfunction] - | ^^^^^^^^^^^^^ - | | - | expected `String`, found `CancelHandle` - | arguments to this function are incorrect - | -note: function defined here - --> tests/ui/invalid_cancel_handle.rs:17:10 +error: async functions are only supported with the `experimental-async` feature + --> tests/ui/invalid_cancel_handle.rs:24:1 | -17 | async fn cancel_handle_wrong_type(#[pyo3(cancel_handle)] _param: String) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^ -------------- - = note: this error originates in the attribute macro `pyfunction` (in Nightly builds, run with -Z macro-backtrace for more info) +24 | async fn missing_cancel_handle_attribute(_param: pyo3::coroutine::CancelHandle) {} + | ^^^^^ -error[E0277]: `CancelHandle` cannot be used as a Python function argument - --> tests/ui/invalid_cancel_handle.rs:20:50 - | -20 | async fn missing_cancel_handle_attribute(_param: pyo3::coroutine::CancelHandle) {} - | ^^^^ the trait `PyClass` is not implemented for `CancelHandle` - | - = note: implement `FromPyObject` to enable using `CancelHandle` as a function argument - = note: `Python<'py>` is also a valid argument type to pass the Python token into `#[pyfunction]`s and `#[pymethods]` - = help: the trait `PyClass` is implemented for `pyo3::coroutine::Coroutine` - = note: required for `CancelHandle` to implement `FromPyObject<'_, '_>` - = note: required for `CancelHandle` to implement `PyFunctionArgument<'_, '_, '_, true>` -note: required by a bound in `extract_argument` - --> src/impl_/extract_argument.rs +error: `from_py_with` and `cancel_handle` cannot be specified together + --> tests/ui/invalid_cancel_handle.rs:30:12 | - | pub fn extract_argument<'a, 'holder, 'py, T, const IMPLEMENTS_FROMPYOBJECT: bool>( - | ---------------- required by a bound in this function -... - | T: PyFunctionArgument<'a, 'holder, 'py, IMPLEMENTS_FROMPYOBJECT>, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `extract_argument` +30 | #[pyo3(cancel_handle, from_py_with = cancel_handle)] _param: pyo3::coroutine::CancelHandle, + | ^^^^^^^^^^^^^ -error[E0277]: `CancelHandle` cannot be used as a Python function argument - --> tests/ui/invalid_cancel_handle.rs:20:50 - | -20 | async fn missing_cancel_handle_attribute(_param: pyo3::coroutine::CancelHandle) {} - | ^^^^ the trait `Clone` is not implemented for `CancelHandle` - | - = note: implement `FromPyObject` to enable using `CancelHandle` as a function argument - = note: `Python<'py>` is also a valid argument type to pass the Python token into `#[pyfunction]`s and `#[pymethods]` - = help: the following other types implement trait `PyFunctionArgument<'a, 'holder, 'py, IMPLEMENTS_FROMPYOBJECT>`: - `&'a pyo3::Bound<'py, T>` implements `PyFunctionArgument<'a, '_, 'py, false>` - `&'holder T` implements `PyFunctionArgument<'a, 'holder, '_, false>` - `&'holder mut T` implements `PyFunctionArgument<'a, 'holder, '_, false>` - `Option` implements `PyFunctionArgument<'a, 'holder, 'py, false>` - = note: required for `CancelHandle` to implement `FromPyObject<'_, '_>` - = note: required for `CancelHandle` to implement `PyFunctionArgument<'_, '_, '_, true>` -note: required by a bound in `extract_argument` - --> src/impl_/extract_argument.rs - | - | pub fn extract_argument<'a, 'holder, 'py, T, const IMPLEMENTS_FROMPYOBJECT: bool>( - | ---------------- required by a bound in this function -... - | T: PyFunctionArgument<'a, 'holder, 'py, IMPLEMENTS_FROMPYOBJECT>, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `extract_argument` +error[E0433]: failed to resolve: could not find `coroutine` in `pyo3` + --> tests/ui/invalid_cancel_handle.rs:24:56 + | + 24 | async fn missing_cancel_handle_attribute(_param: pyo3::coroutine::CancelHandle) {} + | ^^^^^^^^^ could not find `coroutine` in `pyo3` + | +note: found an item that was configured out + --> src/lib.rs:417:9 + | +416 | #[cfg(feature = "experimental-async")] + | ------------------------------ the item is gated behind the `experimental-async` feature +417 | pub mod coroutine; + | ^^^^^^^^^ -error[E0277]: `CancelHandle` cannot be used as a Python function argument - --> tests/ui/invalid_cancel_handle.rs:20:50 - | -20 | async fn missing_cancel_handle_attribute(_param: pyo3::coroutine::CancelHandle) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `PyFunctionArgument<'_, '_, '_, false>` is not implemented for `CancelHandle` - | - = note: implement `FromPyObject` to enable using `CancelHandle` as a function argument - = note: `Python<'py>` is also a valid argument type to pass the Python token into `#[pyfunction]`s and `#[pymethods]` - = help: the following other types implement trait `PyFunctionArgument<'a, 'holder, 'py, IMPLEMENTS_FROMPYOBJECT>`: - `&'a pyo3::Bound<'py, T>` implements `PyFunctionArgument<'a, '_, 'py, false>` - `&'holder T` implements `PyFunctionArgument<'a, 'holder, '_, false>` - `&'holder mut T` implements `PyFunctionArgument<'a, 'holder, '_, false>` - `Option` implements `PyFunctionArgument<'a, 'holder, 'py, false>` +error[E0433]: failed to resolve: could not find `coroutine` in `pyo3` + --> tests/ui/invalid_cancel_handle.rs:30:72 + | + 30 | #[pyo3(cancel_handle, from_py_with = cancel_handle)] _param: pyo3::coroutine::CancelHandle, + | ^^^^^^^^^ could not find `coroutine` in `pyo3` + | +note: found an item that was configured out + --> src/lib.rs:417:9 + | +416 | #[cfg(feature = "experimental-async")] + | ------------------------------ the item is gated behind the `experimental-async` feature +417 | pub mod coroutine; + | ^^^^^^^^^ + +error: aborting due to 8 previous errors + +For more information about this error, try `rustc --explain E0433`. diff --git a/tests/ui/invalid_closure.rs b/tests/ui/invalid_closure.rs index 6dd7d508703..feb64c561b4 100644 --- a/tests/ui/invalid_closure.rs +++ b/tests/ui/invalid_closure.rs @@ -5,6 +5,7 @@ fn main() { let fun: Py = Python::attach(|py| { let local_data = vec![0, 1, 2, 3, 4]; let ref_: &[u8] = &local_data; +//~^ ERROR: `local_data` does not live long enough let closure_fn = |_args: &Bound<'_, PyTuple>, _kwargs: Option<&Bound<'_, PyDict>>| -> PyResult<()> { diff --git a/tests/ui/invalid_closure.stderr b/tests/ui/invalid_closure.stderr index d7fb9bbd04d..6d82dec4f09 100644 --- a/tests/ui/invalid_closure.stderr +++ b/tests/ui/invalid_closure.stderr @@ -6,14 +6,18 @@ error[E0597]: `local_data` does not live long enough 7 | let ref_: &[u8] = &local_data; | ^^^^^^^^^^^ borrowed value does not live long enough ... -14 | PyCFunction::new_closure(py, None, None, closure_fn) +15 | PyCFunction::new_closure(py, None, None, closure_fn) | ---------------------------------------------------- argument requires that `local_data` is borrowed for `'static` ... -17 | }); +18 | }); | - `local_data` dropped here while still borrowed | note: requirement that the value outlives `'static` introduced here - --> src/types/function.rs + --> src/types/function.rs:85:78 | - | F: Fn(&Bound<'_, PyTuple>, Option<&Bound<'_, PyDict>>) -> R + Send + 'static, +85 | F: Fn(&Bound<'_, PyTuple>, Option<&Bound<'_, PyDict>>) -> R + Send + 'static, | ^^^^^^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0597`. diff --git a/tests/ui/invalid_frompy_derive.rs b/tests/ui/invalid_frompy_derive.rs index b6682345d9a..73ea2b0838c 100644 --- a/tests/ui/invalid_frompy_derive.rs +++ b/tests/ui/invalid_frompy_derive.rs @@ -2,37 +2,45 @@ use pyo3::FromPyObject; #[derive(FromPyObject)] struct Foo(); +//~^ ERROR: cannot derive FromPyObject for empty structs and variants #[derive(FromPyObject)] struct Foo2 {} +//~^ ERROR: cannot derive FromPyObject for empty structs and variants #[derive(FromPyObject)] enum EmptyEnum {} +//~^ ERROR: cannot derive FromPyObject for empty enum #[derive(FromPyObject)] enum EnumWithEmptyTupleVar { EmptyTuple(), +//~^ ERROR: cannot derive FromPyObject for empty structs and variants Valid(String), } #[derive(FromPyObject)] enum EnumWithEmptyStructVar { EmptyStruct {}, +//~^ ERROR: cannot derive FromPyObject for empty structs and variants Valid(String), } #[derive(FromPyObject)] #[pyo3(transparent)] struct EmptyTransparentTup(); +//~^ ERROR: cannot derive FromPyObject for empty structs and variants #[derive(FromPyObject)] #[pyo3(transparent)] struct EmptyTransparentStruct {} +//~^ ERROR: cannot derive FromPyObject for empty structs and variants #[derive(FromPyObject)] enum EnumWithTransparentEmptyTupleVar { #[pyo3(transparent)] EmptyTuple(), +//~^ ERROR: cannot derive FromPyObject for empty structs and variants Valid(String), } @@ -40,16 +48,19 @@ enum EnumWithTransparentEmptyTupleVar { enum EnumWithTransparentEmptyStructVar { #[pyo3(transparent)] EmptyStruct {}, +//~^ ERROR: cannot derive FromPyObject for empty structs and variants Valid(String), } #[derive(FromPyObject)] #[pyo3(transparent)] struct TransparentTupTooManyFields(String, String); +//~^ ERROR: transparent structs and variants can only have 1 field #[derive(FromPyObject)] #[pyo3(transparent)] struct TransparentStructTooManyFields { +//~^ ERROR: transparent structs and variants can only have 1 field foo: String, bar: String, } @@ -58,6 +69,7 @@ struct TransparentStructTooManyFields { enum EnumWithTransparentTupleTooMany { #[pyo3(transparent)] EmptyTuple(String, String), +//~^ ERROR: transparent structs and variants can only have 1 field Valid(String), } @@ -65,6 +77,7 @@ enum EnumWithTransparentTupleTooMany { enum EnumWithTransparentStructTooMany { #[pyo3(transparent)] EmptyStruct { +//~^ ERROR: transparent structs and variants can only have 1 field foo: String, bar: String, }, @@ -74,59 +87,69 @@ enum EnumWithTransparentStructTooMany { #[derive(FromPyObject)] struct UnknownAttribute { #[pyo3(attr)] +//~^ ERROR: expected one of: `attribute`, `item`, `from_py_with`, `into_py_with`, `default` a: String, } #[derive(FromPyObject)] struct InvalidAttributeArg { #[pyo3(attribute(1))] +//~^ ERROR: expected string literal a: String, } #[derive(FromPyObject)] struct TooManyAttributeArgs { #[pyo3(attribute("a", "b"))] +//~^ ERROR: expected at most one argument: `attribute` or `attribute("name")` a: String, } #[derive(FromPyObject)] struct EmptyAttributeArg { #[pyo3(attribute(""))] +//~^ ERROR: attribute name cannot be empty a: String, } #[derive(FromPyObject)] struct NoAttributeArg { #[pyo3(attribute())] +//~^ ERROR: unexpected end of input, expected string literal a: String, } #[derive(FromPyObject)] struct TooManyitemArgs { #[pyo3(item("a", "b"))] +//~^ ERROR: expected at most one argument: `item` or `item(key)` a: String, } #[derive(FromPyObject)] struct NoItemArg { #[pyo3(item())] +//~^ ERROR: unexpected end of input, expected literal a: String, } #[derive(FromPyObject)] struct ItemAndAttribute { #[pyo3(item, attribute)] +//~^ ERROR: only one of `attribute` or `item` can be provided a: String, } #[derive(FromPyObject)] #[pyo3(unknown = "should not work")] +//~^ ERROR: expected one of: `transparent`, `from_item_all`, `annotation`, `crate`, `rename_all` struct UnknownContainerAttr { a: String, } #[derive(FromPyObject)] #[pyo3(annotation = "should not work")] +//~^ ERROR: `annotation` is unsupported for structs struct AnnotationOnStruct { a: String, } @@ -134,21 +157,25 @@ struct AnnotationOnStruct { #[derive(FromPyObject)] enum InvalidAnnotatedEnum { #[pyo3(annotation = 1)] +//~^ ERROR: expected string literal Foo(String), } #[derive(FromPyObject)] enum TooManyLifetimes<'a, 'b> { +//~^ ERROR: FromPyObject can be derived with at most one lifetime parameter Foo(&'a str), Bar(&'b str), } #[derive(FromPyObject)] union Union { +//~^ ERROR: #[derive(FromPyObject)] is not supported for unions a: usize, } #[derive(FromPyObject)] +//~^ ERROR: cannot derive FromPyObject for empty structs and variants enum UnitEnum { Unit, } @@ -156,23 +183,27 @@ enum UnitEnum { #[derive(FromPyObject)] struct InvalidFromPyWith { #[pyo3(from_py_with)] +//~^ ERROR: expected `=` field: String, } #[derive(FromPyObject)] struct InvalidFromPyWithNotFound { #[pyo3(from_py_with = func)] +//~^ ERROR: cannot find value `func` in this scope field: String, } #[derive(FromPyObject)] struct InvalidTupleGetter(#[pyo3(item("foo"))] String); +//~^ ERROR: `getter` is not permitted on tuple struct elements. #[derive(FromPyObject)] #[pyo3(transparent)] struct InvalidTransparentWithGetter { #[pyo3(item("foo"))] field: String, +//~^ ERROR: `transparent` structs may not have a `getter` for the inner field } #[derive(FromPyObject)] @@ -184,16 +215,19 @@ struct FromItemAllOnTuple(String); #[pyo3(transparent)] struct FromItemAllWithTransparent { field: String, +//~^ ERROR: `transparent` structs may not have a `getter` for the inner field } #[derive(FromPyObject)] #[pyo3(from_item_all, from_item_all)] +//~^ ERROR: `from_item_all` may only be specified once struct MultipleFromItemAll { field: String, } #[derive(FromPyObject)] #[pyo3(from_item_all)] +//~^ ERROR: Useless `item` - the struct is already annotated with `from_item_all` struct UselessItemAttr { #[pyo3(item)] field: String, @@ -201,6 +235,7 @@ struct UselessItemAttr { #[derive(FromPyObject)] #[pyo3(from_item_all)] +//~^ ERROR: The struct is already annotated with `from_item_all`, `attribute` is not allowed struct FromItemAllConflictAttr { #[pyo3(attribute)] field: String, @@ -208,6 +243,7 @@ struct FromItemAllConflictAttr { #[derive(FromPyObject)] #[pyo3(from_item_all)] +//~^ ERROR: The struct is already annotated with `from_item_all`, `attribute` is not allowed struct FromItemAllConflictAttrWithArgs { #[pyo3(attribute("f"))] field: String, @@ -215,6 +251,7 @@ struct FromItemAllConflictAttrWithArgs { #[derive(FromPyObject)] struct StructWithOnlyDefaultValues { +//~^ ERROR: cannot derive FromPyObject for structs and variants with only default values #[pyo3(default)] field: String, } @@ -222,6 +259,7 @@ struct StructWithOnlyDefaultValues { #[derive(FromPyObject)] enum EnumVariantWithOnlyDefaultValues { Foo { +//~^ ERROR: cannot derive FromPyObject for structs and variants with only default values #[pyo3(default)] field: String, }, @@ -229,25 +267,30 @@ enum EnumVariantWithOnlyDefaultValues { #[derive(FromPyObject)] struct NamedTuplesWithDefaultValues(#[pyo3(default)] String); +//~^ ERROR: `default` is not permitted on tuple struct elements. #[derive(FromPyObject)] #[pyo3(rename_all = "camelCase", rename_all = "kebab-case")] +//~^ ERROR: `rename_all` may only be specified once struct MultipleRenames { snake_case: String, } #[derive(FromPyObject)] #[pyo3(rename_all = "camelCase")] +//~^ ERROR: `rename_all` is useless on tuple structs and variants. struct RenameAllTuple(String); #[derive(FromPyObject)] enum RenameAllEnum { #[pyo3(rename_all = "camelCase")] +//~^ ERROR: `rename_all` is useless on tuple structs and variants. Tuple(String), } #[derive(FromPyObject)] #[pyo3(transparent, rename_all = "camelCase")] +//~^ ERROR: `rename_all` is not permitted on `transparent` structs and variants struct RenameAllTransparent { inner: String, } @@ -256,6 +299,7 @@ struct RenameAllTransparent { #[pyo3(rename_all = "camelCase")] enum UselessRenameAllEnum { #[pyo3(rename_all = "camelCase")] +//~^ ERROR: Useless variant `rename_all` - enum is already annotated with `rename_all Tuple { inner_field: String }, } diff --git a/tests/ui/invalid_frompy_derive.stderr b/tests/ui/invalid_frompy_derive.stderr index 484c4ce44f4..dcd7799ed18 100644 --- a/tests/ui/invalid_frompy_derive.stderr +++ b/tests/ui/invalid_frompy_derive.stderr @@ -5,277 +5,285 @@ error: cannot derive FromPyObject for empty structs and variants | ^^ error: cannot derive FromPyObject for empty structs and variants - --> tests/ui/invalid_frompy_derive.rs:7:13 + --> tests/ui/invalid_frompy_derive.rs:8:13 | -7 | struct Foo2 {} +8 | struct Foo2 {} | ^^ error: cannot derive FromPyObject for empty enum - --> tests/ui/invalid_frompy_derive.rs:10:6 + --> tests/ui/invalid_frompy_derive.rs:12:6 | -10 | enum EmptyEnum {} +12 | enum EmptyEnum {} | ^^^^^^^^^ error: cannot derive FromPyObject for empty structs and variants - --> tests/ui/invalid_frompy_derive.rs:14:15 + --> tests/ui/invalid_frompy_derive.rs:17:15 | -14 | EmptyTuple(), +17 | EmptyTuple(), | ^^ error: cannot derive FromPyObject for empty structs and variants - --> tests/ui/invalid_frompy_derive.rs:20:17 + --> tests/ui/invalid_frompy_derive.rs:24:17 | -20 | EmptyStruct {}, +24 | EmptyStruct {}, | ^^ error: cannot derive FromPyObject for empty structs and variants - --> tests/ui/invalid_frompy_derive.rs:26:27 + --> tests/ui/invalid_frompy_derive.rs:31:27 | -26 | struct EmptyTransparentTup(); +31 | struct EmptyTransparentTup(); | ^^ error: cannot derive FromPyObject for empty structs and variants - --> tests/ui/invalid_frompy_derive.rs:30:31 + --> tests/ui/invalid_frompy_derive.rs:36:31 | -30 | struct EmptyTransparentStruct {} +36 | struct EmptyTransparentStruct {} | ^^ error: cannot derive FromPyObject for empty structs and variants - --> tests/ui/invalid_frompy_derive.rs:35:15 + --> tests/ui/invalid_frompy_derive.rs:42:15 | -35 | EmptyTuple(), +42 | EmptyTuple(), | ^^ error: cannot derive FromPyObject for empty structs and variants - --> tests/ui/invalid_frompy_derive.rs:42:17 + --> tests/ui/invalid_frompy_derive.rs:50:17 | -42 | EmptyStruct {}, +50 | EmptyStruct {}, | ^^ error: transparent structs and variants can only have 1 field - --> tests/ui/invalid_frompy_derive.rs:48:35 + --> tests/ui/invalid_frompy_derive.rs:57:35 | -48 | struct TransparentTupTooManyFields(String, String); +57 | struct TransparentTupTooManyFields(String, String); | ^^^^^^^^^^^^^^^^ error: transparent structs and variants can only have 1 field - --> tests/ui/invalid_frompy_derive.rs:52:39 + --> tests/ui/invalid_frompy_derive.rs:62:39 | -52 | struct TransparentStructTooManyFields { +62 | struct TransparentStructTooManyFields { | _______________________________________^ -53 | | foo: String, -54 | | bar: String, -55 | | } +63 | | +64 | | foo: String, +65 | | bar: String, +66 | | } | |_^ error: transparent structs and variants can only have 1 field - --> tests/ui/invalid_frompy_derive.rs:60:15 + --> tests/ui/invalid_frompy_derive.rs:71:15 | -60 | EmptyTuple(String, String), +71 | EmptyTuple(String, String), | ^^^^^^^^^^^^^^^^ error: transparent structs and variants can only have 1 field - --> tests/ui/invalid_frompy_derive.rs:67:17 + --> tests/ui/invalid_frompy_derive.rs:79:17 | -67 | EmptyStruct { +79 | EmptyStruct { | _________________^ -68 | | foo: String, -69 | | bar: String, -70 | | }, +80 | | +81 | | foo: String, +82 | | bar: String, +83 | | }, | |_____^ error: expected one of: `attribute`, `item`, `from_py_with`, `into_py_with`, `default` - --> tests/ui/invalid_frompy_derive.rs:76:12 + --> tests/ui/invalid_frompy_derive.rs:89:12 | -76 | #[pyo3(attr)] +89 | #[pyo3(attr)] | ^^^^ error: expected string literal - --> tests/ui/invalid_frompy_derive.rs:82:22 + --> tests/ui/invalid_frompy_derive.rs:96:22 | -82 | #[pyo3(attribute(1))] +96 | #[pyo3(attribute(1))] | ^ error: expected at most one argument: `attribute` or `attribute("name")` - --> tests/ui/invalid_frompy_derive.rs:88:25 - | -88 | #[pyo3(attribute("a", "b"))] - | ^ + --> tests/ui/invalid_frompy_derive.rs:103:25 + | +103 | #[pyo3(attribute("a", "b"))] + | ^ error: attribute name cannot be empty - --> tests/ui/invalid_frompy_derive.rs:94:22 - | -94 | #[pyo3(attribute(""))] - | ^^ + --> tests/ui/invalid_frompy_derive.rs:110:22 + | +110 | #[pyo3(attribute(""))] + | ^^ error: unexpected end of input, expected string literal - --> tests/ui/invalid_frompy_derive.rs:100:22 + --> tests/ui/invalid_frompy_derive.rs:117:22 | -100 | #[pyo3(attribute())] +117 | #[pyo3(attribute())] | ^ error: expected at most one argument: `item` or `item(key)` - --> tests/ui/invalid_frompy_derive.rs:106:20 + --> tests/ui/invalid_frompy_derive.rs:124:20 | -106 | #[pyo3(item("a", "b"))] +124 | #[pyo3(item("a", "b"))] | ^ error: unexpected end of input, expected literal - --> tests/ui/invalid_frompy_derive.rs:112:17 + --> tests/ui/invalid_frompy_derive.rs:131:17 | -112 | #[pyo3(item())] +131 | #[pyo3(item())] | ^ error: only one of `attribute` or `item` can be provided - --> tests/ui/invalid_frompy_derive.rs:118:18 + --> tests/ui/invalid_frompy_derive.rs:138:18 | -118 | #[pyo3(item, attribute)] +138 | #[pyo3(item, attribute)] | ^^^^^^^^^ error: expected one of: `transparent`, `from_item_all`, `annotation`, `crate`, `rename_all` - --> tests/ui/invalid_frompy_derive.rs:123:8 + --> tests/ui/invalid_frompy_derive.rs:144:8 | -123 | #[pyo3(unknown = "should not work")] +144 | #[pyo3(unknown = "should not work")] | ^^^^^^^ error: `annotation` is unsupported for structs - --> tests/ui/invalid_frompy_derive.rs:129:21 + --> tests/ui/invalid_frompy_derive.rs:151:21 | -129 | #[pyo3(annotation = "should not work")] +151 | #[pyo3(annotation = "should not work")] | ^^^^^^^^^^^^^^^^^ error: expected string literal - --> tests/ui/invalid_frompy_derive.rs:136:25 + --> tests/ui/invalid_frompy_derive.rs:159:25 | -136 | #[pyo3(annotation = 1)] +159 | #[pyo3(annotation = 1)] | ^ error: FromPyObject can be derived with at most one lifetime parameter - --> tests/ui/invalid_frompy_derive.rs:141:22 + --> tests/ui/invalid_frompy_derive.rs:165:22 | -141 | enum TooManyLifetimes<'a, 'b> { +165 | enum TooManyLifetimes<'a, 'b> { | ^ error: #[derive(FromPyObject)] is not supported for unions - --> tests/ui/invalid_frompy_derive.rs:147:1 + --> tests/ui/invalid_frompy_derive.rs:172:1 | -147 | union Union { +172 | union Union { | ^^^^^ error: cannot derive FromPyObject for empty structs and variants - --> tests/ui/invalid_frompy_derive.rs:151:10 + --> tests/ui/invalid_frompy_derive.rs:177:10 | -151 | #[derive(FromPyObject)] +177 | #[derive(FromPyObject)] | ^^^^^^^^^^^^ | = note: this error originates in the derive macro `FromPyObject` (in Nightly builds, run with -Z macro-backtrace for more info) error: expected `=` - --> tests/ui/invalid_frompy_derive.rs:158:24 + --> tests/ui/invalid_frompy_derive.rs:185:24 | -158 | #[pyo3(from_py_with)] +185 | #[pyo3(from_py_with)] | ^ error: `getter` is not permitted on tuple struct elements. - --> tests/ui/invalid_frompy_derive.rs:169:27 + --> tests/ui/invalid_frompy_derive.rs:198:27 | -169 | struct InvalidTupleGetter(#[pyo3(item("foo"))] String); +198 | struct InvalidTupleGetter(#[pyo3(item("foo"))] String); | ^ error: `transparent` structs may not have a `getter` for the inner field - --> tests/ui/invalid_frompy_derive.rs:175:5 + --> tests/ui/invalid_frompy_derive.rs:205:5 | -175 | field: String, +205 | field: String, | ^^^^^ error: `transparent` structs may not have a `getter` for the inner field - --> tests/ui/invalid_frompy_derive.rs:186:5 + --> tests/ui/invalid_frompy_derive.rs:217:5 | -186 | field: String, +217 | field: String, | ^^^^^ error: `from_item_all` may only be specified once - --> tests/ui/invalid_frompy_derive.rs:190:23 + --> tests/ui/invalid_frompy_derive.rs:222:23 | -190 | #[pyo3(from_item_all, from_item_all)] +222 | #[pyo3(from_item_all, from_item_all)] | ^^^^^^^^^^^^^ error: Useless `item` - the struct is already annotated with `from_item_all` - --> tests/ui/invalid_frompy_derive.rs:196:8 + --> tests/ui/invalid_frompy_derive.rs:229:8 | -196 | #[pyo3(from_item_all)] +229 | #[pyo3(from_item_all)] | ^^^^^^^^^^^^^ error: The struct is already annotated with `from_item_all`, `attribute` is not allowed - --> tests/ui/invalid_frompy_derive.rs:203:8 + --> tests/ui/invalid_frompy_derive.rs:237:8 | -203 | #[pyo3(from_item_all)] +237 | #[pyo3(from_item_all)] | ^^^^^^^^^^^^^ error: The struct is already annotated with `from_item_all`, `attribute` is not allowed - --> tests/ui/invalid_frompy_derive.rs:210:8 + --> tests/ui/invalid_frompy_derive.rs:245:8 | -210 | #[pyo3(from_item_all)] +245 | #[pyo3(from_item_all)] | ^^^^^^^^^^^^^ error: cannot derive FromPyObject for structs and variants with only default values - --> tests/ui/invalid_frompy_derive.rs:217:36 + --> tests/ui/invalid_frompy_derive.rs:253:36 | -217 | struct StructWithOnlyDefaultValues { +253 | struct StructWithOnlyDefaultValues { | ____________________________________^ -218 | | #[pyo3(default)] -219 | | field: String, -220 | | } +254 | | +255 | | #[pyo3(default)] +256 | | field: String, +257 | | } | |_^ error: cannot derive FromPyObject for structs and variants with only default values - --> tests/ui/invalid_frompy_derive.rs:224:9 + --> tests/ui/invalid_frompy_derive.rs:261:9 | -224 | Foo { +261 | Foo { | _________^ -225 | | #[pyo3(default)] -226 | | field: String, -227 | | }, +262 | | +263 | | #[pyo3(default)] +264 | | field: String, +265 | | }, | |_____^ error: `default` is not permitted on tuple struct elements. - --> tests/ui/invalid_frompy_derive.rs:231:37 + --> tests/ui/invalid_frompy_derive.rs:269:37 | -231 | struct NamedTuplesWithDefaultValues(#[pyo3(default)] String); +269 | struct NamedTuplesWithDefaultValues(#[pyo3(default)] String); | ^ error: `rename_all` may only be specified once - --> tests/ui/invalid_frompy_derive.rs:234:34 + --> tests/ui/invalid_frompy_derive.rs:273:34 | -234 | #[pyo3(rename_all = "camelCase", rename_all = "kebab-case")] +273 | #[pyo3(rename_all = "camelCase", rename_all = "kebab-case")] | ^^^^^^^^^^ error: `rename_all` is useless on tuple structs and variants. - --> tests/ui/invalid_frompy_derive.rs:240:8 + --> tests/ui/invalid_frompy_derive.rs:280:8 | -240 | #[pyo3(rename_all = "camelCase")] +280 | #[pyo3(rename_all = "camelCase")] | ^^^^^^^^^^ error: `rename_all` is useless on tuple structs and variants. - --> tests/ui/invalid_frompy_derive.rs:245:12 + --> tests/ui/invalid_frompy_derive.rs:286:12 | -245 | #[pyo3(rename_all = "camelCase")] +286 | #[pyo3(rename_all = "camelCase")] | ^^^^^^^^^^ error: `rename_all` is not permitted on `transparent` structs and variants - --> tests/ui/invalid_frompy_derive.rs:250:21 + --> tests/ui/invalid_frompy_derive.rs:292:21 | -250 | #[pyo3(transparent, rename_all = "camelCase")] +292 | #[pyo3(transparent, rename_all = "camelCase")] | ^^^^^^^^^^ error: Useless variant `rename_all` - enum is already annotated with `rename_all - --> tests/ui/invalid_frompy_derive.rs:258:12 + --> tests/ui/invalid_frompy_derive.rs:301:12 | -258 | #[pyo3(rename_all = "camelCase")] +301 | #[pyo3(rename_all = "camelCase")] | ^^^^^^^^^^ error[E0425]: cannot find value `func` in this scope - --> tests/ui/invalid_frompy_derive.rs:164:27 + --> tests/ui/invalid_frompy_derive.rs:192:27 | -164 | #[pyo3(from_py_with = func)] +192 | #[pyo3(from_py_with = func)] | ^^^^ not found in this scope + +error: aborting due to 44 previous errors + +For more information about this error, try `rustc --explain E0425`. diff --git a/tests/ui/invalid_frozen_pyclass_borrow.rs b/tests/ui/invalid_frozen_pyclass_borrow.rs index 6379a8707c5..2b710a4b265 100644 --- a/tests/ui/invalid_frozen_pyclass_borrow.rs +++ b/tests/ui/invalid_frozen_pyclass_borrow.rs @@ -7,12 +7,15 @@ pub struct Foo { } #[pymethods] +//~^ ERROR: type mismatch resolving `::Frozen == False` impl Foo { fn mut_method(&mut self) {} +//~^ ERROR: type mismatch resolving `::Frozen == False` } fn borrow_mut_fails(foo: Py, py: Python) { let borrow = foo.bind(py).borrow_mut(); +//~^ ERROR: type mismatch resolving `::Frozen == False` } #[pyclass(subclass)] @@ -23,19 +26,23 @@ struct ImmutableChild; fn borrow_mut_of_child_fails(child: Py, py: Python) { let borrow = child.bind(py).borrow_mut(); +//~^ ERROR: type mismatch resolving `::Frozen == False` } fn py_get_of_mutable_class_fails(class: Py) { class.get(); +//~^ ERROR: type mismatch resolving `::Frozen == True` } fn pyclass_get_of_mutable_class_fails(class: &Bound<'_, MutableBase>) { class.get(); +//~^ ERROR: type mismatch resolving `::Frozen == True` } #[pyclass(frozen)] pub struct SetOnFrozenClass { #[pyo3(set)] +//~^ ERROR: cannot use `#[pyo3(set)]` on a `frozen` class field: u32, } diff --git a/tests/ui/invalid_frozen_pyclass_borrow.stderr b/tests/ui/invalid_frozen_pyclass_borrow.stderr index 5bfa9ee0808..f6f15fd63a2 100644 --- a/tests/ui/invalid_frozen_pyclass_borrow.stderr +++ b/tests/ui/invalid_frozen_pyclass_borrow.stderr @@ -1,125 +1,129 @@ error: cannot use `#[pyo3(set)]` on a `frozen` class - --> tests/ui/invalid_frozen_pyclass_borrow.rs:38:12 + --> tests/ui/invalid_frozen_pyclass_borrow.rs:44:12 | -38 | #[pyo3(set)] +44 | #[pyo3(set)] | ^^^ error[E0271]: type mismatch resolving `::Frozen == False` - --> tests/ui/invalid_frozen_pyclass_borrow.rs:11:19 - | -11 | fn mut_method(&mut self) {} - | ^ type mismatch resolving `::Frozen == False` - | + --> tests/ui/invalid_frozen_pyclass_borrow.rs:12:19 + | + 12 | fn mut_method(&mut self) {} + | ^ type mismatch resolving `::Frozen == False` + | note: expected this to be `False` - --> tests/ui/invalid_frozen_pyclass_borrow.rs:3:1 - | - 3 | #[pyclass(frozen)] - | ^^^^^^^^^^^^^^^^^^ + --> tests/ui/invalid_frozen_pyclass_borrow.rs:3:1 + | + 3 | #[pyclass(frozen)] + | ^^^^^^^^^^^^^^^^^^ note: required by a bound in `extract_pyclass_ref_mut` - --> src/impl_/extract_argument.rs - | - | pub fn extract_pyclass_ref_mut<'a, 'holder, T: PyClass>( - | ^^^^^^^^^^^^^^ required by this bound in `extract_pyclass_ref_mut` - = note: this error originates in the attribute macro `pyclass` (in Nightly builds, run with -Z macro-backtrace for more info) + --> src/impl_/extract_argument.rs:212:56 + | +212 | pub fn extract_pyclass_ref_mut<'a, 'holder, T: PyClass>( + | ^^^^^^^^^^^^^^ required by this bound in `extract_pyclass_ref_mut` + = note: this error originates in the attribute macro `pyclass` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0271]: type mismatch resolving `::Frozen == False` - --> tests/ui/invalid_frozen_pyclass_borrow.rs:9:1 - | -9 | #[pymethods] - | ^^^^^^^^^^^^ type mismatch resolving `::Frozen == False` - | + --> tests/ui/invalid_frozen_pyclass_borrow.rs:9:1 + | + 9 | #[pymethods] + | ^^^^^^^^^^^^ type mismatch resolving `::Frozen == False` + | note: expected this to be `False` - --> tests/ui/invalid_frozen_pyclass_borrow.rs:3:1 - | -3 | #[pyclass(frozen)] - | ^^^^^^^^^^^^^^^^^^ + --> tests/ui/invalid_frozen_pyclass_borrow.rs:3:1 + | + 3 | #[pyclass(frozen)] + | ^^^^^^^^^^^^^^^^^^ note: required by a bound in `PyClassGuardMut` - --> src/pyclass/guard.rs - | - | pub struct PyClassGuardMut<'a, T: PyClass> { - | ^^^^^^^^^^^^^^ required by this bound in `PyClassGuardMut` - = note: this error originates in the attribute macro `pymethods` which comes from the expansion of the attribute macro `pyclass` (in Nightly builds, run with -Z macro-backtrace for more info) + --> src/pyclass/guard.rs:592:43 + | +592 | pub struct PyClassGuardMut<'a, T: PyClass> { + | ^^^^^^^^^^^^^^ required by this bound in `PyClassGuardMut` + = note: this error originates in the attribute macro `pymethods` which comes from the expansion of the attribute macro `pyclass` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0271]: type mismatch resolving `::Frozen == False` - --> tests/ui/invalid_frozen_pyclass_borrow.rs:15:31 - | -15 | let borrow = foo.bind(py).borrow_mut(); - | ^^^^^^^^^^ type mismatch resolving `::Frozen == False` - | + --> tests/ui/invalid_frozen_pyclass_borrow.rs:17:31 + | + 17 | let borrow = foo.bind(py).borrow_mut(); + | ^^^^^^^^^^ type mismatch resolving `::Frozen == False` + | note: expected this to be `False` - --> tests/ui/invalid_frozen_pyclass_borrow.rs:3:1 - | - 3 | #[pyclass(frozen)] - | ^^^^^^^^^^^^^^^^^^ + --> tests/ui/invalid_frozen_pyclass_borrow.rs:3:1 + | + 3 | #[pyclass(frozen)] + | ^^^^^^^^^^^^^^^^^^ note: required by a bound in `pyo3::Bound::<'py, T>::borrow_mut` - --> src/instance.rs - | - | pub fn borrow_mut(&self) -> PyRefMut<'py, T> - | ---------- required by a bound in this associated function - | where - | T: PyClass, - | ^^^^^^^^^^^^^^ required by this bound in `Bound::<'py, T>::borrow_mut` - = note: this error originates in the attribute macro `pyclass` (in Nightly builds, run with -Z macro-backtrace for more info) + --> src/instance.rs:591:20 + | +589 | pub fn borrow_mut(&self) -> PyRefMut<'py, T> + | ---------- required by a bound in this associated function +590 | where +591 | T: PyClass, + | ^^^^^^^^^^^^^^ required by this bound in `Bound::<'py, T>::borrow_mut` + = note: this error originates in the attribute macro `pyclass` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0271]: type mismatch resolving `::Frozen == False` - --> tests/ui/invalid_frozen_pyclass_borrow.rs:25:33 - | -25 | let borrow = child.bind(py).borrow_mut(); - | ^^^^^^^^^^ type mismatch resolving `::Frozen == False` - | + --> tests/ui/invalid_frozen_pyclass_borrow.rs:28:33 + | + 28 | let borrow = child.bind(py).borrow_mut(); + | ^^^^^^^^^^ type mismatch resolving `::Frozen == False` + | note: expected this to be `False` - --> tests/ui/invalid_frozen_pyclass_borrow.rs:21:1 - | -21 | #[pyclass(frozen, extends = MutableBase)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + --> tests/ui/invalid_frozen_pyclass_borrow.rs:24:1 + | + 24 | #[pyclass(frozen, extends = MutableBase)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: required by a bound in `pyo3::Bound::<'py, T>::borrow_mut` - --> src/instance.rs - | - | pub fn borrow_mut(&self) -> PyRefMut<'py, T> - | ---------- required by a bound in this associated function - | where - | T: PyClass, - | ^^^^^^^^^^^^^^ required by this bound in `Bound::<'py, T>::borrow_mut` - = note: this error originates in the attribute macro `pyclass` (in Nightly builds, run with -Z macro-backtrace for more info) + --> src/instance.rs:591:20 + | +589 | pub fn borrow_mut(&self) -> PyRefMut<'py, T> + | ---------- required by a bound in this associated function +590 | where +591 | T: PyClass, + | ^^^^^^^^^^^^^^ required by this bound in `Bound::<'py, T>::borrow_mut` + = note: this error originates in the attribute macro `pyclass` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0271]: type mismatch resolving `::Frozen == True` - --> tests/ui/invalid_frozen_pyclass_borrow.rs:29:11 - | -29 | class.get(); - | ^^^ type mismatch resolving `::Frozen == True` - | + --> tests/ui/invalid_frozen_pyclass_borrow.rs:33:11 + | + 33 | class.get(); + | ^^^ type mismatch resolving `::Frozen == True` + | note: expected this to be `True` - --> tests/ui/invalid_frozen_pyclass_borrow.rs:18:1 - | -18 | #[pyclass(subclass)] - | ^^^^^^^^^^^^^^^^^^^^ + --> tests/ui/invalid_frozen_pyclass_borrow.rs:21:1 + | + 21 | #[pyclass(subclass)] + | ^^^^^^^^^^^^^^^^^^^^ note: required by a bound in `pyo3::Py::::get` - --> src/instance.rs - | - | pub fn get(&self) -> &T - | --- required by a bound in this associated function - | where - | T: PyClass + Sync, - | ^^^^^^^^^^^^^ required by this bound in `Py::::get` - = note: this error originates in the attribute macro `pyclass` (in Nightly builds, run with -Z macro-backtrace for more info) + --> src/instance.rs:1713:20 + | +1711 | pub fn get(&self) -> &T + | --- required by a bound in this associated function +1712 | where +1713 | T: PyClass + Sync, + | ^^^^^^^^^^^^^ required by this bound in `Py::::get` + = note: this error originates in the attribute macro `pyclass` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0271]: type mismatch resolving `::Frozen == True` - --> tests/ui/invalid_frozen_pyclass_borrow.rs:33:11 - | -33 | class.get(); - | ^^^ type mismatch resolving `::Frozen == True` - | + --> tests/ui/invalid_frozen_pyclass_borrow.rs:38:11 + | + 38 | class.get(); + | ^^^ type mismatch resolving `::Frozen == True` + | note: expected this to be `True` - --> tests/ui/invalid_frozen_pyclass_borrow.rs:18:1 - | -18 | #[pyclass(subclass)] - | ^^^^^^^^^^^^^^^^^^^^ + --> tests/ui/invalid_frozen_pyclass_borrow.rs:21:1 + | + 21 | #[pyclass(subclass)] + | ^^^^^^^^^^^^^^^^^^^^ note: required by a bound in `pyo3::Bound::<'py, T>::get` - --> src/instance.rs - | - | pub fn get(&self) -> &T - | --- required by a bound in this associated function - | where - | T: PyClass + Sync, - | ^^^^^^^^^^^^^ required by this bound in `Bound::<'py, T>::get` - = note: this error originates in the attribute macro `pyclass` (in Nightly builds, run with -Z macro-backtrace for more info) + --> src/instance.rs:647:20 + | +645 | pub fn get(&self) -> &T + | --- required by a bound in this associated function +646 | where +647 | T: PyClass + Sync, + | ^^^^^^^^^^^^^ required by this bound in `Bound::<'py, T>::get` + = note: this error originates in the attribute macro `pyclass` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 7 previous errors + +For more information about this error, try `rustc --explain E0271`. diff --git a/tests/ui/invalid_intern_arg.rs b/tests/ui/invalid_intern_arg.rs index a90dbdd351a..7c4ca90e123 100644 --- a/tests/ui/invalid_intern_arg.rs +++ b/tests/ui/invalid_intern_arg.rs @@ -3,4 +3,6 @@ use pyo3::Python; fn main() { let _foo = if true { "foo" } else { "bar" }; Python::attach(|py| py.import(pyo3::intern!(py, _foo)).unwrap()); +//~^ ERROR: attempt to use a non-constant value in a constant +//~| ERROR: lifetime may not live long enough } diff --git a/tests/ui/invalid_intern_arg.stderr b/tests/ui/invalid_intern_arg.stderr index eabbc058948..e2e4f697b42 100644 --- a/tests/ui/invalid_intern_arg.stderr +++ b/tests/ui/invalid_intern_arg.stderr @@ -1,15 +1,15 @@ error[E0435]: attempt to use a non-constant value in a constant - --> tests/ui/invalid_intern_arg.rs:5:53 - | -5 | Python::attach(|py| py.import(pyo3::intern!(py, _foo)).unwrap()); - | ^^^^ non-constant value - | + --> tests/ui/invalid_intern_arg.rs:5:53 + | + 5 | Python::attach(|py| py.import(pyo3::intern!(py, _foo)).unwrap()); + | ^^^^ non-constant value + | help: consider using `let` instead of `static` - --> src/sync.rs - | - - static INTERNED: $crate::sync::Interned = $crate::sync::Interned::new($text); - + let INTERNED: $crate::sync::Interned = $crate::sync::Interned::new($text); - | + --> src/sync.rs:232:9 + | +232 - static INTERNED: $crate::sync::Interned = $crate::sync::Interned::new($text); +232 + let INTERNED: $crate::sync::Interned = $crate::sync::Interned::new($text); + | error: lifetime may not live long enough --> tests/ui/invalid_intern_arg.rs:5:25 @@ -19,3 +19,7 @@ error: lifetime may not live long enough | | | | | return type of closure is pyo3::Bound<'2, PyModule> | has type `Python<'1>` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0435`. diff --git a/tests/ui/invalid_intopy_derive.rs b/tests/ui/invalid_intopy_derive.rs index 5d65e36bfcb..a18b5ae6c93 100644 --- a/tests/ui/invalid_intopy_derive.rs +++ b/tests/ui/invalid_intopy_derive.rs @@ -2,37 +2,45 @@ use pyo3::{IntoPyObject, IntoPyObjectRef}; #[derive(IntoPyObject, IntoPyObjectRef)] struct Foo(); +//~^ ERROR: cannot derive `IntoPyObject` for empty structs #[derive(IntoPyObject, IntoPyObjectRef)] struct Foo2 {} +//~^ ERROR: cannot derive `IntoPyObject` for empty structs #[derive(IntoPyObject, IntoPyObjectRef)] enum EmptyEnum {} +//~^ ERROR: cannot derive `IntoPyObject` for empty enum #[derive(IntoPyObject, IntoPyObjectRef)] enum EnumWithEmptyTupleVar { EmptyTuple(), +//~^ ERROR: cannot derive `IntoPyObject` for empty variants Valid(String), } #[derive(IntoPyObject, IntoPyObjectRef)] enum EnumWithEmptyStructVar { EmptyStruct {}, +//~^ ERROR: cannot derive `IntoPyObject` for empty variants Valid(String), } #[derive(IntoPyObject, IntoPyObjectRef)] #[pyo3(transparent)] struct EmptyTransparentTup(); +//~^ ERROR: cannot derive `IntoPyObject` for empty structs #[derive(IntoPyObject, IntoPyObjectRef)] #[pyo3(transparent)] struct EmptyTransparentStruct {} +//~^ ERROR: cannot derive `IntoPyObject` for empty structs #[derive(IntoPyObject, IntoPyObjectRef)] enum EnumWithTransparentEmptyTupleVar { #[pyo3(transparent)] EmptyTuple(), +//~^ ERROR: cannot derive `IntoPyObject` for empty variants Valid(String), } @@ -40,16 +48,19 @@ enum EnumWithTransparentEmptyTupleVar { enum EnumWithTransparentEmptyStructVar { #[pyo3(transparent)] EmptyStruct {}, +//~^ ERROR: cannot derive `IntoPyObject` for empty variants Valid(String), } #[derive(IntoPyObject, IntoPyObjectRef)] #[pyo3(transparent)] struct TransparentTupTooManyFields(String, String); +//~^ ERROR: transparent structs and variants can only have 1 field #[derive(IntoPyObject, IntoPyObjectRef)] #[pyo3(transparent)] struct TransparentStructTooManyFields { +//~^ ERROR: transparent structs and variants can only have 1 field foo: String, bar: String, } @@ -58,6 +69,7 @@ struct TransparentStructTooManyFields { enum EnumWithTransparentTupleTooMany { #[pyo3(transparent)] EmptyTuple(String, String), +//~^ ERROR: transparent structs and variants can only have 1 field Valid(String), } @@ -65,6 +77,7 @@ enum EnumWithTransparentTupleTooMany { enum EnumWithTransparentStructTooMany { #[pyo3(transparent)] EmptyStruct { +//~^ ERROR: transparent structs and variants can only have 1 field foo: String, bar: String, }, @@ -73,25 +86,30 @@ enum EnumWithTransparentStructTooMany { #[derive(IntoPyObject, IntoPyObjectRef)] #[pyo3(unknown = "should not work")] +//~^ ERROR: expected one of: `transparent`, `from_item_all`, `annotation`, `crate`, `rename_all` struct UnknownContainerAttr { a: String, } #[derive(IntoPyObject, IntoPyObjectRef)] union Union { +//~^ ERROR: #[derive(`IntoPyObject`)] is not supported for unions a: usize, } #[derive(IntoPyObject, IntoPyObjectRef)] enum UnitEnum { Unit, +//~^ ERROR: cannot derive `IntoPyObject` for empty variants } #[derive(IntoPyObject, IntoPyObjectRef)] struct TupleAttribute(#[pyo3(attribute)] String, usize); +//~^ ERROR: `item` and `attribute` are not permitted on tuple struct elements. #[derive(IntoPyObject, IntoPyObjectRef)] struct TupleItem(#[pyo3(item)] String, usize); +//~^ ERROR: `item` and `attribute` are not permitted on tuple struct elements. #[derive(IntoPyObject, IntoPyObjectRef)] struct StructAttribute { @@ -103,6 +121,7 @@ struct StructAttribute { #[pyo3(transparent)] struct StructTransparentItem { #[pyo3(item)] +//~^ ERROR: `transparent` structs may not have `item` nor `attribute` for the inner field foo: String, } @@ -110,6 +129,7 @@ struct StructTransparentItem { #[pyo3(transparent)] struct StructTransparentIntoPyWith { #[pyo3(into_py_with = into)] +//~^ ERROR: `into_py_with` is not permitted on `transparent` structs or variants foo: String, } @@ -117,16 +137,19 @@ struct StructTransparentIntoPyWith { #[pyo3(transparent)] struct StructTransparentIntoPyWithRef { #[pyo3(into_py_with = into_ref)] +//~^ ERROR: `into_py_with` is not permitted on `transparent` structs or variants foo: String, } #[derive(IntoPyObject)] #[pyo3(transparent)] struct TupleTransparentIntoPyWith(#[pyo3(into_py_with = into)] String); +//~^ ERROR: `into_py_with` is not permitted on `transparent` structs #[derive(IntoPyObject)] enum EnumTupleIntoPyWith { TransparentTuple(#[pyo3(into_py_with = into)] usize), +//~^ ERROR: `into_py_with` is not permitted on `transparent` structs } #[derive(IntoPyObject)] @@ -134,23 +157,27 @@ enum EnumStructIntoPyWith { #[pyo3(transparent)] TransparentStruct { #[pyo3(into_py_with = into)] +//~^ ERROR: `into_py_with` is not permitted on `transparent` structs or variants a: usize, }, } #[derive(IntoPyObject, IntoPyObjectRef)] #[pyo3(transparent, rename_all = "camelCase")] +//~^ ERROR: `rename_all` is not permitted on `transparent` structs and variants struct StructTransparentRenameAll { foo_bar: String, } #[derive(IntoPyObject, IntoPyObjectRef)] #[pyo3(rename_all = "camelCase")] +//~^ ERROR: `rename_all` is useless on tuple structs and variants. struct StructTupleRenameAll(String, usize); #[derive(IntoPyObject, IntoPyObjectRef)] enum EnumTransparentVariantRenameAll { #[pyo3(rename_all = "camelCase")] +//~^ ERROR: `rename_all` is not permitted on `transparent` structs and variants #[pyo3(transparent)] Variant { foo: String }, } @@ -158,11 +185,13 @@ enum EnumTransparentVariantRenameAll { #[derive(IntoPyObject, IntoPyObjectRef)] enum EnumTupleVariantRenameAll { #[pyo3(rename_all = "camelCase")] +//~^ ERROR: `rename_all` is useless on tuple structs and variants. Variant(String, usize), } #[derive(IntoPyObject, IntoPyObjectRef)] #[pyo3(rename_all = "camelCase")] +//~^ ERROR: `rename_all` is not supported at top level for enums enum EnumTopRenameAll { Variant { foo: String }, } diff --git a/tests/ui/invalid_intopy_derive.stderr b/tests/ui/invalid_intopy_derive.stderr index 518066f3460..38476069aaf 100644 --- a/tests/ui/invalid_intopy_derive.stderr +++ b/tests/ui/invalid_intopy_derive.stderr @@ -5,177 +5,182 @@ error: cannot derive `IntoPyObject` for empty structs | ^^ error: cannot derive `IntoPyObject` for empty structs - --> tests/ui/invalid_intopy_derive.rs:7:13 + --> tests/ui/invalid_intopy_derive.rs:8:13 | -7 | struct Foo2 {} +8 | struct Foo2 {} | ^^ error: cannot derive `IntoPyObject` for empty enum - --> tests/ui/invalid_intopy_derive.rs:10:6 + --> tests/ui/invalid_intopy_derive.rs:12:6 | -10 | enum EmptyEnum {} +12 | enum EmptyEnum {} | ^^^^^^^^^ error: cannot derive `IntoPyObject` for empty variants - --> tests/ui/invalid_intopy_derive.rs:14:5 + --> tests/ui/invalid_intopy_derive.rs:17:5 | -14 | EmptyTuple(), +17 | EmptyTuple(), | ^^^^^^^^^^ error: cannot derive `IntoPyObject` for empty variants - --> tests/ui/invalid_intopy_derive.rs:20:5 + --> tests/ui/invalid_intopy_derive.rs:24:5 | -20 | EmptyStruct {}, +24 | EmptyStruct {}, | ^^^^^^^^^^^ error: cannot derive `IntoPyObject` for empty structs - --> tests/ui/invalid_intopy_derive.rs:26:27 + --> tests/ui/invalid_intopy_derive.rs:31:27 | -26 | struct EmptyTransparentTup(); +31 | struct EmptyTransparentTup(); | ^^ error: cannot derive `IntoPyObject` for empty structs - --> tests/ui/invalid_intopy_derive.rs:30:31 + --> tests/ui/invalid_intopy_derive.rs:36:31 | -30 | struct EmptyTransparentStruct {} +36 | struct EmptyTransparentStruct {} | ^^ error: cannot derive `IntoPyObject` for empty variants - --> tests/ui/invalid_intopy_derive.rs:35:5 + --> tests/ui/invalid_intopy_derive.rs:42:5 | -35 | EmptyTuple(), +42 | EmptyTuple(), | ^^^^^^^^^^ error: cannot derive `IntoPyObject` for empty variants - --> tests/ui/invalid_intopy_derive.rs:42:5 + --> tests/ui/invalid_intopy_derive.rs:50:5 | -42 | EmptyStruct {}, +50 | EmptyStruct {}, | ^^^^^^^^^^^ error: transparent structs and variants can only have 1 field - --> tests/ui/invalid_intopy_derive.rs:48:35 + --> tests/ui/invalid_intopy_derive.rs:57:35 | -48 | struct TransparentTupTooManyFields(String, String); +57 | struct TransparentTupTooManyFields(String, String); | ^^^^^^^^^^^^^^^^ error: transparent structs and variants can only have 1 field - --> tests/ui/invalid_intopy_derive.rs:52:39 + --> tests/ui/invalid_intopy_derive.rs:62:39 | -52 | struct TransparentStructTooManyFields { +62 | struct TransparentStructTooManyFields { | _______________________________________^ -53 | | foo: String, -54 | | bar: String, -55 | | } +63 | | +64 | | foo: String, +65 | | bar: String, +66 | | } | |_^ error: transparent structs and variants can only have 1 field - --> tests/ui/invalid_intopy_derive.rs:60:15 + --> tests/ui/invalid_intopy_derive.rs:71:15 | -60 | EmptyTuple(String, String), +71 | EmptyTuple(String, String), | ^^^^^^^^^^^^^^^^ error: transparent structs and variants can only have 1 field - --> tests/ui/invalid_intopy_derive.rs:67:17 + --> tests/ui/invalid_intopy_derive.rs:79:17 | -67 | EmptyStruct { +79 | EmptyStruct { | _________________^ -68 | | foo: String, -69 | | bar: String, -70 | | }, +80 | | +81 | | foo: String, +82 | | bar: String, +83 | | }, | |_____^ error: expected one of: `transparent`, `from_item_all`, `annotation`, `crate`, `rename_all` - --> tests/ui/invalid_intopy_derive.rs:75:8 + --> tests/ui/invalid_intopy_derive.rs:88:8 | -75 | #[pyo3(unknown = "should not work")] +88 | #[pyo3(unknown = "should not work")] | ^^^^^^^ error: #[derive(`IntoPyObject`)] is not supported for unions - --> tests/ui/invalid_intopy_derive.rs:81:1 + --> tests/ui/invalid_intopy_derive.rs:95:1 | -81 | union Union { +95 | union Union { | ^^^^^ error: cannot derive `IntoPyObject` for empty variants - --> tests/ui/invalid_intopy_derive.rs:87:5 - | -87 | Unit, - | ^^^^ + --> tests/ui/invalid_intopy_derive.rs:102:5 + | +102 | Unit, + | ^^^^ error: `item` and `attribute` are not permitted on tuple struct elements. - --> tests/ui/invalid_intopy_derive.rs:91:30 - | -91 | struct TupleAttribute(#[pyo3(attribute)] String, usize); - | ^^^^^^^^^ + --> tests/ui/invalid_intopy_derive.rs:107:30 + | +107 | struct TupleAttribute(#[pyo3(attribute)] String, usize); + | ^^^^^^^^^ error: `item` and `attribute` are not permitted on tuple struct elements. - --> tests/ui/invalid_intopy_derive.rs:94:25 - | -94 | struct TupleItem(#[pyo3(item)] String, usize); - | ^^^^ + --> tests/ui/invalid_intopy_derive.rs:111:25 + | +111 | struct TupleItem(#[pyo3(item)] String, usize); + | ^^^^ error: `transparent` structs may not have `item` nor `attribute` for the inner field - --> tests/ui/invalid_intopy_derive.rs:105:12 + --> tests/ui/invalid_intopy_derive.rs:123:12 | -105 | #[pyo3(item)] +123 | #[pyo3(item)] | ^^^^ error: `into_py_with` is not permitted on `transparent` structs or variants - --> tests/ui/invalid_intopy_derive.rs:112:12 + --> tests/ui/invalid_intopy_derive.rs:131:12 | -112 | #[pyo3(into_py_with = into)] +131 | #[pyo3(into_py_with = into)] | ^^^^^^^^^^^^ error: `into_py_with` is not permitted on `transparent` structs or variants - --> tests/ui/invalid_intopy_derive.rs:119:12 + --> tests/ui/invalid_intopy_derive.rs:139:12 | -119 | #[pyo3(into_py_with = into_ref)] +139 | #[pyo3(into_py_with = into_ref)] | ^^^^^^^^^^^^ error: `into_py_with` is not permitted on `transparent` structs - --> tests/ui/invalid_intopy_derive.rs:125:42 + --> tests/ui/invalid_intopy_derive.rs:146:42 | -125 | struct TupleTransparentIntoPyWith(#[pyo3(into_py_with = into)] String); +146 | struct TupleTransparentIntoPyWith(#[pyo3(into_py_with = into)] String); | ^^^^^^^^^^^^ error: `into_py_with` is not permitted on `transparent` structs - --> tests/ui/invalid_intopy_derive.rs:129:29 + --> tests/ui/invalid_intopy_derive.rs:151:29 | -129 | TransparentTuple(#[pyo3(into_py_with = into)] usize), +151 | TransparentTuple(#[pyo3(into_py_with = into)] usize), | ^^^^^^^^^^^^ error: `into_py_with` is not permitted on `transparent` structs or variants - --> tests/ui/invalid_intopy_derive.rs:136:16 + --> tests/ui/invalid_intopy_derive.rs:159:16 | -136 | #[pyo3(into_py_with = into)] +159 | #[pyo3(into_py_with = into)] | ^^^^^^^^^^^^ error: `rename_all` is not permitted on `transparent` structs and variants - --> tests/ui/invalid_intopy_derive.rs:142:21 + --> tests/ui/invalid_intopy_derive.rs:166:21 | -142 | #[pyo3(transparent, rename_all = "camelCase")] +166 | #[pyo3(transparent, rename_all = "camelCase")] | ^^^^^^^^^^ error: `rename_all` is useless on tuple structs and variants. - --> tests/ui/invalid_intopy_derive.rs:148:8 + --> tests/ui/invalid_intopy_derive.rs:173:8 | -148 | #[pyo3(rename_all = "camelCase")] +173 | #[pyo3(rename_all = "camelCase")] | ^^^^^^^^^^ error: `rename_all` is not permitted on `transparent` structs and variants - --> tests/ui/invalid_intopy_derive.rs:153:12 + --> tests/ui/invalid_intopy_derive.rs:179:12 | -153 | #[pyo3(rename_all = "camelCase")] +179 | #[pyo3(rename_all = "camelCase")] | ^^^^^^^^^^ error: `rename_all` is useless on tuple structs and variants. - --> tests/ui/invalid_intopy_derive.rs:160:12 + --> tests/ui/invalid_intopy_derive.rs:187:12 | -160 | #[pyo3(rename_all = "camelCase")] +187 | #[pyo3(rename_all = "camelCase")] | ^^^^^^^^^^ error: `rename_all` is not supported at top level for enums - --> tests/ui/invalid_intopy_derive.rs:165:8 + --> tests/ui/invalid_intopy_derive.rs:193:8 | -165 | #[pyo3(rename_all = "camelCase")] +193 | #[pyo3(rename_all = "camelCase")] | ^^^^^^^^^^ + +error: aborting due to 29 previous errors + diff --git a/tests/ui/invalid_intopy_with.rs b/tests/ui/invalid_intopy_with.rs index 7cc910f57d8..d15d6642370 100644 --- a/tests/ui/invalid_intopy_with.rs +++ b/tests/ui/invalid_intopy_with.rs @@ -3,6 +3,8 @@ use pyo3::{IntoPyObject, IntoPyObjectRef}; #[derive(IntoPyObject, IntoPyObjectRef)] struct InvalidIntoPyWithFn { #[pyo3(into_py_with = into)] +//~^ ERROR: mismatched types +//~| ERROR: mismatched types inner: String, } diff --git a/tests/ui/invalid_intopy_with.stderr b/tests/ui/invalid_intopy_with.stderr index bfa3e6ec274..f0d6a80c250 100644 --- a/tests/ui/invalid_intopy_with.stderr +++ b/tests/ui/invalid_intopy_with.stderr @@ -7,8 +7,8 @@ error[E0308]: mismatched types 5 | #[pyo3(into_py_with = into)] | ^^^^ expected fn pointer, found fn item | - = note: expected fn pointer `for<'a> fn(Cow<'a, _>, Python<'py>) -> Result, PyErr>` - found fn item `for<'a> fn(String, Python<'a>) -> Result, PyErr> {into}` + = note: expected fn pointer `for<'a> fn(Cow<'a, _>, Python<'py>) -> Result, _>` + found fn item `for<'a> fn(String, Python<'a>) -> Result, _> {into}` error[E0308]: mismatched types --> tests/ui/invalid_intopy_with.rs:5:27 @@ -19,5 +19,9 @@ error[E0308]: mismatched types 5 | #[pyo3(into_py_with = into)] | ^^^^ expected fn pointer, found fn item | - = note: expected fn pointer `for<'a> fn(Cow<'a, _>, Python<'py>) -> Result, PyErr>` - found fn item `for<'a> fn(String, Python<'a>) -> Result, PyErr> {into}` + = note: expected fn pointer `for<'a> fn(Cow<'a, _>, Python<'py>) -> Result, _>` + found fn item `for<'a> fn(String, Python<'a>) -> Result, _> {into}` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/invalid_property_args.rs b/tests/ui/invalid_property_args.rs index f35367df7aa..0560ef3ae81 100644 --- a/tests/ui/invalid_property_args.rs +++ b/tests/ui/invalid_property_args.rs @@ -7,6 +7,7 @@ struct ClassWithGetter {} impl ClassWithGetter { #[getter] fn getter_with_arg(&self, _py: Python<'_>, _index: u32) {} +//~^ ERROR: getter function can only have one argument (of type pyo3::Python) } #[pyclass] @@ -16,33 +17,41 @@ struct ClassWithSetter {} impl ClassWithSetter { #[setter] fn setter_with_no_arg(&mut self, _py: Python<'_>) {} +//~^ ERROR: setter function expected to have one argument } #[pymethods] impl ClassWithSetter { #[setter] fn setter_with_too_many_args(&mut self, _py: Python<'_>, _foo: u32, _bar: u32) {} +//~^ ERROR: setter function can have at most two arguments ([pyo3::Python,] and value) } #[pyclass] struct TupleGetterSetterNoName(#[pyo3(get, set)] i32); +//~^ ERROR: `get` and `set` with tuple struct fields require `name` #[pyclass] struct MultipleGet(#[pyo3(get, get)] i32); +//~^ ERROR: `get` may only be specified once #[pyclass] struct MultipleSet(#[pyo3(set, set)] i32); +//~^ ERROR: `set` may only be specified once #[pyclass] struct MultipleName(#[pyo3(name = "foo", name = "bar")] i32); +//~^ ERROR: `name` may only be specified once #[pyclass] struct NameWithoutGetSet(#[pyo3(name = "value")] i32); +//~^ ERROR: `name` is useless without `get` or `set` #[pyclass] struct InvalidGetterType { #[pyo3(get)] value: ::std::marker::PhantomData, +//~^ ERROR: `PhantomData` cannot be converted to a Python object } fn main() {} diff --git a/tests/ui/invalid_property_args.stderr b/tests/ui/invalid_property_args.stderr index 223003f11bb..45df8dd1181 100644 --- a/tests/ui/invalid_property_args.stderr +++ b/tests/ui/invalid_property_args.stderr @@ -5,71 +5,75 @@ error: getter function can only have one argument (of type pyo3::Python) | ^^^ error: setter function expected to have one argument - --> tests/ui/invalid_property_args.rs:18:8 + --> tests/ui/invalid_property_args.rs:19:8 | -18 | fn setter_with_no_arg(&mut self, _py: Python<'_>) {} +19 | fn setter_with_no_arg(&mut self, _py: Python<'_>) {} | ^^^^^^^^^^^^^^^^^^ error: setter function can have at most two arguments ([pyo3::Python,] and value) - --> tests/ui/invalid_property_args.rs:24:79 + --> tests/ui/invalid_property_args.rs:26:79 | -24 | fn setter_with_too_many_args(&mut self, _py: Python<'_>, _foo: u32, _bar: u32) {} +26 | fn setter_with_too_many_args(&mut self, _py: Python<'_>, _foo: u32, _bar: u32) {} | ^^^ error: `get` and `set` with tuple struct fields require `name` - --> tests/ui/invalid_property_args.rs:28:50 + --> tests/ui/invalid_property_args.rs:31:50 | -28 | struct TupleGetterSetterNoName(#[pyo3(get, set)] i32); +31 | struct TupleGetterSetterNoName(#[pyo3(get, set)] i32); | ^^^ error: `get` may only be specified once - --> tests/ui/invalid_property_args.rs:31:32 + --> tests/ui/invalid_property_args.rs:35:32 | -31 | struct MultipleGet(#[pyo3(get, get)] i32); +35 | struct MultipleGet(#[pyo3(get, get)] i32); | ^^^ error: `set` may only be specified once - --> tests/ui/invalid_property_args.rs:34:32 + --> tests/ui/invalid_property_args.rs:39:32 | -34 | struct MultipleSet(#[pyo3(set, set)] i32); +39 | struct MultipleSet(#[pyo3(set, set)] i32); | ^^^ error: `name` may only be specified once - --> tests/ui/invalid_property_args.rs:37:42 + --> tests/ui/invalid_property_args.rs:43:42 | -37 | struct MultipleName(#[pyo3(name = "foo", name = "bar")] i32); +43 | struct MultipleName(#[pyo3(name = "foo", name = "bar")] i32); | ^^^^ error: `name` is useless without `get` or `set` - --> tests/ui/invalid_property_args.rs:40:33 + --> tests/ui/invalid_property_args.rs:47:33 | -40 | struct NameWithoutGetSet(#[pyo3(name = "value")] i32); +47 | struct NameWithoutGetSet(#[pyo3(name = "value")] i32); | ^^^^^^^^^^^^^^ error[E0277]: `PhantomData` cannot be converted to a Python object - --> tests/ui/invalid_property_args.rs:45:12 - | -45 | value: ::std::marker::PhantomData, - | ^ required by `#[pyo3(get)]` to create a readable property from a field of type `PhantomData` - | - = help: the trait `IntoPyObject<'_>` is not implemented for `PhantomData` - = note: implement `IntoPyObject` for `&PhantomData` or `IntoPyObject + Clone` for `PhantomData` to define the conversion - = help: the following other types implement trait `IntoPyObject<'py>`: - &&'a T - &&OsStr - &&Path - &&str - &'a (T0, T1) - &'a (T0, T1, T2) - &'a (T0, T1, T2, T3) - &'a (T0, T1, T2, T3, T4) - and $N others - = note: required for `PhantomData` to implement `for<'py> PyO3GetField<'py>` + --> tests/ui/invalid_property_args.rs:53:12 + | + 53 | value: ::std::marker::PhantomData, + | ^ required by `#[pyo3(get)]` to create a readable property from a field of type `PhantomData` + | + = help: the trait `IntoPyObject<'_>` is not implemented for `PhantomData` + = note: implement `IntoPyObject` for `&PhantomData` or `IntoPyObject + Clone` for `PhantomData` to define the conversion + = help: the following other types implement trait `IntoPyObject<'py>`: + &&'a T + &&OsStr + &&Path + &&str + &'a (T0, T1) + &'a (T0, T1, T2) + &'a (T0, T1, T2, T3) + &'a (T0, T1, T2, T3, T4) + and 151 others + = note: required for `PhantomData` to implement `for<'py> PyO3GetField<'py>` note: required by a bound in `PyClassGetterGenerator::::generate` - --> src/impl_/pyclass.rs - | - | pub const fn generate(&self, name: &'static CStr, doc: Option<&'static CStr>) -> PyMethodDefType - | -------- required by a bound in this associated function + --> src/impl_/pyclass.rs:1329:26 + | +1325 | pub const fn generate(&self, name: &'static CStr, doc: Option<&'static CStr>) -> PyMethodDefType + | -------- required by a bound in this associated function ... - | for<'py> FieldT: PyO3GetField<'py>, - | ^^^^^^^^^^^^^^^^^ required by this bound in `PyClassGetterGenerator::::generate` +1329 | for<'py> FieldT: PyO3GetField<'py>, + | ^^^^^^^^^^^^^^^^^ required by this bound in `PyClassGetterGenerator::::generate` + +error: aborting due to 9 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/invalid_proto_pymethods.rs b/tests/ui/invalid_proto_pymethods.rs index c40790c3168..aa4fff2c380 100644 --- a/tests/ui/invalid_proto_pymethods.rs +++ b/tests/ui/invalid_proto_pymethods.rs @@ -17,6 +17,7 @@ struct MyClass {} impl MyClass { #[pyo3(name = "__truediv__")] fn truediv_expects_one_argument(&self) -> PyResult<()> { +//~^ ERROR: Expected 1 arguments, got 0 Ok(()) } } @@ -25,6 +26,7 @@ impl MyClass { impl MyClass { #[pyo3(name = "__truediv__")] fn truediv_expects_one_argument_py(&self, _py: Python<'_>) -> PyResult<()> { +//~^ ERROR: Expected 1 arguments, got 0 Ok(()) } } @@ -36,6 +38,7 @@ impl MyClass { #[pymethods] impl MyClass { #[pyo3(name = "__bool__", signature = ())] +//~^ ERROR: `signature` cannot be used with magic method `__bool__` fn signature_is_forbidden(&self) -> bool { true } @@ -44,6 +47,7 @@ impl MyClass { #[pymethods] impl MyClass { #[pyo3(name = "__bool__", text_signature = "")] +//~^ ERROR: `text_signature` cannot be used with magic method `__bool__` fn text_signature_is_forbidden(&self) -> bool { true } @@ -53,6 +57,9 @@ impl MyClass { struct EqAndRichcmp; #[pymethods] +//~^ ERROR: duplicate definitions with name `__pymethod___richcmp____` +//~| ERROR: multiple applicable items in scope +//~| ERROR: multiple applicable items in scope impl EqAndRichcmp { fn __eq__(&self, _other: &Self) -> bool { true diff --git a/tests/ui/invalid_proto_pymethods.stderr b/tests/ui/invalid_proto_pymethods.stderr index feec5192ed2..b8ee7b33d4e 100644 --- a/tests/ui/invalid_proto_pymethods.stderr +++ b/tests/ui/invalid_proto_pymethods.stderr @@ -5,27 +5,27 @@ error: Expected 1 arguments, got 0 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: Expected 1 arguments, got 0 - --> tests/ui/invalid_proto_pymethods.rs:27:8 + --> tests/ui/invalid_proto_pymethods.rs:28:8 | -27 | fn truediv_expects_one_argument_py(&self, _py: Python<'_>) -> PyResult<()> { +28 | fn truediv_expects_one_argument_py(&self, _py: Python<'_>) -> PyResult<()> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: `signature` cannot be used with magic method `__bool__` - --> tests/ui/invalid_proto_pymethods.rs:38:31 + --> tests/ui/invalid_proto_pymethods.rs:40:31 | -38 | #[pyo3(name = "__bool__", signature = ())] +40 | #[pyo3(name = "__bool__", signature = ())] | ^^^^^^^^^ error: `text_signature` cannot be used with magic method `__bool__` - --> tests/ui/invalid_proto_pymethods.rs:46:31 + --> tests/ui/invalid_proto_pymethods.rs:49:31 | -46 | #[pyo3(name = "__bool__", text_signature = "")] +49 | #[pyo3(name = "__bool__", text_signature = "")] | ^^^^^^^^^^^^^^ error[E0592]: duplicate definitions with name `__pymethod___richcmp____` - --> tests/ui/invalid_proto_pymethods.rs:55:1 + --> tests/ui/invalid_proto_pymethods.rs:59:1 | -55 | #[pymethods] +59 | #[pymethods] | ^^^^^^^^^^^^ | | | duplicate definitions for `__pymethod___richcmp____` @@ -34,37 +34,42 @@ error[E0592]: duplicate definitions with name `__pymethod___richcmp____` = note: this error originates in the macro `::pyo3::impl_::pyclass::generate_pyclass_richcompare_slot` which comes from the expansion of the attribute macro `pymethods` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0034]: multiple applicable items in scope - --> tests/ui/invalid_proto_pymethods.rs:55:1 + --> tests/ui/invalid_proto_pymethods.rs:59:1 | -55 | #[pymethods] +59 | #[pymethods] | ^^^^^^^^^^^^ multiple `__pymethod___richcmp____` found | note: candidate #1 is defined in an impl for the type `EqAndRichcmp` - --> tests/ui/invalid_proto_pymethods.rs:55:1 + --> tests/ui/invalid_proto_pymethods.rs:59:1 | -55 | #[pymethods] +59 | #[pymethods] | ^^^^^^^^^^^^ note: candidate #2 is defined in an impl for the type `EqAndRichcmp` - --> tests/ui/invalid_proto_pymethods.rs:55:1 + --> tests/ui/invalid_proto_pymethods.rs:59:1 | -55 | #[pymethods] +59 | #[pymethods] | ^^^^^^^^^^^^ = note: this error originates in the attribute macro `pymethods` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0034]: multiple applicable items in scope - --> tests/ui/invalid_proto_pymethods.rs:55:1 + --> tests/ui/invalid_proto_pymethods.rs:59:1 | -55 | #[pymethods] +59 | #[pymethods] | ^^^^^^^^^^^^ multiple `__pymethod___richcmp____` found | note: candidate #1 is defined in an impl for the type `EqAndRichcmp` - --> tests/ui/invalid_proto_pymethods.rs:55:1 + --> tests/ui/invalid_proto_pymethods.rs:59:1 | -55 | #[pymethods] +59 | #[pymethods] | ^^^^^^^^^^^^ note: candidate #2 is defined in an impl for the type `EqAndRichcmp` - --> tests/ui/invalid_proto_pymethods.rs:55:1 + --> tests/ui/invalid_proto_pymethods.rs:59:1 | -55 | #[pymethods] +59 | #[pymethods] | ^^^^^^^^^^^^ = note: this error originates in the macro `::pyo3::impl_::pyclass::generate_pyclass_richcompare_slot` which comes from the expansion of the attribute macro `pymethods` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 7 previous errors + +Some errors have detailed explanations: E0034, E0592. +For more information about an error, try `rustc --explain E0034`. diff --git a/tests/ui/invalid_pycallargs.rs b/tests/ui/invalid_pycallargs.rs index e3af53d29c2..7feef5205c1 100644 --- a/tests/ui/invalid_pycallargs.rs +++ b/tests/ui/invalid_pycallargs.rs @@ -1,8 +1,9 @@ -use pyo3::prelude::*; - -fn main() { - Python::attach(|py| { - let any = py.None().into_bound(py); - any.call1("foo"); - }) -} +use pyo3::prelude::*; + +fn main() { + Python::attach(|py| { + let any = py.None().into_bound(py); + any.call1("foo"); +//~^ ERROR: `&str` cannot used as a Python `call` argument + }) +} diff --git a/tests/ui/invalid_pycallargs.stderr b/tests/ui/invalid_pycallargs.stderr index 3cd4410f6e9..15315d13f4e 100644 --- a/tests/ui/invalid_pycallargs.stderr +++ b/tests/ui/invalid_pycallargs.stderr @@ -1,33 +1,37 @@ error[E0277]: `&str` cannot used as a Python `call` argument - --> tests/ui/invalid_pycallargs.rs:6:19 - | -6 | any.call1("foo"); - | ----- ^^^^^ the trait `PyCallArgs<'_>` is not implemented for `&str` - | | - | required by a bound introduced by this call - | - = note: `PyCallArgs` is implemented for Rust tuples, `Bound<'py, PyTuple>` and `Py` - = note: if your type is convertible to `PyTuple` via `IntoPyObject`, call `.into_pyobject(py)` manually - = note: if you meant to pass the type as a single argument, wrap it in a 1-tuple, `(,)` - = help: the following other types implement trait `PyCallArgs<'py>`: - &'a (T0, T1) - &'a (T0, T1, T2) - &'a (T0, T1, T2, T3) - &'a (T0, T1, T2, T3, T4) - &'a (T0, T1, T2, T3, T4, T5) - &'a (T0, T1, T2, T3, T4, T5, T6) - &'a (T0, T1, T2, T3, T4, T5, T6, T7) - &'a (T0, T1, T2, T3, T4, T5, T6, T7, T8) - and $N others + --> tests/ui/invalid_pycallargs.rs:6:19 + | + 6 | any.call1("foo"); + | ----- ^^^^^ the trait `PyCallArgs<'_>` is not implemented for `&str` + | | + | required by a bound introduced by this call + | + = note: `PyCallArgs` is implemented for Rust tuples, `Bound<'py, PyTuple>` and `Py` + = note: if your type is convertible to `PyTuple` via `IntoPyObject`, call `.into_pyobject(py)` manually + = note: if you meant to pass the type as a single argument, wrap it in a 1-tuple, `(,)` + = help: the following other types implement trait `PyCallArgs<'py>`: + &'a (T0, T1) + &'a (T0, T1, T2) + &'a (T0, T1, T2, T3) + &'a (T0, T1, T2, T3, T4) + &'a (T0, T1, T2, T3, T4, T5) + &'a (T0, T1, T2, T3, T4, T5, T6) + &'a (T0, T1, T2, T3, T4, T5, T6, T7) + &'a (T0, T1, T2, T3, T4, T5, T6, T7, T8) + and 22 others note: required by a bound in `call1` - --> src/types/any.rs - | - | fn call1(&self, args: A) -> PyResult> - | ----- required by a bound in this associated function - | where - | A: PyCallArgs<'py>; - | ^^^^^^^^^^^^^^^ required by this bound in `PyAnyMethods::call1` + --> src/types/any.rs:533:12 + | +531 | fn call1(&self, args: A) -> PyResult> + | ----- required by a bound in this associated function +532 | where +533 | A: PyCallArgs<'py>; + | ^^^^^^^^^^^^^^^ required by this bound in `PyAnyMethods::call1` help: use a unary tuple instead - | -6 | any.call1(("foo",)); - | + ++ + | + 6 | any.call1(("foo",)); + | + ++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/invalid_pyclass_args.rs b/tests/ui/invalid_pyclass_args.rs index 49af59b070d..bade9d035f0 100644 --- a/tests/ui/invalid_pyclass_args.rs +++ b/tests/ui/invalid_pyclass_args.rs @@ -2,43 +2,58 @@ use pyo3::prelude::*; use std::fmt::{Display, Formatter}; #[pyclass(extend=pyo3::types::PyDict)] +//~^ ERROR: expected one of: `crate`, `dict`, `eq`, `eq_int`, `extends`, `freelist`, `frozen`, `get_all`, `hash`, `immutable_type`, `mapping`, `module`, `name`, `ord`, `rename_all`, `sequence`, `set_all`, `new`, `str`, `subclass`, `unsendable`, `weakref`, `generic`, `from_py_object`, `skip_from_py_object` struct TypoIntheKey {} #[pyclass(extends = "PyDict")] +//~^ ERROR: expected identifier struct InvalidExtends {} #[pyclass(name = m::MyClass)] +//~^ ERROR: expected string literal struct InvalidName {} #[pyclass(name = "Custom Name")] +//~^ ERROR: expected a single identifier in double quotes struct InvalidName2 {} #[pyclass(name = CustomName)] +//~^ ERROR: expected string literal struct DeprecatedName {} #[pyclass(rename_all = camelCase)] +//~^ ERROR: expected string literal struct InvalidRenamingRule {} #[pyclass(rename_all = "Camel-Case")] +//~^ ERROR: expected a valid renaming rule, possible values are: "camelCase", "kebab-case", "lowercase", "PascalCase", "SCREAMING-KEBAB-CASE", "SCREAMING_SNAKE_CASE", "snake_case", "UPPERCASE" struct InvalidRenamingRule2 {} #[pyclass(module = my_module)] +//~^ ERROR: expected string literal struct InvalidModule {} #[pyclass(weakrev)] +//~^ ERROR: expected one of: `crate`, `dict`, `eq`, `eq_int`, `extends`, `freelist`, `frozen`, `get_all`, `hash`, `immutable_type`, `mapping`, `module`, `name`, `ord`, `rename_all`, `sequence`, `set_all`, `new`, `str`, `subclass`, `unsendable`, `weakref`, `generic`, `from_py_object`, `skip_from_py_object` struct InvalidArg {} #[pyclass(mapping, sequence)] struct CannotBeMappingAndSequence {} +//~^ ERROR: a `#[pyclass]` cannot be both a `mapping` and a `sequence` #[pyclass(eq)] +//~^ ERROR: binary operation `==` cannot be applied to type `&EqOptRequiresEq` +//~| ERROR: binary operation `!=` cannot be applied to type `&EqOptRequiresEq` struct EqOptRequiresEq {} #[pyclass(eq)] +//~^ ERROR: duplicate definitions with name `__pymethod___richcmp____` +//~| ERROR: multiple applicable items in scope #[derive(PartialEq)] struct EqOptAndManualRichCmp {} #[pymethods] +//~^ ERROR: multiple applicable items in scope impl EqOptAndManualRichCmp { fn __richcmp__( &self, @@ -51,21 +66,28 @@ impl EqOptAndManualRichCmp { } #[pyclass(eq_int)] +//~^ ERROR: `eq_int` can only be used on simple enums. struct NoEqInt {} #[pyclass(frozen, eq, hash)] +//~^ ERROR: the trait bound `HashOptRequiresHash: Hash` is not satisfied #[derive(PartialEq)] struct HashOptRequiresHash; #[pyclass(hash)] +//~^ ERROR: The `hash` option requires the `frozen` option. +//~| ERROR: The `hash` option requires the `eq` option. #[derive(Hash)] struct HashWithoutFrozenAndEq; #[pyclass(frozen, eq, hash)] +//~^ ERROR: duplicate definitions with name `__pymethod___hash____` +//~| ERROR: multiple applicable items in scope #[derive(PartialEq, Hash)] struct HashOptAndManualHash {} #[pymethods] +//~^ ERROR: multiple applicable items in scope impl HashOptAndManualHash { fn __hash__(&self) -> u64 { todo!() @@ -73,6 +95,7 @@ impl HashOptAndManualHash { } #[pyclass(ord)] +//~^ ERROR: The `ord` option requires the `eq` option. struct InvalidOrderedStruct { inner: i32, } @@ -80,13 +103,18 @@ struct InvalidOrderedStruct { #[pyclass] struct MultipleErrors { #[pyo3(foo)] +//~^ ERROR: expected one of: `get`, `set`, `name` #[pyo3(blah)] +//~^ ERROR: expected one of: `get`, `set`, `name` x: i32, #[pyo3(pop)] +//~^ ERROR: expected one of: `get`, `set`, `name` y: i32, } #[pyclass(str)] +//~^ ERROR: duplicate definitions with name `__pymethod___str____` +//~| ERROR: multiple applicable items in scope struct StrOptAndManualStr {} impl Display for StrOptAndManualStr { @@ -96,6 +124,7 @@ impl Display for StrOptAndManualStr { } #[pymethods] +//~^ ERROR: multiple applicable items in scope impl StrOptAndManualStr { fn __str__(&self) -> String { todo!() @@ -103,14 +132,17 @@ impl StrOptAndManualStr { } #[pyclass(str = "{")] +//~^ ERROR: invalid format string: expected `}` but string was terminated #[derive(PartialEq)] struct Coord(u32, u32, u32); #[pyclass(str = "{$}")] +//~^ ERROR: invalid format string: expected `}`, found `$` #[derive(PartialEq)] struct Coord2(u32, u32, u32); #[pyclass(str = "X: {aaaa}, Y: {y}, Z: {z}", skip_from_py_object)] +//~^ ERROR: no field `aaaa` on type `&Point` #[derive(PartialEq, Eq, Clone, PartialOrd)] pub struct Point { x: i32, @@ -119,6 +151,7 @@ pub struct Point { } #[pyclass(str = "X: {x}, Y: {y}}}, Z: {zzz}", skip_from_py_object)] +//~^ ERROR: no field `zzz` on type `&Point2` #[derive(PartialEq, Eq, Clone, PartialOrd)] pub struct Point2 { x: i32, @@ -127,27 +160,32 @@ pub struct Point2 { } #[pyclass(str = "{0}, {162543}, {2}")] +//~^ ERROR: no field `162543` on type `&Coord3` #[derive(PartialEq)] struct Coord3(u32, u32, u32); #[pyclass(name = "aaa", str = "unsafe: {unsafe_variable}")] +//~^ ERROR: The format string syntax is incompatible with any renaming via `name` or `rename_all` struct StructRenamingWithStrFormatter { #[pyo3(name = "unsafe", get, set)] unsafe_variable: usize, } #[pyclass(name = "aaa", str = "unsafe: {unsafe_variable}")] +//~^ ERROR: The format string syntax is incompatible with any renaming via `name` or `rename_all` struct StructRenamingWithStrFormatter2 { unsafe_variable: usize, } #[pyclass(str = "unsafe: {unsafe_variable}")] +//~^ ERROR: The format string syntax is incompatible with any renaming via `name` or `rename_all` struct StructRenamingWithStrFormatter3 { #[pyo3(name = "unsafe", get, set)] unsafe_variable: usize, } #[pyclass(rename_all = "SCREAMING_SNAKE_CASE", str = "{a_a}, {b_b}, {c_d_e}")] +//~^ ERROR: The format string syntax is incompatible with any renaming via `name` or `rename_all` struct RenameAllVariantsStruct { a_a: u32, b_b: u32, @@ -155,6 +193,7 @@ struct RenameAllVariantsStruct { } #[pyclass(str = "{:?}")] +//~^ ERROR: No member found, you must provide a named or positionally specified member. #[derive(Debug)] struct StructWithNoMember { a: String, @@ -162,6 +201,7 @@ struct StructWithNoMember { } #[pyclass(str = "{}")] +//~^ ERROR: No member found, you must provide a named or positionally specified member. #[derive(Debug)] struct StructWithNoMember2 { a: String, @@ -169,6 +209,7 @@ struct StructWithNoMember2 { } #[pyclass(eq, str = "Stuff...")] +//~^ ERROR: The format string syntax cannot be used with enums #[derive(Debug, PartialEq)] pub enum MyEnumInvalidStrFmt { Variant, @@ -182,12 +223,14 @@ impl Display for MyEnumInvalidStrFmt { } #[pyclass(from_py_object, skip_from_py_object)] +//~^ ERROR: `skip_from_py_object` and `from_py_object` are mutually exclusive struct StructTooManyFromPyObject { a: String, b: String, } #[pyclass(from_py_object)] +//~^ ERROR: the trait bound `StructFromPyObjectNoClone: Clone` is not satisfied struct StructFromPyObjectNoClone { a: String, b: String, @@ -203,14 +246,21 @@ struct StructImplicitFromPyObjectDeprecated { #[pyclass(new = "from_fields")] struct NonPythonField { field: Box, +//~^ ERROR: `Box` cannot be used as a Python function argument +//~| ERROR: `Box` cannot be used as a Python function argument +//~| ERROR: the trait bound `dyn std::error::Error + Send + Sync: Clone` is not satisfied } #[pyclass(new = "from_fields")] +//~^ ERROR: conflicting implementations of trait `PyClassNewTextSignature` for type `NewFromFieldsWithManualNew` +//~| ERROR: duplicate definitions with name `__pymethod___new____` +//~| ERROR: multiple applicable items in scope struct NewFromFieldsWithManualNew { field: i32, } #[pymethods] +//~^ ERROR: multiple applicable items in scope impl NewFromFieldsWithManualNew { #[new] fn new(field: i32) -> Self { diff --git a/tests/ui/invalid_pyclass_args.stderr b/tests/ui/invalid_pyclass_args.stderr index f63db6926dd..98a852102c0 100644 --- a/tests/ui/invalid_pyclass_args.stderr +++ b/tests/ui/invalid_pyclass_args.stderr @@ -5,105 +5,105 @@ error: expected one of: `crate`, `dict`, `eq`, `eq_int`, `extends`, `freelist`, | ^^^^^^ error: expected identifier - --> tests/ui/invalid_pyclass_args.rs:7:21 + --> tests/ui/invalid_pyclass_args.rs:8:21 | -7 | #[pyclass(extends = "PyDict")] +8 | #[pyclass(extends = "PyDict")] | ^^^^^^^^ error: expected string literal - --> tests/ui/invalid_pyclass_args.rs:10:18 + --> tests/ui/invalid_pyclass_args.rs:12:18 | -10 | #[pyclass(name = m::MyClass)] +12 | #[pyclass(name = m::MyClass)] | ^ error: expected a single identifier in double quotes - --> tests/ui/invalid_pyclass_args.rs:13:18 + --> tests/ui/invalid_pyclass_args.rs:16:18 | -13 | #[pyclass(name = "Custom Name")] +16 | #[pyclass(name = "Custom Name")] | ^^^^^^^^^^^^^ error: expected string literal - --> tests/ui/invalid_pyclass_args.rs:16:18 + --> tests/ui/invalid_pyclass_args.rs:20:18 | -16 | #[pyclass(name = CustomName)] +20 | #[pyclass(name = CustomName)] | ^^^^^^^^^^ error: expected string literal - --> tests/ui/invalid_pyclass_args.rs:19:24 + --> tests/ui/invalid_pyclass_args.rs:24:24 | -19 | #[pyclass(rename_all = camelCase)] +24 | #[pyclass(rename_all = camelCase)] | ^^^^^^^^^ error: expected a valid renaming rule, possible values are: "camelCase", "kebab-case", "lowercase", "PascalCase", "SCREAMING-KEBAB-CASE", "SCREAMING_SNAKE_CASE", "snake_case", "UPPERCASE" - --> tests/ui/invalid_pyclass_args.rs:22:24 + --> tests/ui/invalid_pyclass_args.rs:28:24 | -22 | #[pyclass(rename_all = "Camel-Case")] +28 | #[pyclass(rename_all = "Camel-Case")] | ^^^^^^^^^^^^ error: expected string literal - --> tests/ui/invalid_pyclass_args.rs:25:20 + --> tests/ui/invalid_pyclass_args.rs:32:20 | -25 | #[pyclass(module = my_module)] +32 | #[pyclass(module = my_module)] | ^^^^^^^^^ error: expected one of: `crate`, `dict`, `eq`, `eq_int`, `extends`, `freelist`, `frozen`, `get_all`, `hash`, `immutable_type`, `mapping`, `module`, `name`, `ord`, `rename_all`, `sequence`, `set_all`, `new`, `str`, `subclass`, `unsendable`, `weakref`, `generic`, `from_py_object`, `skip_from_py_object` - --> tests/ui/invalid_pyclass_args.rs:28:11 + --> tests/ui/invalid_pyclass_args.rs:36:11 | -28 | #[pyclass(weakrev)] +36 | #[pyclass(weakrev)] | ^^^^^^^ error: a `#[pyclass]` cannot be both a `mapping` and a `sequence` - --> tests/ui/invalid_pyclass_args.rs:32:8 + --> tests/ui/invalid_pyclass_args.rs:41:8 | -32 | struct CannotBeMappingAndSequence {} +41 | struct CannotBeMappingAndSequence {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: `eq_int` can only be used on simple enums. - --> tests/ui/invalid_pyclass_args.rs:53:11 + --> tests/ui/invalid_pyclass_args.rs:68:11 | -53 | #[pyclass(eq_int)] +68 | #[pyclass(eq_int)] | ^^^^^^ error: The `hash` option requires the `frozen` option. - --> tests/ui/invalid_pyclass_args.rs:60:11 + --> tests/ui/invalid_pyclass_args.rs:77:11 | -60 | #[pyclass(hash)] +77 | #[pyclass(hash)] | ^^^^ error: The `hash` option requires the `eq` option. - --> tests/ui/invalid_pyclass_args.rs:60:11 + --> tests/ui/invalid_pyclass_args.rs:77:11 | -60 | #[pyclass(hash)] +77 | #[pyclass(hash)] | ^^^^ error: The `ord` option requires the `eq` option. - --> tests/ui/invalid_pyclass_args.rs:75:11 + --> tests/ui/invalid_pyclass_args.rs:97:11 | -75 | #[pyclass(ord)] +97 | #[pyclass(ord)] | ^^^ error: expected one of: `get`, `set`, `name` - --> tests/ui/invalid_pyclass_args.rs:82:12 - | -82 | #[pyo3(foo)] - | ^^^ + --> tests/ui/invalid_pyclass_args.rs:105:12 + | +105 | #[pyo3(foo)] + | ^^^ error: expected one of: `get`, `set`, `name` - --> tests/ui/invalid_pyclass_args.rs:83:12 - | -83 | #[pyo3(blah)] - | ^^^^ + --> tests/ui/invalid_pyclass_args.rs:107:12 + | +107 | #[pyo3(blah)] + | ^^^^ error: expected one of: `get`, `set`, `name` - --> tests/ui/invalid_pyclass_args.rs:85:12 - | -85 | #[pyo3(pop)] - | ^^^ + --> tests/ui/invalid_pyclass_args.rs:110:12 + | +110 | #[pyo3(pop)] + | ^^^ error: invalid format string: expected `}` but string was terminated - --> tests/ui/invalid_pyclass_args.rs:105:19 + --> tests/ui/invalid_pyclass_args.rs:134:19 | -105 | #[pyclass(str = "{")] +134 | #[pyclass(str = "{")] | -^ expected `}` in format string | | | because of this opening brace @@ -111,9 +111,9 @@ error: invalid format string: expected `}` but string was terminated = note: if you intended to print `{`, you can escape it using `{{` error: invalid format string: expected `}`, found `$` - --> tests/ui/invalid_pyclass_args.rs:109:19 + --> tests/ui/invalid_pyclass_args.rs:139:19 | -109 | #[pyclass(str = "{$}")] +139 | #[pyclass(str = "{$}")] | -^ expected `}` in format string | | | because of this opening brace @@ -121,346 +121,317 @@ error: invalid format string: expected `}`, found `$` = note: if you intended to print `{`, you can escape it using `{{` error: The format string syntax is incompatible with any renaming via `name` or `rename_all` - --> tests/ui/invalid_pyclass_args.rs:133:31 + --> tests/ui/invalid_pyclass_args.rs:167:31 | -133 | #[pyclass(name = "aaa", str = "unsafe: {unsafe_variable}")] +167 | #[pyclass(name = "aaa", str = "unsafe: {unsafe_variable}")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: The format string syntax is incompatible with any renaming via `name` or `rename_all` - --> tests/ui/invalid_pyclass_args.rs:139:31 + --> tests/ui/invalid_pyclass_args.rs:174:31 | -139 | #[pyclass(name = "aaa", str = "unsafe: {unsafe_variable}")] +174 | #[pyclass(name = "aaa", str = "unsafe: {unsafe_variable}")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: The format string syntax is incompatible with any renaming via `name` or `rename_all` - --> tests/ui/invalid_pyclass_args.rs:144:17 + --> tests/ui/invalid_pyclass_args.rs:180:17 | -144 | #[pyclass(str = "unsafe: {unsafe_variable}")] +180 | #[pyclass(str = "unsafe: {unsafe_variable}")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: The format string syntax is incompatible with any renaming via `name` or `rename_all` - --> tests/ui/invalid_pyclass_args.rs:150:54 + --> tests/ui/invalid_pyclass_args.rs:187:54 | -150 | #[pyclass(rename_all = "SCREAMING_SNAKE_CASE", str = "{a_a}, {b_b}, {c_d_e}")] +187 | #[pyclass(rename_all = "SCREAMING_SNAKE_CASE", str = "{a_a}, {b_b}, {c_d_e}")] | ^^^^^^^^^^^^^^^^^^^^^^^ error: No member found, you must provide a named or positionally specified member. - --> tests/ui/invalid_pyclass_args.rs:157:17 + --> tests/ui/invalid_pyclass_args.rs:195:17 | -157 | #[pyclass(str = "{:?}")] +195 | #[pyclass(str = "{:?}")] | ^^^^^^ error: No member found, you must provide a named or positionally specified member. - --> tests/ui/invalid_pyclass_args.rs:164:17 + --> tests/ui/invalid_pyclass_args.rs:203:17 | -164 | #[pyclass(str = "{}")] +203 | #[pyclass(str = "{}")] | ^^^^ error: The format string syntax cannot be used with enums - --> tests/ui/invalid_pyclass_args.rs:171:21 + --> tests/ui/invalid_pyclass_args.rs:211:21 | -171 | #[pyclass(eq, str = "Stuff...")] +211 | #[pyclass(eq, str = "Stuff...")] | ^^^^^^^^^^ error: `skip_from_py_object` and `from_py_object` are mutually exclusive - --> tests/ui/invalid_pyclass_args.rs:184:27 + --> tests/ui/invalid_pyclass_args.rs:225:27 | -184 | #[pyclass(from_py_object, skip_from_py_object)] +225 | #[pyclass(from_py_object, skip_from_py_object)] | ^^^^^^^^^^^^^^^^^^^ error[E0277]: the trait bound `StructFromPyObjectNoClone: Clone` is not satisfied - --> tests/ui/invalid_pyclass_args.rs:190:11 + --> tests/ui/invalid_pyclass_args.rs:232:11 | -190 | #[pyclass(from_py_object)] +232 | #[pyclass(from_py_object)] | ^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `StructFromPyObjectNoClone` | = help: see issue #48214 help: consider annotating `StructFromPyObjectNoClone` with `#[derive(Clone)]` | -191 + #[derive(Clone)] -192 | struct StructFromPyObjectNoClone { +234 + #[derive(Clone)] +235 | struct StructFromPyObjectNoClone { | error[E0119]: conflicting implementations of trait `PyClassNewTextSignature` for type `NewFromFieldsWithManualNew` - --> tests/ui/invalid_pyclass_args.rs:213:1 + --> tests/ui/invalid_pyclass_args.rs:262:1 | -208 | #[pyclass(new = "from_fields")] +254 | #[pyclass(new = "from_fields")] | ------------------------------- first implementation here ... -213 | #[pymethods] +262 | #[pymethods] | ^^^^^^^^^^^^ conflicting implementation for `NewFromFieldsWithManualNew` | = note: this error originates in the attribute macro `pymethods` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0277]: `Box` cannot be used as a Python function argument - --> tests/ui/invalid_pyclass_args.rs:205:12 - | -205 | field: Box, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `PyFunctionArgument<'_, '_, '_, false>` is not implemented for `Box` - | - = note: implement `FromPyObject` to enable using `Box` as a function argument - = note: `Python<'py>` is also a valid argument type to pass the Python token into `#[pyfunction]`s and `#[pymethods]` -help: the following other types implement trait `PyFunctionArgument<'a, 'holder, 'py, IMPLEMENTS_FROMPYOBJECT>` - --> src/impl_/extract_argument.rs - | - | / impl<'a, 'holder, 'py, T: 'a + 'py> PyFunctionArgument<'a, 'holder, 'py, false> - | | for &'holder Bound<'py, T> - | | where - | | T: PyTypeCheck, - | |___________________^ `&'holder pyo3::Bound<'py, T>` implements `PyFunctionArgument<'a, 'holder, 'py, false>` -... - | / impl<'a, 'holder, 'py, T> PyFunctionArgument<'a, 'holder, 'py, false> for Option - | | where - | | T: PyFunctionArgument<'a, 'holder, 'py, false>, - | |___________________________________________________^ `Option` implements `PyFunctionArgument<'a, 'holder, 'py, false>` -... - | impl<'a, 'holder, T: PyClass> PyFunctionArgument<'a, 'holder, '_, false> for &'holder T { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `&'holder T` implements `PyFunctionArgument<'a, 'holder, '_, false>` -... - | / impl<'a, 'holder, T: PyClass> PyFunctionArgument<'a, 'holder, '_, false> - | | for &'holder mut T - | |______________________^ `&'holder mut T` implements `PyFunctionArgument<'a, 'holder, '_, false>` - error[E0592]: duplicate definitions with name `__pymethod___richcmp____` - --> tests/ui/invalid_pyclass_args.rs:37:1 + --> tests/ui/invalid_pyclass_args.rs:49:1 | -37 | #[pyclass(eq)] +49 | #[pyclass(eq)] | ^^^^^^^^^^^^^^ duplicate definitions for `__pymethod___richcmp____` ... -41 | #[pymethods] +55 | #[pymethods] | ------------ other definition for `__pymethod___richcmp____` | = note: this error originates in the attribute macro `pyclass` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0592]: duplicate definitions with name `__pymethod___hash____` - --> tests/ui/invalid_pyclass_args.rs:64:1 + --> tests/ui/invalid_pyclass_args.rs:83:1 | -64 | #[pyclass(frozen, eq, hash)] +83 | #[pyclass(frozen, eq, hash)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ duplicate definitions for `__pymethod___hash____` ... -68 | #[pymethods] +89 | #[pymethods] | ------------ other definition for `__pymethod___hash____` | = note: this error originates in the attribute macro `pyclass` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0592]: duplicate definitions with name `__pymethod___str____` - --> tests/ui/invalid_pyclass_args.rs:89:1 - | -89 | #[pyclass(str)] - | ^^^^^^^^^^^^^^^ duplicate definitions for `__pymethod___str____` + --> tests/ui/invalid_pyclass_args.rs:115:1 + | +115 | #[pyclass(str)] + | ^^^^^^^^^^^^^^^ duplicate definitions for `__pymethod___str____` ... -98 | #[pymethods] - | ------------ other definition for `__pymethod___str____` - | - = note: this error originates in the attribute macro `pyclass` (in Nightly builds, run with -Z macro-backtrace for more info) +126 | #[pymethods] + | ------------ other definition for `__pymethod___str____` + | + = note: this error originates in the attribute macro `pyclass` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0592]: duplicate definitions with name `__pymethod___new____` - --> tests/ui/invalid_pyclass_args.rs:208:1 + --> tests/ui/invalid_pyclass_args.rs:254:1 | -208 | #[pyclass(new = "from_fields")] +254 | #[pyclass(new = "from_fields")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ duplicate definitions for `__pymethod___new____` ... -213 | #[pymethods] +262 | #[pymethods] | ------------ other definition for `__pymethod___new____` | = note: this error originates in the attribute macro `pyclass` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0369]: binary operation `==` cannot be applied to type `&EqOptRequiresEq` - --> tests/ui/invalid_pyclass_args.rs:34:11 + --> tests/ui/invalid_pyclass_args.rs:44:11 | -34 | #[pyclass(eq)] +44 | #[pyclass(eq)] | ^^ | note: an implementation of `PartialEq` might be missing for `EqOptRequiresEq` - --> tests/ui/invalid_pyclass_args.rs:35:1 + --> tests/ui/invalid_pyclass_args.rs:47:1 | -35 | struct EqOptRequiresEq {} +47 | struct EqOptRequiresEq {} | ^^^^^^^^^^^^^^^^^^^^^^ must implement `PartialEq` help: consider annotating `EqOptRequiresEq` with `#[derive(PartialEq)]` | -35 + #[derive(PartialEq)] -36 | struct EqOptRequiresEq {} +47 + #[derive(PartialEq)] +48 | struct EqOptRequiresEq {} | error[E0369]: binary operation `!=` cannot be applied to type `&EqOptRequiresEq` - --> tests/ui/invalid_pyclass_args.rs:34:11 + --> tests/ui/invalid_pyclass_args.rs:44:11 | -34 | #[pyclass(eq)] +44 | #[pyclass(eq)] | ^^ | note: an implementation of `PartialEq` might be missing for `EqOptRequiresEq` - --> tests/ui/invalid_pyclass_args.rs:35:1 + --> tests/ui/invalid_pyclass_args.rs:47:1 | -35 | struct EqOptRequiresEq {} +47 | struct EqOptRequiresEq {} | ^^^^^^^^^^^^^^^^^^^^^^ must implement `PartialEq` help: consider annotating `EqOptRequiresEq` with `#[derive(PartialEq)]` | -35 + #[derive(PartialEq)] -36 | struct EqOptRequiresEq {} +47 + #[derive(PartialEq)] +48 | struct EqOptRequiresEq {} | error[E0034]: multiple applicable items in scope - --> tests/ui/invalid_pyclass_args.rs:37:1 + --> tests/ui/invalid_pyclass_args.rs:49:1 | -37 | #[pyclass(eq)] +49 | #[pyclass(eq)] | ^^^^^^^^^^^^^^ multiple `__pymethod___richcmp____` found | note: candidate #1 is defined in an impl for the type `EqOptAndManualRichCmp` - --> tests/ui/invalid_pyclass_args.rs:37:1 + --> tests/ui/invalid_pyclass_args.rs:49:1 | -37 | #[pyclass(eq)] +49 | #[pyclass(eq)] | ^^^^^^^^^^^^^^ note: candidate #2 is defined in an impl for the type `EqOptAndManualRichCmp` - --> tests/ui/invalid_pyclass_args.rs:41:1 + --> tests/ui/invalid_pyclass_args.rs:55:1 | -41 | #[pymethods] +55 | #[pymethods] | ^^^^^^^^^^^^ = note: this error originates in the attribute macro `pyclass` which comes from the expansion of the attribute macro `pymethods` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0034]: multiple applicable items in scope - --> tests/ui/invalid_pyclass_args.rs:41:1 + --> tests/ui/invalid_pyclass_args.rs:55:1 | -41 | #[pymethods] +55 | #[pymethods] | ^^^^^^^^^^^^ multiple `__pymethod___richcmp____` found | note: candidate #1 is defined in an impl for the type `EqOptAndManualRichCmp` - --> tests/ui/invalid_pyclass_args.rs:37:1 + --> tests/ui/invalid_pyclass_args.rs:49:1 | -37 | #[pyclass(eq)] +49 | #[pyclass(eq)] | ^^^^^^^^^^^^^^ note: candidate #2 is defined in an impl for the type `EqOptAndManualRichCmp` - --> tests/ui/invalid_pyclass_args.rs:41:1 + --> tests/ui/invalid_pyclass_args.rs:55:1 | -41 | #[pymethods] +55 | #[pymethods] | ^^^^^^^^^^^^ = note: this error originates in the attribute macro `pymethods` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: the trait bound `HashOptRequiresHash: Hash` is not satisfied - --> tests/ui/invalid_pyclass_args.rs:56:23 + --> tests/ui/invalid_pyclass_args.rs:72:23 | -56 | #[pyclass(frozen, eq, hash)] +72 | #[pyclass(frozen, eq, hash)] | ^^^^ the trait `Hash` is not implemented for `HashOptRequiresHash` | help: consider annotating `HashOptRequiresHash` with `#[derive(Hash)]` | -58 + #[derive(Hash)] -59 | struct HashOptRequiresHash; +75 + #[derive(Hash)] +76 | struct HashOptRequiresHash; | error[E0034]: multiple applicable items in scope - --> tests/ui/invalid_pyclass_args.rs:64:1 + --> tests/ui/invalid_pyclass_args.rs:83:1 | -64 | #[pyclass(frozen, eq, hash)] +83 | #[pyclass(frozen, eq, hash)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ multiple `__pymethod___hash____` found | note: candidate #1 is defined in an impl for the type `HashOptAndManualHash` - --> tests/ui/invalid_pyclass_args.rs:64:1 + --> tests/ui/invalid_pyclass_args.rs:83:1 | -64 | #[pyclass(frozen, eq, hash)] +83 | #[pyclass(frozen, eq, hash)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: candidate #2 is defined in an impl for the type `HashOptAndManualHash` - --> tests/ui/invalid_pyclass_args.rs:68:1 + --> tests/ui/invalid_pyclass_args.rs:89:1 | -68 | #[pymethods] +89 | #[pymethods] | ^^^^^^^^^^^^ = note: this error originates in the attribute macro `pyclass` which comes from the expansion of the attribute macro `pymethods` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0034]: multiple applicable items in scope - --> tests/ui/invalid_pyclass_args.rs:68:1 + --> tests/ui/invalid_pyclass_args.rs:89:1 | -68 | #[pymethods] +89 | #[pymethods] | ^^^^^^^^^^^^ multiple `__pymethod___hash____` found | note: candidate #1 is defined in an impl for the type `HashOptAndManualHash` - --> tests/ui/invalid_pyclass_args.rs:64:1 + --> tests/ui/invalid_pyclass_args.rs:83:1 | -64 | #[pyclass(frozen, eq, hash)] +83 | #[pyclass(frozen, eq, hash)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: candidate #2 is defined in an impl for the type `HashOptAndManualHash` - --> tests/ui/invalid_pyclass_args.rs:68:1 + --> tests/ui/invalid_pyclass_args.rs:89:1 | -68 | #[pymethods] +89 | #[pymethods] | ^^^^^^^^^^^^ = note: this error originates in the attribute macro `pymethods` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0034]: multiple applicable items in scope - --> tests/ui/invalid_pyclass_args.rs:89:1 - | -89 | #[pyclass(str)] - | ^^^^^^^^^^^^^^^ multiple `__pymethod___str____` found - | + --> tests/ui/invalid_pyclass_args.rs:115:1 + | +115 | #[pyclass(str)] + | ^^^^^^^^^^^^^^^ multiple `__pymethod___str____` found + | note: candidate #1 is defined in an impl for the type `StrOptAndManualStr` - --> tests/ui/invalid_pyclass_args.rs:89:1 - | -89 | #[pyclass(str)] - | ^^^^^^^^^^^^^^^ + --> tests/ui/invalid_pyclass_args.rs:115:1 + | +115 | #[pyclass(str)] + | ^^^^^^^^^^^^^^^ note: candidate #2 is defined in an impl for the type `StrOptAndManualStr` - --> tests/ui/invalid_pyclass_args.rs:98:1 - | -98 | #[pymethods] - | ^^^^^^^^^^^^ - = note: this error originates in the attribute macro `pyclass` which comes from the expansion of the attribute macro `pymethods` (in Nightly builds, run with -Z macro-backtrace for more info) + --> tests/ui/invalid_pyclass_args.rs:126:1 + | +126 | #[pymethods] + | ^^^^^^^^^^^^ + = note: this error originates in the attribute macro `pyclass` which comes from the expansion of the attribute macro `pymethods` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0034]: multiple applicable items in scope - --> tests/ui/invalid_pyclass_args.rs:98:1 - | -98 | #[pymethods] - | ^^^^^^^^^^^^ multiple `__pymethod___str____` found - | + --> tests/ui/invalid_pyclass_args.rs:126:1 + | +126 | #[pymethods] + | ^^^^^^^^^^^^ multiple `__pymethod___str____` found + | note: candidate #1 is defined in an impl for the type `StrOptAndManualStr` - --> tests/ui/invalid_pyclass_args.rs:89:1 - | -89 | #[pyclass(str)] - | ^^^^^^^^^^^^^^^ + --> tests/ui/invalid_pyclass_args.rs:115:1 + | +115 | #[pyclass(str)] + | ^^^^^^^^^^^^^^^ note: candidate #2 is defined in an impl for the type `StrOptAndManualStr` - --> tests/ui/invalid_pyclass_args.rs:98:1 - | -98 | #[pymethods] - | ^^^^^^^^^^^^ - = note: this error originates in the attribute macro `pymethods` (in Nightly builds, run with -Z macro-backtrace for more info) + --> tests/ui/invalid_pyclass_args.rs:126:1 + | +126 | #[pymethods] + | ^^^^^^^^^^^^ + = note: this error originates in the attribute macro `pymethods` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0609]: no field `aaaa` on type `&Point` - --> tests/ui/invalid_pyclass_args.rs:113:17 + --> tests/ui/invalid_pyclass_args.rs:144:17 | -113 | #[pyclass(str = "X: {aaaa}, Y: {y}, Z: {z}", skip_from_py_object)] +144 | #[pyclass(str = "X: {aaaa}, Y: {y}, Z: {z}", skip_from_py_object)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ unknown field | = note: available fields are: `x`, `y`, `z` error[E0609]: no field `zzz` on type `&Point2` - --> tests/ui/invalid_pyclass_args.rs:121:17 + --> tests/ui/invalid_pyclass_args.rs:153:17 | -121 | #[pyclass(str = "X: {x}, Y: {y}}}, Z: {zzz}", skip_from_py_object)] +153 | #[pyclass(str = "X: {x}, Y: {y}}}, Z: {zzz}", skip_from_py_object)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unknown field | = note: available fields are: `x`, `y`, `z` error[E0609]: no field `162543` on type `&Coord3` - --> tests/ui/invalid_pyclass_args.rs:129:17 + --> tests/ui/invalid_pyclass_args.rs:162:17 | -129 | #[pyclass(str = "{0}, {162543}, {2}")] +162 | #[pyclass(str = "{0}, {162543}, {2}")] | ^^^^^^^^^^^^^^^^^^^^ unknown field | = note: available fields are: `0`, `1`, `2` warning: use of deprecated associated constant `pyo3::impl_::deprecated::HasAutomaticFromPyObject::::MSG`: The `FromPyObject` implementation for `#[pyclass]` types which implement `Clone` is changing to an opt-in option. Use `#[pyclass(from_py_object)]` to opt-in to the `FromPyObject` derive now, or `#[pyclass(skip_from_py_object)]` to skip the `FromPyObject` implementation. - --> tests/ui/invalid_pyclass_args.rs:196:1 + --> tests/ui/invalid_pyclass_args.rs:239:1 | -196 | #[pyclass] +239 | #[pyclass] | ^^^^^^^^^^ | = note: `#[warn(deprecated)]` on by default = note: this warning originates in the attribute macro `pyclass` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: `Box` cannot be used as a Python function argument - --> tests/ui/invalid_pyclass_args.rs:205:12 + --> tests/ui/invalid_pyclass_args.rs:248:12 | -205 | field: Box, - | ^^^ the trait `pyo3::PyClass` is not implemented for `Box` +248 | field: Box, + | ^^^ the trait `PyClass` is not implemented for `Box` | = note: implement `FromPyObject` to enable using `Box` as a function argument = note: `Python<'py>` is also a valid argument type to pass the Python token into `#[pyfunction]`s and `#[pymethods]` - = help: the following other types implement trait `pyo3::PyClass`: + = help: the following other types implement trait `PyClass`: Coord Coord2 Coord3 @@ -469,22 +440,22 @@ error[E0277]: `Box` cannot be used as a Pyt HashOptAndManualHash HashOptRequiresHash NewFromFieldsWithManualNew - and $N others + and 6 others = note: required for `Box` to implement `pyo3::FromPyObject<'_, '_>` = note: required for `Box` to implement `PyFunctionArgument<'_, '_, '_, true>` note: required by a bound in `extract_argument` - --> src/impl_/extract_argument.rs + --> src/impl_/extract_argument.rs:226:8 | - | pub fn extract_argument<'a, 'holder, 'py, T, const IMPLEMENTS_FROMPYOBJECT: bool>( +220 | pub fn extract_argument<'a, 'holder, 'py, T, const IMPLEMENTS_FROMPYOBJECT: bool>( | ---------------- required by a bound in this function ... - | T: PyFunctionArgument<'a, 'holder, 'py, IMPLEMENTS_FROMPYOBJECT>, +226 | T: PyFunctionArgument<'a, 'holder, 'py, IMPLEMENTS_FROMPYOBJECT>, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `extract_argument` error[E0277]: `Box` cannot be used as a Python function argument - --> tests/ui/invalid_pyclass_args.rs:205:12 + --> tests/ui/invalid_pyclass_args.rs:248:12 | -205 | field: Box, +248 | field: Box, | ^^^ the trait `ExtractPyClassWithClone` is not implemented for `Box` | = note: implement `FromPyObject` to enable using `Box` as a function argument @@ -498,88 +469,79 @@ error[E0277]: `Box` cannot be used as a Pyt HashOptAndManualHash HashOptRequiresHash NewFromFieldsWithManualNew - and $N others + and 3 others = note: required for `Box` to implement `pyo3::FromPyObject<'_, '_>` = note: required for `Box` to implement `PyFunctionArgument<'_, '_, '_, true>` note: required by a bound in `extract_argument` - --> src/impl_/extract_argument.rs + --> src/impl_/extract_argument.rs:226:8 | - | pub fn extract_argument<'a, 'holder, 'py, T, const IMPLEMENTS_FROMPYOBJECT: bool>( +220 | pub fn extract_argument<'a, 'holder, 'py, T, const IMPLEMENTS_FROMPYOBJECT: bool>( | ---------------- required by a bound in this function ... - | T: PyFunctionArgument<'a, 'holder, 'py, IMPLEMENTS_FROMPYOBJECT>, +226 | T: PyFunctionArgument<'a, 'holder, 'py, IMPLEMENTS_FROMPYOBJECT>, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `extract_argument` error[E0277]: the trait bound `dyn std::error::Error + Send + Sync: Clone` is not satisfied - --> tests/ui/invalid_pyclass_args.rs:205:12 + --> tests/ui/invalid_pyclass_args.rs:248:12 | -205 | field: Box, +248 | field: Box, | ^^^ the trait `Clone` is not implemented for `dyn std::error::Error + Send + Sync` | -help: the following other types implement trait `PyFunctionArgument<'a, 'holder, 'py, IMPLEMENTS_FROMPYOBJECT>` - --> src/impl_/extract_argument.rs - | - | / impl<'a, 'holder, 'py, T: 'a + 'py> PyFunctionArgument<'a, 'holder, 'py, false> - | | for &'holder Bound<'py, T> - | | where - | | T: PyTypeCheck, - | |___________________^ `&'holder pyo3::Bound<'py, T>` implements `PyFunctionArgument<'a, 'holder, 'py, false>` -... - | / impl<'a, 'holder, 'py, T> PyFunctionArgument<'a, 'holder, 'py, false> for Option - | | where - | | T: PyFunctionArgument<'a, 'holder, 'py, false>, - | |___________________________________________________^ `Option` implements `PyFunctionArgument<'a, 'holder, 'py, false>` -... - | impl<'a, 'holder, T: PyClass> PyFunctionArgument<'a, 'holder, '_, false> for &'holder T { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `&'holder T` implements `PyFunctionArgument<'a, 'holder, '_, false>` -... - | / impl<'a, 'holder, T: PyClass> PyFunctionArgument<'a, 'holder, '_, false> - | | for &'holder mut T - | |______________________^ `&'holder mut T` implements `PyFunctionArgument<'a, 'holder, '_, false>` + = help: the following other types implement trait `PyFunctionArgument<'a, 'holder, 'py, IMPLEMENTS_FROMPYOBJECT>`: + `&'holder T` implements `PyFunctionArgument<'a, 'holder, '_, false>` + `&'holder mut T` implements `PyFunctionArgument<'a, 'holder, '_, false>` + `&'holder pyo3::Bound<'py, T>` implements `PyFunctionArgument<'a, 'holder, 'py, false>` + `&'holder str` implements `PyFunctionArgument<'a, 'holder, 'py, false>` + `Option` implements `PyFunctionArgument<'a, 'holder, 'py, false>` = note: required for `Box` to implement `Clone` = note: required for `Box` to implement `pyo3::FromPyObject<'_, '_>` = note: required for `Box` to implement `PyFunctionArgument<'_, '_, '_, true>` note: required by a bound in `extract_argument` - --> src/impl_/extract_argument.rs + --> src/impl_/extract_argument.rs:226:8 | - | pub fn extract_argument<'a, 'holder, 'py, T, const IMPLEMENTS_FROMPYOBJECT: bool>( +220 | pub fn extract_argument<'a, 'holder, 'py, T, const IMPLEMENTS_FROMPYOBJECT: bool>( | ---------------- required by a bound in this function ... - | T: PyFunctionArgument<'a, 'holder, 'py, IMPLEMENTS_FROMPYOBJECT>, +226 | T: PyFunctionArgument<'a, 'holder, 'py, IMPLEMENTS_FROMPYOBJECT>, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `extract_argument` error[E0034]: multiple applicable items in scope - --> tests/ui/invalid_pyclass_args.rs:208:1 + --> tests/ui/invalid_pyclass_args.rs:254:1 | -208 | #[pyclass(new = "from_fields")] +254 | #[pyclass(new = "from_fields")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ multiple `__pymethod___new____` found | note: candidate #1 is defined in an impl for the type `NewFromFieldsWithManualNew` - --> tests/ui/invalid_pyclass_args.rs:208:1 + --> tests/ui/invalid_pyclass_args.rs:254:1 | -208 | #[pyclass(new = "from_fields")] +254 | #[pyclass(new = "from_fields")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: candidate #2 is defined in an impl for the type `NewFromFieldsWithManualNew` - --> tests/ui/invalid_pyclass_args.rs:213:1 + --> tests/ui/invalid_pyclass_args.rs:262:1 | -213 | #[pymethods] +262 | #[pymethods] | ^^^^^^^^^^^^ = note: this error originates in the attribute macro `pyclass` which comes from the expansion of the attribute macro `pymethods` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0034]: multiple applicable items in scope - --> tests/ui/invalid_pyclass_args.rs:213:1 + --> tests/ui/invalid_pyclass_args.rs:262:1 | -213 | #[pymethods] +262 | #[pymethods] | ^^^^^^^^^^^^ multiple `__pymethod___new____` found | note: candidate #1 is defined in an impl for the type `NewFromFieldsWithManualNew` - --> tests/ui/invalid_pyclass_args.rs:208:1 + --> tests/ui/invalid_pyclass_args.rs:254:1 | -208 | #[pyclass(new = "from_fields")] +254 | #[pyclass(new = "from_fields")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: candidate #2 is defined in an impl for the type `NewFromFieldsWithManualNew` - --> tests/ui/invalid_pyclass_args.rs:213:1 + --> tests/ui/invalid_pyclass_args.rs:262:1 | -213 | #[pymethods] +262 | #[pymethods] | ^^^^^^^^^^^^ = note: this error originates in the attribute macro `pymethods` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 50 previous errors; 1 warning emitted + +Some errors have detailed explanations: E0034, E0119, E0277, E0369, E0592, E0609. +For more information about an error, try `rustc --explain E0034`. diff --git a/tests/ui/invalid_pyclass_doc.rs b/tests/ui/invalid_pyclass_doc.rs index 55122aa29db..03bfebb883a 100644 --- a/tests/ui/invalid_pyclass_doc.rs +++ b/tests/ui/invalid_pyclass_doc.rs @@ -1,6 +1,7 @@ use pyo3::prelude::*; #[doc = "This \0 contains a nul byte!"] +//~^ ERROR: Python doc may not contain nul byte, found nul at position 5 #[pyclass] struct InvalidDocWithNulByte {} diff --git a/tests/ui/invalid_pyclass_doc.stderr b/tests/ui/invalid_pyclass_doc.stderr index 7341125f85b..5763e9e19db 100644 --- a/tests/ui/invalid_pyclass_doc.stderr +++ b/tests/ui/invalid_pyclass_doc.stderr @@ -3,3 +3,6 @@ error: Python doc may not contain nul byte, found nul at position 5 | 3 | #[doc = "This \0 contains a nul byte!"] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/invalid_pyclass_enum.rs b/tests/ui/invalid_pyclass_enum.rs index 99ccb8d5fdd..9d1eb63da67 100644 --- a/tests/ui/invalid_pyclass_enum.rs +++ b/tests/ui/invalid_pyclass_enum.rs @@ -1,12 +1,14 @@ use pyo3::prelude::*; #[pyclass(subclass)] +//~^ ERROR: enums can't be inherited by other classes enum NotBaseClass { X, Y, } #[pyclass(extends = PyList)] +//~^ ERROR: enums can't extend from other classes enum NotDerivedClass { X, Y, @@ -14,45 +16,55 @@ enum NotDerivedClass { #[pyclass] enum NoEmptyEnum {} +//~^ ERROR: #[pyclass] can't be used on enums without any variants #[pyclass] enum NoUnitVariants { StructVariant { field: i32 }, UnitVariant, +//~^ ERROR: Unit variant `UnitVariant` is not yet supported in a complex enum } #[pyclass] enum SimpleNoSignature { #[pyo3(constructor = (a, b))] +//~^ ERROR: `constructor` can't be used on a simple enum variant A, B, } #[pyclass(eq, eq_int)] +//~^ ERROR: binary operation `==` cannot be applied to type `&SimpleEqOptRequiresPartialEq` +//~| ERROR: binary operation `!=` cannot be applied to type `&SimpleEqOptRequiresPartialEq` enum SimpleEqOptRequiresPartialEq { A, B, } #[pyclass(eq)] +//~^ ERROR: binary operation `==` cannot be applied to type `&ComplexEqOptRequiresPartialEq` +//~| ERROR: binary operation `!=` cannot be applied to type `&ComplexEqOptRequiresPartialEq` enum ComplexEqOptRequiresPartialEq { A(i32), B { msg: String }, } #[pyclass(eq_int)] +//~^ ERROR: The `eq_int` option requires the `eq` option. enum SimpleEqIntWithoutEq { A, B, } #[pyclass(eq_int)] +//~^ ERROR: `eq_int` can only be used on simple enums. enum NoEqInt { A(i32), B { msg: String }, } #[pyclass(frozen, eq, eq_int, hash)] +//~^ ERROR: the trait bound `SimpleHashOptRequiresHash: Hash` is not satisfied #[derive(PartialEq)] enum SimpleHashOptRequiresHash { A, @@ -60,6 +72,7 @@ enum SimpleHashOptRequiresHash { } #[pyclass(frozen, eq, hash)] +//~^ ERROR: the trait bound `ComplexHashOptRequiresHash: Hash` is not satisfied #[derive(PartialEq)] enum ComplexHashOptRequiresHash { A(i32), @@ -67,6 +80,8 @@ enum ComplexHashOptRequiresHash { } #[pyclass(hash)] +//~^ ERROR: The `hash` option requires the `frozen` option. +//~| ERROR: The `hash` option requires the `eq` option. #[derive(Hash)] enum SimpleHashOptRequiresFrozenAndEq { A, @@ -74,6 +89,7 @@ enum SimpleHashOptRequiresFrozenAndEq { } #[pyclass(hash)] +//~^ ERROR: The `hash` option requires the `eq` option. #[derive(Hash)] enum ComplexHashOptRequiresEq { A(i32), @@ -81,12 +97,17 @@ enum ComplexHashOptRequiresEq { } #[pyclass(ord)] +//~^ ERROR: The `ord` option requires the `eq` option. enum InvalidOrderedComplexEnum { VariantA (i32), VariantB { msg: String } } #[pyclass(eq,ord)] +//~^ ERROR: binary operation `>` cannot be applied to type `&InvalidOrderedComplexEnum2` +//~| ERROR: binary operation `<` cannot be applied to type `&InvalidOrderedComplexEnum2` +//~| ERROR: binary operation `<=` cannot be applied to type `&InvalidOrderedComplexEnum2` +//~| ERROR: binary operation `>=` cannot be applied to type `&InvalidOrderedComplexEnum2` #[derive(PartialEq)] enum InvalidOrderedComplexEnum2 { VariantA (i32), @@ -96,6 +117,7 @@ enum InvalidOrderedComplexEnum2 { #[pyclass(eq)] #[derive(PartialEq)] enum AllEnumVariantsDisabled { +//~^ ERROR: #[pyclass] can't be used on enums without any variants - all variants of enum `AllEnumVariantsDisabled` have been configured out by cfg attributes #[cfg(any())] DisabledA, #[cfg(not(all()))] diff --git a/tests/ui/invalid_pyclass_enum.stderr b/tests/ui/invalid_pyclass_enum.stderr index 80dc9539748..cc5faa53700 100644 --- a/tests/ui/invalid_pyclass_enum.stderr +++ b/tests/ui/invalid_pyclass_enum.stderr @@ -5,229 +5,234 @@ error: enums can't be inherited by other classes | ^^^^^^^^ error: enums can't extend from other classes - --> tests/ui/invalid_pyclass_enum.rs:9:11 - | -9 | #[pyclass(extends = PyList)] - | ^^^^^^^ + --> tests/ui/invalid_pyclass_enum.rs:10:11 + | +10 | #[pyclass(extends = PyList)] + | ^^^^^^^ error: #[pyclass] can't be used on enums without any variants - --> tests/ui/invalid_pyclass_enum.rs:16:18 + --> tests/ui/invalid_pyclass_enum.rs:18:18 | -16 | enum NoEmptyEnum {} +18 | enum NoEmptyEnum {} | ^^ error: Unit variant `UnitVariant` is not yet supported in a complex enum = help: change to an empty tuple variant instead: `UnitVariant()` = note: the enum is complex because of non-unit variant `StructVariant` - --> tests/ui/invalid_pyclass_enum.rs:21:5 + --> tests/ui/invalid_pyclass_enum.rs:24:5 | -21 | UnitVariant, +24 | UnitVariant, | ^^^^^^^^^^^ error: `constructor` can't be used on a simple enum variant - --> tests/ui/invalid_pyclass_enum.rs:26:12 + --> tests/ui/invalid_pyclass_enum.rs:30:12 | -26 | #[pyo3(constructor = (a, b))] +30 | #[pyo3(constructor = (a, b))] | ^^^^^^^^^^^ error: The `eq_int` option requires the `eq` option. - --> tests/ui/invalid_pyclass_enum.rs:43:11 + --> tests/ui/invalid_pyclass_enum.rs:52:11 | -43 | #[pyclass(eq_int)] +52 | #[pyclass(eq_int)] | ^^^^^^ error: `eq_int` can only be used on simple enums. - --> tests/ui/invalid_pyclass_enum.rs:49:11 + --> tests/ui/invalid_pyclass_enum.rs:59:11 | -49 | #[pyclass(eq_int)] +59 | #[pyclass(eq_int)] | ^^^^^^ error: The `hash` option requires the `frozen` option. - --> tests/ui/invalid_pyclass_enum.rs:69:11 + --> tests/ui/invalid_pyclass_enum.rs:82:11 | -69 | #[pyclass(hash)] +82 | #[pyclass(hash)] | ^^^^ error: The `hash` option requires the `eq` option. - --> tests/ui/invalid_pyclass_enum.rs:69:11 + --> tests/ui/invalid_pyclass_enum.rs:82:11 | -69 | #[pyclass(hash)] +82 | #[pyclass(hash)] | ^^^^ error: The `hash` option requires the `eq` option. - --> tests/ui/invalid_pyclass_enum.rs:76:11 + --> tests/ui/invalid_pyclass_enum.rs:91:11 | -76 | #[pyclass(hash)] +91 | #[pyclass(hash)] | ^^^^ error: The `ord` option requires the `eq` option. - --> tests/ui/invalid_pyclass_enum.rs:83:11 + --> tests/ui/invalid_pyclass_enum.rs:99:11 | -83 | #[pyclass(ord)] +99 | #[pyclass(ord)] | ^^^ error: #[pyclass] can't be used on enums without any variants - all variants of enum `AllEnumVariantsDisabled` have been configured out by cfg attributes - --> tests/ui/invalid_pyclass_enum.rs:98:6 - | -98 | enum AllEnumVariantsDisabled { - | ^^^^^^^^^^^^^^^^^^^^^^^ + --> tests/ui/invalid_pyclass_enum.rs:119:6 + | +119 | enum AllEnumVariantsDisabled { + | ^^^^^^^^^^^^^^^^^^^^^^^ error[E0369]: binary operation `==` cannot be applied to type `&SimpleEqOptRequiresPartialEq` - --> tests/ui/invalid_pyclass_enum.rs:31:11 + --> tests/ui/invalid_pyclass_enum.rs:36:11 | -31 | #[pyclass(eq, eq_int)] +36 | #[pyclass(eq, eq_int)] | ^^ | note: an implementation of `PartialEq` might be missing for `SimpleEqOptRequiresPartialEq` - --> tests/ui/invalid_pyclass_enum.rs:32:1 + --> tests/ui/invalid_pyclass_enum.rs:39:1 | -32 | enum SimpleEqOptRequiresPartialEq { +39 | enum SimpleEqOptRequiresPartialEq { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ must implement `PartialEq` help: consider annotating `SimpleEqOptRequiresPartialEq` with `#[derive(PartialEq)]` | -32 + #[derive(PartialEq)] -33 | enum SimpleEqOptRequiresPartialEq { +39 + #[derive(PartialEq)] +40 | enum SimpleEqOptRequiresPartialEq { | error[E0369]: binary operation `!=` cannot be applied to type `&SimpleEqOptRequiresPartialEq` - --> tests/ui/invalid_pyclass_enum.rs:31:11 + --> tests/ui/invalid_pyclass_enum.rs:36:11 | -31 | #[pyclass(eq, eq_int)] +36 | #[pyclass(eq, eq_int)] | ^^ | note: an implementation of `PartialEq` might be missing for `SimpleEqOptRequiresPartialEq` - --> tests/ui/invalid_pyclass_enum.rs:32:1 + --> tests/ui/invalid_pyclass_enum.rs:39:1 | -32 | enum SimpleEqOptRequiresPartialEq { +39 | enum SimpleEqOptRequiresPartialEq { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ must implement `PartialEq` help: consider annotating `SimpleEqOptRequiresPartialEq` with `#[derive(PartialEq)]` | -32 + #[derive(PartialEq)] -33 | enum SimpleEqOptRequiresPartialEq { +39 + #[derive(PartialEq)] +40 | enum SimpleEqOptRequiresPartialEq { | error[E0369]: binary operation `==` cannot be applied to type `&ComplexEqOptRequiresPartialEq` - --> tests/ui/invalid_pyclass_enum.rs:37:11 + --> tests/ui/invalid_pyclass_enum.rs:44:11 | -37 | #[pyclass(eq)] +44 | #[pyclass(eq)] | ^^ | note: an implementation of `PartialEq` might be missing for `ComplexEqOptRequiresPartialEq` - --> tests/ui/invalid_pyclass_enum.rs:38:1 + --> tests/ui/invalid_pyclass_enum.rs:47:1 | -38 | enum ComplexEqOptRequiresPartialEq { +47 | enum ComplexEqOptRequiresPartialEq { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ must implement `PartialEq` help: consider annotating `ComplexEqOptRequiresPartialEq` with `#[derive(PartialEq)]` | -38 + #[derive(PartialEq)] -39 | enum ComplexEqOptRequiresPartialEq { +47 + #[derive(PartialEq)] +48 | enum ComplexEqOptRequiresPartialEq { | error[E0369]: binary operation `!=` cannot be applied to type `&ComplexEqOptRequiresPartialEq` - --> tests/ui/invalid_pyclass_enum.rs:37:11 + --> tests/ui/invalid_pyclass_enum.rs:44:11 | -37 | #[pyclass(eq)] +44 | #[pyclass(eq)] | ^^ | note: an implementation of `PartialEq` might be missing for `ComplexEqOptRequiresPartialEq` - --> tests/ui/invalid_pyclass_enum.rs:38:1 + --> tests/ui/invalid_pyclass_enum.rs:47:1 | -38 | enum ComplexEqOptRequiresPartialEq { +47 | enum ComplexEqOptRequiresPartialEq { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ must implement `PartialEq` help: consider annotating `ComplexEqOptRequiresPartialEq` with `#[derive(PartialEq)]` | -38 + #[derive(PartialEq)] -39 | enum ComplexEqOptRequiresPartialEq { +47 + #[derive(PartialEq)] +48 | enum ComplexEqOptRequiresPartialEq { | error[E0277]: the trait bound `SimpleHashOptRequiresHash: Hash` is not satisfied - --> tests/ui/invalid_pyclass_enum.rs:55:31 + --> tests/ui/invalid_pyclass_enum.rs:66:31 | -55 | #[pyclass(frozen, eq, eq_int, hash)] +66 | #[pyclass(frozen, eq, eq_int, hash)] | ^^^^ the trait `Hash` is not implemented for `SimpleHashOptRequiresHash` | help: consider annotating `SimpleHashOptRequiresHash` with `#[derive(Hash)]` | -57 + #[derive(Hash)] -58 | enum SimpleHashOptRequiresHash { +69 + #[derive(Hash)] +70 | enum SimpleHashOptRequiresHash { | error[E0277]: the trait bound `ComplexHashOptRequiresHash: Hash` is not satisfied - --> tests/ui/invalid_pyclass_enum.rs:62:23 + --> tests/ui/invalid_pyclass_enum.rs:74:23 | -62 | #[pyclass(frozen, eq, hash)] +74 | #[pyclass(frozen, eq, hash)] | ^^^^ the trait `Hash` is not implemented for `ComplexHashOptRequiresHash` | help: consider annotating `ComplexHashOptRequiresHash` with `#[derive(Hash)]` | -64 + #[derive(Hash)] -65 | enum ComplexHashOptRequiresHash { +77 + #[derive(Hash)] +78 | enum ComplexHashOptRequiresHash { | error[E0369]: binary operation `>` cannot be applied to type `&InvalidOrderedComplexEnum2` - --> tests/ui/invalid_pyclass_enum.rs:89:14 - | -89 | #[pyclass(eq,ord)] - | ^^^ - | + --> tests/ui/invalid_pyclass_enum.rs:106:14 + | +106 | #[pyclass(eq,ord)] + | ^^^ + | note: an implementation of `PartialOrd` might be missing for `InvalidOrderedComplexEnum2` - --> tests/ui/invalid_pyclass_enum.rs:91:1 - | -91 | enum InvalidOrderedComplexEnum2 { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ must implement `PartialOrd` + --> tests/ui/invalid_pyclass_enum.rs:112:1 + | +112 | enum InvalidOrderedComplexEnum2 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ must implement `PartialOrd` help: consider annotating `InvalidOrderedComplexEnum2` with `#[derive(PartialEq, PartialOrd)]` - | -91 + #[derive(PartialEq, PartialOrd)] -92 | enum InvalidOrderedComplexEnum2 { - | + | +112 + #[derive(PartialEq, PartialOrd)] +113 | enum InvalidOrderedComplexEnum2 { + | error[E0369]: binary operation `<` cannot be applied to type `&InvalidOrderedComplexEnum2` - --> tests/ui/invalid_pyclass_enum.rs:89:14 - | -89 | #[pyclass(eq,ord)] - | ^^^ - | + --> tests/ui/invalid_pyclass_enum.rs:106:14 + | +106 | #[pyclass(eq,ord)] + | ^^^ + | note: an implementation of `PartialOrd` might be missing for `InvalidOrderedComplexEnum2` - --> tests/ui/invalid_pyclass_enum.rs:91:1 - | -91 | enum InvalidOrderedComplexEnum2 { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ must implement `PartialOrd` + --> tests/ui/invalid_pyclass_enum.rs:112:1 + | +112 | enum InvalidOrderedComplexEnum2 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ must implement `PartialOrd` help: consider annotating `InvalidOrderedComplexEnum2` with `#[derive(PartialEq, PartialOrd)]` - | -91 + #[derive(PartialEq, PartialOrd)] -92 | enum InvalidOrderedComplexEnum2 { - | + | +112 + #[derive(PartialEq, PartialOrd)] +113 | enum InvalidOrderedComplexEnum2 { + | error[E0369]: binary operation `<=` cannot be applied to type `&InvalidOrderedComplexEnum2` - --> tests/ui/invalid_pyclass_enum.rs:89:14 - | -89 | #[pyclass(eq,ord)] - | ^^^ - | + --> tests/ui/invalid_pyclass_enum.rs:106:14 + | +106 | #[pyclass(eq,ord)] + | ^^^ + | note: an implementation of `PartialOrd` might be missing for `InvalidOrderedComplexEnum2` - --> tests/ui/invalid_pyclass_enum.rs:91:1 - | -91 | enum InvalidOrderedComplexEnum2 { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ must implement `PartialOrd` + --> tests/ui/invalid_pyclass_enum.rs:112:1 + | +112 | enum InvalidOrderedComplexEnum2 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ must implement `PartialOrd` help: consider annotating `InvalidOrderedComplexEnum2` with `#[derive(PartialEq, PartialOrd)]` - | -91 + #[derive(PartialEq, PartialOrd)] -92 | enum InvalidOrderedComplexEnum2 { - | + | +112 + #[derive(PartialEq, PartialOrd)] +113 | enum InvalidOrderedComplexEnum2 { + | error[E0369]: binary operation `>=` cannot be applied to type `&InvalidOrderedComplexEnum2` - --> tests/ui/invalid_pyclass_enum.rs:89:14 - | -89 | #[pyclass(eq,ord)] - | ^^^ - | + --> tests/ui/invalid_pyclass_enum.rs:106:14 + | +106 | #[pyclass(eq,ord)] + | ^^^ + | note: an implementation of `PartialOrd` might be missing for `InvalidOrderedComplexEnum2` - --> tests/ui/invalid_pyclass_enum.rs:91:1 - | -91 | enum InvalidOrderedComplexEnum2 { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ must implement `PartialOrd` + --> tests/ui/invalid_pyclass_enum.rs:112:1 + | +112 | enum InvalidOrderedComplexEnum2 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ must implement `PartialOrd` help: consider annotating `InvalidOrderedComplexEnum2` with `#[derive(PartialEq, PartialOrd)]` - | -91 + #[derive(PartialEq, PartialOrd)] -92 | enum InvalidOrderedComplexEnum2 { - | + | +112 + #[derive(PartialEq, PartialOrd)] +113 | enum InvalidOrderedComplexEnum2 { + | + +error: aborting due to 22 previous errors + +Some errors have detailed explanations: E0277, E0369. +For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/invalid_pyclass_generic.rs b/tests/ui/invalid_pyclass_generic.rs index dac8c057d81..7b7267802e3 100644 --- a/tests/ui/invalid_pyclass_generic.rs +++ b/tests/ui/invalid_pyclass_generic.rs @@ -2,6 +2,9 @@ use pyo3::prelude::*; use pyo3::types::PyType; #[pyclass(generic)] +//~^ ERROR: duplicate definitions with name `__pymethod___class_getitem____` +//~| ERROR: duplicate definitions with name `__class_getitem__` +//~| ERROR: multiple applicable items in scope struct ClassRedefinesClassGetItem {} #[pymethods] @@ -13,10 +16,13 @@ impl ClassRedefinesClassGetItem { #[classmethod] pub fn __class_getitem__( + //~^ ERROR: multiple applicable items in scope cls: &Bound<'_, PyType>, key: &Bound<'_, PyAny>, ) -> PyResult> { + //~^ ERROR: multiple applicable items in scope pyo3::types::PyGenericAlias::new(cls.py(), cls.as_any(), key) + //~^ ERROR: mismatched types } } diff --git a/tests/ui/invalid_pyclass_generic.stderr b/tests/ui/invalid_pyclass_generic.stderr index 03981816475..2a4db17e7cf 100644 --- a/tests/ui/invalid_pyclass_generic.stderr +++ b/tests/ui/invalid_pyclass_generic.stderr @@ -1,13 +1,57 @@ +error[E0433]: failed to resolve: could not find `PyGenericAlias` in `types` + --> tests/ui/invalid_pyclass_generic.rs:4:1 + | + 4 | #[pyclass(generic)] + | ^^^^^^^^^^^^^^^^^^^ could not find `PyGenericAlias` in `types` + | +note: found an item that was configured out + --> src/types/mod.rs:25:29 + | +24 | #[cfg(Py_3_9)] + | ------ the item is gated here +25 | pub use self::genericalias::PyGenericAlias; + | ^^^^^^^^^^^^^^ + = note: this error originates in the attribute macro `pyclass` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0433]: failed to resolve: could not find `PyGenericAlias` in `types` + --> tests/ui/invalid_pyclass_generic.rs:24:22 + | +24 | pyo3::types::PyGenericAlias::new(cls.py(), cls.as_any(), key) + | ^^^^^^^^^^^^^^ could not find `PyGenericAlias` in `types` + | +note: found an item that was configured out + --> src/types/mod.rs:25:29 + | +24 | #[cfg(Py_3_9)] + | ------ the item is gated here +25 | pub use self::genericalias::PyGenericAlias; + | ^^^^^^^^^^^^^^ + +error[E0425]: cannot find type `PyGenericAlias` in module `pyo3::types` + --> tests/ui/invalid_pyclass_generic.rs:4:1 + | + 4 | #[pyclass(generic)] + | ^^^^^^^^^^^^^^^^^^^ not found in `pyo3::types` + | +note: found an item that was configured out + --> src/types/mod.rs:25:29 + | +24 | #[cfg(Py_3_9)] + | ------ the item is gated here +25 | pub use self::genericalias::PyGenericAlias; + | ^^^^^^^^^^^^^^ + = note: this error originates in the attribute macro `pyclass` (in Nightly builds, run with -Z macro-backtrace for more info) + error[E0592]: duplicate definitions with name `__pymethod___class_getitem____` - --> tests/ui/invalid_pyclass_generic.rs:4:1 - | -4 | #[pyclass(generic)] - | ^^^^^^^^^^^^^^^^^^^ duplicate definitions for `__pymethod___class_getitem____` + --> tests/ui/invalid_pyclass_generic.rs:4:1 + | + 4 | #[pyclass(generic)] + | ^^^^^^^^^^^^^^^^^^^ duplicate definitions for `__pymethod___class_getitem____` ... -7 | #[pymethods] - | ------------ other definition for `__pymethod___class_getitem____` - | - = note: this error originates in the macro `::pyo3::impl_::pymethods::maybe_define_fastcall_function_with_keywords` which comes from the expansion of the attribute macro `pyclass` (in Nightly builds, run with -Z macro-backtrace for more info) +10 | #[pymethods] + | ------------ other definition for `__pymethod___class_getitem____` + | + = note: this error originates in the macro `::pyo3::impl_::pymethods::maybe_define_fastcall_function_with_keywords` which comes from the expansion of the attribute macro `pyclass` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0592]: duplicate definitions with name `__class_getitem__` --> tests/ui/invalid_pyclass_generic.rs:4:1 @@ -15,31 +59,32 @@ error[E0592]: duplicate definitions with name `__class_getitem__` 4 | #[pyclass(generic)] | ^^^^^^^^^^^^^^^^^^^ duplicate definitions for `__class_getitem__` ... -15 | / pub fn __class_getitem__( -16 | | cls: &Bound<'_, PyType>, -17 | | key: &Bound<'_, PyAny>, -18 | | ) -> PyResult> { +18 | / pub fn __class_getitem__( +19 | | +20 | | cls: &Bound<'_, PyType>, +21 | | key: &Bound<'_, PyAny>, +22 | | ) -> PyResult> { | |____________________________- other definition for `__class_getitem__` | = note: this error originates in the attribute macro `pyclass` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0034]: multiple applicable items in scope - --> tests/ui/invalid_pyclass_generic.rs:4:1 - | -4 | #[pyclass(generic)] - | ^^^^^^^^^^^^^^^^^^^ multiple `__pymethod___class_getitem____` found - | + --> tests/ui/invalid_pyclass_generic.rs:4:1 + | + 4 | #[pyclass(generic)] + | ^^^^^^^^^^^^^^^^^^^ multiple `__pymethod___class_getitem____` found + | note: candidate #1 is defined in an impl for the type `ClassRedefinesClassGetItem` - --> tests/ui/invalid_pyclass_generic.rs:4:1 - | -4 | #[pyclass(generic)] - | ^^^^^^^^^^^^^^^^^^^ + --> tests/ui/invalid_pyclass_generic.rs:4:1 + | + 4 | #[pyclass(generic)] + | ^^^^^^^^^^^^^^^^^^^ note: candidate #2 is defined in an impl for the type `ClassRedefinesClassGetItem` - --> tests/ui/invalid_pyclass_generic.rs:7:1 - | -7 | #[pymethods] - | ^^^^^^^^^^^^ - = note: this error originates in the attribute macro `pyclass` which comes from the expansion of the attribute macro `pymethods` (in Nightly builds, run with -Z macro-backtrace for more info) + --> tests/ui/invalid_pyclass_generic.rs:10:1 + | +10 | #[pymethods] + | ^^^^^^^^^^^^ + = note: this error originates in the attribute macro `pyclass` which comes from the expansion of the attribute macro `pymethods` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0034]: multiple applicable items in scope --> tests/ui/invalid_pyclass_generic.rs:4:1 @@ -53,12 +98,13 @@ note: candidate #1 is defined in an impl for the type `ClassRedefinesClassGetIte 4 | #[pyclass(generic)] | ^^^^^^^^^^^^^^^^^^^ note: candidate #2 is defined in an impl for the type `ClassRedefinesClassGetItem` - --> tests/ui/invalid_pyclass_generic.rs:15:5 + --> tests/ui/invalid_pyclass_generic.rs:18:5 | -15 | / pub fn __class_getitem__( -16 | | cls: &Bound<'_, PyType>, -17 | | key: &Bound<'_, PyAny>, -18 | | ) -> PyResult> { +18 | / pub fn __class_getitem__( +19 | | +20 | | cls: &Bound<'_, PyType>, +21 | | key: &Bound<'_, PyAny>, +22 | | ) -> PyResult> { | |____________________________^ = note: this error originates in the attribute macro `pyclass` (in Nightly builds, run with -Z macro-backtrace for more info) @@ -72,21 +118,10 @@ error[E0034]: multiple applicable items in scope = note: candidate #2 is defined in an impl for the type `IntoPyObjectConverter` = note: this error originates in the attribute macro `pyclass` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0308]: mismatched types - --> tests/ui/invalid_pyclass_generic.rs:19:9 - | -18 | ) -> PyResult> { - | ------------------- expected `Result, PyErr>` because of return type -19 | pyo3::types::PyGenericAlias::new(cls.py(), cls.as_any(), key) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Result, PyErr>`, found `Result, PyErr>` - | - = note: expected enum `Result, PyErr>` - found enum `Result, PyErr>` - error[E0034]: multiple applicable items in scope - --> tests/ui/invalid_pyclass_generic.rs:15:12 + --> tests/ui/invalid_pyclass_generic.rs:18:12 | -15 | pub fn __class_getitem__( +18 | pub fn __class_getitem__( | ^^^^^^^^^^^^^^^^^ multiple `__pymethod___class_getitem____` found | note: candidate #1 is defined in an impl for the type `ClassRedefinesClassGetItem` @@ -95,16 +130,16 @@ note: candidate #1 is defined in an impl for the type `ClassRedefinesClassGetIte 4 | #[pyclass(generic)] | ^^^^^^^^^^^^^^^^^^^ note: candidate #2 is defined in an impl for the type `ClassRedefinesClassGetItem` - --> tests/ui/invalid_pyclass_generic.rs:7:1 + --> tests/ui/invalid_pyclass_generic.rs:10:1 | - 7 | #[pymethods] +10 | #[pymethods] | ^^^^^^^^^^^^ = note: this error originates in the macro `::pyo3::impl_::pymethods::maybe_define_fastcall_function_with_keywords` which comes from the expansion of the attribute macro `pymethods` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0034]: multiple applicable items in scope - --> tests/ui/invalid_pyclass_generic.rs:15:12 + --> tests/ui/invalid_pyclass_generic.rs:18:12 | -15 | pub fn __class_getitem__( +18 | pub fn __class_getitem__( | ^^^^^^^^^^^^^^^^^ multiple `__class_getitem__` found | note: candidate #1 is defined in an impl for the type `ClassRedefinesClassGetItem` @@ -113,20 +148,26 @@ note: candidate #1 is defined in an impl for the type `ClassRedefinesClassGetIte 4 | #[pyclass(generic)] | ^^^^^^^^^^^^^^^^^^^ note: candidate #2 is defined in an impl for the type `ClassRedefinesClassGetItem` - --> tests/ui/invalid_pyclass_generic.rs:15:5 + --> tests/ui/invalid_pyclass_generic.rs:18:5 | -15 | / pub fn __class_getitem__( -16 | | cls: &Bound<'_, PyType>, -17 | | key: &Bound<'_, PyAny>, -18 | | ) -> PyResult> { +18 | / pub fn __class_getitem__( +19 | | +20 | | cls: &Bound<'_, PyType>, +21 | | key: &Bound<'_, PyAny>, +22 | | ) -> PyResult> { | |____________________________^ = note: this error originates in the attribute macro `pyclass` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0034]: multiple applicable items in scope - --> tests/ui/invalid_pyclass_generic.rs:18:10 + --> tests/ui/invalid_pyclass_generic.rs:22:10 | -18 | ) -> PyResult> { +22 | ) -> PyResult> { | ^^^^^^^^ multiple `wrap` found | = note: candidate #1 is defined in an impl for the type `IntoPyObjectConverter>` = note: candidate #2 is defined in an impl for the type `IntoPyObjectConverter` + +error: aborting due to 11 previous errors + +Some errors have detailed explanations: E0034, E0425, E0433, E0592. +For more information about an error, try `rustc --explain E0034`. diff --git a/tests/ui/invalid_pyclass_init.rs b/tests/ui/invalid_pyclass_init.rs index 5fae78fbec3..9b7734620b0 100644 --- a/tests/ui/invalid_pyclass_init.rs +++ b/tests/ui/invalid_pyclass_init.rs @@ -1,13 +1,14 @@ -use pyo3::prelude::*; - -#[pyclass] -struct InvalidInitReturn; - -#[pymethods] -impl InvalidInitReturn { - fn __init__(&self) -> i32 { - 0 - } -} - -fn main() {} +use pyo3::prelude::*; + +#[pyclass] +struct InvalidInitReturn; + +#[pymethods] +impl InvalidInitReturn { + fn __init__(&self) -> i32 { +//~^ ERROR: the trait bound `i32: IntoPyCallbackOutput<'_, i32>` is not satisfied + 0 + } +} + +fn main() {} diff --git a/tests/ui/invalid_pyclass_init.stderr b/tests/ui/invalid_pyclass_init.stderr index 245d58de593..30091643140 100644 --- a/tests/ui/invalid_pyclass_init.stderr +++ b/tests/ui/invalid_pyclass_init.stderr @@ -1,14 +1,18 @@ error[E0277]: the trait bound `i32: IntoPyCallbackOutput<'_, i32>` is not satisfied - --> tests/ui/invalid_pyclass_init.rs:8:27 - | -8 | fn __init__(&self) -> i32 { - | ^^^ the trait `IntoPyCallbackOutput<'_, i32>` is not implemented for `i32` - | + --> tests/ui/invalid_pyclass_init.rs:8:27 + | + 8 | fn __init__(&self) -> i32 { + | ^^^ the trait `IntoPyCallbackOutput<'_, i32>` is not implemented for `i32` + | help: the following other types implement trait `IntoPyCallbackOutput<'py, Target>` - --> src/impl_/callback.rs - | - | impl IntoPyCallbackOutput<'_, ffi::Py_ssize_t> for usize { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `usize` implements `IntoPyCallbackOutput<'_, isize>` + --> src/impl_/callback.rs:127:1 + | +127 | impl IntoPyCallbackOutput<'_, ffi::Py_ssize_t> for usize { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `usize` implements `IntoPyCallbackOutput<'_, isize>` ... - | impl IntoPyCallbackOutput<'_, usize> for usize { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `usize` implements `IntoPyCallbackOutput<'_, usize>` +143 | impl IntoPyCallbackOutput<'_, usize> for usize { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `usize` implements `IntoPyCallbackOutput<'_, usize>` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/invalid_pyclass_item.rs b/tests/ui/invalid_pyclass_item.rs index 4b348540608..03c77ee4a09 100644 --- a/tests/ui/invalid_pyclass_item.rs +++ b/tests/ui/invalid_pyclass_item.rs @@ -2,5 +2,6 @@ use pyo3::prelude::*; #[pyclass] fn foo() {} +//~^ ERROR: #[pyclass] only supports structs and enums. fn main() {} diff --git a/tests/ui/invalid_pyclass_item.stderr b/tests/ui/invalid_pyclass_item.stderr index f29756dfaec..afd17c4e665 100644 --- a/tests/ui/invalid_pyclass_item.stderr +++ b/tests/ui/invalid_pyclass_item.stderr @@ -3,3 +3,6 @@ error: #[pyclass] only supports structs and enums. | 4 | fn foo() {} | ^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/invalid_pyfunction_argument.rs b/tests/ui/invalid_pyfunction_argument.rs index 0505c2f0ad0..5b619e85aed 100644 --- a/tests/ui/invalid_pyfunction_argument.rs +++ b/tests/ui/invalid_pyfunction_argument.rs @@ -3,6 +3,9 @@ use std::sync::atomic::AtomicPtr; #[pyfunction] fn invalid_pyfunction_argument(arg: AtomicPtr<()>) { +//~^ ERROR: `AtomicPtr<()>` cannot be used as a Python function argument +//~| ERROR: `AtomicPtr<()>` cannot be used as a Python function argument +//~| ERROR: `AtomicPtr<()>` cannot be used as a Python function argument let _ = arg; } @@ -12,6 +15,7 @@ struct Foo; #[pyfunction] fn skip_from_py_object_without_custom_from_py_object(arg: Foo) { +//~^ ERROR: `Foo` cannot be used as a Python function argument let _ = arg; } diff --git a/tests/ui/invalid_pyfunction_argument.stderr b/tests/ui/invalid_pyfunction_argument.stderr index 073137e293f..71f7c55fa94 100644 --- a/tests/ui/invalid_pyfunction_argument.stderr +++ b/tests/ui/invalid_pyfunction_argument.stderr @@ -1,146 +1,108 @@ error[E0277]: `AtomicPtr<()>` cannot be used as a Python function argument - --> tests/ui/invalid_pyfunction_argument.rs:5:37 - | -5 | fn invalid_pyfunction_argument(arg: AtomicPtr<()>) { - | ^^^^^^^^^ the trait `PyClass` is not implemented for `AtomicPtr<()>` - | - = note: implement `FromPyObject` to enable using `AtomicPtr<()>` as a function argument - = note: `Python<'py>` is also a valid argument type to pass the Python token into `#[pyfunction]`s and `#[pymethods]` + --> tests/ui/invalid_pyfunction_argument.rs:5:37 + | + 5 | fn invalid_pyfunction_argument(arg: AtomicPtr<()>) { + | ^^^^^^^^^ the trait `PyClass` is not implemented for `AtomicPtr<()>` + | + = note: implement `FromPyObject` to enable using `AtomicPtr<()>` as a function argument + = note: `Python<'py>` is also a valid argument type to pass the Python token into `#[pyfunction]`s and `#[pymethods]` help: the trait `PyClass` is implemented for `Foo` - --> tests/ui/invalid_pyfunction_argument.rs:9:1 - | -9 | #[pyclass(skip_from_py_object)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: required for `AtomicPtr<()>` to implement `FromPyObject<'_, '_>` - = note: required for `AtomicPtr<()>` to implement `PyFunctionArgument<'_, '_, '_, true>` + --> tests/ui/invalid_pyfunction_argument.rs:12:1 + | + 12 | #[pyclass(skip_from_py_object)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: required for `AtomicPtr<()>` to implement `FromPyObject<'_, '_>` + = note: required for `AtomicPtr<()>` to implement `PyFunctionArgument<'_, '_, '_, true>` note: required by a bound in `extract_argument` - --> src/impl_/extract_argument.rs - | - | pub fn extract_argument<'a, 'holder, 'py, T, const IMPLEMENTS_FROMPYOBJECT: bool>( - | ---------------- required by a bound in this function + --> src/impl_/extract_argument.rs:226:8 + | +220 | pub fn extract_argument<'a, 'holder, 'py, T, const IMPLEMENTS_FROMPYOBJECT: bool>( + | ---------------- required by a bound in this function ... - | T: PyFunctionArgument<'a, 'holder, 'py, IMPLEMENTS_FROMPYOBJECT>, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `extract_argument` - = note: this error originates in the attribute macro `pyclass` (in Nightly builds, run with -Z macro-backtrace for more info) +226 | T: PyFunctionArgument<'a, 'holder, 'py, IMPLEMENTS_FROMPYOBJECT>, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `extract_argument` + = note: this error originates in the attribute macro `pyclass` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: `AtomicPtr<()>` cannot be used as a Python function argument - --> tests/ui/invalid_pyfunction_argument.rs:5:37 - | -5 | fn invalid_pyfunction_argument(arg: AtomicPtr<()>) { - | ^^^^^^^^^ the trait `Clone` is not implemented for `AtomicPtr<()>` - | - = note: implement `FromPyObject` to enable using `AtomicPtr<()>` as a function argument - = note: `Python<'py>` is also a valid argument type to pass the Python token into `#[pyfunction]`s and `#[pymethods]` -help: the following other types implement trait `PyFunctionArgument<'a, 'holder, 'py, IMPLEMENTS_FROMPYOBJECT>` - --> src/impl_/extract_argument.rs - | - | / impl<'a, 'holder, 'py, T: 'a + 'py> PyFunctionArgument<'a, 'holder, 'py, false> - | | for &'holder Bound<'py, T> - | | where - | | T: PyTypeCheck, - | |___________________^ `&'holder pyo3::Bound<'py, T>` implements `PyFunctionArgument<'a, 'holder, 'py, false>` -... - | / impl<'a, 'holder, 'py, T> PyFunctionArgument<'a, 'holder, 'py, false> for Option - | | where - | | T: PyFunctionArgument<'a, 'holder, 'py, false>, - | |___________________________________________________^ `Option` implements `PyFunctionArgument<'a, 'holder, 'py, false>` -... - | impl<'a, 'holder, T: PyClass> PyFunctionArgument<'a, 'holder, '_, false> for &'holder T { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `&'holder T` implements `PyFunctionArgument<'a, 'holder, '_, false>` -... - | / impl<'a, 'holder, T: PyClass> PyFunctionArgument<'a, 'holder, '_, false> - | | for &'holder mut T - | |______________________^ `&'holder mut T` implements `PyFunctionArgument<'a, 'holder, '_, false>` - = note: required for `AtomicPtr<()>` to implement `FromPyObject<'_, '_>` - = note: required for `AtomicPtr<()>` to implement `PyFunctionArgument<'_, '_, '_, true>` + --> tests/ui/invalid_pyfunction_argument.rs:5:37 + | + 5 | fn invalid_pyfunction_argument(arg: AtomicPtr<()>) { + | ^^^^^^^^^ the trait `Clone` is not implemented for `AtomicPtr<()>` + | + = note: implement `FromPyObject` to enable using `AtomicPtr<()>` as a function argument + = note: `Python<'py>` is also a valid argument type to pass the Python token into `#[pyfunction]`s and `#[pymethods]` + = help: the following other types implement trait `PyFunctionArgument<'a, 'holder, 'py, IMPLEMENTS_FROMPYOBJECT>`: + `&'holder T` implements `PyFunctionArgument<'a, 'holder, '_, false>` + `&'holder mut T` implements `PyFunctionArgument<'a, 'holder, '_, false>` + `&'holder pyo3::Bound<'py, T>` implements `PyFunctionArgument<'a, 'holder, 'py, false>` + `&'holder str` implements `PyFunctionArgument<'a, 'holder, 'py, false>` + `Option` implements `PyFunctionArgument<'a, 'holder, 'py, false>` + = note: required for `AtomicPtr<()>` to implement `FromPyObject<'_, '_>` + = note: required for `AtomicPtr<()>` to implement `PyFunctionArgument<'_, '_, '_, true>` note: required by a bound in `extract_argument` - --> src/impl_/extract_argument.rs - | - | pub fn extract_argument<'a, 'holder, 'py, T, const IMPLEMENTS_FROMPYOBJECT: bool>( - | ---------------- required by a bound in this function + --> src/impl_/extract_argument.rs:226:8 + | +220 | pub fn extract_argument<'a, 'holder, 'py, T, const IMPLEMENTS_FROMPYOBJECT: bool>( + | ---------------- required by a bound in this function ... - | T: PyFunctionArgument<'a, 'holder, 'py, IMPLEMENTS_FROMPYOBJECT>, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `extract_argument` +226 | T: PyFunctionArgument<'a, 'holder, 'py, IMPLEMENTS_FROMPYOBJECT>, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `extract_argument` error[E0277]: `AtomicPtr<()>` cannot be used as a Python function argument - --> tests/ui/invalid_pyfunction_argument.rs:5:37 - | -5 | fn invalid_pyfunction_argument(arg: AtomicPtr<()>) { - | ^^^^^^^^^ the trait `ExtractPyClassWithClone` is not implemented for `AtomicPtr<()>` - | - = note: implement `FromPyObject` to enable using `AtomicPtr<()>` as a function argument - = note: `Python<'py>` is also a valid argument type to pass the Python token into `#[pyfunction]`s and `#[pymethods]` -help: the following other types implement trait `PyFunctionArgument<'a, 'holder, 'py, IMPLEMENTS_FROMPYOBJECT>` - --> src/impl_/extract_argument.rs - | - | / impl<'a, 'holder, 'py, T: 'a + 'py> PyFunctionArgument<'a, 'holder, 'py, false> - | | for &'holder Bound<'py, T> - | | where - | | T: PyTypeCheck, - | |___________________^ `&'holder pyo3::Bound<'py, T>` implements `PyFunctionArgument<'a, 'holder, 'py, false>` -... - | / impl<'a, 'holder, 'py, T> PyFunctionArgument<'a, 'holder, 'py, false> for Option - | | where - | | T: PyFunctionArgument<'a, 'holder, 'py, false>, - | |___________________________________________________^ `Option` implements `PyFunctionArgument<'a, 'holder, 'py, false>` -... - | impl<'a, 'holder, T: PyClass> PyFunctionArgument<'a, 'holder, '_, false> for &'holder T { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `&'holder T` implements `PyFunctionArgument<'a, 'holder, '_, false>` -... - | / impl<'a, 'holder, T: PyClass> PyFunctionArgument<'a, 'holder, '_, false> - | | for &'holder mut T - | |______________________^ `&'holder mut T` implements `PyFunctionArgument<'a, 'holder, '_, false>` - = note: required for `AtomicPtr<()>` to implement `FromPyObject<'_, '_>` - = note: required for `AtomicPtr<()>` to implement `PyFunctionArgument<'_, '_, '_, true>` + --> tests/ui/invalid_pyfunction_argument.rs:5:37 + | + 5 | fn invalid_pyfunction_argument(arg: AtomicPtr<()>) { + | ^^^^^^^^^ the trait `ExtractPyClassWithClone` is not implemented for `AtomicPtr<()>` + | + = note: implement `FromPyObject` to enable using `AtomicPtr<()>` as a function argument + = note: `Python<'py>` is also a valid argument type to pass the Python token into `#[pyfunction]`s and `#[pymethods]` + = help: the following other types implement trait `PyFunctionArgument<'a, 'holder, 'py, IMPLEMENTS_FROMPYOBJECT>`: + `&'holder T` implements `PyFunctionArgument<'a, 'holder, '_, false>` + `&'holder mut T` implements `PyFunctionArgument<'a, 'holder, '_, false>` + `&'holder pyo3::Bound<'py, T>` implements `PyFunctionArgument<'a, 'holder, 'py, false>` + `&'holder str` implements `PyFunctionArgument<'a, 'holder, 'py, false>` + `Option` implements `PyFunctionArgument<'a, 'holder, 'py, false>` + = note: required for `AtomicPtr<()>` to implement `FromPyObject<'_, '_>` + = note: required for `AtomicPtr<()>` to implement `PyFunctionArgument<'_, '_, '_, true>` note: required by a bound in `extract_argument` - --> src/impl_/extract_argument.rs - | - | pub fn extract_argument<'a, 'holder, 'py, T, const IMPLEMENTS_FROMPYOBJECT: bool>( - | ---------------- required by a bound in this function + --> src/impl_/extract_argument.rs:226:8 + | +220 | pub fn extract_argument<'a, 'holder, 'py, T, const IMPLEMENTS_FROMPYOBJECT: bool>( + | ---------------- required by a bound in this function ... - | T: PyFunctionArgument<'a, 'holder, 'py, IMPLEMENTS_FROMPYOBJECT>, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `extract_argument` +226 | T: PyFunctionArgument<'a, 'holder, 'py, IMPLEMENTS_FROMPYOBJECT>, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `extract_argument` error[E0277]: `Foo` cannot be used as a Python function argument - --> tests/ui/invalid_pyfunction_argument.rs:14:59 - | -14 | fn skip_from_py_object_without_custom_from_py_object(arg: Foo) { - | ^^^ unsatisfied trait bound - | + --> tests/ui/invalid_pyfunction_argument.rs:17:59 + | + 17 | fn skip_from_py_object_without_custom_from_py_object(arg: Foo) { + | ^^^ unsatisfied trait bound + | help: the trait `ExtractPyClassWithClone` is not implemented for `Foo` - --> tests/ui/invalid_pyfunction_argument.rs:11:1 - | -11 | struct Foo; - | ^^^^^^^^^^ - = note: implement `FromPyObject` to enable using `Foo` as a function argument - = note: `Python<'py>` is also a valid argument type to pass the Python token into `#[pyfunction]`s and `#[pymethods]` -help: the following other types implement trait `PyFunctionArgument<'a, 'holder, 'py, IMPLEMENTS_FROMPYOBJECT>` - --> src/impl_/extract_argument.rs - | - | / impl<'a, 'holder, 'py, T: 'a + 'py> PyFunctionArgument<'a, 'holder, 'py, false> - | | for &'holder Bound<'py, T> - | | where - | | T: PyTypeCheck, - | |___________________^ `&'holder pyo3::Bound<'py, T>` implements `PyFunctionArgument<'a, 'holder, 'py, false>` -... - | / impl<'a, 'holder, 'py, T> PyFunctionArgument<'a, 'holder, 'py, false> for Option - | | where - | | T: PyFunctionArgument<'a, 'holder, 'py, false>, - | |___________________________________________________^ `Option` implements `PyFunctionArgument<'a, 'holder, 'py, false>` -... - | impl<'a, 'holder, T: PyClass> PyFunctionArgument<'a, 'holder, '_, false> for &'holder T { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `&'holder T` implements `PyFunctionArgument<'a, 'holder, '_, false>` -... - | / impl<'a, 'holder, T: PyClass> PyFunctionArgument<'a, 'holder, '_, false> - | | for &'holder mut T - | |______________________^ `&'holder mut T` implements `PyFunctionArgument<'a, 'holder, '_, false>` - = note: required for `Foo` to implement `FromPyObject<'_, '_>` - = note: required for `Foo` to implement `PyFunctionArgument<'_, '_, '_, true>` + --> tests/ui/invalid_pyfunction_argument.rs:14:1 + | + 14 | struct Foo; + | ^^^^^^^^^^ + = note: implement `FromPyObject` to enable using `Foo` as a function argument + = note: `Python<'py>` is also a valid argument type to pass the Python token into `#[pyfunction]`s and `#[pymethods]` + = help: the following other types implement trait `PyFunctionArgument<'a, 'holder, 'py, IMPLEMENTS_FROMPYOBJECT>`: + `&'holder T` implements `PyFunctionArgument<'a, 'holder, '_, false>` + `&'holder mut T` implements `PyFunctionArgument<'a, 'holder, '_, false>` + `&'holder pyo3::Bound<'py, T>` implements `PyFunctionArgument<'a, 'holder, 'py, false>` + `&'holder str` implements `PyFunctionArgument<'a, 'holder, 'py, false>` + `Option` implements `PyFunctionArgument<'a, 'holder, 'py, false>` + = note: required for `Foo` to implement `FromPyObject<'_, '_>` + = note: required for `Foo` to implement `PyFunctionArgument<'_, '_, '_, true>` note: required by a bound in `extract_argument` - --> src/impl_/extract_argument.rs - | - | pub fn extract_argument<'a, 'holder, 'py, T, const IMPLEMENTS_FROMPYOBJECT: bool>( - | ---------------- required by a bound in this function + --> src/impl_/extract_argument.rs:226:8 + | +220 | pub fn extract_argument<'a, 'holder, 'py, T, const IMPLEMENTS_FROMPYOBJECT: bool>( + | ---------------- required by a bound in this function ... - | T: PyFunctionArgument<'a, 'holder, 'py, IMPLEMENTS_FROMPYOBJECT>, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `extract_argument` +226 | T: PyFunctionArgument<'a, 'holder, 'py, IMPLEMENTS_FROMPYOBJECT>, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `extract_argument` + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/invalid_pyfunction_definition.rs b/tests/ui/invalid_pyfunction_definition.rs index 2f08ff421b9..7dfad1eb38c 100644 --- a/tests/ui/invalid_pyfunction_definition.rs +++ b/tests/ui/invalid_pyfunction_definition.rs @@ -9,6 +9,7 @@ mod pyo3_scratch { impl Foo { #[pyfunction] fn bug() {} +//~^ ERROR: functions inside #[pymethods] do not need to be annotated with #[pyfunction] } } diff --git a/tests/ui/invalid_pyfunction_definition.stderr b/tests/ui/invalid_pyfunction_definition.stderr index 9c7cac1f0f3..7ebb07c5d93 100644 --- a/tests/ui/invalid_pyfunction_definition.stderr +++ b/tests/ui/invalid_pyfunction_definition.stderr @@ -3,3 +3,6 @@ error: functions inside #[pymethods] do not need to be annotated with #[pyfuncti | 11 | fn bug() {} | ^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/invalid_pyfunction_signatures.rs b/tests/ui/invalid_pyfunction_signatures.rs index d6799885cbb..ab227e19da9 100644 --- a/tests/ui/invalid_pyfunction_signatures.rs +++ b/tests/ui/invalid_pyfunction_signatures.rs @@ -3,19 +3,23 @@ use pyo3::types::{PyDict, PyTuple}; #[pyfunction] #[pyo3(signature = ())] +//~^ ERROR: missing signature entry for argument `_x` fn function_with_one_argument_empty_signature(_x: i32) {} #[pyfunction] #[pyo3(signature = (x))] +//~^ ERROR: signature entry does not have a corresponding function argument fn function_with_one_entry_signature_no_args() {} #[pyfunction] #[pyo3(signature = (x))] +//~^ ERROR: expected argument from function definition `y` but got argument `x` fn function_with_incorrect_argument_names(y: i32) { let _ = y; } #[pyfunction(x)] +//~^ ERROR: expected one of: `name`, `pass_module`, `signature`, `text_signature`, `crate`, `warn` #[pyo3(signature = (x))] fn function_with_both_args_and_signature(x: i32) { let _ = x; @@ -23,16 +27,19 @@ fn function_with_both_args_and_signature(x: i32) { #[pyfunction] #[pyo3(signature = (*, *args))] +//~^ ERROR: `*args` not allowed after `*` fn function_with_args_after_args_sep(args: &PyTuple) { let _ = args; } #[pyfunction] #[pyo3(signature = (*, *))] +//~^ ERROR: `*` not allowed after `*` fn function_with_args_sep_after_args_sep() {} #[pyfunction] #[pyo3(signature = (**kwargs, *args))] +//~^ ERROR: `*args` not allowed after `**kwargs` fn function_with_args_after_kwargs(kwargs: Option<&PyDict>, args: &PyTuple) { let _ = args; let _ = kwargs; @@ -40,12 +47,14 @@ fn function_with_args_after_kwargs(kwargs: Option<&PyDict>, args: &PyTuple) { #[pyfunction] #[pyo3(signature = (**kwargs_a, **kwargs_b))] +//~^ ERROR: `**kwargs_b` not allowed after `**kwargs_a` fn function_with_kwargs_after_kwargs(kwargs_a: Option<&PyDict>, kwargs_b: Option<&PyDict>) { let _ = kwargs_a; let _ = kwargs_b; } #[pyfunction(signature = (py))] +//~^ ERROR: arguments of type `Python` must not be part of the signature fn signature_contains_py(py: Python<'_>) { let _ = py; } @@ -56,6 +65,7 @@ struct MyClass; #[pymethods] impl MyClass { #[pyo3(signature = (**kwargs, *, *args, x))] +//~^ ERROR: expected argument from function definition `args` but got argument `kwargs` fn multiple_errors_same_order(kwargs: Option<&PyDict>, args: &PyTuple, x: i32) { let _ = kwargs; let _ = args; @@ -63,6 +73,7 @@ impl MyClass { } #[pyo3(signature = (**kwargs, *, *args, x))] +//~^ ERROR: expected argument from function definition `x` but got argument `kwargs` fn multiple_errors_different_order(args: &PyTuple, x: i32, kwargs: Option<&PyDict>) { let _ = kwargs; let _ = args; diff --git a/tests/ui/invalid_pyfunction_signatures.stderr b/tests/ui/invalid_pyfunction_signatures.stderr index c7ddb11dd37..b36b650f7b1 100644 --- a/tests/ui/invalid_pyfunction_signatures.stderr +++ b/tests/ui/invalid_pyfunction_signatures.stderr @@ -5,61 +5,64 @@ error: missing signature entry for argument `_x` | ^^^^^^^^^ error: signature entry does not have a corresponding function argument - --> tests/ui/invalid_pyfunction_signatures.rs:9:21 - | -9 | #[pyo3(signature = (x))] - | ^ + --> tests/ui/invalid_pyfunction_signatures.rs:10:21 + | +10 | #[pyo3(signature = (x))] + | ^ error: expected argument from function definition `y` but got argument `x` - --> tests/ui/invalid_pyfunction_signatures.rs:13:21 + --> tests/ui/invalid_pyfunction_signatures.rs:15:21 | -13 | #[pyo3(signature = (x))] +15 | #[pyo3(signature = (x))] | ^ error: expected one of: `name`, `pass_module`, `signature`, `text_signature`, `crate`, `warn` - --> tests/ui/invalid_pyfunction_signatures.rs:18:14 + --> tests/ui/invalid_pyfunction_signatures.rs:21:14 | -18 | #[pyfunction(x)] +21 | #[pyfunction(x)] | ^ error: `*args` not allowed after `*` - --> tests/ui/invalid_pyfunction_signatures.rs:25:24 + --> tests/ui/invalid_pyfunction_signatures.rs:29:24 | -25 | #[pyo3(signature = (*, *args))] +29 | #[pyo3(signature = (*, *args))] | ^ error: `*` not allowed after `*` - --> tests/ui/invalid_pyfunction_signatures.rs:31:24 + --> tests/ui/invalid_pyfunction_signatures.rs:36:24 | -31 | #[pyo3(signature = (*, *))] +36 | #[pyo3(signature = (*, *))] | ^ error: `*args` not allowed after `**kwargs` - --> tests/ui/invalid_pyfunction_signatures.rs:35:31 + --> tests/ui/invalid_pyfunction_signatures.rs:41:31 | -35 | #[pyo3(signature = (**kwargs, *args))] +41 | #[pyo3(signature = (**kwargs, *args))] | ^ error: `**kwargs_b` not allowed after `**kwargs_a` - --> tests/ui/invalid_pyfunction_signatures.rs:42:33 + --> tests/ui/invalid_pyfunction_signatures.rs:49:33 | -42 | #[pyo3(signature = (**kwargs_a, **kwargs_b))] +49 | #[pyo3(signature = (**kwargs_a, **kwargs_b))] | ^ error: arguments of type `Python` must not be part of the signature - --> tests/ui/invalid_pyfunction_signatures.rs:48:27 + --> tests/ui/invalid_pyfunction_signatures.rs:56:27 | -48 | #[pyfunction(signature = (py))] +56 | #[pyfunction(signature = (py))] | ^^ error: expected argument from function definition `args` but got argument `kwargs` - --> tests/ui/invalid_pyfunction_signatures.rs:58:27 + --> tests/ui/invalid_pyfunction_signatures.rs:67:27 | -58 | #[pyo3(signature = (**kwargs, *, *args, x))] +67 | #[pyo3(signature = (**kwargs, *, *args, x))] | ^^^^^^ error: expected argument from function definition `x` but got argument `kwargs` - --> tests/ui/invalid_pyfunction_signatures.rs:65:27 + --> tests/ui/invalid_pyfunction_signatures.rs:75:27 | -65 | #[pyo3(signature = (**kwargs, *, *args, x))] +75 | #[pyo3(signature = (**kwargs, *, *args, x))] | ^^^^^^ + +error: aborting due to 11 previous errors + diff --git a/tests/ui/invalid_pyfunction_warn.rs b/tests/ui/invalid_pyfunction_warn.rs index fe1b72dbc3f..974bc535201 100644 --- a/tests/ui/invalid_pyfunction_warn.rs +++ b/tests/ui/invalid_pyfunction_warn.rs @@ -2,26 +2,32 @@ use pyo3::prelude::*; #[pyfunction] #[pyo3(warn)] +//~^ ERROR: unexpected end of input, expected parentheses fn no_parenthesis_deprecated() {} #[pyfunction] #[pyo3(warn())] +//~^ ERROR: missing `message` in `warn` attribute fn no_message_deprecated() {} #[pyfunction] #[pyo3(warn(category = pyo3::exceptions::PyDeprecationWarning))] +//~^ ERROR: missing `message` in `warn` attribute fn no_message_deprecated_with_category() {} #[pyfunction] #[pyo3(warn(category = pyo3::exceptions::PyDeprecationWarning, message = ,))] +//~^ ERROR: expected string literal fn empty_message_deprecated_with_category() {} #[pyfunction] #[pyo3(warn(message = "deprecated function", category = ,))] +//~^ ERROR: expected identifier fn empty_category_deprecated_with_message() {} #[pyfunction] #[pyo3(warn(message = "deprecated function", random_key))] +//~^ ERROR: expected `message` or `category` fn random_key_deprecated() {} #[pyclass] @@ -31,6 +37,7 @@ struct DeprecatedMethodContainer {} impl DeprecatedMethodContainer { #[classattr] #[pyo3(warn(message = "deprecated class attr"))] +//~^ ERROR: #[classattr] cannot be used with #[pyo3(warn)] fn deprecated_class_attr() -> i32 { 5 } @@ -39,6 +46,7 @@ impl DeprecatedMethodContainer { #[pymethods] impl DeprecatedMethodContainer { #[pyo3(warn(message = "deprecated __traverse__"))] +//~^ ERROR: __traverse__ cannot be used with #[pyo3(warn)] fn __traverse__(&self, _visit: pyo3::gc::PyVisit<'_>) -> Result<(), pyo3::PyTraverseError> { Ok(()) } diff --git a/tests/ui/invalid_pyfunction_warn.stderr b/tests/ui/invalid_pyfunction_warn.stderr index 584abfcdeaf..ec9b4d520bc 100644 --- a/tests/ui/invalid_pyfunction_warn.stderr +++ b/tests/ui/invalid_pyfunction_warn.stderr @@ -5,43 +5,46 @@ error: unexpected end of input, expected parentheses | ^ error: missing `message` in `warn` attribute - --> tests/ui/invalid_pyfunction_warn.rs:8:13 + --> tests/ui/invalid_pyfunction_warn.rs:9:13 | -8 | #[pyo3(warn())] +9 | #[pyo3(warn())] | ^ error: missing `message` in `warn` attribute - --> tests/ui/invalid_pyfunction_warn.rs:12:62 + --> tests/ui/invalid_pyfunction_warn.rs:14:62 | -12 | #[pyo3(warn(category = pyo3::exceptions::PyDeprecationWarning))] +14 | #[pyo3(warn(category = pyo3::exceptions::PyDeprecationWarning))] | ^ error: expected string literal - --> tests/ui/invalid_pyfunction_warn.rs:16:74 + --> tests/ui/invalid_pyfunction_warn.rs:19:74 | -16 | #[pyo3(warn(category = pyo3::exceptions::PyDeprecationWarning, message = ,))] +19 | #[pyo3(warn(category = pyo3::exceptions::PyDeprecationWarning, message = ,))] | ^ error: expected identifier - --> tests/ui/invalid_pyfunction_warn.rs:20:57 + --> tests/ui/invalid_pyfunction_warn.rs:24:57 | -20 | #[pyo3(warn(message = "deprecated function", category = ,))] +24 | #[pyo3(warn(message = "deprecated function", category = ,))] | ^ error: expected `message` or `category` - --> tests/ui/invalid_pyfunction_warn.rs:24:46 + --> tests/ui/invalid_pyfunction_warn.rs:29:46 | -24 | #[pyo3(warn(message = "deprecated function", random_key))] +29 | #[pyo3(warn(message = "deprecated function", random_key))] | ^^^^^^^^^^ error: #[classattr] cannot be used with #[pyo3(warn)] - --> tests/ui/invalid_pyfunction_warn.rs:33:12 + --> tests/ui/invalid_pyfunction_warn.rs:39:12 | -33 | #[pyo3(warn(message = "deprecated class attr"))] +39 | #[pyo3(warn(message = "deprecated class attr"))] | ^^^^ error: __traverse__ cannot be used with #[pyo3(warn)] - --> tests/ui/invalid_pyfunction_warn.rs:41:12 + --> tests/ui/invalid_pyfunction_warn.rs:48:12 | -41 | #[pyo3(warn(message = "deprecated __traverse__"))] +48 | #[pyo3(warn(message = "deprecated __traverse__"))] | ^^^^ + +error: aborting due to 8 previous errors + diff --git a/tests/ui/invalid_pyfunctions.rs b/tests/ui/invalid_pyfunctions.rs index cb59808ecc7..05096f252b1 100644 --- a/tests/ui/invalid_pyfunctions.rs +++ b/tests/ui/invalid_pyfunctions.rs @@ -3,34 +3,42 @@ use pyo3::types::{PyDict, PyString, PyTuple}; #[pyfunction] fn generic_function(_value: T) {} +//~^ ERROR: Python functions cannot have generic type parameters #[pyfunction] fn impl_trait_function(_impl_trait: impl AsRef) {} +//~^ ERROR: Python functions cannot have `impl Trait` arguments #[pyfunction] fn wildcard_argument(_: i32) {} +//~^ ERROR: wildcard argument names are not supported #[pyfunction] fn destructured_argument((_a, _b): (i32, i32)) {} +//~^ ERROR: destructuring in arguments is not supported #[pyfunction] #[pyo3(signature=(*args))] fn function_with_optional_args(args: Option>) { +//~^ ERROR: args cannot be optional let _ = args; } #[pyfunction] #[pyo3(signature=(**kwargs))] fn function_with_required_kwargs(kwargs: Bound<'_, PyDict>) { +//~^ ERROR: kwargs must be Option<_> let _ = kwargs; } #[pyfunction(pass_module)] fn pass_module_but_no_arguments<'py>() {} +//~^ ERROR: expected `&PyModule` or `Py` as first argument with `pass_module` #[pyfunction(pass_module)] fn first_argument_not_module<'a, 'py>( _string: &str, +//~^ ERROR: the trait bound `&str: From>` is not satisfied module: &'a Bound<'py, PyModule>, ) -> PyResult> { module.name() diff --git a/tests/ui/invalid_pyfunctions.stderr b/tests/ui/invalid_pyfunctions.stderr index e48c522976a..80a517aa8f5 100644 --- a/tests/ui/invalid_pyfunctions.stderr +++ b/tests/ui/invalid_pyfunctions.stderr @@ -5,45 +5,45 @@ error: Python functions cannot have generic type parameters | ^ error: Python functions cannot have `impl Trait` arguments - --> tests/ui/invalid_pyfunctions.rs:8:37 + --> tests/ui/invalid_pyfunctions.rs:9:37 | -8 | fn impl_trait_function(_impl_trait: impl AsRef) {} +9 | fn impl_trait_function(_impl_trait: impl AsRef) {} | ^^^^ error: wildcard argument names are not supported - --> tests/ui/invalid_pyfunctions.rs:11:22 + --> tests/ui/invalid_pyfunctions.rs:13:22 | -11 | fn wildcard_argument(_: i32) {} +13 | fn wildcard_argument(_: i32) {} | ^ error: destructuring in arguments is not supported - --> tests/ui/invalid_pyfunctions.rs:14:26 + --> tests/ui/invalid_pyfunctions.rs:17:26 | -14 | fn destructured_argument((_a, _b): (i32, i32)) {} +17 | fn destructured_argument((_a, _b): (i32, i32)) {} | ^^^^^^^^ error: args cannot be optional - --> tests/ui/invalid_pyfunctions.rs:18:32 + --> tests/ui/invalid_pyfunctions.rs:22:32 | -18 | fn function_with_optional_args(args: Option>) { +22 | fn function_with_optional_args(args: Option>) { | ^^^^ error: kwargs must be Option<_> - --> tests/ui/invalid_pyfunctions.rs:24:34 + --> tests/ui/invalid_pyfunctions.rs:29:34 | -24 | fn function_with_required_kwargs(kwargs: Bound<'_, PyDict>) { +29 | fn function_with_required_kwargs(kwargs: Bound<'_, PyDict>) { | ^^^^^^ error: expected `&PyModule` or `Py` as first argument with `pass_module` - --> tests/ui/invalid_pyfunctions.rs:29:37 + --> tests/ui/invalid_pyfunctions.rs:35:37 | -29 | fn pass_module_but_no_arguments<'py>() {} +35 | fn pass_module_but_no_arguments<'py>() {} | ^^ error[E0277]: the trait bound `&str: From>` is not satisfied - --> tests/ui/invalid_pyfunctions.rs:33:14 + --> tests/ui/invalid_pyfunctions.rs:40:14 | -33 | _string: &str, +40 | _string: &str, | ^ the trait `From>` is not implemented for `&str` | = help: the following other types implement trait `From`: @@ -54,3 +54,7 @@ error[E0277]: the trait bound `&str: From>` `String` implements `From` = note: required for `BoundRef<'_, '_, pyo3::types::PyModule>` to implement `Into<&str>` + +error: aborting due to 8 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/invalid_pymethod_enum.rs b/tests/ui/invalid_pymethod_enum.rs index 5c41d19d4e7..062f8b00cc2 100644 --- a/tests/ui/invalid_pymethod_enum.rs +++ b/tests/ui/invalid_pymethod_enum.rs @@ -7,8 +7,10 @@ enum ComplexEnum { } #[pymethods] +//~^ ERROR: type mismatch resolving `::Frozen == False` impl ComplexEnum { fn mutate_in_place(&mut self) { +//~^ ERROR: type mismatch resolving `::Frozen == False` *self = match self { ComplexEnum::Int { int } => ComplexEnum::Str { string: int.to_string() }, ComplexEnum::Str { string } => ComplexEnum::Int { int: string.len() as i32 }, @@ -23,8 +25,10 @@ enum TupleEnum { } #[pymethods] +//~^ ERROR: type mismatch resolving `::Frozen == False` impl TupleEnum { fn mutate_in_place(&mut self) { +//~^ ERROR: type mismatch resolving `::Frozen == False` *self = match self { TupleEnum::Int(int) => TupleEnum::Str(int.to_string()), TupleEnum::Str(string) => TupleEnum::Int(string.len() as i32), diff --git a/tests/ui/invalid_pymethod_enum.stderr b/tests/ui/invalid_pymethod_enum.stderr index 3c574320cb5..9c057d49cab 100644 --- a/tests/ui/invalid_pymethod_enum.stderr +++ b/tests/ui/invalid_pymethod_enum.stderr @@ -1,71 +1,75 @@ error[E0271]: type mismatch resolving `::Frozen == False` - --> tests/ui/invalid_pymethod_enum.rs:11:24 - | -11 | fn mutate_in_place(&mut self) { - | ^ type mismatch resolving `::Frozen == False` - | + --> tests/ui/invalid_pymethod_enum.rs:12:24 + | + 12 | fn mutate_in_place(&mut self) { + | ^ type mismatch resolving `::Frozen == False` + | note: expected this to be `False` - --> tests/ui/invalid_pymethod_enum.rs:3:1 - | - 3 | #[pyclass] - | ^^^^^^^^^^ + --> tests/ui/invalid_pymethod_enum.rs:3:1 + | + 3 | #[pyclass] + | ^^^^^^^^^^ note: required by a bound in `extract_pyclass_ref_mut` - --> src/impl_/extract_argument.rs - | - | pub fn extract_pyclass_ref_mut<'a, 'holder, T: PyClass>( - | ^^^^^^^^^^^^^^ required by this bound in `extract_pyclass_ref_mut` - = note: this error originates in the attribute macro `pyclass` (in Nightly builds, run with -Z macro-backtrace for more info) + --> src/impl_/extract_argument.rs:212:56 + | +212 | pub fn extract_pyclass_ref_mut<'a, 'holder, T: PyClass>( + | ^^^^^^^^^^^^^^ required by this bound in `extract_pyclass_ref_mut` + = note: this error originates in the attribute macro `pyclass` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0271]: type mismatch resolving `::Frozen == False` - --> tests/ui/invalid_pymethod_enum.rs:9:1 - | -9 | #[pymethods] - | ^^^^^^^^^^^^ type mismatch resolving `::Frozen == False` - | + --> tests/ui/invalid_pymethod_enum.rs:9:1 + | + 9 | #[pymethods] + | ^^^^^^^^^^^^ type mismatch resolving `::Frozen == False` + | note: expected this to be `False` - --> tests/ui/invalid_pymethod_enum.rs:3:1 - | -3 | #[pyclass] - | ^^^^^^^^^^ + --> tests/ui/invalid_pymethod_enum.rs:3:1 + | + 3 | #[pyclass] + | ^^^^^^^^^^ note: required by a bound in `PyClassGuardMut` - --> src/pyclass/guard.rs - | - | pub struct PyClassGuardMut<'a, T: PyClass> { - | ^^^^^^^^^^^^^^ required by this bound in `PyClassGuardMut` - = note: this error originates in the attribute macro `pymethods` which comes from the expansion of the attribute macro `pyclass` (in Nightly builds, run with -Z macro-backtrace for more info) + --> src/pyclass/guard.rs:592:43 + | +592 | pub struct PyClassGuardMut<'a, T: PyClass> { + | ^^^^^^^^^^^^^^ required by this bound in `PyClassGuardMut` + = note: this error originates in the attribute macro `pymethods` which comes from the expansion of the attribute macro `pyclass` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0271]: type mismatch resolving `::Frozen == False` - --> tests/ui/invalid_pymethod_enum.rs:27:24 - | -27 | fn mutate_in_place(&mut self) { - | ^ type mismatch resolving `::Frozen == False` - | + --> tests/ui/invalid_pymethod_enum.rs:30:24 + | + 30 | fn mutate_in_place(&mut self) { + | ^ type mismatch resolving `::Frozen == False` + | note: expected this to be `False` - --> tests/ui/invalid_pymethod_enum.rs:19:1 - | -19 | #[pyclass] - | ^^^^^^^^^^ + --> tests/ui/invalid_pymethod_enum.rs:21:1 + | + 21 | #[pyclass] + | ^^^^^^^^^^ note: required by a bound in `extract_pyclass_ref_mut` - --> src/impl_/extract_argument.rs - | - | pub fn extract_pyclass_ref_mut<'a, 'holder, T: PyClass>( - | ^^^^^^^^^^^^^^ required by this bound in `extract_pyclass_ref_mut` - = note: this error originates in the attribute macro `pyclass` (in Nightly builds, run with -Z macro-backtrace for more info) + --> src/impl_/extract_argument.rs:212:56 + | +212 | pub fn extract_pyclass_ref_mut<'a, 'holder, T: PyClass>( + | ^^^^^^^^^^^^^^ required by this bound in `extract_pyclass_ref_mut` + = note: this error originates in the attribute macro `pyclass` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0271]: type mismatch resolving `::Frozen == False` - --> tests/ui/invalid_pymethod_enum.rs:25:1 - | -25 | #[pymethods] - | ^^^^^^^^^^^^ type mismatch resolving `::Frozen == False` - | + --> tests/ui/invalid_pymethod_enum.rs:27:1 + | + 27 | #[pymethods] + | ^^^^^^^^^^^^ type mismatch resolving `::Frozen == False` + | note: expected this to be `False` - --> tests/ui/invalid_pymethod_enum.rs:19:1 - | -19 | #[pyclass] - | ^^^^^^^^^^ + --> tests/ui/invalid_pymethod_enum.rs:21:1 + | + 21 | #[pyclass] + | ^^^^^^^^^^ note: required by a bound in `PyClassGuardMut` - --> src/pyclass/guard.rs - | - | pub struct PyClassGuardMut<'a, T: PyClass> { - | ^^^^^^^^^^^^^^ required by this bound in `PyClassGuardMut` - = note: this error originates in the attribute macro `pymethods` which comes from the expansion of the attribute macro `pyclass` (in Nightly builds, run with -Z macro-backtrace for more info) + --> src/pyclass/guard.rs:592:43 + | +592 | pub struct PyClassGuardMut<'a, T: PyClass> { + | ^^^^^^^^^^^^^^ required by this bound in `PyClassGuardMut` + = note: this error originates in the attribute macro `pymethods` which comes from the expansion of the attribute macro `pyclass` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0271`. diff --git a/tests/ui/invalid_pymethod_names.rs b/tests/ui/invalid_pymethod_names.rs index 1334bcabde4..6d910fc8f8a 100644 --- a/tests/ui/invalid_pymethod_names.rs +++ b/tests/ui/invalid_pymethod_names.rs @@ -9,6 +9,7 @@ struct TestClass { impl TestClass { #[pyo3(name = "num")] #[getter(number)] +//~^ ERROR: `name` may only be specified once fn get_num(&self) -> u32 { self.num } } @@ -16,12 +17,14 @@ impl TestClass { impl TestClass { #[pyo3(name = "foo")] #[pyo3(name = "bar")] +//~^ ERROR: `name` may only be specified once fn qux(&self) -> u32 { self.num } } #[pymethods] impl TestClass { #[pyo3(name = "makenew")] +//~^ ERROR: `name` not allowed with `#[new]` #[new] fn new(&self) -> Self { Self { num: 0 } } } @@ -29,12 +32,14 @@ impl TestClass { #[pymethods] impl TestClass { #[getter(1)] +//~^ ERROR: expected ident or string literal for property name fn get_one(&self) -> Self { Self { num: 0 } } } #[pymethods] impl TestClass { #[getter = 1] +//~^ ERROR: expected `#[getter(name)]` to set the name fn get_two(&self) -> Self { Self { num: 0 } } } diff --git a/tests/ui/invalid_pymethod_names.stderr b/tests/ui/invalid_pymethod_names.stderr index 1e7a6f44065..bf8ff8f9514 100644 --- a/tests/ui/invalid_pymethod_names.stderr +++ b/tests/ui/invalid_pymethod_names.stderr @@ -5,25 +5,28 @@ error: `name` may only be specified once | ^^^^^^ error: `name` may only be specified once - --> tests/ui/invalid_pymethod_names.rs:18:12 + --> tests/ui/invalid_pymethod_names.rs:19:12 | -18 | #[pyo3(name = "bar")] +19 | #[pyo3(name = "bar")] | ^^^^ error: `name` not allowed with `#[new]` - --> tests/ui/invalid_pymethod_names.rs:24:19 + --> tests/ui/invalid_pymethod_names.rs:26:19 | -24 | #[pyo3(name = "makenew")] +26 | #[pyo3(name = "makenew")] | ^^^^^^^^^ error: expected ident or string literal for property name - --> tests/ui/invalid_pymethod_names.rs:31:14 + --> tests/ui/invalid_pymethod_names.rs:34:14 | -31 | #[getter(1)] +34 | #[getter(1)] | ^ error: expected `#[getter(name)]` to set the name - --> tests/ui/invalid_pymethod_names.rs:37:14 + --> tests/ui/invalid_pymethod_names.rs:41:14 | -37 | #[getter = 1] +41 | #[getter = 1] | ^ + +error: aborting due to 5 previous errors + diff --git a/tests/ui/invalid_pymethod_receiver.rs b/tests/ui/invalid_pymethod_receiver.rs index 4949ff96022..9d73feffed7 100644 --- a/tests/ui/invalid_pymethod_receiver.rs +++ b/tests/ui/invalid_pymethod_receiver.rs @@ -6,6 +6,7 @@ struct MyClass {} #[pymethods] impl MyClass { fn method_with_invalid_self_type(_slf: i32, _py: Python<'_>, _index: u32) {} +//~^ ERROR: the trait bound `i32: TryFrom>` is not satisfied } fn main() {} diff --git a/tests/ui/invalid_pymethod_receiver.stderr b/tests/ui/invalid_pymethod_receiver.stderr index 7d81c0fae91..4e72fb16a06 100644 --- a/tests/ui/invalid_pymethod_receiver.stderr +++ b/tests/ui/invalid_pymethod_receiver.stderr @@ -12,3 +12,7 @@ error[E0277]: the trait bound `i32: TryFrom>` is not s `i32` implements `From` = note: required for `BoundRef<'_, '_, MyClass>` to implement `Into` = note: required for `i32` to implement `TryFrom>` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/invalid_pymethods.rs b/tests/ui/invalid_pymethods.rs index 372490ca580..c5886dc21ce 100644 --- a/tests/ui/invalid_pymethods.rs +++ b/tests/ui/invalid_pymethods.rs @@ -7,20 +7,26 @@ struct MyClass {} impl MyClass { #[classattr] fn class_attr_with_args(_foo: i32) {} +//~^ ERROR: #[classattr] can only have one argument (of type pyo3::Python) #[classattr(foobar)] +//~^ ERROR: `#[classattr]` does not take any arguments const CLASS_ATTR_WITH_ATTRIBUTE_ARG: i32 = 3; fn staticmethod_without_attribute() {} +//~^ ERROR: static method needs #[staticmethod] attribute #[staticmethod] fn staticmethod_with_receiver(&self) {} +//~^ ERROR: unexpected receiver #[classmethod] fn classmethod_with_receiver(&self) {} +//~^ ERROR: Expected `&Bound` or `Py` as the first argument to `#[classmethod]` #[classmethod] fn classmethod_missing_argument() -> Self { +//~^ ERROR: Expected `&Bound` or `Py` as the first argument to `#[classmethod]` Self {} } } @@ -31,6 +37,7 @@ struct NotATypeObject; impl MyClass { #[classmethod] fn classmethod_wrong_first_argument(_t: NotATypeObject) -> Self { +//~^ ERROR: the trait bound `NotATypeObject: From>` is not satisfied Self {} } } @@ -39,36 +46,44 @@ impl MyClass { impl MyClass { #[getter(x)] fn getter_without_receiver() {} +//~^ ERROR: expected receiver for `#[getter]` } #[pymethods] impl MyClass { #[setter(x)] fn setter_without_receiver() {} +//~^ ERROR: expected receiver for `#[setter]` } #[pymethods] impl MyClass { #[pyo3(name = "__call__", text_signature = "()")] fn text_signature_on_call() {} +//~^ ERROR: static method needs #[staticmethod] attribute #[getter(x)] #[pyo3(text_signature = "()")] +//~^ ERROR: `text_signature` not allowed with `getter` fn text_signature_on_getter(&self) {} #[setter(x)] #[pyo3(text_signature = "()")] +//~^ ERROR: `text_signature` not allowed with `setter` fn text_signature_on_setter(&self) {} #[classattr] #[pyo3(text_signature = "()")] +//~^ ERROR: `text_signature` not allowed with `classattr` fn text_signature_on_classattr() {} #[pyo3(text_signature = 1)] +//~^ ERROR: expected a string literal or `None` fn invalid_text_signature() {} #[pyo3(text_signature = "()")] #[pyo3(text_signature = None)] +//~^ ERROR: `text_signature` may only be specified once fn duplicate_text_signature() {} } @@ -76,20 +91,24 @@ impl MyClass { impl MyClass { #[getter(x)] #[pyo3(signature = ())] +//~^ ERROR: `signature` not allowed with `getter` fn signature_on_getter(&self) {} #[setter(x)] #[pyo3(signature = ())] +//~^ ERROR: `signature` not allowed with `setter` fn signature_on_setter(&self) {} #[classattr] #[pyo3(signature = ())] +//~^ ERROR: `signature` not allowed with `classattr` fn signature_on_classattr() {} } #[pymethods] impl MyClass { #[new] +//~^ ERROR: `#[new]` may not be combined with `#[classmethod]` `#[staticmethod]`, `#[classattr]`, `#[getter]`, and `#[setter]` #[classmethod] #[staticmethod] #[classattr] @@ -101,54 +120,64 @@ impl MyClass { #[pymethods] impl MyClass { #[new(signature = ())] +//~^ ERROR: `#[new]` does not take any arguments fn new_takes_no_arguments(&self) {} } #[pymethods] impl MyClass { #[new = ()] // in this form there's no suggestion to move arguments to `#[pyo3()]` attribute +//~^ ERROR: `#[new]` does not take any arguments fn new_takes_no_arguments_nv(&self) {} } #[pymethods] impl MyClass { #[classmethod(signature = ())] +//~^ ERROR: `#[classmethod]` does not take any arguments fn classmethod_takes_no_arguments(&self) {} } #[pymethods] impl MyClass { #[staticmethod(signature = ())] +//~^ ERROR: `#[staticmethod]` does not take any arguments fn staticmethod_takes_no_arguments(&self) {} } #[pymethods] impl MyClass { #[classattr(signature = ())] +//~^ ERROR: `#[classattr]` does not take any arguments fn classattr_takes_no_arguments(&self) {} } #[pymethods] impl MyClass { fn generic_method(_value: T) {} +//~^ ERROR: Python functions cannot have generic type parameters } #[pymethods] impl MyClass { fn impl_trait_method_first_arg(_impl_trait: impl AsRef) {} +//~^ ERROR: Python functions cannot have `impl Trait` arguments fn impl_trait_method_second_arg(&self, _impl_trait: impl AsRef) {} +//~^ ERROR: Python functions cannot have `impl Trait` arguments } #[pymethods] impl MyClass { #[pyo3(pass_module)] +//~^ ERROR: `pass_module` cannot be used on Python methods fn method_cannot_pass_module(&self, _m: &PyModule) {} } #[pymethods] impl MyClass { fn method_self_by_value(self) {} +//~^ ERROR: Python objects are shared, so 'self' cannot be moved out of the Python interpreter. } macro_rules! macro_invocation { @@ -158,19 +187,23 @@ macro_rules! macro_invocation { #[pymethods] impl MyClass { macro_invocation!(); +//~^ ERROR: macros cannot be used as items in `#[pymethods]` impl blocks } #[pymethods] impl MyClass { #[staticmethod] +//~^ ERROR: `#[staticmethod]` may not be combined with `#[classmethod]` #[classmethod] fn multiple_errors_static_and_class_method() {} #[staticmethod] fn multiple_errors_staticmethod_with_receiver(&self) {} +//~^ ERROR: unexpected receiver #[classmethod] fn multiple_errors_classmethod_with_receiver(&self) {} +//~^ ERROR: Expected `&Bound` or `Py` as the first argument to `#[classmethod]` } fn main() {} diff --git a/tests/ui/invalid_pymethods.stderr b/tests/ui/invalid_pymethods.stderr index 94c3604e7fe..866ee9d9e8d 100644 --- a/tests/ui/invalid_pymethods.stderr +++ b/tests/ui/invalid_pymethods.stderr @@ -5,207 +5,211 @@ error: #[classattr] can only have one argument (of type pyo3::Python) | ^^^ error: `#[classattr]` does not take any arguments - --> tests/ui/invalid_pymethods.rs:11:5 + --> tests/ui/invalid_pymethods.rs:12:5 | -11 | #[classattr(foobar)] +12 | #[classattr(foobar)] | ^ error: static method needs #[staticmethod] attribute - --> tests/ui/invalid_pymethods.rs:14:5 + --> tests/ui/invalid_pymethods.rs:16:5 | -14 | fn staticmethod_without_attribute() {} +16 | fn staticmethod_without_attribute() {} | ^^ error: unexpected receiver - --> tests/ui/invalid_pymethods.rs:17:35 + --> tests/ui/invalid_pymethods.rs:20:35 | -17 | fn staticmethod_with_receiver(&self) {} +20 | fn staticmethod_with_receiver(&self) {} | ^ error: Expected `&Bound` or `Py` as the first argument to `#[classmethod]` - --> tests/ui/invalid_pymethods.rs:20:33 + --> tests/ui/invalid_pymethods.rs:24:33 | -20 | fn classmethod_with_receiver(&self) {} +24 | fn classmethod_with_receiver(&self) {} | ^^^^^^^ error: Expected `&Bound` or `Py` as the first argument to `#[classmethod]` - --> tests/ui/invalid_pymethods.rs:23:36 + --> tests/ui/invalid_pymethods.rs:28:36 | -23 | fn classmethod_missing_argument() -> Self { +28 | fn classmethod_missing_argument() -> Self { | ^^ error: expected receiver for `#[getter]` - --> tests/ui/invalid_pymethods.rs:41:5 + --> tests/ui/invalid_pymethods.rs:48:5 | -41 | fn getter_without_receiver() {} +48 | fn getter_without_receiver() {} | ^^ error: expected receiver for `#[setter]` - --> tests/ui/invalid_pymethods.rs:47:5 + --> tests/ui/invalid_pymethods.rs:55:5 | -47 | fn setter_without_receiver() {} +55 | fn setter_without_receiver() {} | ^^ error: static method needs #[staticmethod] attribute - --> tests/ui/invalid_pymethods.rs:53:5 + --> tests/ui/invalid_pymethods.rs:62:5 | -53 | fn text_signature_on_call() {} +62 | fn text_signature_on_call() {} | ^^ error: `text_signature` not allowed with `getter` - --> tests/ui/invalid_pymethods.rs:56:12 + --> tests/ui/invalid_pymethods.rs:66:12 | -56 | #[pyo3(text_signature = "()")] +66 | #[pyo3(text_signature = "()")] | ^^^^^^^^^^^^^^ error: `text_signature` not allowed with `setter` - --> tests/ui/invalid_pymethods.rs:60:12 + --> tests/ui/invalid_pymethods.rs:71:12 | -60 | #[pyo3(text_signature = "()")] +71 | #[pyo3(text_signature = "()")] | ^^^^^^^^^^^^^^ error: `text_signature` not allowed with `classattr` - --> tests/ui/invalid_pymethods.rs:64:12 + --> tests/ui/invalid_pymethods.rs:76:12 | -64 | #[pyo3(text_signature = "()")] +76 | #[pyo3(text_signature = "()")] | ^^^^^^^^^^^^^^ error: expected a string literal or `None` - --> tests/ui/invalid_pymethods.rs:67:30 + --> tests/ui/invalid_pymethods.rs:80:30 | -67 | #[pyo3(text_signature = 1)] +80 | #[pyo3(text_signature = 1)] | ^ error: `text_signature` may only be specified once - --> tests/ui/invalid_pymethods.rs:71:12 + --> tests/ui/invalid_pymethods.rs:85:12 | -71 | #[pyo3(text_signature = None)] +85 | #[pyo3(text_signature = None)] | ^^^^^^^^^^^^^^ error: `signature` not allowed with `getter` - --> tests/ui/invalid_pymethods.rs:78:12 + --> tests/ui/invalid_pymethods.rs:93:12 | -78 | #[pyo3(signature = ())] +93 | #[pyo3(signature = ())] | ^^^^^^^^^ error: `signature` not allowed with `setter` - --> tests/ui/invalid_pymethods.rs:82:12 + --> tests/ui/invalid_pymethods.rs:98:12 | -82 | #[pyo3(signature = ())] +98 | #[pyo3(signature = ())] | ^^^^^^^^^ error: `signature` not allowed with `classattr` - --> tests/ui/invalid_pymethods.rs:86:12 - | -86 | #[pyo3(signature = ())] - | ^^^^^^^^^ + --> tests/ui/invalid_pymethods.rs:103:12 + | +103 | #[pyo3(signature = ())] + | ^^^^^^^^^ error: `#[new]` may not be combined with `#[classmethod]` `#[staticmethod]`, `#[classattr]`, `#[getter]`, and `#[setter]` - --> tests/ui/invalid_pymethods.rs:92:7 - | -92 | #[new] - | ^^^ + --> tests/ui/invalid_pymethods.rs:110:7 + | +110 | #[new] + | ^^^ error: `#[new]` does not take any arguments = help: did you mean `#[new] #[pyo3(signature = ())]`? - --> tests/ui/invalid_pymethods.rs:103:7 + --> tests/ui/invalid_pymethods.rs:122:7 | -103 | #[new(signature = ())] +122 | #[new(signature = ())] | ^^^ error: `#[new]` does not take any arguments = note: this was previously accepted and ignored - --> tests/ui/invalid_pymethods.rs:109:11 + --> tests/ui/invalid_pymethods.rs:129:11 | -109 | #[new = ()] // in this form there's no suggestion to move arguments to `#[pyo3()]` attribute +129 | #[new = ()] // in this form there's no suggestion to move arguments to `#[pyo3()]` attribute | ^ error: `#[classmethod]` does not take any arguments = help: did you mean `#[classmethod] #[pyo3(signature = ())]`? - --> tests/ui/invalid_pymethods.rs:115:7 + --> tests/ui/invalid_pymethods.rs:136:7 | -115 | #[classmethod(signature = ())] +136 | #[classmethod(signature = ())] | ^^^^^^^^^^^ error: `#[staticmethod]` does not take any arguments = help: did you mean `#[staticmethod] #[pyo3(signature = ())]`? - --> tests/ui/invalid_pymethods.rs:121:7 + --> tests/ui/invalid_pymethods.rs:143:7 | -121 | #[staticmethod(signature = ())] +143 | #[staticmethod(signature = ())] | ^^^^^^^^^^^^ error: `#[classattr]` does not take any arguments = help: did you mean `#[classattr] #[pyo3(signature = ())]`? - --> tests/ui/invalid_pymethods.rs:127:7 + --> tests/ui/invalid_pymethods.rs:150:7 | -127 | #[classattr(signature = ())] +150 | #[classattr(signature = ())] | ^^^^^^^^^ error: Python functions cannot have generic type parameters - --> tests/ui/invalid_pymethods.rs:133:23 + --> tests/ui/invalid_pymethods.rs:157:23 | -133 | fn generic_method(_value: T) {} +157 | fn generic_method(_value: T) {} | ^ error: Python functions cannot have `impl Trait` arguments - --> tests/ui/invalid_pymethods.rs:138:49 + --> tests/ui/invalid_pymethods.rs:163:49 | -138 | fn impl_trait_method_first_arg(_impl_trait: impl AsRef) {} +163 | fn impl_trait_method_first_arg(_impl_trait: impl AsRef) {} | ^^^^ error: Python functions cannot have `impl Trait` arguments - --> tests/ui/invalid_pymethods.rs:140:57 + --> tests/ui/invalid_pymethods.rs:166:57 | -140 | fn impl_trait_method_second_arg(&self, _impl_trait: impl AsRef) {} +166 | fn impl_trait_method_second_arg(&self, _impl_trait: impl AsRef) {} | ^^^^ error: `pass_module` cannot be used on Python methods - --> tests/ui/invalid_pymethods.rs:145:12 + --> tests/ui/invalid_pymethods.rs:172:12 | -145 | #[pyo3(pass_module)] +172 | #[pyo3(pass_module)] | ^^^^^^^^^^^ error: Python objects are shared, so 'self' cannot be moved out of the Python interpreter. Try `&self`, `&mut self, `slf: PyClassGuard<'_, Self>` or `slf: PyClassGuardMut<'_, Self>`. - --> tests/ui/invalid_pymethods.rs:151:29 + --> tests/ui/invalid_pymethods.rs:179:29 | -151 | fn method_self_by_value(self) {} +179 | fn method_self_by_value(self) {} | ^^^^ error: macros cannot be used as items in `#[pymethods]` impl blocks = note: this was previously accepted and ignored - --> tests/ui/invalid_pymethods.rs:160:5 + --> tests/ui/invalid_pymethods.rs:189:5 | -160 | macro_invocation!(); +189 | macro_invocation!(); | ^^^^^^^^^^^^^^^^ error: `#[staticmethod]` may not be combined with `#[classmethod]` - --> tests/ui/invalid_pymethods.rs:165:7 + --> tests/ui/invalid_pymethods.rs:195:7 | -165 | #[staticmethod] +195 | #[staticmethod] | ^^^^^^^^^^^^ error: unexpected receiver - --> tests/ui/invalid_pymethods.rs:170:51 + --> tests/ui/invalid_pymethods.rs:201:51 | -170 | fn multiple_errors_staticmethod_with_receiver(&self) {} +201 | fn multiple_errors_staticmethod_with_receiver(&self) {} | ^ error: Expected `&Bound` or `Py` as the first argument to `#[classmethod]` - --> tests/ui/invalid_pymethods.rs:173:49 + --> tests/ui/invalid_pymethods.rs:205:49 | -173 | fn multiple_errors_classmethod_with_receiver(&self) {} +205 | fn multiple_errors_classmethod_with_receiver(&self) {} | ^^^^^^^ error[E0277]: the trait bound `NotATypeObject: From>` is not satisfied - --> tests/ui/invalid_pymethods.rs:33:45 + --> tests/ui/invalid_pymethods.rs:39:45 | -33 | fn classmethod_wrong_first_argument(_t: NotATypeObject) -> Self { +39 | fn classmethod_wrong_first_argument(_t: NotATypeObject) -> Self { | ^^^^^^^^^^^^^^ unsatisfied trait bound | help: the trait `From>` is not implemented for `NotATypeObject` - --> tests/ui/invalid_pymethods.rs:28:1 + --> tests/ui/invalid_pymethods.rs:34:1 | -28 | struct NotATypeObject; +34 | struct NotATypeObject; | ^^^^^^^^^^^^^^^^^^^^^ = note: required for `BoundRef<'_, '_, PyType>` to implement `Into` + +error: aborting due to 33 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/invalid_pymethods_buffer.rs b/tests/ui/invalid_pymethods_buffer.rs index d16eddee37a..f518bdd4774 100644 --- a/tests/ui/invalid_pymethods_buffer.rs +++ b/tests/ui/invalid_pymethods_buffer.rs @@ -7,12 +7,14 @@ struct MyClass {} impl MyClass { #[pyo3(name = "__getbuffer__")] fn getbuffer_must_be_unsafe(&self, _view: *mut pyo3::ffi::Py_buffer, _flags: std::ffi::c_int) {} +//~^ ERROR: `__getbuffer__` must be `unsafe fn` } #[pymethods] impl MyClass { #[pyo3(name = "__releasebuffer__")] fn releasebuffer_must_be_unsafe(&self, _view: *mut pyo3::ffi::Py_buffer) {} +//~^ ERROR: `__releasebuffer__` must be `unsafe fn` } fn main() {} diff --git a/tests/ui/invalid_pymethods_buffer.stderr b/tests/ui/invalid_pymethods_buffer.stderr index 899d4a569f4..4d66108e054 100644 --- a/tests/ui/invalid_pymethods_buffer.stderr +++ b/tests/ui/invalid_pymethods_buffer.stderr @@ -5,7 +5,23 @@ error: `__getbuffer__` must be `unsafe fn` | ^^^^^^^^^^^^^^^^^^^^^^^^ error: `__releasebuffer__` must be `unsafe fn` - --> tests/ui/invalid_pymethods_buffer.rs:15:8 + --> tests/ui/invalid_pymethods_buffer.rs:16:8 | -15 | fn releasebuffer_must_be_unsafe(&self, _view: *mut pyo3::ffi::Py_buffer) {} +16 | fn releasebuffer_must_be_unsafe(&self, _view: *mut pyo3::ffi::Py_buffer) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0425]: cannot find type `Py_buffer` in module `pyo3::ffi` + --> tests/ui/invalid_pymethods_buffer.rs:9:63 + | +9 | fn getbuffer_must_be_unsafe(&self, _view: *mut pyo3::ffi::Py_buffer, _flags: std::ffi::c_int) {} + | ^^^^^^^^^ not found in `pyo3::ffi` + +error[E0425]: cannot find type `Py_buffer` in module `pyo3::ffi` + --> tests/ui/invalid_pymethods_buffer.rs:16:67 + | +16 | fn releasebuffer_must_be_unsafe(&self, _view: *mut pyo3::ffi::Py_buffer) {} + | ^^^^^^^^^ not found in `pyo3::ffi` + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0425`. diff --git a/tests/ui/invalid_pymethods_duplicates.rs b/tests/ui/invalid_pymethods_duplicates.rs index 04435dcb64a..c6f9befd3cb 100644 --- a/tests/ui/invalid_pymethods_duplicates.rs +++ b/tests/ui/invalid_pymethods_duplicates.rs @@ -7,6 +7,8 @@ use pyo3::prelude::*; struct TwoNew {} #[pymethods] +//~^ ERROR: conflicting implementations of trait `PyClassNewTextSignature` for type `TwoNew` +//~| ERROR: duplicate definitions with name `__pymethod___new____` impl TwoNew { #[new] fn new_1() -> Self { @@ -23,6 +25,7 @@ impl TwoNew { struct DuplicateMethod {} #[pymethods] +//~^ ERROR: duplicate definitions with name `__pymethod_func__` impl DuplicateMethod { #[pyo3(name = "func")] fn func_a(&self) {} diff --git a/tests/ui/invalid_pymethods_duplicates.stderr b/tests/ui/invalid_pymethods_duplicates.stderr index 215bc0640cd..92472a2414f 100644 --- a/tests/ui/invalid_pymethods_duplicates.stderr +++ b/tests/ui/invalid_pymethods_duplicates.stderr @@ -21,12 +21,17 @@ error[E0592]: duplicate definitions with name `__pymethod___new____` = note: this error originates in the attribute macro `pymethods` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0592]: duplicate definitions with name `__pymethod_func__` - --> tests/ui/invalid_pymethods_duplicates.rs:25:1 + --> tests/ui/invalid_pymethods_duplicates.rs:27:1 | -25 | #[pymethods] +27 | #[pymethods] | ^^^^^^^^^^^^ | | | duplicate definitions for `__pymethod_func__` | other definition for `__pymethod_func__` | = note: this error originates in the attribute macro `pymethods` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0119, E0592. +For more information about an error, try `rustc --explain E0119`. diff --git a/tests/ui/invalid_pymethods_warn.rs b/tests/ui/invalid_pymethods_warn.rs index 6c6f39f5dc0..0a17a6e9a92 100644 --- a/tests/ui/invalid_pymethods_warn.rs +++ b/tests/ui/invalid_pymethods_warn.rs @@ -6,6 +6,7 @@ struct WarningMethodContainer {} #[pymethods] impl WarningMethodContainer { #[pyo3(warn(message = "warn on __traverse__"))] +//~^ ERROR: __traverse__ cannot be used with #[pyo3(warn)] fn __traverse__(&self) {} } @@ -13,6 +14,7 @@ impl WarningMethodContainer { impl WarningMethodContainer { #[classattr] #[pyo3(warn(message = "warn for class attr"))] +//~^ ERROR: #[classattr] cannot be used with #[pyo3(warn)] fn a_class_attr(_py: pyo3::Python<'_>) -> i64 { 5 } diff --git a/tests/ui/invalid_pymethods_warn.stderr b/tests/ui/invalid_pymethods_warn.stderr index 9e0c8f1d7e9..dcc41ab94d1 100644 --- a/tests/ui/invalid_pymethods_warn.stderr +++ b/tests/ui/invalid_pymethods_warn.stderr @@ -5,7 +5,10 @@ error: __traverse__ cannot be used with #[pyo3(warn)] | ^^^^ error: #[classattr] cannot be used with #[pyo3(warn)] - --> tests/ui/invalid_pymethods_warn.rs:15:12 + --> tests/ui/invalid_pymethods_warn.rs:16:12 | -15 | #[pyo3(warn(message = "warn for class attr"))] +16 | #[pyo3(warn(message = "warn for class attr"))] | ^^^^ + +error: aborting due to 2 previous errors + diff --git a/tests/ui/invalid_pymodule_args.rs b/tests/ui/invalid_pymodule_args.rs index 4a6e65de150..e7eda436a42 100644 --- a/tests/ui/invalid_pymodule_args.rs +++ b/tests/ui/invalid_pymodule_args.rs @@ -1,16 +1,21 @@ use pyo3::prelude::*; #[pymodule(some_arg)] +//~^ ERROR: expected one of: `name`, `crate`, `module`, `submodule`, `gil_used` fn module(m: &Bound<'_, PyModule>) -> PyResult<()> { Ok(()) } #[pyo3::pymodule(gil_used = false, gil_used = true, name = "foo", name = "bar")] +//~^ ERROR: `name` may only be specified once +//~| ERROR: `gil_used` may only be specified once fn module_fn_multiple_errors(m: &Bound<'_, PyModule>) -> PyResult<()> { Ok(()) } #[pyo3::pymodule(gil_used = false, gil_used = true, name = "foo", name = "bar")] +//~^ ERROR: `name` may only be specified once +//~| ERROR: `gil_used` may only be specified once mod pyo3_module_multiple_errors {} fn main() {} diff --git a/tests/ui/invalid_pymodule_args.stderr b/tests/ui/invalid_pymodule_args.stderr index f741d83a82d..de86964e728 100644 --- a/tests/ui/invalid_pymodule_args.stderr +++ b/tests/ui/invalid_pymodule_args.stderr @@ -5,25 +5,28 @@ error: expected one of: `name`, `crate`, `module`, `submodule`, `gil_used` | ^^^^^^^^ error: `gil_used` may only be specified once - --> tests/ui/invalid_pymodule_args.rs:8:36 + --> tests/ui/invalid_pymodule_args.rs:9:36 | -8 | #[pyo3::pymodule(gil_used = false, gil_used = true, name = "foo", name = "bar")] +9 | #[pyo3::pymodule(gil_used = false, gil_used = true, name = "foo", name = "bar")] | ^^^^^^^^ error: `name` may only be specified once - --> tests/ui/invalid_pymodule_args.rs:8:67 + --> tests/ui/invalid_pymodule_args.rs:9:67 | -8 | #[pyo3::pymodule(gil_used = false, gil_used = true, name = "foo", name = "bar")] +9 | #[pyo3::pymodule(gil_used = false, gil_used = true, name = "foo", name = "bar")] | ^^^^ error: `gil_used` may only be specified once - --> tests/ui/invalid_pymodule_args.rs:13:36 + --> tests/ui/invalid_pymodule_args.rs:16:36 | -13 | #[pyo3::pymodule(gil_used = false, gil_used = true, name = "foo", name = "bar")] +16 | #[pyo3::pymodule(gil_used = false, gil_used = true, name = "foo", name = "bar")] | ^^^^^^^^ error: `name` may only be specified once - --> tests/ui/invalid_pymodule_args.rs:13:67 + --> tests/ui/invalid_pymodule_args.rs:16:67 | -13 | #[pyo3::pymodule(gil_used = false, gil_used = true, name = "foo", name = "bar")] +16 | #[pyo3::pymodule(gil_used = false, gil_used = true, name = "foo", name = "bar")] | ^^^^ + +error: aborting due to 5 previous errors + diff --git a/tests/ui/invalid_pymodule_glob.rs b/tests/ui/invalid_pymodule_glob.rs index 853493b535e..14ebc866ea2 100644 --- a/tests/ui/invalid_pymodule_glob.rs +++ b/tests/ui/invalid_pymodule_glob.rs @@ -11,6 +11,7 @@ fn foo() -> usize { mod module { #[pymodule_export] use super::*; +//~^ ERROR: #[pymodule] cannot import glob statements } fn main() {} diff --git a/tests/ui/invalid_pymodule_glob.stderr b/tests/ui/invalid_pymodule_glob.stderr index 1c033083e0c..b2bbc140354 100644 --- a/tests/ui/invalid_pymodule_glob.stderr +++ b/tests/ui/invalid_pymodule_glob.stderr @@ -3,3 +3,6 @@ error: #[pymodule] cannot import glob statements | 13 | use super::*; | ^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/invalid_pymodule_in_root.rs b/tests/ui/invalid_pymodule_in_root.rs index 76ced6c3fb6..046759f98db 100644 --- a/tests/ui/invalid_pymodule_in_root.rs +++ b/tests/ui/invalid_pymodule_in_root.rs @@ -3,5 +3,7 @@ use pyo3::prelude::*; #[pymodule] #[path = "empty.rs"] // to silence error related to missing file mod invalid_pymodule_in_root_module; +//~^ ERROR: file modules in proc macro input are unstable +//~| ERROR: `#[pymodule]` can only be used on inline modules fn main() {} diff --git a/tests/ui/invalid_pymodule_in_root.stderr b/tests/ui/invalid_pymodule_in_root.stderr index 1e763279d81..ae89fda1e5c 100644 --- a/tests/ui/invalid_pymodule_in_root.stderr +++ b/tests/ui/invalid_pymodule_in_root.stderr @@ -11,3 +11,7 @@ error: `#[pymodule]` can only be used on inline modules | 5 | mod invalid_pymodule_in_root_module; | ^^^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/invalid_pymodule_trait.rs b/tests/ui/invalid_pymodule_trait.rs index 6649a3547a0..c320f919b8f 100644 --- a/tests/ui/invalid_pymodule_trait.rs +++ b/tests/ui/invalid_pymodule_trait.rs @@ -3,6 +3,8 @@ use pyo3::prelude::*; #[pymodule] mod module { #[pymodule_export] +//~^ ERROR: cannot find attribute `pymodule_export` in this scope +//~| ERROR: `#[pymodule_export]` may only be used on `use` or `const` statements trait Foo {} } diff --git a/tests/ui/invalid_pymodule_trait.stderr b/tests/ui/invalid_pymodule_trait.stderr index f8cfc1b1bdf..36713b488ad 100644 --- a/tests/ui/invalid_pymodule_trait.stderr +++ b/tests/ui/invalid_pymodule_trait.stderr @@ -9,3 +9,6 @@ error: cannot find attribute `pymodule_export` in this scope | 5 | #[pymodule_export] | ^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + diff --git a/tests/ui/invalid_pymodule_two_pymodule_init.rs b/tests/ui/invalid_pymodule_two_pymodule_init.rs index ed72cbb7237..e0df90373d1 100644 --- a/tests/ui/invalid_pymodule_two_pymodule_init.rs +++ b/tests/ui/invalid_pymodule_two_pymodule_init.rs @@ -11,6 +11,7 @@ mod module { #[pymodule_init] fn init2(_m: &Bound<'_, PyModule>) -> PyResult<()> { +//~^ ERROR: only one `#[pymodule_init]` may be specified Ok(()) } } diff --git a/tests/ui/invalid_pymodule_two_pymodule_init.stderr b/tests/ui/invalid_pymodule_two_pymodule_init.stderr index 8fbd12f2e45..30eef8bd2c4 100644 --- a/tests/ui/invalid_pymodule_two_pymodule_init.stderr +++ b/tests/ui/invalid_pymodule_two_pymodule_init.stderr @@ -3,3 +3,6 @@ error: only one `#[pymodule_init]` may be specified | 13 | fn init2(_m: &Bound<'_, PyModule>) -> PyResult<()> { | ^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/invalid_result_conversion.rs b/tests/ui/invalid_result_conversion.rs index 692ce71f6dd..0b5f931f753 100644 --- a/tests/ui/invalid_result_conversion.rs +++ b/tests/ui/invalid_result_conversion.rs @@ -20,6 +20,7 @@ impl fmt::Display for MyError { #[pyfunction] fn should_not_work() -> Result<(), MyError> { +//~^ ERROR: the trait bound `PyErr: From` is not satisfied Err(MyError { descr: "something went wrong", }) diff --git a/tests/ui/invalid_result_conversion.stderr b/tests/ui/invalid_result_conversion.stderr index ef31f073689..7124a31a1c1 100644 --- a/tests/ui/invalid_result_conversion.stderr +++ b/tests/ui/invalid_result_conversion.stderr @@ -13,5 +13,9 @@ error[E0277]: the trait bound `PyErr: From` is not satisfied `PyErr` implements `From>` `PyErr` implements `From` `PyErr` implements `From` - and $N others + and 16 others = note: required for `MyError` to implement `Into` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/missing_intopy.rs b/tests/ui/missing_intopy.rs index 36de7bdee78..0c1a0b58448 100644 --- a/tests/ui/missing_intopy.rs +++ b/tests/ui/missing_intopy.rs @@ -2,6 +2,8 @@ struct Blah; #[pyo3::pyfunction] fn blah() -> Blah { +//~^ ERROR: `Blah` cannot be converted to a Python object +//~| ERROR: no method named `map_err` found for struct `Blah` in the current scope Blah } diff --git a/tests/ui/missing_intopy.stderr b/tests/ui/missing_intopy.stderr index 2d3e39dadea..02706a2659c 100644 --- a/tests/ui/missing_intopy.stderr +++ b/tests/ui/missing_intopy.stderr @@ -1,35 +1,35 @@ error[E0277]: `Blah` cannot be converted to a Python object - --> tests/ui/missing_intopy.rs:4:14 - | -4 | fn blah() -> Blah { - | ^^^^ unsatisfied trait bound - | + --> tests/ui/missing_intopy.rs:4:14 + | + 4 | fn blah() -> Blah { + | ^^^^ unsatisfied trait bound + | help: the trait `IntoPyObject<'_>` is not implemented for `Blah` - --> tests/ui/missing_intopy.rs:1:1 - | -1 | struct Blah; - | ^^^^^^^^^^^ - = note: `IntoPyObject` is automatically implemented by the `#[pyclass]` macro - = note: if you do not wish to have a corresponding Python type, implement it manually - = note: if you do not own `Blah` you can perform a manual conversion to one of the types in `pyo3::types::*` - = help: the following other types implement trait `IntoPyObject<'py>`: - &&'a T - &&OsStr - &&Path - &&str - &'a (T0, T1) - &'a (T0, T1, T2) - &'a (T0, T1, T2, T3) - &'a (T0, T1, T2, T3, T4) - and $N others + --> tests/ui/missing_intopy.rs:1:1 + | + 1 | struct Blah; + | ^^^^^^^^^^^ + = note: `IntoPyObject` is automatically implemented by the `#[pyclass]` macro + = note: if you do not wish to have a corresponding Python type, implement it manually + = note: if you do not own `Blah` you can perform a manual conversion to one of the types in `pyo3::types::*` + = help: the following other types implement trait `IntoPyObject<'py>`: + &&'a T + &&OsStr + &&Path + &&str + &'a (T0, T1) + &'a (T0, T1, T2) + &'a (T0, T1, T2, T3) + &'a (T0, T1, T2, T3, T4) + and 148 others note: required by a bound in `UnknownReturnType::::wrap` - --> src/impl_/wrap.rs - | - | pub fn wrap<'py>(&self, _: T) -> T - | ---- required by a bound in this associated function - | where - | T: IntoPyObject<'py>, - | ^^^^^^^^^^^^^^^^^ required by this bound in `UnknownReturnType::::wrap` + --> src/impl_/wrap.rs:122:12 + | +120 | pub fn wrap<'py>(&self, _: T) -> T + | ---- required by a bound in this associated function +121 | where +122 | T: IntoPyObject<'py>, + | ^^^^^^^^^^^^^^^^^ required by this bound in `UnknownReturnType::::wrap` error[E0599]: no method named `map_err` found for struct `Blah` in the current scope --> tests/ui/missing_intopy.rs:4:14 @@ -39,3 +39,8 @@ error[E0599]: no method named `map_err` found for struct `Blah` in the current s ... 4 | fn blah() -> Blah { | ^^^^ method not found in `Blah` + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0277, E0599. +For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/not_send.rs b/tests/ui/not_send.rs index 926343538aa..d93d605327d 100644 --- a/tests/ui/not_send.rs +++ b/tests/ui/not_send.rs @@ -2,6 +2,7 @@ use pyo3::prelude::*; fn test_not_send_detach(py: Python<'_>) { py.detach(|| { drop(py); }); +//~^ ERROR: `*mut pyo3::Python<'static>` cannot be shared between threads safely } fn main() { diff --git a/tests/ui/not_send.stderr b/tests/ui/not_send.stderr index 0cb4039b186..837f0a6963f 100644 --- a/tests/ui/not_send.stderr +++ b/tests/ui/not_send.stderr @@ -1,44 +1,48 @@ error[E0277]: `*mut pyo3::Python<'static>` cannot be shared between threads safely - --> tests/ui/not_send.rs:4:15 - | -4 | py.detach(|| { drop(py); }); - | ------ ^^^^^^^^^^^^^^^^ `*mut pyo3::Python<'static>` cannot be shared between threads safely - | | - | required by a bound introduced by this call - | - = help: within `pyo3::Python<'_>`, the trait `Sync` is not implemented for `*mut pyo3::Python<'static>` + --> tests/ui/not_send.rs:4:15 + | + 4 | py.detach(|| { drop(py); }); + | ------ ^^^^^^^^^^^^^^^^ `*mut pyo3::Python<'static>` cannot be shared between threads safely + | | + | required by a bound introduced by this call + | + = help: within `pyo3::Python<'_>`, the trait `Sync` is not implemented for `*mut pyo3::Python<'static>` note: required because it appears within the type `PhantomData<*mut pyo3::Python<'static>>` - --> $RUST/core/src/marker.rs - | - | pub struct PhantomData; - | ^^^^^^^^^^^ + --> /Users/david/.rustup/toolchains/stable-aarch64-apple-darwin/lib/rustlib/src/rust/library/core/src/marker.rs:819:12 + | +819 | pub struct PhantomData; + | ^^^^^^^^^^^ note: required because it appears within the type `pyo3::marker::NotSend` - --> src/marker.rs - | - | struct NotSend(PhantomData<*mut Python<'static>>); - | ^^^^^^^ + --> src/marker.rs:357:8 + | +357 | struct NotSend(PhantomData<*mut Python<'static>>); + | ^^^^^^^ note: required because it appears within the type `PhantomData` - --> $RUST/core/src/marker.rs - | - | pub struct PhantomData; - | ^^^^^^^^^^^ + --> /Users/david/.rustup/toolchains/stable-aarch64-apple-darwin/lib/rustlib/src/rust/library/core/src/marker.rs:819:12 + | +819 | pub struct PhantomData; + | ^^^^^^^^^^^ note: required because it appears within the type `pyo3::Python<'_>` - --> src/marker.rs - | - | pub struct Python<'py>(PhantomData<&'py AttachGuard>, PhantomData); - | ^^^^^^ - = note: required for `&pyo3::Python<'_>` to implement `Send` + --> src/marker.rs:353:12 + | +353 | pub struct Python<'py>(PhantomData<&'py AttachGuard>, PhantomData); + | ^^^^^^ + = note: required for `&pyo3::Python<'_>` to implement `Send` note: required because it's used within this closure - --> tests/ui/not_send.rs:4:15 - | -4 | py.detach(|| { drop(py); }); - | ^^ - = note: required for `{closure@$DIR/tests/ui/not_send.rs:4:15: 4:17}` to implement `Ungil` + --> tests/ui/not_send.rs:4:15 + | + 4 | py.detach(|| { drop(py); }); + | ^^ + = note: required for `{closure@tests/ui/not_send.rs:4:15: 4:17}` to implement `Ungil` note: required by a bound in `pyo3::Python::<'py>::detach` - --> src/marker.rs - | - | pub fn detach(self, f: F) -> T - | ------ required by a bound in this associated function - | where - | F: Ungil + FnOnce() -> T, - | ^^^^^ required by this bound in `Python::<'py>::detach` + --> src/marker.rs:560:12 + | +558 | pub fn detach(self, f: F) -> T + | ------ required by a bound in this associated function +559 | where +560 | F: Ungil + FnOnce() -> T, + | ^^^^^ required by this bound in `Python::<'py>::detach` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/not_send2.rs b/tests/ui/not_send2.rs index 78c73d5e9c8..b1d3262ead5 100644 --- a/tests/ui/not_send2.rs +++ b/tests/ui/not_send2.rs @@ -6,6 +6,7 @@ fn main() { let string = PyString::new(py, "foo"); py.detach(|| { +//~^ ERROR: `*mut pyo3::Python<'static>` cannot be shared between threads safely println!("{:?}", string); }); }); diff --git a/tests/ui/not_send2.stderr b/tests/ui/not_send2.stderr index 3d76b5ebc11..6921905be46 100644 --- a/tests/ui/not_send2.stderr +++ b/tests/ui/not_send2.stderr @@ -1,52 +1,57 @@ error[E0277]: `*mut pyo3::Python<'static>` cannot be shared between threads safely - --> tests/ui/not_send2.rs:8:19 - | - 8 | py.detach(|| { - | ____________------_^ - | | | - | | required by a bound introduced by this call - 9 | | println!("{:?}", string); -10 | | }); - | |_________^ `*mut pyo3::Python<'static>` cannot be shared between threads safely - | - = help: within `pyo3::Bound<'_, PyString>`, the trait `Sync` is not implemented for `*mut pyo3::Python<'static>` + --> tests/ui/not_send2.rs:8:19 + | + 8 | py.detach(|| { + | ____________------_^ + | | | + | | required by a bound introduced by this call + 9 | | + 10 | | println!("{:?}", string); + 11 | | }); + | |_________^ `*mut pyo3::Python<'static>` cannot be shared between threads safely + | + = help: within `pyo3::Bound<'_, PyString>`, the trait `Sync` is not implemented for `*mut pyo3::Python<'static>` note: required because it appears within the type `PhantomData<*mut pyo3::Python<'static>>` - --> $RUST/core/src/marker.rs - | - | pub struct PhantomData; - | ^^^^^^^^^^^ + --> /Users/david/.rustup/toolchains/stable-aarch64-apple-darwin/lib/rustlib/src/rust/library/core/src/marker.rs:819:12 + | +819 | pub struct PhantomData; + | ^^^^^^^^^^^ note: required because it appears within the type `pyo3::marker::NotSend` - --> src/marker.rs - | - | struct NotSend(PhantomData<*mut Python<'static>>); - | ^^^^^^^ + --> src/marker.rs:357:8 + | +357 | struct NotSend(PhantomData<*mut Python<'static>>); + | ^^^^^^^ note: required because it appears within the type `PhantomData` - --> $RUST/core/src/marker.rs - | - | pub struct PhantomData; - | ^^^^^^^^^^^ + --> /Users/david/.rustup/toolchains/stable-aarch64-apple-darwin/lib/rustlib/src/rust/library/core/src/marker.rs:819:12 + | +819 | pub struct PhantomData; + | ^^^^^^^^^^^ note: required because it appears within the type `pyo3::Python<'_>` - --> src/marker.rs - | - | pub struct Python<'py>(PhantomData<&'py AttachGuard>, PhantomData); - | ^^^^^^ + --> src/marker.rs:353:12 + | +353 | pub struct Python<'py>(PhantomData<&'py AttachGuard>, PhantomData); + | ^^^^^^ note: required because it appears within the type `pyo3::Bound<'_, PyString>` - --> src/instance.rs - | - | pub struct Bound<'py, T>(Python<'py>, ManuallyDrop>); - | ^^^^^ - = note: required for `&pyo3::Bound<'_, PyString>` to implement `Send` + --> src/instance.rs:75:12 + | + 75 | pub struct Bound<'py, T>(Python<'py>, ManuallyDrop>); + | ^^^^^ + = note: required for `&pyo3::Bound<'_, PyString>` to implement `Send` note: required because it's used within this closure - --> tests/ui/not_send2.rs:8:19 - | - 8 | py.detach(|| { - | ^^ - = note: required for `{closure@$DIR/tests/ui/not_send2.rs:8:19: 8:21}` to implement `Ungil` + --> tests/ui/not_send2.rs:8:19 + | + 8 | py.detach(|| { + | ^^ + = note: required for `{closure@tests/ui/not_send2.rs:8:19: 8:21}` to implement `Ungil` note: required by a bound in `pyo3::Python::<'py>::detach` - --> src/marker.rs - | - | pub fn detach(self, f: F) -> T - | ------ required by a bound in this associated function - | where - | F: Ungil + FnOnce() -> T, - | ^^^^^ required by this bound in `Python::<'py>::detach` + --> src/marker.rs:560:12 + | +558 | pub fn detach(self, f: F) -> T + | ------ required by a bound in this associated function +559 | where +560 | F: Ungil + FnOnce() -> T, + | ^^^^^ required by this bound in `Python::<'py>::detach` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/pyclass_generic_enum.rs b/tests/ui/pyclass_generic_enum.rs index 94fd779b2d4..110c9a0e37b 100644 --- a/tests/ui/pyclass_generic_enum.rs +++ b/tests/ui/pyclass_generic_enum.rs @@ -1,12 +1,14 @@ use pyo3::prelude::*; #[pyclass(generic)] +//~^ ERROR: enums do not support #[pyclass(generic)] enum NotGenericForEnum { A, B, } #[pyclass(generic)] +//~^ ERROR: enums do not support #[pyclass(generic)] enum NoGenericForComplexEnum { A { x: f64 }, B { y: f64, z: f64 }, diff --git a/tests/ui/pyclass_generic_enum.stderr b/tests/ui/pyclass_generic_enum.stderr index cfc1e178af3..9e9637ffa9d 100644 --- a/tests/ui/pyclass_generic_enum.stderr +++ b/tests/ui/pyclass_generic_enum.stderr @@ -5,7 +5,10 @@ error: enums do not support #[pyclass(generic)] | ^^^^^^^ error: enums do not support #[pyclass(generic)] - --> tests/ui/pyclass_generic_enum.rs:9:11 - | -9 | #[pyclass(generic)] - | ^^^^^^^ + --> tests/ui/pyclass_generic_enum.rs:10:11 + | +10 | #[pyclass(generic)] + | ^^^^^^^ + +error: aborting due to 2 previous errors + diff --git a/tests/ui/pyclass_probe.rs b/tests/ui/pyclass_probe.rs index 7a18ddc1aef..7919cb82de9 100644 --- a/tests/ui/pyclass_probe.rs +++ b/tests/ui/pyclass_probe.rs @@ -1,52 +1,53 @@ -#![deny(unused_imports)] -use pyo3::prelude::*; - -#[pymodule] -mod probe_no_fields { - use pyo3::prelude::*; - #[pyclass] - pub struct Probe {} - - #[pymethods] - impl Probe { - #[new] - fn new() -> Self { - Self {} - } - } -} - -#[pymodule] -mod probe_with_fields { - use pyo3::prelude::*; - #[pyclass(get_all)] - pub struct Probe { - field: u8, - } - - #[pymethods] - impl Probe { - #[new] - fn new() -> Self { - Self { field: 0 } - } - } -} - -#[pyclass] -struct Check5029(); - -macro_rules! impl_methods { - ($name:ident) => { - #[pymethods] - impl Check5029 { - fn $name(&self, _value: Option<&str>) -> PyResult<()> { - Ok(()) - } - } - }; -} - -impl_methods!(some_method); - -fn main() {} +//@check-pass +#![deny(unused_imports)] +use pyo3::prelude::*; + +#[pymodule] +mod probe_no_fields { + use pyo3::prelude::*; + #[pyclass] + pub struct Probe {} + + #[pymethods] + impl Probe { + #[new] + fn new() -> Self { + Self {} + } + } +} + +#[pymodule] +mod probe_with_fields { + use pyo3::prelude::*; + #[pyclass(get_all)] + pub struct Probe { + field: u8, + } + + #[pymethods] + impl Probe { + #[new] + fn new() -> Self { + Self { field: 0 } + } + } +} + +#[pyclass] +struct Check5029(); + +macro_rules! impl_methods { + ($name:ident) => { + #[pymethods] + impl Check5029 { + fn $name(&self, _value: Option<&str>) -> PyResult<()> { + Ok(()) + } + } + }; +} + +impl_methods!(some_method); + +fn main() {} diff --git a/tests/ui/pyclass_send.rs b/tests/ui/pyclass_send.rs index 1a764f621f0..93d39343fa8 100644 --- a/tests/ui/pyclass_send.rs +++ b/tests/ui/pyclass_send.rs @@ -3,13 +3,17 @@ use std::ffi::c_void; #[pyclass] struct NotSyncNotSend(*mut c_void); +//~^ ERROR: `*mut c_void` cannot be sent between threads safely +//~| ERROR: `*mut c_void` cannot be shared between threads safely #[pyclass] struct SendNotSync(*mut c_void); +//~^ ERROR: `*mut c_void` cannot be shared between threads safely unsafe impl Send for SendNotSync {} #[pyclass] struct SyncNotSend(*mut c_void); +//~^ ERROR: `*mut c_void` cannot be sent between threads safely unsafe impl Sync for SyncNotSend {} // None of the `unsendable` forms below should fail to compile diff --git a/tests/ui/pyclass_send.stderr b/tests/ui/pyclass_send.stderr index e4f1680edd2..16c68e1c46c 100644 --- a/tests/ui/pyclass_send.stderr +++ b/tests/ui/pyclass_send.stderr @@ -11,12 +11,12 @@ note: required because it appears within the type `NotSyncNotSend` 5 | struct NotSyncNotSend(*mut c_void); | ^^^^^^^^^^^^^^ note: required by a bound in `assert_pyclass_send_sync` - --> src/impl_/pyclass/assertions.rs + --> src/impl_/pyclass/assertions.rs:6:8 | - | pub const fn assert_pyclass_send_sync() +4 | pub const fn assert_pyclass_send_sync() | ------------------------ required by a bound in this function - | where - | T: Send + Sync, +5 | where +6 | T: Send + Sync, | ^^^^ required by this bound in `assert_pyclass_send_sync` error[E0277]: `*mut c_void` cannot be shared between threads safely @@ -32,52 +32,56 @@ note: required because it appears within the type `NotSyncNotSend` 5 | struct NotSyncNotSend(*mut c_void); | ^^^^^^^^^^^^^^ note: required by a bound in `assert_pyclass_send_sync` - --> src/impl_/pyclass/assertions.rs + --> src/impl_/pyclass/assertions.rs:6:15 | - | pub const fn assert_pyclass_send_sync() +4 | pub const fn assert_pyclass_send_sync() | ------------------------ required by a bound in this function - | where - | T: Send + Sync, +5 | where +6 | T: Send + Sync, | ^^^^ required by this bound in `assert_pyclass_send_sync` error[E0277]: `*mut c_void` cannot be shared between threads safely - --> tests/ui/pyclass_send.rs:8:8 - | -8 | struct SendNotSync(*mut c_void); - | ^^^^^^^^^^^ `*mut c_void` cannot be shared between threads safely - | - = help: within `SendNotSync`, the trait `Sync` is not implemented for `*mut c_void` + --> tests/ui/pyclass_send.rs:10:8 + | +10 | struct SendNotSync(*mut c_void); + | ^^^^^^^^^^^ `*mut c_void` cannot be shared between threads safely + | + = help: within `SendNotSync`, the trait `Sync` is not implemented for `*mut c_void` note: required because it appears within the type `SendNotSync` - --> tests/ui/pyclass_send.rs:8:8 - | -8 | struct SendNotSync(*mut c_void); - | ^^^^^^^^^^^ + --> tests/ui/pyclass_send.rs:10:8 + | +10 | struct SendNotSync(*mut c_void); + | ^^^^^^^^^^^ note: required by a bound in `assert_pyclass_send_sync` - --> src/impl_/pyclass/assertions.rs - | - | pub const fn assert_pyclass_send_sync() - | ------------------------ required by a bound in this function - | where - | T: Send + Sync, - | ^^^^ required by this bound in `assert_pyclass_send_sync` + --> src/impl_/pyclass/assertions.rs:6:15 + | + 4 | pub const fn assert_pyclass_send_sync() + | ------------------------ required by a bound in this function + 5 | where + 6 | T: Send + Sync, + | ^^^^ required by this bound in `assert_pyclass_send_sync` error[E0277]: `*mut c_void` cannot be sent between threads safely - --> tests/ui/pyclass_send.rs:12:8 + --> tests/ui/pyclass_send.rs:15:8 | -12 | struct SyncNotSend(*mut c_void); +15 | struct SyncNotSend(*mut c_void); | ^^^^^^^^^^^ `*mut c_void` cannot be sent between threads safely | = help: within `SyncNotSend`, the trait `Send` is not implemented for `*mut c_void` note: required because it appears within the type `SyncNotSend` - --> tests/ui/pyclass_send.rs:12:8 + --> tests/ui/pyclass_send.rs:15:8 | -12 | struct SyncNotSend(*mut c_void); +15 | struct SyncNotSend(*mut c_void); | ^^^^^^^^^^^ note: required by a bound in `assert_pyclass_send_sync` - --> src/impl_/pyclass/assertions.rs + --> src/impl_/pyclass/assertions.rs:6:8 | - | pub const fn assert_pyclass_send_sync() + 4 | pub const fn assert_pyclass_send_sync() | ------------------------ required by a bound in this function - | where - | T: Send + Sync, + 5 | where + 6 | T: Send + Sync, | ^^^^ required by this bound in `assert_pyclass_send_sync` + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/pymodule_missing_docs.rs b/tests/ui/pymodule_missing_docs.rs index d8bf2eb4d2f..ee2a58314fc 100644 --- a/tests/ui/pymodule_missing_docs.rs +++ b/tests/ui/pymodule_missing_docs.rs @@ -1,3 +1,4 @@ +//@check-pass #![deny(missing_docs)] //! Some crate docs diff --git a/tests/ui/reject_generics.rs b/tests/ui/reject_generics.rs index 55142ee0e37..1fbab904ac7 100644 --- a/tests/ui/reject_generics.rs +++ b/tests/ui/reject_generics.rs @@ -2,11 +2,13 @@ use pyo3::prelude::*; #[pyclass] struct ClassWithGenerics { +//~^ ERROR: #[pyclass] cannot have generic parameters. For an explanation, see https://pyo3.rs/v0.28.2/class.html#no-generic-parameters a: A, } #[pyclass] struct ClassWithLifetimes<'a> { +//~^ ERROR: #[pyclass] cannot have lifetime parameters. For an explanation, see https://pyo3.rs/v0.28.2/class.html#no-lifetime-parameters a: &'a str, } diff --git a/tests/ui/reject_generics.stderr b/tests/ui/reject_generics.stderr index 8e5544c3feb..85d873a0f8f 100644 --- a/tests/ui/reject_generics.stderr +++ b/tests/ui/reject_generics.stderr @@ -5,7 +5,10 @@ error: #[pyclass] cannot have generic parameters. For an explanation, see https: | ^ error: #[pyclass] cannot have lifetime parameters. For an explanation, see https://pyo3.rs/v0.28.2/class.html#no-lifetime-parameters - --> tests/ui/reject_generics.rs:9:27 - | -9 | struct ClassWithLifetimes<'a> { - | ^^ + --> tests/ui/reject_generics.rs:10:27 + | +10 | struct ClassWithLifetimes<'a> { + | ^^ + +error: aborting due to 2 previous errors + diff --git a/tests/ui/static_ref.rs b/tests/ui/static_ref.rs index e8015db2f64..6465848a589 100644 --- a/tests/ui/static_ref.rs +++ b/tests/ui/static_ref.rs @@ -2,11 +2,14 @@ use pyo3::prelude::*; use pyo3::types::PyList; #[pyfunction] +//~^ ERROR: borrowed data escapes outside of function +//~| ERROR: temporary value dropped while borrowed fn static_ref(list: &'static Bound<'_, PyList>) -> usize { list.len() } #[pyfunction] +//~^ ERROR: borrowed data escapes outside of function fn static_py(list: &Bound<'static, PyList>) -> usize { list.len() } diff --git a/tests/ui/static_ref.stderr b/tests/ui/static_ref.stderr index d32b7508c4b..3886b89c690 100644 --- a/tests/ui/static_ref.stderr +++ b/tests/ui/static_ref.stderr @@ -24,14 +24,19 @@ error[E0716]: temporary value dropped while borrowed = note: this error originates in the attribute macro `pyfunction` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0521]: borrowed data escapes outside of function - --> tests/ui/static_ref.rs:9:1 - | -9 | #[pyfunction] - | ^^^^^^^^^^^^^ - | | - | `py` is a reference that is only valid in the function body - | `py` escapes the function body here - | lifetime `'py` defined here - | argument requires that `'py` must outlive `'static` - | - = note: this error originates in the attribute macro `pyfunction` (in Nightly builds, run with -Z macro-backtrace for more info) + --> tests/ui/static_ref.rs:11:1 + | +11 | #[pyfunction] + | ^^^^^^^^^^^^^ + | | + | `py` is a reference that is only valid in the function body + | `py` escapes the function body here + | lifetime `'py` defined here + | argument requires that `'py` must outlive `'static` + | + = note: this error originates in the attribute macro `pyfunction` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0521, E0716. +For more information about an error, try `rustc --explain E0521`. diff --git a/tests/ui/traverse.rs b/tests/ui/traverse.rs index faa7b5c041d..d65d46e3e71 100644 --- a/tests/ui/traverse.rs +++ b/tests/ui/traverse.rs @@ -8,6 +8,7 @@ struct TraverseTriesToTakePyRef {} #[pymethods] impl TraverseTriesToTakePyRef { fn __traverse__(_slf: PyRef, _visit: PyVisit) -> Result<(), PyTraverseError> { +//~^ ERROR: __traverse__ may not take a receiver other than `&self`. Usually, an implementation of `__traverse__(&self, visit: PyVisit<'_>) -> Result<(), PyTraverseError>` should do nothing but calls to `visit.call`. Most importantly, safe access to the Python interpreter is prohibited inside implementations of `__traverse__`, i.e. `Python::attach` will panic. Ok(()) } } @@ -18,6 +19,7 @@ struct TraverseTriesToTakePyRefMut {} #[pymethods] impl TraverseTriesToTakePyRefMut { fn __traverse__(_slf: PyRefMut, _visit: PyVisit) -> Result<(), PyTraverseError> { +//~^ ERROR: __traverse__ may not take a receiver other than `&self`. Usually, an implementation of `__traverse__(&self, visit: PyVisit<'_>) -> Result<(), PyTraverseError>` should do nothing but calls to `visit.call`. Most importantly, safe access to the Python interpreter is prohibited inside implementations of `__traverse__`, i.e. `Python::attach` will panic. Ok(()) } } @@ -28,6 +30,7 @@ struct TraverseTriesToTakeBound {} #[pymethods] impl TraverseTriesToTakeBound { fn __traverse__(_slf: Bound<'_, Self>, _visit: PyVisit) -> Result<(), PyTraverseError> { +//~^ ERROR: __traverse__ may not take a receiver other than `&self`. Usually, an implementation of `__traverse__(&self, visit: PyVisit<'_>) -> Result<(), PyTraverseError>` should do nothing but calls to `visit.call`. Most importantly, safe access to the Python interpreter is prohibited inside implementations of `__traverse__`, i.e. `Python::attach` will panic. Ok(()) } } @@ -38,6 +41,7 @@ struct TraverseTriesToTakeMutSelf {} #[pymethods] impl TraverseTriesToTakeMutSelf { fn __traverse__(&mut self, _visit: PyVisit) -> Result<(), PyTraverseError> { +//~^ ERROR: __traverse__ may not take a receiver other than `&self`. Usually, an implementation of `__traverse__(&self, visit: PyVisit<'_>) -> Result<(), PyTraverseError>` should do nothing but calls to `visit.call`. Most importantly, safe access to the Python interpreter is prohibited inside implementations of `__traverse__`, i.e. `Python::attach` will panic. Ok(()) } } @@ -58,6 +62,7 @@ struct Class; #[pymethods] impl Class { fn __traverse__(&self, _py: Python<'_>, _visit: PyVisit<'_>) -> Result<(), PyTraverseError> { +//~^ ERROR: __traverse__ may not take `Python`. Usually, an implementation of `__traverse__(&self, visit: PyVisit<'_>) -> Result<(), PyTraverseError>` should do nothing but calls to `visit.call`. Most importantly, safe access to the Python interpreter is prohibited inside implementations of `__traverse__`, i.e. `Python::attach` will panic. Ok(()) } diff --git a/tests/ui/traverse.stderr b/tests/ui/traverse.stderr index 343a67f5641..48bb4f84c83 100644 --- a/tests/ui/traverse.stderr +++ b/tests/ui/traverse.stderr @@ -5,25 +5,28 @@ error: __traverse__ may not take a receiver other than `&self`. Usually, an impl | ^^^^^ error: __traverse__ may not take a receiver other than `&self`. Usually, an implementation of `__traverse__(&self, visit: PyVisit<'_>) -> Result<(), PyTraverseError>` should do nothing but calls to `visit.call`. Most importantly, safe access to the Python interpreter is prohibited inside implementations of `__traverse__`, i.e. `Python::attach` will panic. - --> tests/ui/traverse.rs:20:27 + --> tests/ui/traverse.rs:21:27 | -20 | fn __traverse__(_slf: PyRefMut, _visit: PyVisit) -> Result<(), PyTraverseError> { +21 | fn __traverse__(_slf: PyRefMut, _visit: PyVisit) -> Result<(), PyTraverseError> { | ^^^^^^^^ error: __traverse__ may not take a receiver other than `&self`. Usually, an implementation of `__traverse__(&self, visit: PyVisit<'_>) -> Result<(), PyTraverseError>` should do nothing but calls to `visit.call`. Most importantly, safe access to the Python interpreter is prohibited inside implementations of `__traverse__`, i.e. `Python::attach` will panic. - --> tests/ui/traverse.rs:30:27 + --> tests/ui/traverse.rs:32:27 | -30 | fn __traverse__(_slf: Bound<'_, Self>, _visit: PyVisit) -> Result<(), PyTraverseError> { +32 | fn __traverse__(_slf: Bound<'_, Self>, _visit: PyVisit) -> Result<(), PyTraverseError> { | ^^^^^ error: __traverse__ may not take a receiver other than `&self`. Usually, an implementation of `__traverse__(&self, visit: PyVisit<'_>) -> Result<(), PyTraverseError>` should do nothing but calls to `visit.call`. Most importantly, safe access to the Python interpreter is prohibited inside implementations of `__traverse__`, i.e. `Python::attach` will panic. - --> tests/ui/traverse.rs:40:21 + --> tests/ui/traverse.rs:43:21 | -40 | fn __traverse__(&mut self, _visit: PyVisit) -> Result<(), PyTraverseError> { +43 | fn __traverse__(&mut self, _visit: PyVisit) -> Result<(), PyTraverseError> { | ^ error: __traverse__ may not take `Python`. Usually, an implementation of `__traverse__(&self, visit: PyVisit<'_>) -> Result<(), PyTraverseError>` should do nothing but calls to `visit.call`. Most importantly, safe access to the Python interpreter is prohibited inside implementations of `__traverse__`, i.e. `Python::attach` will panic. - --> tests/ui/traverse.rs:60:33 + --> tests/ui/traverse.rs:64:33 | -60 | fn __traverse__(&self, _py: Python<'_>, _visit: PyVisit<'_>) -> Result<(), PyTraverseError> { +64 | fn __traverse__(&self, _py: Python<'_>, _visit: PyVisit<'_>) -> Result<(), PyTraverseError> { | ^^^^^^^^^^ + +error: aborting due to 5 previous errors + diff --git a/tests/ui/wrong_aspyref_lifetimes.rs b/tests/ui/wrong_aspyref_lifetimes.rs index b5f050ebcf9..6438ae4636a 100644 --- a/tests/ui/wrong_aspyref_lifetimes.rs +++ b/tests/ui/wrong_aspyref_lifetimes.rs @@ -5,6 +5,7 @@ fn main() { // Should not be able to get access to Py contents outside of `attach`. let dict: &Bound<'_, PyDict> = Python::attach(|py| dict.bind(py)); +//~^ ERROR: lifetime may not live long enough let _py: Python = dict.py(); // Obtain a Python<'p> without GIL. } diff --git a/tests/ui/wrong_aspyref_lifetimes.stderr b/tests/ui/wrong_aspyref_lifetimes.stderr index 8a9cc553349..71394972685 100644 --- a/tests/ui/wrong_aspyref_lifetimes.stderr +++ b/tests/ui/wrong_aspyref_lifetimes.stderr @@ -6,3 +6,6 @@ error: lifetime may not live long enough | | | | | return type of closure is &'2 pyo3::Bound<'_, PyDict> | has type `Python<'1>` + +error: aborting due to 1 previous error + From 985d2d3470c1506cbb40020c63ec8a137bb8e7b7 Mon Sep 17 00:00:00 2001 From: David Hewitt Date: Sat, 7 Mar 2026 13:23:23 +0000 Subject: [PATCH 02/21] clippy --- tests/test_compile_error.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_compile_error.rs b/tests/test_compile_error.rs index de171070a07..a607b9287bb 100644 --- a/tests/test_compile_error.rs +++ b/tests/test_compile_error.rs @@ -102,7 +102,7 @@ fn test_compile_errors() { let mut config = Config::rustc("tests/ui"); - let deps_features = vec![ + let deps_features = [ #[cfg(feature = "macros")] "pyo3/macros".to_string(), #[cfg(feature = "abi3")] From 2f90d42ae4ca5513fa3f2df582a5594b60dea145 Mon Sep 17 00:00:00 2001 From: David Hewitt Date: Sun, 8 Mar 2026 14:26:15 +0000 Subject: [PATCH 03/21] fixup several ui-test setups --- tests/test_compile_error.rs | 37 +++--- tests/ui/forbid_unsafe.rs | 2 +- tests/ui/forbid_unsafe.stderr | 86 ++------------ tests/ui/invalid_base_class.stderr | 48 ++++---- tests/ui/invalid_intern_arg.stderr | 8 +- tests/ui/invalid_pyclass_args.stderr | 26 ++++- tests/ui/invalid_pyclass_generic.rs | 3 + tests/ui/invalid_pyclass_generic.stderr | 123 ++++++++------------ tests/ui/invalid_pyfunction_argument.stderr | 78 ++++++++++--- tests/ui/invalid_pymethods_buffer.stderr | 15 +-- 10 files changed, 194 insertions(+), 232 deletions(-) diff --git a/tests/test_compile_error.rs b/tests/test_compile_error.rs index a607b9287bb..03b694781de 100644 --- a/tests/test_compile_error.rs +++ b/tests/test_compile_error.rs @@ -146,24 +146,25 @@ fn test_compile_errors() { .compile_flags .push("--diagnostic-width=140".into()); - // not a test file, used to configure dependencies for the tests - config.skip_files.push("base/src/lib.rs".into()); - - // don't run abi3-only tests when not testing abi3 features - #[cfg(not(Py_LIMITED_API))] - config.skip_files.push("abi3".into()); - - #[cfg(Py_LIMITED_API)] - config.skip_files.push("forbid_unsafe.rs".into()); - - #[cfg(all(Py_LIMITED_API, not(Py_3_11)))] - config.skip_files.push("buffer".into()); - - #[cfg(any(Py_3_14, all(Py_3_10, not(Py_LIMITED_API))))] - config.skip_files.push("immutable_type.rs".into()); - - #[cfg(not(Py_3_9))] - config.skip_files.push("invalid_pyclass_generic.rs".into()); + config.skip_files.extend([ + // not a test file, used to configure dependencies for the tests + "base/src/lib.rs".into(), + // don't run abi3-only tests when not testing abi3 features + #[cfg(not(Py_LIMITED_API))] + "abi3".into(), + // this test doesn't work properly without the full API available + #[cfg(Py_LIMITED_API)] + "forbid_unsafe.rs".into(), + // buffer protocol only supported on 3.11+ with abi3 + #[cfg(all(Py_LIMITED_API, not(Py_3_11)))] + "buffer".into(), + // only needs to run on versions where `#[pyclass(immutable_type)]` is unsupported + #[cfg(any(Py_3_14, all(Py_3_10, not(Py_LIMITED_API))))] + "immutable_type.rs".into(), + // generic pyclasses only supported on 3.9+, doesn't fail gracefully on older versions + #[cfg(not(Py_3_9))] + "invalid_pyclass_generic.rs".into(), + ]); config.output_conflict_handling = ui_test::bless_output_files; diff --git a/tests/ui/forbid_unsafe.rs b/tests/ui/forbid_unsafe.rs index 356326e65d3..612a50fb213 100644 --- a/tests/ui/forbid_unsafe.rs +++ b/tests/ui/forbid_unsafe.rs @@ -1,9 +1,9 @@ +//@check-pass #![forbid(unsafe_code)] #![forbid(unsafe_op_in_unsafe_fn)] use pyo3::*; -#[expect(unexpected_cfgs)] #[path = "../../src/tests/hygiene/mod.rs"] mod hygiene; diff --git a/tests/ui/forbid_unsafe.stderr b/tests/ui/forbid_unsafe.stderr index b51b989da09..a93bbb4146b 100644 --- a/tests/ui/forbid_unsafe.stderr +++ b/tests/ui/forbid_unsafe.stderr @@ -1,80 +1,16 @@ -error[E0277]: pyclass `PyWarning` cannot be subclassed - --> tests/ui/../../src/tests/hygiene/pymethods.rs:462:1 - | -462 | #[crate::pyclass(crate = "crate", extends=crate::exceptions::PyWarning)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required for `#[pyclass(extends=PyWarning)]` - | - = help: the trait `PyClassBaseType` is not implemented for `PyWarning` - = note: `PyWarning` must have `#[pyclass(subclass)]` to be eligible for subclassing - = note: with the `abi3` feature enabled, PyO3 does not support subclassing native types - = help: the following other types implement trait `PyClassBaseType`: - Bar - ComplexEnumEqOrd - ComplexEnumManyVariantFields - TupleEnumEqOrd - pyo3::PyAny - = note: this error originates in the attribute macro `crate::pyclass` (in Nightly builds, run with -Z macro-backtrace for more info) - -error[E0277]: pyclass `PyWarning` cannot be subclassed - --> tests/ui/../../src/tests/hygiene/pymethods.rs:462:43 - | -462 | #[crate::pyclass(crate = "crate", extends=crate::exceptions::PyWarning)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required for `#[pyclass(extends=PyWarning)]` - | - = help: the trait `PyClassBaseType` is not implemented for `PyWarning` - = note: `PyWarning` must have `#[pyclass(subclass)]` to be eligible for subclassing - = note: with the `abi3` feature enabled, PyO3 does not support subclassing native types - = help: the following other types implement trait `PyClassBaseType`: - Bar - ComplexEnumEqOrd - ComplexEnumManyVariantFields - TupleEnumEqOrd - pyo3::PyAny -note: required by a bound in `PyClassImpl::BaseType` - --> src/impl_/pyclass.rs:184:33 - | -184 | type BaseType: PyTypeInfo + PyClassBaseType; - | ^^^^^^^^^^^^^^^ required by this bound in `PyClassImpl::BaseType` - -error[E0080]: evaluation panicked: `dict` requires Python >= 3.9 when using the `abi3` feature - --> tests/ui/../../src/tests/hygiene/pyclass.rs:18:5 +warning: function `bytes_from_py` is never used + --> tests/ui/forbid_unsafe.rs:35:8 | -18 | dict - | ^^^^ evaluation of `hygiene::pyclass::_::ASSERT_DICT_SUPPORTED` failed here - -error[E0080]: evaluation panicked: `weakref` requires Python >= 3.9 when using the `abi3` feature - --> tests/ui/../../src/tests/hygiene/pyclass.rs:17:5 +35 | fn bytes_from_py(bytes: &Bound<'_, PyAny>) -> PyResult> { + | ^^^^^^^^^^^^^ | -17 | weakref, - | ^^^^^^^ evaluation of `hygiene::pyclass::_::ASSERT_WEAKREF_SUPPORTED` failed here + = note: `#[warn(dead_code)]` (part of `#[warn(unused)]`) on by default -error[E0277]: pyclass `PyWarning` cannot be subclassed - --> tests/ui/../../src/tests/hygiene/pymethods.rs:466:1 - | -466 | #[crate::pymethods(crate = "crate")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required for `#[pyclass(extends=PyWarning)]` - | - = help: the trait `PyClassBaseType` is not implemented for `PyWarning` - = note: `PyWarning` must have `#[pyclass(subclass)]` to be eligible for subclassing - = note: with the `abi3` feature enabled, PyO3 does not support subclassing native types - = help: the following other types implement trait `PyClassBaseType`: - Bar - ComplexEnumEqOrd - ComplexEnumManyVariantFields - TupleEnumEqOrd - pyo3::PyAny - = note: required for `UserDefinedWarning` to implement `PyClassInit<'_, true, false>` -note: required by a bound in `tp_new_impl` - --> src/impl_/pymethods.rs:825:8 - | -819 | pub unsafe fn tp_new_impl<'py, T, const IS_PYCLASS: bool, const IS_INITIALIZER_TUPLE: bool>( - | ----------- required by a bound in this function -... -825 | T: super::pyclass_init::PyClassInit<'py, IS_PYCLASS, IS_INITIALIZER_TUPLE>, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `tp_new_impl` - = note: this error originates in the attribute macro `crate::pymethods` (in Nightly builds, run with -Z macro-backtrace for more info) +warning: function `f` is never used + --> tests/ui/forbid_unsafe.rs:40:8 + | +40 | fn f(#[pyo3(from_py_with = bytes_from_py)] _bytes: Vec) {} + | ^ -error: aborting due to 5 previous errors +warning: 2 warnings emitted -Some errors have detailed explanations: E0080, E0277. -For more information about an error, try `rustc --explain E0080`. diff --git a/tests/ui/invalid_base_class.stderr b/tests/ui/invalid_base_class.stderr index 5463942de95..5ee05a405a6 100644 --- a/tests/ui/invalid_base_class.stderr +++ b/tests/ui/invalid_base_class.stderr @@ -1,18 +1,22 @@ error[E0277]: pyclass `PyBool` cannot be subclassed - --> tests/ui/invalid_base_class.rs:4:1 - | - 4 | #[pyclass(extends=PyBool)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ required for `#[pyclass(extends=PyBool)]` - | - = help: the trait `PyClassBaseType` is not implemented for `PyBool` - = note: `PyBool` must have `#[pyclass(subclass)]` to be eligible for subclassing - = note: with the `abi3` feature enabled, PyO3 does not support subclassing native types -help: the trait `PyClassBaseType` is implemented for `PyAny` - --> src/types/any.rs:55:1 - | -55 | impl crate::impl_::pyclass::PyClassBaseType for PyAny { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: this error originates in the attribute macro `pyclass` (in Nightly builds, run with -Z macro-backtrace for more info) + --> tests/ui/invalid_base_class.rs:4:1 + | +4 | #[pyclass(extends=PyBool)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ required for `#[pyclass(extends=PyBool)]` + | + = help: the trait `PyClassBaseType` is not implemented for `PyBool` + = note: `PyBool` must have `#[pyclass(subclass)]` to be eligible for subclassing + = help: the following other types implement trait `PyClassBaseType`: + PyAny + PyArithmeticError + PyAssertionError + PyAttributeError + PyBaseException + PyBaseExceptionGroup + PyBlockingIOError + PyBrokenPipeError + and 69 others + = note: this error originates in the attribute macro `pyclass` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: pyclass `PyBool` cannot be subclassed --> tests/ui/invalid_base_class.rs:4:19 @@ -22,12 +26,16 @@ error[E0277]: pyclass `PyBool` cannot be subclassed | = help: the trait `PyClassBaseType` is not implemented for `PyBool` = note: `PyBool` must have `#[pyclass(subclass)]` to be eligible for subclassing - = note: with the `abi3` feature enabled, PyO3 does not support subclassing native types -help: the trait `PyClassBaseType` is implemented for `PyAny` - --> src/types/any.rs:55:1 - | - 55 | impl crate::impl_::pyclass::PyClassBaseType for PyAny { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = help: the following other types implement trait `PyClassBaseType`: + PyAny + PyArithmeticError + PyAssertionError + PyAttributeError + PyBaseException + PyBaseExceptionGroup + PyBlockingIOError + PyBrokenPipeError + and 69 others note: required by a bound in `PyClassImpl::BaseType` --> src/impl_/pyclass.rs:184:33 | diff --git a/tests/ui/invalid_intern_arg.stderr b/tests/ui/invalid_intern_arg.stderr index 43595657cd8..e2e4f697b42 100644 --- a/tests/ui/invalid_intern_arg.stderr +++ b/tests/ui/invalid_intern_arg.stderr @@ -5,10 +5,10 @@ error[E0435]: attempt to use a non-constant value in a constant | ^^^^ non-constant value | help: consider using `let` instead of `static` - --> src/sync.rs - | - - static INTERNED: $crate::sync::Interned = $crate::sync::Interned::new($text); - + let INTERNED: $crate::sync::Interned = $crate::sync::Interned::new($text); + --> src/sync.rs:232:9 + | +232 - static INTERNED: $crate::sync::Interned = $crate::sync::Interned::new($text); +232 + let INTERNED: $crate::sync::Interned = $crate::sync::Interned::new($text); | error: lifetime may not live long enough diff --git a/tests/ui/invalid_pyclass_args.stderr b/tests/ui/invalid_pyclass_args.stderr index 98a852102c0..9a848d70711 100644 --- a/tests/ui/invalid_pyclass_args.stderr +++ b/tests/ui/invalid_pyclass_args.stderr @@ -487,12 +487,26 @@ error[E0277]: the trait bound `dyn std::error::Error + Send + Sync: Clone` is no 248 | field: Box, | ^^^ the trait `Clone` is not implemented for `dyn std::error::Error + Send + Sync` | - = help: the following other types implement trait `PyFunctionArgument<'a, 'holder, 'py, IMPLEMENTS_FROMPYOBJECT>`: - `&'holder T` implements `PyFunctionArgument<'a, 'holder, '_, false>` - `&'holder mut T` implements `PyFunctionArgument<'a, 'holder, '_, false>` - `&'holder pyo3::Bound<'py, T>` implements `PyFunctionArgument<'a, 'holder, 'py, false>` - `&'holder str` implements `PyFunctionArgument<'a, 'holder, 'py, false>` - `Option` implements `PyFunctionArgument<'a, 'holder, 'py, false>` +help: the following other types implement trait `PyFunctionArgument<'a, 'holder, 'py, IMPLEMENTS_FROMPYOBJECT>` + --> src/impl_/extract_argument.rs:92:1 + | + 92 | / impl<'a, 'holder, 'py, T: 'a + 'py> PyFunctionArgument<'a, 'holder, 'py, false> + 93 | | for &'holder Bound<'py, T> + 94 | | where + 95 | | T: PyTypeCheck, + | |___________________^ `&'holder pyo3::Bound<'py, T>` implements `PyFunctionArgument<'a, 'holder, 'py, false>` +... +113 | / impl<'a, 'holder, 'py, T> PyFunctionArgument<'a, 'holder, 'py, false> for Option +114 | | where +115 | | T: PyFunctionArgument<'a, 'holder, 'py, false>, + | |___________________________________________________^ `Option` implements `PyFunctionArgument<'a, 'holder, 'py, false>` +... +175 | impl<'a, 'holder, T: PyClass> PyFunctionArgument<'a, 'holder, '_, false> for &'holder T { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `&'holder T` implements `PyFunctionArgument<'a, 'holder, '_, false>` +... +188 | / impl<'a, 'holder, T: PyClass> PyFunctionArgument<'a, 'holder, '_, false> +189 | | for &'holder mut T + | |______________________^ `&'holder mut T` implements `PyFunctionArgument<'a, 'holder, '_, false>` = note: required for `Box` to implement `Clone` = note: required for `Box` to implement `pyo3::FromPyObject<'_, '_>` = note: required for `Box` to implement `PyFunctionArgument<'_, '_, '_, true>` diff --git a/tests/ui/invalid_pyclass_generic.rs b/tests/ui/invalid_pyclass_generic.rs index 7b7267802e3..23524bb1237 100644 --- a/tests/ui/invalid_pyclass_generic.rs +++ b/tests/ui/invalid_pyclass_generic.rs @@ -5,6 +5,8 @@ use pyo3::types::PyType; //~^ ERROR: duplicate definitions with name `__pymethod___class_getitem____` //~| ERROR: duplicate definitions with name `__class_getitem__` //~| ERROR: multiple applicable items in scope +//~| ERROR: multiple applicable items in scope +//~| ERROR: multiple applicable items in scope struct ClassRedefinesClassGetItem {} #[pymethods] @@ -17,6 +19,7 @@ impl ClassRedefinesClassGetItem { #[classmethod] pub fn __class_getitem__( //~^ ERROR: multiple applicable items in scope + //~| ERROR: multiple applicable items in scope cls: &Bound<'_, PyType>, key: &Bound<'_, PyAny>, ) -> PyResult> { diff --git a/tests/ui/invalid_pyclass_generic.stderr b/tests/ui/invalid_pyclass_generic.stderr index 2a4db17e7cf..c60f34713b9 100644 --- a/tests/ui/invalid_pyclass_generic.stderr +++ b/tests/ui/invalid_pyclass_generic.stderr @@ -1,54 +1,10 @@ -error[E0433]: failed to resolve: could not find `PyGenericAlias` in `types` - --> tests/ui/invalid_pyclass_generic.rs:4:1 - | - 4 | #[pyclass(generic)] - | ^^^^^^^^^^^^^^^^^^^ could not find `PyGenericAlias` in `types` - | -note: found an item that was configured out - --> src/types/mod.rs:25:29 - | -24 | #[cfg(Py_3_9)] - | ------ the item is gated here -25 | pub use self::genericalias::PyGenericAlias; - | ^^^^^^^^^^^^^^ - = note: this error originates in the attribute macro `pyclass` (in Nightly builds, run with -Z macro-backtrace for more info) - -error[E0433]: failed to resolve: could not find `PyGenericAlias` in `types` - --> tests/ui/invalid_pyclass_generic.rs:24:22 - | -24 | pyo3::types::PyGenericAlias::new(cls.py(), cls.as_any(), key) - | ^^^^^^^^^^^^^^ could not find `PyGenericAlias` in `types` - | -note: found an item that was configured out - --> src/types/mod.rs:25:29 - | -24 | #[cfg(Py_3_9)] - | ------ the item is gated here -25 | pub use self::genericalias::PyGenericAlias; - | ^^^^^^^^^^^^^^ - -error[E0425]: cannot find type `PyGenericAlias` in module `pyo3::types` - --> tests/ui/invalid_pyclass_generic.rs:4:1 - | - 4 | #[pyclass(generic)] - | ^^^^^^^^^^^^^^^^^^^ not found in `pyo3::types` - | -note: found an item that was configured out - --> src/types/mod.rs:25:29 - | -24 | #[cfg(Py_3_9)] - | ------ the item is gated here -25 | pub use self::genericalias::PyGenericAlias; - | ^^^^^^^^^^^^^^ - = note: this error originates in the attribute macro `pyclass` (in Nightly builds, run with -Z macro-backtrace for more info) - error[E0592]: duplicate definitions with name `__pymethod___class_getitem____` --> tests/ui/invalid_pyclass_generic.rs:4:1 | 4 | #[pyclass(generic)] | ^^^^^^^^^^^^^^^^^^^ duplicate definitions for `__pymethod___class_getitem____` ... -10 | #[pymethods] +12 | #[pymethods] | ------------ other definition for `__pymethod___class_getitem____` | = note: this error originates in the macro `::pyo3::impl_::pymethods::maybe_define_fastcall_function_with_keywords` which comes from the expansion of the attribute macro `pyclass` (in Nightly builds, run with -Z macro-backtrace for more info) @@ -59,11 +15,12 @@ error[E0592]: duplicate definitions with name `__class_getitem__` 4 | #[pyclass(generic)] | ^^^^^^^^^^^^^^^^^^^ duplicate definitions for `__class_getitem__` ... -18 | / pub fn __class_getitem__( -19 | | -20 | | cls: &Bound<'_, PyType>, -21 | | key: &Bound<'_, PyAny>, -22 | | ) -> PyResult> { +20 | / pub fn __class_getitem__( +21 | | +22 | | +23 | | cls: &Bound<'_, PyType>, +24 | | key: &Bound<'_, PyAny>, +25 | | ) -> PyResult> { | |____________________________- other definition for `__class_getitem__` | = note: this error originates in the attribute macro `pyclass` (in Nightly builds, run with -Z macro-backtrace for more info) @@ -80,9 +37,9 @@ note: candidate #1 is defined in an impl for the type `ClassRedefinesClassGetIte 4 | #[pyclass(generic)] | ^^^^^^^^^^^^^^^^^^^ note: candidate #2 is defined in an impl for the type `ClassRedefinesClassGetItem` - --> tests/ui/invalid_pyclass_generic.rs:10:1 + --> tests/ui/invalid_pyclass_generic.rs:12:1 | -10 | #[pymethods] +12 | #[pymethods] | ^^^^^^^^^^^^ = note: this error originates in the attribute macro `pyclass` which comes from the expansion of the attribute macro `pymethods` (in Nightly builds, run with -Z macro-backtrace for more info) @@ -98,13 +55,14 @@ note: candidate #1 is defined in an impl for the type `ClassRedefinesClassGetIte 4 | #[pyclass(generic)] | ^^^^^^^^^^^^^^^^^^^ note: candidate #2 is defined in an impl for the type `ClassRedefinesClassGetItem` - --> tests/ui/invalid_pyclass_generic.rs:18:5 - | -18 | / pub fn __class_getitem__( -19 | | -20 | | cls: &Bound<'_, PyType>, -21 | | key: &Bound<'_, PyAny>, -22 | | ) -> PyResult> { + --> tests/ui/invalid_pyclass_generic.rs:20:5 + | +20 | / pub fn __class_getitem__( +21 | | +22 | | +23 | | cls: &Bound<'_, PyType>, +24 | | key: &Bound<'_, PyAny>, +25 | | ) -> PyResult> { | |____________________________^ = note: this error originates in the attribute macro `pyclass` (in Nightly builds, run with -Z macro-backtrace for more info) @@ -118,10 +76,22 @@ error[E0034]: multiple applicable items in scope = note: candidate #2 is defined in an impl for the type `IntoPyObjectConverter` = note: this error originates in the attribute macro `pyclass` (in Nightly builds, run with -Z macro-backtrace for more info) +error[E0308]: mismatched types + --> tests/ui/invalid_pyclass_generic.rs:27:9 + | +25 | ) -> PyResult> { + | ------------------- expected `Result, PyErr>` because of return type +26 | +27 | pyo3::types::PyGenericAlias::new(cls.py(), cls.as_any(), key) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Result, PyErr>`, found `Result, PyErr>` + | + = note: expected enum `Result, _>` + found enum `Result, _>` + error[E0034]: multiple applicable items in scope - --> tests/ui/invalid_pyclass_generic.rs:18:12 + --> tests/ui/invalid_pyclass_generic.rs:20:12 | -18 | pub fn __class_getitem__( +20 | pub fn __class_getitem__( | ^^^^^^^^^^^^^^^^^ multiple `__pymethod___class_getitem____` found | note: candidate #1 is defined in an impl for the type `ClassRedefinesClassGetItem` @@ -130,16 +100,16 @@ note: candidate #1 is defined in an impl for the type `ClassRedefinesClassGetIte 4 | #[pyclass(generic)] | ^^^^^^^^^^^^^^^^^^^ note: candidate #2 is defined in an impl for the type `ClassRedefinesClassGetItem` - --> tests/ui/invalid_pyclass_generic.rs:10:1 + --> tests/ui/invalid_pyclass_generic.rs:12:1 | -10 | #[pymethods] +12 | #[pymethods] | ^^^^^^^^^^^^ = note: this error originates in the macro `::pyo3::impl_::pymethods::maybe_define_fastcall_function_with_keywords` which comes from the expansion of the attribute macro `pymethods` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0034]: multiple applicable items in scope - --> tests/ui/invalid_pyclass_generic.rs:18:12 + --> tests/ui/invalid_pyclass_generic.rs:20:12 | -18 | pub fn __class_getitem__( +20 | pub fn __class_getitem__( | ^^^^^^^^^^^^^^^^^ multiple `__class_getitem__` found | note: candidate #1 is defined in an impl for the type `ClassRedefinesClassGetItem` @@ -148,26 +118,27 @@ note: candidate #1 is defined in an impl for the type `ClassRedefinesClassGetIte 4 | #[pyclass(generic)] | ^^^^^^^^^^^^^^^^^^^ note: candidate #2 is defined in an impl for the type `ClassRedefinesClassGetItem` - --> tests/ui/invalid_pyclass_generic.rs:18:5 - | -18 | / pub fn __class_getitem__( -19 | | -20 | | cls: &Bound<'_, PyType>, -21 | | key: &Bound<'_, PyAny>, -22 | | ) -> PyResult> { + --> tests/ui/invalid_pyclass_generic.rs:20:5 + | +20 | / pub fn __class_getitem__( +21 | | +22 | | +23 | | cls: &Bound<'_, PyType>, +24 | | key: &Bound<'_, PyAny>, +25 | | ) -> PyResult> { | |____________________________^ = note: this error originates in the attribute macro `pyclass` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0034]: multiple applicable items in scope - --> tests/ui/invalid_pyclass_generic.rs:22:10 + --> tests/ui/invalid_pyclass_generic.rs:25:10 | -22 | ) -> PyResult> { +25 | ) -> PyResult> { | ^^^^^^^^ multiple `wrap` found | = note: candidate #1 is defined in an impl for the type `IntoPyObjectConverter>` = note: candidate #2 is defined in an impl for the type `IntoPyObjectConverter` -error: aborting due to 11 previous errors +error: aborting due to 9 previous errors -Some errors have detailed explanations: E0034, E0425, E0433, E0592. +Some errors have detailed explanations: E0034, E0308, E0592. For more information about an error, try `rustc --explain E0034`. diff --git a/tests/ui/invalid_pyfunction_argument.stderr b/tests/ui/invalid_pyfunction_argument.stderr index 71f7c55fa94..3a8023afce3 100644 --- a/tests/ui/invalid_pyfunction_argument.stderr +++ b/tests/ui/invalid_pyfunction_argument.stderr @@ -31,12 +31,26 @@ error[E0277]: `AtomicPtr<()>` cannot be used as a Python function argument | = note: implement `FromPyObject` to enable using `AtomicPtr<()>` as a function argument = note: `Python<'py>` is also a valid argument type to pass the Python token into `#[pyfunction]`s and `#[pymethods]` - = help: the following other types implement trait `PyFunctionArgument<'a, 'holder, 'py, IMPLEMENTS_FROMPYOBJECT>`: - `&'holder T` implements `PyFunctionArgument<'a, 'holder, '_, false>` - `&'holder mut T` implements `PyFunctionArgument<'a, 'holder, '_, false>` - `&'holder pyo3::Bound<'py, T>` implements `PyFunctionArgument<'a, 'holder, 'py, false>` - `&'holder str` implements `PyFunctionArgument<'a, 'holder, 'py, false>` - `Option` implements `PyFunctionArgument<'a, 'holder, 'py, false>` +help: the following other types implement trait `PyFunctionArgument<'a, 'holder, 'py, IMPLEMENTS_FROMPYOBJECT>` + --> src/impl_/extract_argument.rs:92:1 + | + 92 | / impl<'a, 'holder, 'py, T: 'a + 'py> PyFunctionArgument<'a, 'holder, 'py, false> + 93 | | for &'holder Bound<'py, T> + 94 | | where + 95 | | T: PyTypeCheck, + | |___________________^ `&'holder pyo3::Bound<'py, T>` implements `PyFunctionArgument<'a, 'holder, 'py, false>` +... +113 | / impl<'a, 'holder, 'py, T> PyFunctionArgument<'a, 'holder, 'py, false> for Option +114 | | where +115 | | T: PyFunctionArgument<'a, 'holder, 'py, false>, + | |___________________________________________________^ `Option` implements `PyFunctionArgument<'a, 'holder, 'py, false>` +... +175 | impl<'a, 'holder, T: PyClass> PyFunctionArgument<'a, 'holder, '_, false> for &'holder T { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `&'holder T` implements `PyFunctionArgument<'a, 'holder, '_, false>` +... +188 | / impl<'a, 'holder, T: PyClass> PyFunctionArgument<'a, 'holder, '_, false> +189 | | for &'holder mut T + | |______________________^ `&'holder mut T` implements `PyFunctionArgument<'a, 'holder, '_, false>` = note: required for `AtomicPtr<()>` to implement `FromPyObject<'_, '_>` = note: required for `AtomicPtr<()>` to implement `PyFunctionArgument<'_, '_, '_, true>` note: required by a bound in `extract_argument` @@ -56,12 +70,26 @@ error[E0277]: `AtomicPtr<()>` cannot be used as a Python function argument | = note: implement `FromPyObject` to enable using `AtomicPtr<()>` as a function argument = note: `Python<'py>` is also a valid argument type to pass the Python token into `#[pyfunction]`s and `#[pymethods]` - = help: the following other types implement trait `PyFunctionArgument<'a, 'holder, 'py, IMPLEMENTS_FROMPYOBJECT>`: - `&'holder T` implements `PyFunctionArgument<'a, 'holder, '_, false>` - `&'holder mut T` implements `PyFunctionArgument<'a, 'holder, '_, false>` - `&'holder pyo3::Bound<'py, T>` implements `PyFunctionArgument<'a, 'holder, 'py, false>` - `&'holder str` implements `PyFunctionArgument<'a, 'holder, 'py, false>` - `Option` implements `PyFunctionArgument<'a, 'holder, 'py, false>` +help: the following other types implement trait `PyFunctionArgument<'a, 'holder, 'py, IMPLEMENTS_FROMPYOBJECT>` + --> src/impl_/extract_argument.rs:92:1 + | + 92 | / impl<'a, 'holder, 'py, T: 'a + 'py> PyFunctionArgument<'a, 'holder, 'py, false> + 93 | | for &'holder Bound<'py, T> + 94 | | where + 95 | | T: PyTypeCheck, + | |___________________^ `&'holder pyo3::Bound<'py, T>` implements `PyFunctionArgument<'a, 'holder, 'py, false>` +... +113 | / impl<'a, 'holder, 'py, T> PyFunctionArgument<'a, 'holder, 'py, false> for Option +114 | | where +115 | | T: PyFunctionArgument<'a, 'holder, 'py, false>, + | |___________________________________________________^ `Option` implements `PyFunctionArgument<'a, 'holder, 'py, false>` +... +175 | impl<'a, 'holder, T: PyClass> PyFunctionArgument<'a, 'holder, '_, false> for &'holder T { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `&'holder T` implements `PyFunctionArgument<'a, 'holder, '_, false>` +... +188 | / impl<'a, 'holder, T: PyClass> PyFunctionArgument<'a, 'holder, '_, false> +189 | | for &'holder mut T + | |______________________^ `&'holder mut T` implements `PyFunctionArgument<'a, 'holder, '_, false>` = note: required for `AtomicPtr<()>` to implement `FromPyObject<'_, '_>` = note: required for `AtomicPtr<()>` to implement `PyFunctionArgument<'_, '_, '_, true>` note: required by a bound in `extract_argument` @@ -86,12 +114,26 @@ help: the trait `ExtractPyClassWithClone` is not implemented for `Foo` | ^^^^^^^^^^ = note: implement `FromPyObject` to enable using `Foo` as a function argument = note: `Python<'py>` is also a valid argument type to pass the Python token into `#[pyfunction]`s and `#[pymethods]` - = help: the following other types implement trait `PyFunctionArgument<'a, 'holder, 'py, IMPLEMENTS_FROMPYOBJECT>`: - `&'holder T` implements `PyFunctionArgument<'a, 'holder, '_, false>` - `&'holder mut T` implements `PyFunctionArgument<'a, 'holder, '_, false>` - `&'holder pyo3::Bound<'py, T>` implements `PyFunctionArgument<'a, 'holder, 'py, false>` - `&'holder str` implements `PyFunctionArgument<'a, 'holder, 'py, false>` - `Option` implements `PyFunctionArgument<'a, 'holder, 'py, false>` +help: the following other types implement trait `PyFunctionArgument<'a, 'holder, 'py, IMPLEMENTS_FROMPYOBJECT>` + --> src/impl_/extract_argument.rs:92:1 + | + 92 | / impl<'a, 'holder, 'py, T: 'a + 'py> PyFunctionArgument<'a, 'holder, 'py, false> + 93 | | for &'holder Bound<'py, T> + 94 | | where + 95 | | T: PyTypeCheck, + | |___________________^ `&'holder pyo3::Bound<'py, T>` implements `PyFunctionArgument<'a, 'holder, 'py, false>` +... +113 | / impl<'a, 'holder, 'py, T> PyFunctionArgument<'a, 'holder, 'py, false> for Option +114 | | where +115 | | T: PyFunctionArgument<'a, 'holder, 'py, false>, + | |___________________________________________________^ `Option` implements `PyFunctionArgument<'a, 'holder, 'py, false>` +... +175 | impl<'a, 'holder, T: PyClass> PyFunctionArgument<'a, 'holder, '_, false> for &'holder T { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `&'holder T` implements `PyFunctionArgument<'a, 'holder, '_, false>` +... +188 | / impl<'a, 'holder, T: PyClass> PyFunctionArgument<'a, 'holder, '_, false> +189 | | for &'holder mut T + | |______________________^ `&'holder mut T` implements `PyFunctionArgument<'a, 'holder, '_, false>` = note: required for `Foo` to implement `FromPyObject<'_, '_>` = note: required for `Foo` to implement `PyFunctionArgument<'_, '_, '_, true>` note: required by a bound in `extract_argument` diff --git a/tests/ui/invalid_pymethods_buffer.stderr b/tests/ui/invalid_pymethods_buffer.stderr index 4d66108e054..c93692593ff 100644 --- a/tests/ui/invalid_pymethods_buffer.stderr +++ b/tests/ui/invalid_pymethods_buffer.stderr @@ -10,18 +10,5 @@ error: `__releasebuffer__` must be `unsafe fn` 16 | fn releasebuffer_must_be_unsafe(&self, _view: *mut pyo3::ffi::Py_buffer) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0425]: cannot find type `Py_buffer` in module `pyo3::ffi` - --> tests/ui/invalid_pymethods_buffer.rs:9:63 - | -9 | fn getbuffer_must_be_unsafe(&self, _view: *mut pyo3::ffi::Py_buffer, _flags: std::ffi::c_int) {} - | ^^^^^^^^^ not found in `pyo3::ffi` - -error[E0425]: cannot find type `Py_buffer` in module `pyo3::ffi` - --> tests/ui/invalid_pymethods_buffer.rs:16:67 - | -16 | fn releasebuffer_must_be_unsafe(&self, _view: *mut pyo3::ffi::Py_buffer) {} - | ^^^^^^^^^ not found in `pyo3::ffi` - -error: aborting due to 4 previous errors +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0425`. From 4ea3933f56dc636e7de4d982b8286301b9924d8d Mon Sep 17 00:00:00 2001 From: David Hewitt Date: Sun, 8 Mar 2026 15:32:12 +0000 Subject: [PATCH 04/21] attempt to fix CI errors --- Cargo.toml | 1 + tests/test_compile_error.rs | 19 ++++++++++++++----- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 6c9ebecb054..ede01f7314e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -81,6 +81,7 @@ static_assertions = "1.1.0" uuid = { version = "1.10.0", features = ["v4"] } parking_lot = { version = "0.12.3", features = ["arc_lock"] } ui_test = "0.30.4" +[target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies] ctrlc = "3.5.2" [build-dependencies] diff --git a/tests/test_compile_error.rs b/tests/test_compile_error.rs index 03b694781de..f86ae5b3966 100644 --- a/tests/test_compile_error.rs +++ b/tests/test_compile_error.rs @@ -149,9 +149,15 @@ fn test_compile_errors() { config.skip_files.extend([ // not a test file, used to configure dependencies for the tests "base/src/lib.rs".into(), - // don't run abi3-only tests when not testing abi3 features - #[cfg(not(Py_LIMITED_API))] - "abi3".into(), + // abi3-only tests only need to check when the feature is unsupported + #[cfg(any(not(Py_LIMITED_API), Py_3_9))] + "abi3_dict".into(), + #[cfg(any(not(Py_LIMITED_API), Py_3_9))] + "abi3_weakref".into(), + #[cfg(any(not(Py_LIMITED_API), Py_3_12))] + "abi3_nativetype_inheritance".into(), + #[cfg(any(not(Py_LIMITED_API), Py_3_12))] + "abi3_inheritance".into(), // this test doesn't work properly without the full API available #[cfg(Py_LIMITED_API)] "forbid_unsafe.rs".into(), @@ -168,8 +174,11 @@ fn test_compile_errors() { config.output_conflict_handling = ui_test::bless_output_files; - let abort_check = config.abort_check.clone(); - ctrlc::set_handler(move || abort_check.abort()).unwrap(); + #[cfg(not(target_arch = "wasm32"))] // doesn't work on wasm + { + let abort_check = config.abort_check.clone(); + ctrlc::set_handler(move || abort_check.abort()).unwrap(); + } run_tests(config).unwrap(); } From ae05fddd5be77319a94645b9a870de30e7f3ec0a Mon Sep 17 00:00:00 2001 From: David Hewitt Date: Wed, 25 Mar 2026 16:29:00 +0000 Subject: [PATCH 05/21] forward cargo target to ui-test --- tests/test_compile_error.rs | 97 ++----------------------------------- 1 file changed, 4 insertions(+), 93 deletions(-) diff --git a/tests/test_compile_error.rs b/tests/test_compile_error.rs index f86ae5b3966..8e9c171314b 100644 --- a/tests/test_compile_error.rs +++ b/tests/test_compile_error.rs @@ -3,99 +3,6 @@ #[cfg(not(target_arch = "wasm32"))] // Not possible to invoke compiler from wasm #[test] fn test_compile_errors() { - // let t = trybuild::TestCases::new(); - - // t.compile_fail("tests/ui/deprecated_pyfn.rs"); - // #[cfg(not(feature = "experimental-inspect"))] - // t.compile_fail("tests/ui/invalid_property_args.rs"); - // t.compile_fail("tests/ui/invalid_proto_pymethods.rs"); - // #[cfg(not(all(Py_LIMITED_API, not(Py_3_10))))] // to avoid PyFunctionArgument for &str - // t.compile_fail("tests/ui/invalid_pyclass_args.rs"); - // t.compile_fail("tests/ui/invalid_pyclass_doc.rs"); - // t.compile_fail("tests/ui/invalid_pyclass_enum.rs"); - // t.compile_fail("tests/ui/invalid_pyclass_init.rs"); - // t.compile_fail("tests/ui/invalid_pyclass_item.rs"); - // #[cfg(Py_3_9)] - // t.compile_fail("tests/ui/invalid_pyclass_generic.rs"); - // #[cfg(Py_3_9)] - // t.compile_fail("tests/ui/pyclass_generic_enum.rs"); - // #[cfg(not(feature = "experimental-inspect"))] - // #[cfg(not(all(Py_LIMITED_API, not(Py_3_10))))] // to avoid PyFunctionArgument for &str - // t.compile_fail("tests/ui/invalid_pyfunction_argument.rs"); - // t.compile_fail("tests/ui/invalid_pyfunction_definition.rs"); - // t.compile_fail("tests/ui/invalid_pyfunction_signatures.rs"); - // #[cfg(any(not(Py_LIMITED_API), Py_3_11))] - // t.compile_fail("tests/ui/invalid_pymethods_buffer.rs"); - // // The output is not stable across abi3 / not abi3 and features - // #[cfg(all(not(Py_LIMITED_API), feature = "full"))] - // t.compile_fail("tests/ui/invalid_pymethods_duplicates.rs"); - // t.compile_fail("tests/ui/invalid_pymethod_enum.rs"); - // t.compile_fail("tests/ui/invalid_pymethod_names.rs"); - // t.compile_fail("tests/ui/invalid_pymodule_args.rs"); - // t.compile_fail("tests/ui/invalid_pycallargs.rs"); - // t.compile_fail("tests/ui/reject_generics.rs"); - // t.compile_fail("tests/ui/invalid_closure.rs"); - // t.compile_fail("tests/ui/pyclass_send.rs"); - // #[cfg(not(feature = "experimental-inspect"))] - // t.compile_fail("tests/ui/invalid_annotation.rs"); - // #[cfg(not(feature = "experimental-inspect"))] - // t.compile_fail("tests/ui/invalid_annotation_return.rs"); - // t.compile_fail("tests/ui/invalid_argument_attributes.rs"); - // t.compile_fail("tests/ui/invalid_intopy_derive.rs"); - // #[cfg(not(windows))] - // t.compile_fail("tests/ui/invalid_intopy_with.rs"); - // t.compile_fail("tests/ui/invalid_frompy_derive.rs"); - // t.compile_fail("tests/ui/static_ref.rs"); - // t.compile_fail("tests/ui/wrong_aspyref_lifetimes.rs"); - // #[cfg(not(feature = "uuid"))] - // t.compile_fail("tests/ui/invalid_pyfunctions.rs"); - // t.compile_fail("tests/ui/invalid_pymethods.rs"); - // // output changes with async feature - // #[cfg(all(not(Py_3_12), Py_LIMITED_API, feature = "experimental-async"))] - // t.compile_fail("tests/ui/abi3_nativetype_inheritance.rs"); - // #[cfg(not(feature = "experimental-async"))] - // t.compile_fail("tests/ui/invalid_async.rs"); - // t.compile_fail("tests/ui/invalid_intern_arg.rs"); - // t.compile_fail("tests/ui/invalid_frozen_pyclass_borrow.rs"); - // #[cfg(not(any(feature = "hashbrown", feature = "indexmap")))] - // t.compile_fail("tests/ui/invalid_pymethod_receiver.rs"); - // #[cfg(not(feature = "experimental-inspect"))] - // t.compile_fail("tests/ui/missing_intopy.rs"); - // // adding extra error conversion impls changes the output - // #[cfg(not(any(windows, feature = "eyre", feature = "anyhow", Py_LIMITED_API)))] - // t.compile_fail("tests/ui/invalid_result_conversion.rs"); - // t.compile_fail("tests/ui/not_send.rs"); - // t.compile_fail("tests/ui/not_send2.rs"); - // t.compile_fail("tests/ui/get_set_all.rs"); - // t.compile_fail("tests/ui/traverse.rs"); - // t.compile_fail("tests/ui/invalid_pymodule_in_root.rs"); - // t.compile_fail("tests/ui/invalid_pymodule_glob.rs"); - // t.compile_fail("tests/ui/invalid_pymodule_trait.rs"); - // t.compile_fail("tests/ui/invalid_pymodule_two_pymodule_init.rs"); - // #[cfg(all(feature = "experimental-async", not(feature = "experimental-inspect")))] - // #[cfg(any(not(Py_LIMITED_API), Py_3_10))] // to avoid PyFunctionArgument for &str - // t.compile_fail("tests/ui/invalid_cancel_handle.rs"); - // t.pass("tests/ui/pymodule_missing_docs.rs"); - // #[cfg(not(any(Py_LIMITED_API, feature = "experimental-inspect")))] - // t.pass("tests/ui/forbid_unsafe.rs"); - // #[cfg(all(Py_LIMITED_API, not(feature = "experimental-async")))] - // // output changes with async feature - // t.compile_fail("tests/ui/abi3_inheritance.rs"); - // #[cfg(all(Py_LIMITED_API, not(Py_3_9)))] - // t.compile_fail("tests/ui/abi3_weakref.rs"); - // #[cfg(all(Py_LIMITED_API, not(Py_3_9)))] - // t.compile_fail("tests/ui/abi3_dict.rs"); - // #[cfg(not(feature = "experimental-inspect"))] - // t.compile_fail("tests/ui/duplicate_pymodule_submodule.rs"); - // #[cfg(all(not(Py_LIMITED_API), Py_3_11))] - // t.compile_fail("tests/ui/invalid_base_class.rs"); - // #[cfg(any(not(Py_3_10), all(not(Py_3_14), Py_LIMITED_API)))] - // t.compile_fail("tests/ui/immutable_type.rs"); - // t.pass("tests/ui/ambiguous_associated_items.rs"); - // t.pass("tests/ui/pyclass_probe.rs"); - // t.compile_fail("tests/ui/invalid_pyfunction_warn.rs"); - // t.compile_fail("tests/ui/invalid_pymethods_warn.rs"); - use std::path::PathBuf; use ui_test::{run_tests, Config}; @@ -140,6 +47,10 @@ fn test_compile_errors() { }, ); + if let Ok(target) = std::env::var("CARGO_BUILD_TARGET") { + config.target = Some(target); + } + config .comment_defaults .base() From d598cdb0f61299c1ca87a83e78c879acec6c83ae Mon Sep 17 00:00:00 2001 From: David Hewitt Date: Fri, 27 Mar 2026 21:28:17 +0000 Subject: [PATCH 06/21] fix ignore mechanism --- .github/workflows/build.yml | 4 ++-- .github/workflows/ci.yml | 4 ++-- Cargo.toml | 2 +- Contributing.md | 4 ++-- noxfile.py | 2 +- tests/test_compile_error.rs | 24 +++++++++++++++++-- tests/ui/ambiguous_associated_items.stderr | 1 - tests/ui/deprecated_pyfn.stderr | 1 - tests/ui/forbid_unsafe.stderr | 1 - tests/ui/get_set_all.stderr | 1 - tests/ui/invalid_annotation.stderr | 1 - tests/ui/invalid_annotation_return.stderr | 1 - tests/ui/invalid_async.stderr | 1 - tests/ui/invalid_cancel_handle.stderr | 12 +++++----- tests/ui/invalid_intopy_derive.stderr | 1 - tests/ui/invalid_property_args.stderr | 6 ++--- tests/ui/invalid_pyclass_doc.stderr | 1 - tests/ui/invalid_pyclass_item.stderr | 1 - tests/ui/invalid_pyfunction_definition.stderr | 1 - tests/ui/invalid_pyfunction_signatures.stderr | 1 - tests/ui/invalid_pyfunction_warn.stderr | 1 - tests/ui/invalid_pymethod_names.stderr | 1 - tests/ui/invalid_pymethods_buffer.stderr | 1 - tests/ui/invalid_pymethods_warn.stderr | 1 - tests/ui/invalid_pymodule_args.stderr | 1 - tests/ui/invalid_pymodule_glob.stderr | 1 - tests/ui/invalid_pymodule_trait.stderr | 1 - .../invalid_pymodule_two_pymodule_init.stderr | 1 - tests/ui/invalid_result_conversion.stderr | 4 +++- tests/ui/missing_intopy.stderr | 8 +++---- tests/ui/pyclass_generic_enum.stderr | 1 - tests/ui/reject_generics.stderr | 1 - tests/ui/traverse.stderr | 1 - tests/ui/wrong_aspyref_lifetimes.stderr | 1 - 34 files changed, 46 insertions(+), 48 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 46cb88bc798..8828fc9c6cf 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -106,8 +106,8 @@ jobs: run: nox -s set-msrv-package-versions - if: inputs.rust != 'stable' - name: Ignore changed error messages when using trybuild - run: echo "TRYBUILD=overwrite" >> "$GITHUB_ENV" + name: Ignore changed error messages for ui tests (still run for coverage) + run: echo "UI_TEST=ignore" >> "$GITHUB_ENV" - uses: dorny/paths-filter@v4 if: ${{ inputs.rust == 'stable' && !startsWith(inputs.python-version, 'graalpy') }} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 29e252cb235..f06890b9bc9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -407,7 +407,7 @@ jobs: env: CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_RUNNER: valgrind --leak-check=no --error-exitcode=1 RUST_BACKTRACE: 1 - TRYBUILD: overwrite + UI_TEST: ignore careful: if: ${{ contains(github.event.pull_request.labels.*.name, 'CI-build-full') || github.event_name != 'pull_request' }} @@ -429,7 +429,7 @@ jobs: - run: nox -s test-rust -- careful skip-full env: RUST_BACKTRACE: 1 - TRYBUILD: overwrite + UI_TEST: ignore docsrs: if: ${{ contains(github.event.pull_request.labels.*.name, 'CI-build-full') || github.event_name != 'pull_request' }} diff --git a/Cargo.toml b/Cargo.toml index 0a613131f79..e795678179c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -69,7 +69,6 @@ portable-atomic = "1.0" assert_approx_eq = "1.1.0" chrono = "0.4.25" chrono-tz = ">= 0.10, < 0.11" -trybuild = ">=1.0.115" proptest = { version = "1.0", default-features = false, features = ["std"] } send_wrapper = "0.6" serde = { version = "1.0", features = ["derive"] } @@ -81,6 +80,7 @@ static_assertions = "1.1.0" uuid = { version = "1.10.0", features = ["v4"] } parking_lot = { version = "0.12.3", features = ["arc_lock"] } ui_test = "0.30.4" +regex = "1.12.3" [target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies] ctrlc = "3.5.2" diff --git a/Contributing.md b/Contributing.md index 5b07b36d2c6..3a742a96837 100644 --- a/Contributing.md +++ b/Contributing.md @@ -45,7 +45,7 @@ Use `nox -l` to list the full set of subcommands you can run. #### UI Tests -PyO3 uses [`trybuild`][trybuild] to develop UI tests to capture error messages from the Rust compiler for some of the macro functionality. +PyO3 uses [`ui_test`][ui_test] to develop UI tests to capture error messages from the Rust compiler for some of the macro functionality. The Rust compiler's error output differs depending on whether the `rust-src` component is installed. PyO3's CI has `rust-src` installed, so you need it locally for your UI test output to match: @@ -265,4 +265,4 @@ In the meanwhile, some of our maintainers have personal GitHub sponsorship pages [lychee]: https://github.com/lycheeverse/lychee [nox]: https://github.com/theacodes/nox [pipx]: https://pipx.pypa.io/stable/ -[trybuild]: https://github.com/dtolnay/trybuild +[ui_test]: https://github.com/oli-obk/ui_test diff --git a/noxfile.py b/noxfile.py index 42cf158e1b5..433f1ebc03c 100644 --- a/noxfile.py +++ b/noxfile.py @@ -1404,7 +1404,7 @@ def check_feature_powerset(session: nox.Session): @nox.session(name="update-ui-tests", venv_backend="none") def update_ui_tests(session: nox.Session): env = os.environ.copy() - env["TRYBUILD"] = "overwrite" + env["UI_TEST"] = "bless" command = ["test", "--test", "test_compile_error"] _run_cargo(session, *command, env=env) _run_cargo(session, *command, "--features=full", env=env) diff --git a/tests/test_compile_error.rs b/tests/test_compile_error.rs index 8e9c171314b..f6750cda281 100644 --- a/tests/test_compile_error.rs +++ b/tests/test_compile_error.rs @@ -3,12 +3,15 @@ #[cfg(not(target_arch = "wasm32"))] // Not possible to invoke compiler from wasm #[test] fn test_compile_errors() { - use std::path::PathBuf; + use std::{env::VarError, path::PathBuf}; + use regex::bytes::Regex; use ui_test::{run_tests, Config}; let mut config = Config::rustc("tests/ui"); + // There doesn't seem to be a good way to forward all these features automatically, + // so have to just list the relevant ones here. let deps_features = [ #[cfg(feature = "macros")] "pyo3/macros".to_string(), @@ -83,7 +86,24 @@ fn test_compile_errors() { "invalid_pyclass_generic.rs".into(), ]); - config.output_conflict_handling = ui_test::bless_output_files; + match std::env::var("UI_TEST").as_deref() { + Ok("bless") => config.output_conflict_handling = ui_test::bless_output_files, + Ok("ignore") => config.output_conflict_handling = ui_test::ignore_output_conflict, + Err(VarError::NotPresent) => { + config.output_conflict_handling = ui_test::error_on_output_conflict + } + Err(e) => panic!("error reading UI_TEST environment variable: {e}"), + Ok(unknown) => panic!("invalid UI_TEST value: {unknown}"), + } + + config.bless_command = Some("UI_TEST=bless cargo test --test test_compile_error".into()); + + // Normalize multiple trailing newlines to a single newline + config + .comment_defaults + .base() + .normalize_stderr + .push((Regex::new("\n\n$").unwrap().into(), vec![b'\n'])); #[cfg(not(target_arch = "wasm32"))] // doesn't work on wasm { diff --git a/tests/ui/ambiguous_associated_items.stderr b/tests/ui/ambiguous_associated_items.stderr index 20008d42b9b..a8b30ca7fb4 100644 --- a/tests/ui/ambiguous_associated_items.stderr +++ b/tests/ui/ambiguous_associated_items.stderr @@ -13,4 +13,3 @@ warning: enum `DeriveItemsFromPyObject` is never used | ^^^^^^^^^^^^^^^^^^^^^^^ warning: 2 warnings emitted - diff --git a/tests/ui/deprecated_pyfn.stderr b/tests/ui/deprecated_pyfn.stderr index 16bf82f6451..9399a270e3d 100644 --- a/tests/ui/deprecated_pyfn.stderr +++ b/tests/ui/deprecated_pyfn.stderr @@ -11,4 +11,3 @@ note: the lint level is defined here | ^^^^^^^^^^ error: aborting due to 1 previous error - diff --git a/tests/ui/forbid_unsafe.stderr b/tests/ui/forbid_unsafe.stderr index a93bbb4146b..44b9d7456db 100644 --- a/tests/ui/forbid_unsafe.stderr +++ b/tests/ui/forbid_unsafe.stderr @@ -13,4 +13,3 @@ warning: function `f` is never used | ^ warning: 2 warnings emitted - diff --git a/tests/ui/get_set_all.stderr b/tests/ui/get_set_all.stderr index 33b47e1c7cb..6b6f101df71 100644 --- a/tests/ui/get_set_all.stderr +++ b/tests/ui/get_set_all.stderr @@ -23,4 +23,3 @@ error: useless `get` - the struct is already annotated with `get_all` | ^^^ error: aborting due to 4 previous errors - diff --git a/tests/ui/invalid_annotation.stderr b/tests/ui/invalid_annotation.stderr index 4f62a7554bb..5323756bb49 100644 --- a/tests/ui/invalid_annotation.stderr +++ b/tests/ui/invalid_annotation.stderr @@ -5,4 +5,3 @@ error: Type annotations in the signature is only supported with the `experimenta | ^^^^^ error: aborting due to 1 previous error - diff --git a/tests/ui/invalid_annotation_return.stderr b/tests/ui/invalid_annotation_return.stderr index 37ae25d81f6..8680b82cead 100644 --- a/tests/ui/invalid_annotation_return.stderr +++ b/tests/ui/invalid_annotation_return.stderr @@ -5,4 +5,3 @@ error: Return type annotation in the signature is only supported with the `exper | ^^^^^ error: aborting due to 1 previous error - diff --git a/tests/ui/invalid_async.stderr b/tests/ui/invalid_async.stderr index 533684075a9..35649d07955 100644 --- a/tests/ui/invalid_async.stderr +++ b/tests/ui/invalid_async.stderr @@ -17,4 +17,3 @@ error: async functions are only supported with the `experimental-async` feature | ^^^^^ error: aborting due to 3 previous errors - diff --git a/tests/ui/invalid_cancel_handle.stderr b/tests/ui/invalid_cancel_handle.stderr index 8936e97fab8..55dd934c1bb 100644 --- a/tests/ui/invalid_cancel_handle.stderr +++ b/tests/ui/invalid_cancel_handle.stderr @@ -41,11 +41,11 @@ error[E0433]: failed to resolve: could not find `coroutine` in `pyo3` | ^^^^^^^^^ could not find `coroutine` in `pyo3` | note: found an item that was configured out - --> src/lib.rs:417:9 + --> src/lib.rs:418:9 | -416 | #[cfg(feature = "experimental-async")] +417 | #[cfg(feature = "experimental-async")] | ------------------------------ the item is gated behind the `experimental-async` feature -417 | pub mod coroutine; +418 | pub mod coroutine; | ^^^^^^^^^ error[E0433]: failed to resolve: could not find `coroutine` in `pyo3` @@ -55,11 +55,11 @@ error[E0433]: failed to resolve: could not find `coroutine` in `pyo3` | ^^^^^^^^^ could not find `coroutine` in `pyo3` | note: found an item that was configured out - --> src/lib.rs:417:9 + --> src/lib.rs:418:9 | -416 | #[cfg(feature = "experimental-async")] +417 | #[cfg(feature = "experimental-async")] | ------------------------------ the item is gated behind the `experimental-async` feature -417 | pub mod coroutine; +418 | pub mod coroutine; | ^^^^^^^^^ error: aborting due to 8 previous errors diff --git a/tests/ui/invalid_intopy_derive.stderr b/tests/ui/invalid_intopy_derive.stderr index 38476069aaf..8a9b30025df 100644 --- a/tests/ui/invalid_intopy_derive.stderr +++ b/tests/ui/invalid_intopy_derive.stderr @@ -183,4 +183,3 @@ error: `rename_all` is not supported at top level for enums | ^^^^^^^^^^ error: aborting due to 29 previous errors - diff --git a/tests/ui/invalid_property_args.stderr b/tests/ui/invalid_property_args.stderr index 45df8dd1181..e2c719babd5 100644 --- a/tests/ui/invalid_property_args.stderr +++ b/tests/ui/invalid_property_args.stderr @@ -66,12 +66,12 @@ error[E0277]: `PhantomData` cannot be converted to a Python object and 151 others = note: required for `PhantomData` to implement `for<'py> PyO3GetField<'py>` note: required by a bound in `PyClassGetterGenerator::::generate` - --> src/impl_/pyclass.rs:1329:26 + --> src/impl_/pyclass.rs:1328:26 | -1325 | pub const fn generate(&self, name: &'static CStr, doc: Option<&'static CStr>) -> PyMethodDefType +1324 | pub const fn generate(&self, name: &'static CStr, doc: Option<&'static CStr>) -> PyMethodDefType | -------- required by a bound in this associated function ... -1329 | for<'py> FieldT: PyO3GetField<'py>, +1328 | for<'py> FieldT: PyO3GetField<'py>, | ^^^^^^^^^^^^^^^^^ required by this bound in `PyClassGetterGenerator::::generate` error: aborting due to 9 previous errors diff --git a/tests/ui/invalid_pyclass_doc.stderr b/tests/ui/invalid_pyclass_doc.stderr index 5763e9e19db..aa9d62c27fa 100644 --- a/tests/ui/invalid_pyclass_doc.stderr +++ b/tests/ui/invalid_pyclass_doc.stderr @@ -5,4 +5,3 @@ error: Python doc may not contain nul byte, found nul at position 5 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 1 previous error - diff --git a/tests/ui/invalid_pyclass_item.stderr b/tests/ui/invalid_pyclass_item.stderr index afd17c4e665..30d7fdec2c8 100644 --- a/tests/ui/invalid_pyclass_item.stderr +++ b/tests/ui/invalid_pyclass_item.stderr @@ -5,4 +5,3 @@ error: #[pyclass] only supports structs and enums. | ^^^^^^^^^^^ error: aborting due to 1 previous error - diff --git a/tests/ui/invalid_pyfunction_definition.stderr b/tests/ui/invalid_pyfunction_definition.stderr index 7ebb07c5d93..35a00fc7e14 100644 --- a/tests/ui/invalid_pyfunction_definition.stderr +++ b/tests/ui/invalid_pyfunction_definition.stderr @@ -5,4 +5,3 @@ error: functions inside #[pymethods] do not need to be annotated with #[pyfuncti | ^^ error: aborting due to 1 previous error - diff --git a/tests/ui/invalid_pyfunction_signatures.stderr b/tests/ui/invalid_pyfunction_signatures.stderr index b36b650f7b1..7ad4f52d495 100644 --- a/tests/ui/invalid_pyfunction_signatures.stderr +++ b/tests/ui/invalid_pyfunction_signatures.stderr @@ -65,4 +65,3 @@ error: expected argument from function definition `x` but got argument `kwargs` | ^^^^^^ error: aborting due to 11 previous errors - diff --git a/tests/ui/invalid_pyfunction_warn.stderr b/tests/ui/invalid_pyfunction_warn.stderr index ec9b4d520bc..40491543a9a 100644 --- a/tests/ui/invalid_pyfunction_warn.stderr +++ b/tests/ui/invalid_pyfunction_warn.stderr @@ -47,4 +47,3 @@ error: __traverse__ cannot be used with #[pyo3(warn)] | ^^^^ error: aborting due to 8 previous errors - diff --git a/tests/ui/invalid_pymethod_names.stderr b/tests/ui/invalid_pymethod_names.stderr index bf8ff8f9514..09a031f19c4 100644 --- a/tests/ui/invalid_pymethod_names.stderr +++ b/tests/ui/invalid_pymethod_names.stderr @@ -29,4 +29,3 @@ error: expected `#[getter(name)]` to set the name | ^ error: aborting due to 5 previous errors - diff --git a/tests/ui/invalid_pymethods_buffer.stderr b/tests/ui/invalid_pymethods_buffer.stderr index c93692593ff..4ecaaca3a58 100644 --- a/tests/ui/invalid_pymethods_buffer.stderr +++ b/tests/ui/invalid_pymethods_buffer.stderr @@ -11,4 +11,3 @@ error: `__releasebuffer__` must be `unsafe fn` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 2 previous errors - diff --git a/tests/ui/invalid_pymethods_warn.stderr b/tests/ui/invalid_pymethods_warn.stderr index dcc41ab94d1..76cca26f9d7 100644 --- a/tests/ui/invalid_pymethods_warn.stderr +++ b/tests/ui/invalid_pymethods_warn.stderr @@ -11,4 +11,3 @@ error: #[classattr] cannot be used with #[pyo3(warn)] | ^^^^ error: aborting due to 2 previous errors - diff --git a/tests/ui/invalid_pymodule_args.stderr b/tests/ui/invalid_pymodule_args.stderr index de86964e728..88e0eafbb9e 100644 --- a/tests/ui/invalid_pymodule_args.stderr +++ b/tests/ui/invalid_pymodule_args.stderr @@ -29,4 +29,3 @@ error: `name` may only be specified once | ^^^^ error: aborting due to 5 previous errors - diff --git a/tests/ui/invalid_pymodule_glob.stderr b/tests/ui/invalid_pymodule_glob.stderr index b2bbc140354..7a1db45a211 100644 --- a/tests/ui/invalid_pymodule_glob.stderr +++ b/tests/ui/invalid_pymodule_glob.stderr @@ -5,4 +5,3 @@ error: #[pymodule] cannot import glob statements | ^ error: aborting due to 1 previous error - diff --git a/tests/ui/invalid_pymodule_trait.stderr b/tests/ui/invalid_pymodule_trait.stderr index 36713b488ad..f1204f18d1b 100644 --- a/tests/ui/invalid_pymodule_trait.stderr +++ b/tests/ui/invalid_pymodule_trait.stderr @@ -11,4 +11,3 @@ error: cannot find attribute `pymodule_export` in this scope | ^^^^^^^^^^^^^^^ error: aborting due to 2 previous errors - diff --git a/tests/ui/invalid_pymodule_two_pymodule_init.stderr b/tests/ui/invalid_pymodule_two_pymodule_init.stderr index 30eef8bd2c4..8de162f8a06 100644 --- a/tests/ui/invalid_pymodule_two_pymodule_init.stderr +++ b/tests/ui/invalid_pymodule_two_pymodule_init.stderr @@ -5,4 +5,3 @@ error: only one `#[pymodule_init]` may be specified | ^^ error: aborting due to 1 previous error - diff --git a/tests/ui/invalid_result_conversion.stderr b/tests/ui/invalid_result_conversion.stderr index 5efbe8322de..17361ce0995 100644 --- a/tests/ui/invalid_result_conversion.stderr +++ b/tests/ui/invalid_result_conversion.stderr @@ -11,7 +11,9 @@ error[E0277]: the trait bound `PyErr: From` is not satisfied `PyErr` implements `From>` `PyErr` implements `From>` `PyErr` implements `From` - and 16 others + `PyErr` implements `From` + `PyErr` implements `From>` + and 13 others = note: required for `MyError` to implement `Into` error: aborting due to 1 previous error diff --git a/tests/ui/missing_intopy.stderr b/tests/ui/missing_intopy.stderr index 02706a2659c..7a6b6d69afb 100644 --- a/tests/ui/missing_intopy.stderr +++ b/tests/ui/missing_intopy.stderr @@ -23,12 +23,12 @@ help: the trait `IntoPyObject<'_>` is not implemented for `Blah` &'a (T0, T1, T2, T3, T4) and 148 others note: required by a bound in `UnknownReturnType::::wrap` - --> src/impl_/wrap.rs:122:12 + --> src/impl_/wrap.rs:124:12 | -120 | pub fn wrap<'py>(&self, _: T) -> T +122 | pub fn wrap<'py>(&self, _: T) -> T | ---- required by a bound in this associated function -121 | where -122 | T: IntoPyObject<'py>, +123 | where +124 | T: IntoPyObject<'py>, | ^^^^^^^^^^^^^^^^^ required by this bound in `UnknownReturnType::::wrap` error[E0599]: no method named `map_err` found for struct `Blah` in the current scope diff --git a/tests/ui/pyclass_generic_enum.stderr b/tests/ui/pyclass_generic_enum.stderr index 9e9637ffa9d..9ae4d0ad285 100644 --- a/tests/ui/pyclass_generic_enum.stderr +++ b/tests/ui/pyclass_generic_enum.stderr @@ -11,4 +11,3 @@ error: enums do not support #[pyclass(generic)] | ^^^^^^^ error: aborting due to 2 previous errors - diff --git a/tests/ui/reject_generics.stderr b/tests/ui/reject_generics.stderr index 85d873a0f8f..57d8e20f6b7 100644 --- a/tests/ui/reject_generics.stderr +++ b/tests/ui/reject_generics.stderr @@ -11,4 +11,3 @@ error: #[pyclass] cannot have lifetime parameters. For an explanation, see https | ^^ error: aborting due to 2 previous errors - diff --git a/tests/ui/traverse.stderr b/tests/ui/traverse.stderr index 48bb4f84c83..701ce4bccb4 100644 --- a/tests/ui/traverse.stderr +++ b/tests/ui/traverse.stderr @@ -29,4 +29,3 @@ error: __traverse__ may not take `Python`. Usually, an implementation of `__trav | ^^^^^^^^^^ error: aborting due to 5 previous errors - diff --git a/tests/ui/wrong_aspyref_lifetimes.stderr b/tests/ui/wrong_aspyref_lifetimes.stderr index 71394972685..1a681292c7c 100644 --- a/tests/ui/wrong_aspyref_lifetimes.stderr +++ b/tests/ui/wrong_aspyref_lifetimes.stderr @@ -8,4 +8,3 @@ error: lifetime may not live long enough | has type `Python<'1>` error: aborting due to 1 previous error - From 7129160757f7e41bb57c99db33b611b4194dc228 Mon Sep 17 00:00:00 2001 From: David Hewitt Date: Fri, 27 Mar 2026 21:35:45 +0000 Subject: [PATCH 07/21] remove abi3-py37 reference --- tests/test_compile_error.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/test_compile_error.rs b/tests/test_compile_error.rs index f6750cda281..22784c9df00 100644 --- a/tests/test_compile_error.rs +++ b/tests/test_compile_error.rs @@ -17,8 +17,6 @@ fn test_compile_errors() { "pyo3/macros".to_string(), #[cfg(feature = "abi3")] "pyo3/abi3".to_string(), - #[cfg(feature = "abi3-py37")] - "pyo3/abi3-py37".to_string(), #[cfg(feature = "abi3-py38")] "pyo3/abi3-py38".to_string(), #[cfg(feature = "abi3-py39")] From 50a4e103a106ffa15ce805a46af2d9eed98dcd9c Mon Sep 17 00:00:00 2001 From: David Hewitt Date: Sat, 28 Mar 2026 18:21:12 +0000 Subject: [PATCH 08/21] apply suggestions from code review Co-authored-by: Icxolu <10486322+Icxolu@users.noreply.github.com> --- tests/test_compile_error.rs | 7 +++++++ tests/ui/ambiguous_associated_items.rs | 1 + tests/ui/ambiguous_associated_items.stderr | 15 --------------- tests/ui/invalid_base_class.stderr | 6 ++++-- tests/ui/invalid_property_args.stderr | 6 +++--- tests/ui/not_send.rs | 5 +++-- tests/ui/not_send.stderr | 16 ++++++++-------- tests/ui/not_send2.rs | 3 ++- tests/ui/not_send2.stderr | 20 ++++++++++---------- 9 files changed, 38 insertions(+), 41 deletions(-) delete mode 100644 tests/ui/ambiguous_associated_items.stderr diff --git a/tests/test_compile_error.rs b/tests/test_compile_error.rs index 22784c9df00..de83f6a7e1f 100644 --- a/tests/test_compile_error.rs +++ b/tests/test_compile_error.rs @@ -82,6 +82,13 @@ fn test_compile_errors() { // generic pyclasses only supported on 3.9+, doesn't fail gracefully on older versions #[cfg(not(Py_3_9))] "invalid_pyclass_generic.rs".into(), + // an extra "note" is emitted on abi3 + #[cfg(any(not(Py_LIMITED_API), not(Py_3_12)))] + "invalid_base_class.rs".into(), + #[cfg(all(Py_LIMITED_API, not(Py_3_10)))] + "invalid_pyfunction_argument.rs".into(), + #[cfg(all(Py_LIMITED_API, not(Py_3_10)))] + "invalid_pyclass_args.rs".into(), ]); match std::env::var("UI_TEST").as_deref() { diff --git a/tests/ui/ambiguous_associated_items.rs b/tests/ui/ambiguous_associated_items.rs index 3c9f4b0039f..bd905fab99f 100644 --- a/tests/ui/ambiguous_associated_items.rs +++ b/tests/ui/ambiguous_associated_items.rs @@ -1,4 +1,5 @@ //@check-pass +#![allow(dead_code)] use pyo3::prelude::*; #[pyclass(eq)] diff --git a/tests/ui/ambiguous_associated_items.stderr b/tests/ui/ambiguous_associated_items.stderr deleted file mode 100644 index a8b30ca7fb4..00000000000 --- a/tests/ui/ambiguous_associated_items.stderr +++ /dev/null @@ -1,15 +0,0 @@ -warning: enum `DeriveItems` is never used - --> tests/ui/ambiguous_associated_items.rs:20:6 - | -20 | enum DeriveItems { - | ^^^^^^^^^^^ - | - = note: `#[warn(dead_code)]` (part of `#[warn(unused)]`) on by default - -warning: enum `DeriveItemsFromPyObject` is never used - --> tests/ui/ambiguous_associated_items.rs:43:6 - | -43 | enum DeriveItemsFromPyObject { - | ^^^^^^^^^^^^^^^^^^^^^^^ - -warning: 2 warnings emitted diff --git a/tests/ui/invalid_base_class.stderr b/tests/ui/invalid_base_class.stderr index 5ee05a405a6..7f6a85b2d6e 100644 --- a/tests/ui/invalid_base_class.stderr +++ b/tests/ui/invalid_base_class.stderr @@ -6,6 +6,7 @@ error[E0277]: pyclass `PyBool` cannot be subclassed | = help: the trait `PyClassBaseType` is not implemented for `PyBool` = note: `PyBool` must have `#[pyclass(subclass)]` to be eligible for subclassing + = note: with the `abi3` feature enabled, PyO3 does not support subclassing native types = help: the following other types implement trait `PyClassBaseType`: PyAny PyArithmeticError @@ -15,7 +16,7 @@ error[E0277]: pyclass `PyBool` cannot be subclassed PyBaseExceptionGroup PyBlockingIOError PyBrokenPipeError - and 69 others + and 63 others = note: this error originates in the attribute macro `pyclass` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: pyclass `PyBool` cannot be subclassed @@ -26,6 +27,7 @@ error[E0277]: pyclass `PyBool` cannot be subclassed | = help: the trait `PyClassBaseType` is not implemented for `PyBool` = note: `PyBool` must have `#[pyclass(subclass)]` to be eligible for subclassing + = note: with the `abi3` feature enabled, PyO3 does not support subclassing native types = help: the following other types implement trait `PyClassBaseType`: PyAny PyArithmeticError @@ -35,7 +37,7 @@ error[E0277]: pyclass `PyBool` cannot be subclassed PyBaseExceptionGroup PyBlockingIOError PyBrokenPipeError - and 69 others + and 63 others note: required by a bound in `PyClassImpl::BaseType` --> src/impl_/pyclass.rs:184:33 | diff --git a/tests/ui/invalid_property_args.stderr b/tests/ui/invalid_property_args.stderr index e2c719babd5..f819a76271e 100644 --- a/tests/ui/invalid_property_args.stderr +++ b/tests/ui/invalid_property_args.stderr @@ -66,12 +66,12 @@ error[E0277]: `PhantomData` cannot be converted to a Python object and 151 others = note: required for `PhantomData` to implement `for<'py> PyO3GetField<'py>` note: required by a bound in `PyClassGetterGenerator::::generate` - --> src/impl_/pyclass.rs:1328:26 + --> src/impl_/pyclass.rs:1297:26 | -1324 | pub const fn generate(&self, name: &'static CStr, doc: Option<&'static CStr>) -> PyMethodDefType +1293 | pub const fn generate(&self, name: &'static CStr, doc: Option<&'static CStr>) -> PyMethodDefType | -------- required by a bound in this associated function ... -1328 | for<'py> FieldT: PyO3GetField<'py>, +1297 | for<'py> FieldT: PyO3GetField<'py>, | ^^^^^^^^^^^^^^^^^ required by this bound in `PyClassGetterGenerator::::generate` error: aborting due to 9 previous errors diff --git a/tests/ui/not_send.rs b/tests/ui/not_send.rs index d93d605327d..6ff785d4635 100644 --- a/tests/ui/not_send.rs +++ b/tests/ui/not_send.rs @@ -1,8 +1,9 @@ +//@normalize-stderr-test: ".*/src/rust/(.*)" -> "../src/$1" use pyo3::prelude::*; fn test_not_send_detach(py: Python<'_>) { - py.detach(|| { drop(py); }); -//~^ ERROR: `*mut pyo3::Python<'static>` cannot be shared between threads safely + py.detach(|| drop(py)); + //~^ ERROR: `*mut pyo3::Python<'static>` cannot be shared between threads safely } fn main() { diff --git a/tests/ui/not_send.stderr b/tests/ui/not_send.stderr index 837f0a6963f..81ae40120a1 100644 --- a/tests/ui/not_send.stderr +++ b/tests/ui/not_send.stderr @@ -1,14 +1,14 @@ error[E0277]: `*mut pyo3::Python<'static>` cannot be shared between threads safely - --> tests/ui/not_send.rs:4:15 + --> tests/ui/not_send.rs:5:15 | - 4 | py.detach(|| { drop(py); }); - | ------ ^^^^^^^^^^^^^^^^ `*mut pyo3::Python<'static>` cannot be shared between threads safely + 5 | py.detach(|| drop(py)); + | ------ ^^^^^^^^^^^ `*mut pyo3::Python<'static>` cannot be shared between threads safely | | | required by a bound introduced by this call | = help: within `pyo3::Python<'_>`, the trait `Sync` is not implemented for `*mut pyo3::Python<'static>` note: required because it appears within the type `PhantomData<*mut pyo3::Python<'static>>` - --> /Users/david/.rustup/toolchains/stable-aarch64-apple-darwin/lib/rustlib/src/rust/library/core/src/marker.rs:819:12 +../src/library/core/src/marker.rs:819:12 | 819 | pub struct PhantomData; | ^^^^^^^^^^^ @@ -18,7 +18,7 @@ note: required because it appears within the type `pyo3::marker::NotSend` 357 | struct NotSend(PhantomData<*mut Python<'static>>); | ^^^^^^^ note: required because it appears within the type `PhantomData` - --> /Users/david/.rustup/toolchains/stable-aarch64-apple-darwin/lib/rustlib/src/rust/library/core/src/marker.rs:819:12 +../src/library/core/src/marker.rs:819:12 | 819 | pub struct PhantomData; | ^^^^^^^^^^^ @@ -29,11 +29,11 @@ note: required because it appears within the type `pyo3::Python<'_>` | ^^^^^^ = note: required for `&pyo3::Python<'_>` to implement `Send` note: required because it's used within this closure - --> tests/ui/not_send.rs:4:15 + --> tests/ui/not_send.rs:5:15 | - 4 | py.detach(|| { drop(py); }); + 5 | py.detach(|| drop(py)); | ^^ - = note: required for `{closure@tests/ui/not_send.rs:4:15: 4:17}` to implement `Ungil` + = note: required for `{closure@tests/ui/not_send.rs:5:15: 5:17}` to implement `Ungil` note: required by a bound in `pyo3::Python::<'py>::detach` --> src/marker.rs:560:12 | diff --git a/tests/ui/not_send2.rs b/tests/ui/not_send2.rs index b1d3262ead5..58382a7c207 100644 --- a/tests/ui/not_send2.rs +++ b/tests/ui/not_send2.rs @@ -1,3 +1,4 @@ +//@normalize-stderr-test: ".*/src/rust/(.*)" -> "../src/$1" use pyo3::prelude::*; use pyo3::types::PyString; @@ -6,7 +7,7 @@ fn main() { let string = PyString::new(py, "foo"); py.detach(|| { -//~^ ERROR: `*mut pyo3::Python<'static>` cannot be shared between threads safely + //~^ ERROR: `*mut pyo3::Python<'static>` cannot be shared between threads safely println!("{:?}", string); }); }); diff --git a/tests/ui/not_send2.stderr b/tests/ui/not_send2.stderr index 6921905be46..c69132e46bc 100644 --- a/tests/ui/not_send2.stderr +++ b/tests/ui/not_send2.stderr @@ -1,18 +1,18 @@ error[E0277]: `*mut pyo3::Python<'static>` cannot be shared between threads safely - --> tests/ui/not_send2.rs:8:19 + --> tests/ui/not_send2.rs:9:19 | - 8 | py.detach(|| { + 9 | py.detach(|| { | ____________------_^ | | | | | required by a bound introduced by this call - 9 | | - 10 | | println!("{:?}", string); - 11 | | }); + 10 | | + 11 | | println!("{:?}", string); + 12 | | }); | |_________^ `*mut pyo3::Python<'static>` cannot be shared between threads safely | = help: within `pyo3::Bound<'_, PyString>`, the trait `Sync` is not implemented for `*mut pyo3::Python<'static>` note: required because it appears within the type `PhantomData<*mut pyo3::Python<'static>>` - --> /Users/david/.rustup/toolchains/stable-aarch64-apple-darwin/lib/rustlib/src/rust/library/core/src/marker.rs:819:12 +../src/library/core/src/marker.rs:819:12 | 819 | pub struct PhantomData; | ^^^^^^^^^^^ @@ -22,7 +22,7 @@ note: required because it appears within the type `pyo3::marker::NotSend` 357 | struct NotSend(PhantomData<*mut Python<'static>>); | ^^^^^^^ note: required because it appears within the type `PhantomData` - --> /Users/david/.rustup/toolchains/stable-aarch64-apple-darwin/lib/rustlib/src/rust/library/core/src/marker.rs:819:12 +../src/library/core/src/marker.rs:819:12 | 819 | pub struct PhantomData; | ^^^^^^^^^^^ @@ -38,11 +38,11 @@ note: required because it appears within the type `pyo3::Bound<'_, PyString>` | ^^^^^ = note: required for `&pyo3::Bound<'_, PyString>` to implement `Send` note: required because it's used within this closure - --> tests/ui/not_send2.rs:8:19 + --> tests/ui/not_send2.rs:9:19 | - 8 | py.detach(|| { + 9 | py.detach(|| { | ^^ - = note: required for `{closure@tests/ui/not_send2.rs:8:19: 8:21}` to implement `Ungil` + = note: required for `{closure@tests/ui/not_send2.rs:9:19: 9:21}` to implement `Ungil` note: required by a bound in `pyo3::Python::<'py>::detach` --> src/marker.rs:560:12 | From 0818da7e0e1834e1a9e02859d2d790e3c3ec5289 Mon Sep 17 00:00:00 2001 From: David Hewitt Date: Sat, 28 Mar 2026 18:35:48 +0000 Subject: [PATCH 09/21] skip ui testing on careful / valgrind --- .github/workflows/ci.yml | 4 ++-- tests/test_compile_error.rs | 33 +++++++++++++++++++++------------ 2 files changed, 23 insertions(+), 14 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8413563100e..117cb9273a4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -378,7 +378,7 @@ jobs: env: CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_RUNNER: valgrind --leak-check=no --error-exitcode=1 RUST_BACKTRACE: 1 - UI_TEST: ignore + UI_TEST: skip careful: if: ${{ contains(github.event.pull_request.labels.*.name, 'CI-build-full') || github.event_name != 'pull_request' }} @@ -400,7 +400,7 @@ jobs: - run: nox -s test-rust -- careful skip-full env: RUST_BACKTRACE: 1 - UI_TEST: ignore + UI_TEST: skip docsrs: if: ${{ contains(github.event.pull_request.labels.*.name, 'CI-build-full') || github.event_name != 'pull_request' }} diff --git a/tests/test_compile_error.rs b/tests/test_compile_error.rs index de83f6a7e1f..812a3e3a9ad 100644 --- a/tests/test_compile_error.rs +++ b/tests/test_compile_error.rs @@ -10,6 +10,27 @@ fn test_compile_errors() { let mut config = Config::rustc("tests/ui"); + // Various configurations of of + match std::env::var("UI_TEST").as_deref() { + // Default is to run the test as normal, erroring if output is not as expected. + Err(VarError::NotPresent) => { + config.output_conflict_handling = ui_test::error_on_output_conflict + } + // Used to update the output files to match expected output + Ok("bless") => config.output_conflict_handling = ui_test::bless_output_files, + // This mode is useful for exercising coverage of the proc macros, e.g. on the + // nightly compiler and MSRV, where the output may differ from expected. + Ok("ignore") => config.output_conflict_handling = ui_test::ignore_output_conflict, + // Completely running the tests, e.g. under `cargo careful` there is some issue which + // doesn't seem worth understanding (we don't gain anything from extra assertions in + // the proc-macro code, which is all quite pedestrian). + Ok("skip") => return, + Err(e) => panic!("error reading UI_TEST environment variable: {e}"), + Ok(unknown) => panic!("invalid UI_TEST value: {unknown}"), + } + + config.bless_command = Some("UI_TEST=bless cargo test --test test_compile_error".into()); + // There doesn't seem to be a good way to forward all these features automatically, // so have to just list the relevant ones here. let deps_features = [ @@ -91,18 +112,6 @@ fn test_compile_errors() { "invalid_pyclass_args.rs".into(), ]); - match std::env::var("UI_TEST").as_deref() { - Ok("bless") => config.output_conflict_handling = ui_test::bless_output_files, - Ok("ignore") => config.output_conflict_handling = ui_test::ignore_output_conflict, - Err(VarError::NotPresent) => { - config.output_conflict_handling = ui_test::error_on_output_conflict - } - Err(e) => panic!("error reading UI_TEST environment variable: {e}"), - Ok(unknown) => panic!("invalid UI_TEST value: {unknown}"), - } - - config.bless_command = Some("UI_TEST=bless cargo test --test test_compile_error".into()); - // Normalize multiple trailing newlines to a single newline config .comment_defaults From f26cb22f236b66cc58a3949d0bb34b73b7f6d64b Mon Sep 17 00:00:00 2001 From: David Hewitt Date: Sat, 28 Mar 2026 19:24:43 +0000 Subject: [PATCH 10/21] fixup MSRV handling --- tests/test_compile_error.rs | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/tests/test_compile_error.rs b/tests/test_compile_error.rs index 812a3e3a9ad..347062789e9 100644 --- a/tests/test_compile_error.rs +++ b/tests/test_compile_error.rs @@ -6,7 +6,7 @@ fn test_compile_errors() { use std::{env::VarError, path::PathBuf}; use regex::bytes::Regex; - use ui_test::{run_tests, Config}; + use ui_test::{run_tests, Config, OptWithLine}; let mut config = Config::rustc("tests/ui"); @@ -20,7 +20,24 @@ fn test_compile_errors() { Ok("bless") => config.output_conflict_handling = ui_test::bless_output_files, // This mode is useful for exercising coverage of the proc macros, e.g. on the // nightly compiler and MSRV, where the output may differ from expected. - Ok("ignore") => config.output_conflict_handling = ui_test::ignore_output_conflict, + Ok("ignore") => { + use ui_test::spanned::Span; + + // Ignore mismatches on stderr / stdout files + config.output_conflict_handling = ui_test::ignore_output_conflict; + + // This combination of settings helps ui test ignore the annotations on + // the test files themselves: + + // The annotations by default start with //~, changing this to a pattern + // which never appears in the files effectively means "ignore all annotations" + config.comment_start = "/*DISABLED*/"; + // Don't error if there are no annotations + config.comment_defaults.base().require_annotations = + OptWithLine::new(false, Span::default()); + // Don't error if the test "passes" because there were no annotations + config.comment_defaults.base().exit_status = OptWithLine::default(); + } // Completely running the tests, e.g. under `cargo careful` there is some issue which // doesn't seem worth understanding (we don't gain anything from extra assertions in // the proc-macro code, which is all quite pedestrian). From b4d0cff3ed8989593986300fcd226da419eabd27 Mon Sep 17 00:00:00 2001 From: David Hewitt Date: Sat, 28 Mar 2026 19:25:16 +0000 Subject: [PATCH 11/21] tidy import --- tests/test_compile_error.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tests/test_compile_error.rs b/tests/test_compile_error.rs index 347062789e9..bb853ffceac 100644 --- a/tests/test_compile_error.rs +++ b/tests/test_compile_error.rs @@ -6,7 +6,7 @@ fn test_compile_errors() { use std::{env::VarError, path::PathBuf}; use regex::bytes::Regex; - use ui_test::{run_tests, Config, OptWithLine}; + use ui_test::{run_tests, spanned::Span, Config, OptWithLine}; let mut config = Config::rustc("tests/ui"); @@ -21,8 +21,6 @@ fn test_compile_errors() { // This mode is useful for exercising coverage of the proc macros, e.g. on the // nightly compiler and MSRV, where the output may differ from expected. Ok("ignore") => { - use ui_test::spanned::Span; - // Ignore mismatches on stderr / stdout files config.output_conflict_handling = ui_test::ignore_output_conflict; From d645b4772511b617631995f27c7172682fb735cb Mon Sep 17 00:00:00 2001 From: David Hewitt Date: Sun, 29 Mar 2026 13:54:08 +0100 Subject: [PATCH 12/21] `empty.rs` not a real UI test --- tests/test_compile_error.rs | 2 ++ tests/ui/empty.rs | 1 - 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/test_compile_error.rs b/tests/test_compile_error.rs index bb853ffceac..710a2227cf3 100644 --- a/tests/test_compile_error.rs +++ b/tests/test_compile_error.rs @@ -97,6 +97,8 @@ fn test_compile_errors() { config.skip_files.extend([ // not a test file, used to configure dependencies for the tests "base/src/lib.rs".into(), + // similarly, just a component of `invalid_pymodule_in_root.rs` + "empty.rs".into(), // abi3-only tests only need to check when the feature is unsupported #[cfg(any(not(Py_LIMITED_API), Py_3_9))] "abi3_dict".into(), diff --git a/tests/ui/empty.rs b/tests/ui/empty.rs index 4fc5b5a031a..be89c636426 100644 --- a/tests/ui/empty.rs +++ b/tests/ui/empty.rs @@ -1,2 +1 @@ -//@check-pass // see invalid_pymodule_in_root.rs From 3b891bdb9428e38dfe55f4a823f393e510eb7247 Mon Sep 17 00:00:00 2001 From: David Hewitt Date: Sun, 29 Mar 2026 14:49:18 +0100 Subject: [PATCH 13/21] add `.gitattributes` --- .gitattributes | 1 + 1 file changed, 1 insertion(+) create mode 100644 .gitattributes diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 00000000000..6313b56c578 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +* text=auto eol=lf From d5df48dcb503d62b340b5ff3d01c22140f49d936 Mon Sep 17 00:00:00 2001 From: David Hewitt Date: Sun, 29 Mar 2026 14:49:47 +0100 Subject: [PATCH 14/21] clean up ui test harness --- Cargo.toml | 5 +++++ tests/test_compile_error.rs | 13 ++++++------- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index edecc44c74e..c5602ba2ea7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -226,3 +226,8 @@ bare_urls = "warn" [lints] workspace = true + +[[test]] +name = "test_compile_error" +path = "tests/test_compile_error.rs" +harness = false diff --git a/tests/test_compile_error.rs b/tests/test_compile_error.rs index 710a2227cf3..5404b57b93c 100644 --- a/tests/test_compile_error.rs +++ b/tests/test_compile_error.rs @@ -1,8 +1,7 @@ #![cfg(feature = "macros")] #[cfg(not(target_arch = "wasm32"))] // Not possible to invoke compiler from wasm -#[test] -fn test_compile_errors() { +fn main() { use std::{env::VarError, path::PathBuf}; use regex::bytes::Regex; @@ -136,11 +135,11 @@ fn test_compile_errors() { .normalize_stderr .push((Regex::new("\n\n$").unwrap().into(), vec![b'\n'])); - #[cfg(not(target_arch = "wasm32"))] // doesn't work on wasm - { - let abort_check = config.abort_check.clone(); - ctrlc::set_handler(move || abort_check.abort()).unwrap(); - } + let abort_check = config.abort_check.clone(); + ctrlc::set_handler(move || abort_check.abort()).unwrap(); run_tests(config).unwrap(); } + +#[cfg(target_arch = "wasm32")] +fn main() {} From 6e92432c3d12ffc82a85d2c96c5a2ec7d5814c06 Mon Sep 17 00:00:00 2001 From: David Hewitt Date: Sun, 29 Mar 2026 14:59:47 +0100 Subject: [PATCH 15/21] fix invalid_cancel_handle test --- tests/test_compile_error.rs | 6 ++ tests/ui/invalid_cancel_handle.rs | 12 +-- tests/ui/invalid_cancel_handle.stderr | 142 +++++++++++++++++++------- 3 files changed, 116 insertions(+), 44 deletions(-) diff --git a/tests/test_compile_error.rs b/tests/test_compile_error.rs index 5404b57b93c..35b21680545 100644 --- a/tests/test_compile_error.rs +++ b/tests/test_compile_error.rs @@ -66,6 +66,10 @@ fn main() { "pyo3/abi3-py313".to_string(), #[cfg(feature = "abi3-py314")] "pyo3/abi3-py314".to_string(), + #[cfg(feature = "experimental-async")] + "pyo3/experimental-async".to_string(), + #[cfg(feature = "full")] + "pyo3/full".to_string(), ]; let mut deps_cargo = ui_test::CommandBuilder::cargo(); @@ -126,6 +130,8 @@ fn main() { "invalid_pyfunction_argument.rs".into(), #[cfg(all(Py_LIMITED_API, not(Py_3_10)))] "invalid_pyclass_args.rs".into(), + #[cfg(not(feature = "experimental-async"))] + "invalid_cancel_handle.rs".into(), ]); // Normalize multiple trailing newlines to a single newline diff --git a/tests/ui/invalid_cancel_handle.rs b/tests/ui/invalid_cancel_handle.rs index 6287eccdad4..e9188f775b4 100644 --- a/tests/ui/invalid_cancel_handle.rs +++ b/tests/ui/invalid_cancel_handle.rs @@ -6,9 +6,9 @@ async fn cancel_handle_repeated(#[pyo3(cancel_handle, cancel_handle)] _param: St #[pyfunction] async fn cancel_handle_repeated2( -//~^ ERROR: async functions are only supported with the `experimental-async` feature #[pyo3(cancel_handle)] _param: String, #[pyo3(cancel_handle)] _param2: String, + //~^ ERROR: `cancel_handle` may only be specified once ) { } @@ -17,19 +17,19 @@ fn cancel_handle_synchronous(#[pyo3(cancel_handle)] _param: String) {} //~^ ERROR: `cancel_handle` attribute can only be used with `async fn` #[pyfunction] +//~^ ERROR: mismatched types async fn cancel_handle_wrong_type(#[pyo3(cancel_handle)] _param: String) {} -//~^ ERROR: async functions are only supported with the `experimental-async` feature #[pyfunction] async fn missing_cancel_handle_attribute(_param: pyo3::coroutine::CancelHandle) {} -//~^ ERROR: failed to resolve: could not find `coroutine` in `pyo3` -//~| ERROR: async functions are only supported with the `experimental-async` feature +//~^ ERROR: `CancelHandle` cannot be used as a Python function argument +//~| ERROR: `CancelHandle` cannot be used as a Python function argument +//~| ERROR: `CancelHandle` cannot be used as a Python function argument #[pyfunction] async fn cancel_handle_and_from_py_with( #[pyo3(cancel_handle, from_py_with = cancel_handle)] _param: pyo3::coroutine::CancelHandle, -//~^ ERROR: failed to resolve: could not find `coroutine` in `pyo3` -//~| ERROR: `from_py_with` and `cancel_handle` cannot be specified together + //~^ ERROR: `from_py_with` and `cancel_handle` cannot be specified together ) { } diff --git a/tests/ui/invalid_cancel_handle.stderr b/tests/ui/invalid_cancel_handle.stderr index 55dd934c1bb..895752fcad2 100644 --- a/tests/ui/invalid_cancel_handle.stderr +++ b/tests/ui/invalid_cancel_handle.stderr @@ -4,11 +4,11 @@ error: `cancel_handle` may only be specified once per argument 4 | async fn cancel_handle_repeated(#[pyo3(cancel_handle, cancel_handle)] _param: String) {} | ^^^^^^^^^^^^^ -error: async functions are only supported with the `experimental-async` feature - --> tests/ui/invalid_cancel_handle.rs:8:1 - | -8 | async fn cancel_handle_repeated2( - | ^^^^^ +error: `cancel_handle` may only be specified once + --> tests/ui/invalid_cancel_handle.rs:10:28 + | +10 | #[pyo3(cancel_handle)] _param2: String, + | ^^^^^^^ error: `cancel_handle` attribute can only be used with `async fn` --> tests/ui/invalid_cancel_handle.rs:16:53 @@ -16,52 +16,118 @@ error: `cancel_handle` attribute can only be used with `async fn` 16 | fn cancel_handle_synchronous(#[pyo3(cancel_handle)] _param: String) {} | ^^^^^^ -error: async functions are only supported with the `experimental-async` feature - --> tests/ui/invalid_cancel_handle.rs:20:1 +error: `from_py_with` and `cancel_handle` cannot be specified together + --> tests/ui/invalid_cancel_handle.rs:31:12 | -20 | async fn cancel_handle_wrong_type(#[pyo3(cancel_handle)] _param: String) {} - | ^^^^^ +31 | #[pyo3(cancel_handle, from_py_with = cancel_handle)] _param: pyo3::coroutine::CancelHandle, + | ^^^^^^^^^^^^^ -error: async functions are only supported with the `experimental-async` feature - --> tests/ui/invalid_cancel_handle.rs:24:1 +error[E0308]: mismatched types + --> tests/ui/invalid_cancel_handle.rs:19:1 | -24 | async fn missing_cancel_handle_attribute(_param: pyo3::coroutine::CancelHandle) {} - | ^^^^^ - -error: `from_py_with` and `cancel_handle` cannot be specified together - --> tests/ui/invalid_cancel_handle.rs:30:12 +19 | #[pyfunction] + | ^^^^^^^^^^^^^ + | | + | expected `String`, found `CancelHandle` + | arguments to this function are incorrect | -30 | #[pyo3(cancel_handle, from_py_with = cancel_handle)] _param: pyo3::coroutine::CancelHandle, - | ^^^^^^^^^^^^^ +note: function defined here + --> tests/ui/invalid_cancel_handle.rs:21:10 + | +21 | async fn cancel_handle_wrong_type(#[pyo3(cancel_handle)] _param: String) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^ -------------- + = note: this error originates in the attribute macro `pyfunction` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0433]: failed to resolve: could not find `coroutine` in `pyo3` - --> tests/ui/invalid_cancel_handle.rs:24:56 +error[E0277]: `CancelHandle` cannot be used as a Python function argument + --> tests/ui/invalid_cancel_handle.rs:24:50 | 24 | async fn missing_cancel_handle_attribute(_param: pyo3::coroutine::CancelHandle) {} - | ^^^^^^^^^ could not find `coroutine` in `pyo3` + | ^^^^ the trait `PyClass` is not implemented for `CancelHandle` + | + = note: implement `FromPyObject` to enable using `CancelHandle` as a function argument + = note: `Python<'py>` is also a valid argument type to pass the Python token into `#[pyfunction]`s and `#[pymethods]` +help: the trait `PyClass` is implemented for `pyo3::coroutine::Coroutine` + --> src/coroutine.rs:29:1 | -note: found an item that was configured out - --> src/lib.rs:418:9 + 29 | #[pyclass(crate = "crate")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: required for `CancelHandle` to implement `FromPyObject<'_, '_>` + = note: required for `CancelHandle` to implement `PyFunctionArgument<'_, '_, '_, true>` +note: required by a bound in `extract_argument` + --> src/impl_/extract_argument.rs:226:8 | -417 | #[cfg(feature = "experimental-async")] - | ------------------------------ the item is gated behind the `experimental-async` feature -418 | pub mod coroutine; - | ^^^^^^^^^ +220 | pub fn extract_argument<'a, 'holder, 'py, T, const IMPLEMENTS_FROMPYOBJECT: bool>( + | ---------------- required by a bound in this function +... +226 | T: PyFunctionArgument<'a, 'holder, 'py, IMPLEMENTS_FROMPYOBJECT>, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `extract_argument` + = note: this error originates in the attribute macro `pyclass` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0433]: failed to resolve: could not find `coroutine` in `pyo3` - --> tests/ui/invalid_cancel_handle.rs:30:72 +error[E0277]: `CancelHandle` cannot be used as a Python function argument + --> tests/ui/invalid_cancel_handle.rs:24:50 + | + 24 | async fn missing_cancel_handle_attribute(_param: pyo3::coroutine::CancelHandle) {} + | ^^^^ the trait `Clone` is not implemented for `CancelHandle` + | + = note: implement `FromPyObject` to enable using `CancelHandle` as a function argument + = note: `Python<'py>` is also a valid argument type to pass the Python token into `#[pyfunction]`s and `#[pymethods]` +help: the following other types implement trait `PyFunctionArgument<'a, 'holder, 'py, IMPLEMENTS_FROMPYOBJECT>` + --> src/impl_/extract_argument.rs:92:1 + | + 92 | / impl<'a, 'holder, 'py, T: 'a + 'py> PyFunctionArgument<'a, 'holder, 'py, false> + 93 | | for &'holder Bound<'py, T> + 94 | | where + 95 | | T: PyTypeCheck, + | |___________________^ `&'holder pyo3::Bound<'py, T>` implements `PyFunctionArgument<'a, 'holder, 'py, false>` +... +113 | / impl<'a, 'holder, 'py, T> PyFunctionArgument<'a, 'holder, 'py, false> for Option +114 | | where +115 | | T: PyFunctionArgument<'a, 'holder, 'py, false>, + | |___________________________________________________^ `Option` implements `PyFunctionArgument<'a, 'holder, 'py, false>` +... +175 | impl<'a, 'holder, T: PyClass> PyFunctionArgument<'a, 'holder, '_, false> for &'holder T { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `&'holder T` implements `PyFunctionArgument<'a, 'holder, '_, false>` +... +188 | / impl<'a, 'holder, T: PyClass> PyFunctionArgument<'a, 'holder, '_, false> +189 | | for &'holder mut T + | |______________________^ `&'holder mut T` implements `PyFunctionArgument<'a, 'holder, '_, false>` + = note: required for `CancelHandle` to implement `FromPyObject<'_, '_>` + = note: required for `CancelHandle` to implement `PyFunctionArgument<'_, '_, '_, true>` +note: required by a bound in `extract_argument` + --> src/impl_/extract_argument.rs:226:8 + | +220 | pub fn extract_argument<'a, 'holder, 'py, T, const IMPLEMENTS_FROMPYOBJECT: bool>( + | ---------------- required by a bound in this function +... +226 | T: PyFunctionArgument<'a, 'holder, 'py, IMPLEMENTS_FROMPYOBJECT>, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `extract_argument` + +error[E0277]: `CancelHandle` cannot be used as a Python function argument + --> tests/ui/invalid_cancel_handle.rs:24:50 + | + 24 | async fn missing_cancel_handle_attribute(_param: pyo3::coroutine::CancelHandle) {} + | ^^^^ the trait `ExtractPyClassWithClone` is not implemented for `CancelHandle` | - 30 | #[pyo3(cancel_handle, from_py_with = cancel_handle)] _param: pyo3::coroutine::CancelHandle, - | ^^^^^^^^^ could not find `coroutine` in `pyo3` + = note: implement `FromPyObject` to enable using `CancelHandle` as a function argument + = note: `Python<'py>` is also a valid argument type to pass the Python token into `#[pyfunction]`s and `#[pymethods]` +help: the trait `ExtractPyClassWithClone` is implemented for `pyo3::coroutine::Coroutine` + --> src/coroutine.rs:29:1 | -note: found an item that was configured out - --> src/lib.rs:418:9 + 29 | #[pyclass(crate = "crate")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: required for `CancelHandle` to implement `FromPyObject<'_, '_>` + = note: required for `CancelHandle` to implement `PyFunctionArgument<'_, '_, '_, true>` +note: required by a bound in `extract_argument` + --> src/impl_/extract_argument.rs:226:8 | -417 | #[cfg(feature = "experimental-async")] - | ------------------------------ the item is gated behind the `experimental-async` feature -418 | pub mod coroutine; - | ^^^^^^^^^ +220 | pub fn extract_argument<'a, 'holder, 'py, T, const IMPLEMENTS_FROMPYOBJECT: bool>( + | ---------------- required by a bound in this function +... +226 | T: PyFunctionArgument<'a, 'holder, 'py, IMPLEMENTS_FROMPYOBJECT>, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `extract_argument` + = note: this error originates in the attribute macro `pyclass` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 8 previous errors -For more information about this error, try `rustc --explain E0433`. +Some errors have detailed explanations: E0277, E0308. +For more information about an error, try `rustc --explain E0277`. From eacdcc478a6d929abfe0989be788385df3a29382 Mon Sep 17 00:00:00 2001 From: David Hewitt Date: Sun, 29 Mar 2026 15:14:28 +0100 Subject: [PATCH 16/21] clean up a bunch of cases --- tests/test_compile_error.rs | 21 ++++++++++- tests/ui/duplicate_pymodule_submodule.rs | 6 +-- tests/ui/duplicate_pymodule_submodule.stderr | 2 +- tests/ui/invalid_cancel_handle.rs | 1 + tests/ui/invalid_cancel_handle.stderr | 39 +++++++++++++++++--- tests/ui/invalid_pyfunction_argument.rs | 8 ++-- tests/ui/invalid_pyfunctions.stderr | 1 + tests/ui/invalid_pymethod_receiver.stderr | 1 + tests/ui/invalid_result_conversion.stderr | 2 +- 9 files changed, 65 insertions(+), 16 deletions(-) diff --git a/tests/test_compile_error.rs b/tests/test_compile_error.rs index 35b21680545..c3732038bd2 100644 --- a/tests/test_compile_error.rs +++ b/tests/test_compile_error.rs @@ -66,8 +66,6 @@ fn main() { "pyo3/abi3-py313".to_string(), #[cfg(feature = "abi3-py314")] "pyo3/abi3-py314".to_string(), - #[cfg(feature = "experimental-async")] - "pyo3/experimental-async".to_string(), #[cfg(feature = "full")] "pyo3/full".to_string(), ]; @@ -130,10 +128,29 @@ fn main() { "invalid_pyfunction_argument.rs".into(), #[cfg(all(Py_LIMITED_API, not(Py_3_10)))] "invalid_pyclass_args.rs".into(), + // tests that async functions are rejected without the feature + #[cfg(feature = "experimental-async")] + "invalid_async.rs".into(), + // requires the async feature #[cfg(not(feature = "experimental-async"))] "invalid_cancel_handle.rs".into(), ]); + // differs on `experimental-inspect` feature + #[cfg(feature = "experimental-inspect")] + config.skip_files.extend([ + // some functionality requires the feature + "invalid_annotation.rs".into(), + "invalid_annotation_return.rs".into(), + // extra error messages appear due to additional macro processing + // would be nice to somehow make this not a problem + "duplicate_pymodule_submodule.rs".into(), + "missing_intopy.rs".into(), + "invalid_pyclass_args.rs".into(), + "invalid_property_args.rs".into(), + "invalid_pyfunction_argument.rs".into(), + ]); + // Normalize multiple trailing newlines to a single newline config .comment_defaults diff --git a/tests/ui/duplicate_pymodule_submodule.rs b/tests/ui/duplicate_pymodule_submodule.rs index eb910722f0f..c18b7d7724f 100644 --- a/tests/ui/duplicate_pymodule_submodule.rs +++ b/tests/ui/duplicate_pymodule_submodule.rs @@ -1,9 +1,9 @@ #[pyo3::pymodule] //~^ ERROR: cannot find value `_PYO3_DEF` in module `submod` mod mymodule { - #[pyo3::pymodule(submodule)] - mod submod {} -//~^ ERROR: `submodule` may only be specified once (it is implicitly always specified for nested modules) + #[pyo3::pymodule(submodule)] + mod submod {} + //~^ ERROR: `submodule` may only be specified once (it is implicitly always specified for nested modules) } fn main() {} diff --git a/tests/ui/duplicate_pymodule_submodule.stderr b/tests/ui/duplicate_pymodule_submodule.stderr index ba4a6cf92b8..8ea91edfb33 100644 --- a/tests/ui/duplicate_pymodule_submodule.stderr +++ b/tests/ui/duplicate_pymodule_submodule.stderr @@ -1,5 +1,5 @@ error: `submodule` may only be specified once (it is implicitly always specified for nested modules) - --> tests/ui/duplicate_pymodule_submodule.rs:5:2 + --> tests/ui/duplicate_pymodule_submodule.rs:5:5 | 5 | mod submod {} | ^^^ diff --git a/tests/ui/invalid_cancel_handle.rs b/tests/ui/invalid_cancel_handle.rs index e9188f775b4..c04cb3ea71f 100644 --- a/tests/ui/invalid_cancel_handle.rs +++ b/tests/ui/invalid_cancel_handle.rs @@ -25,6 +25,7 @@ async fn missing_cancel_handle_attribute(_param: pyo3::coroutine::CancelHandle) //~^ ERROR: `CancelHandle` cannot be used as a Python function argument //~| ERROR: `CancelHandle` cannot be used as a Python function argument //~| ERROR: `CancelHandle` cannot be used as a Python function argument +//~| ERROR: `CancelHandle` cannot be used as a Python function argument #[pyfunction] async fn cancel_handle_and_from_py_with( diff --git a/tests/ui/invalid_cancel_handle.stderr b/tests/ui/invalid_cancel_handle.stderr index 895752fcad2..1d864b02ca1 100644 --- a/tests/ui/invalid_cancel_handle.stderr +++ b/tests/ui/invalid_cancel_handle.stderr @@ -17,11 +17,40 @@ error: `cancel_handle` attribute can only be used with `async fn` | ^^^^^^ error: `from_py_with` and `cancel_handle` cannot be specified together - --> tests/ui/invalid_cancel_handle.rs:31:12 + --> tests/ui/invalid_cancel_handle.rs:32:12 | -31 | #[pyo3(cancel_handle, from_py_with = cancel_handle)] _param: pyo3::coroutine::CancelHandle, +32 | #[pyo3(cancel_handle, from_py_with = cancel_handle)] _param: pyo3::coroutine::CancelHandle, | ^^^^^^^^^^^^^ +error[E0277]: `CancelHandle` cannot be used as a Python function argument + --> tests/ui/invalid_cancel_handle.rs:24:50 + | + 24 | async fn missing_cancel_handle_attribute(_param: pyo3::coroutine::CancelHandle) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `PyFunctionArgument<'_, '_, '_, false>` is not implemented for `CancelHandle` + | + = note: implement `FromPyObject` to enable using `CancelHandle` as a function argument + = note: `Python<'py>` is also a valid argument type to pass the Python token into `#[pyfunction]`s and `#[pymethods]` +help: the following other types implement trait `PyFunctionArgument<'a, 'holder, 'py, IMPLEMENTS_FROMPYOBJECT>` + --> src/impl_/extract_argument.rs:92:1 + | + 92 | / impl<'a, 'holder, 'py, T: 'a + 'py> PyFunctionArgument<'a, 'holder, 'py, false> + 93 | | for &'holder Bound<'py, T> + 94 | | where + 95 | | T: PyTypeCheck, + | |___________________^ `&'holder pyo3::Bound<'py, T>` implements `PyFunctionArgument<'a, 'holder, 'py, false>` +... +113 | / impl<'a, 'holder, 'py, T> PyFunctionArgument<'a, 'holder, 'py, false> for Option +114 | | where +115 | | T: PyFunctionArgument<'a, 'holder, 'py, false>, + | |___________________________________________________^ `Option` implements `PyFunctionArgument<'a, 'holder, 'py, false>` +... +175 | impl<'a, 'holder, T: PyClass> PyFunctionArgument<'a, 'holder, '_, false> for &'holder T { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `&'holder T` implements `PyFunctionArgument<'a, 'holder, '_, false>` +... +188 | / impl<'a, 'holder, T: PyClass> PyFunctionArgument<'a, 'holder, '_, false> +189 | | for &'holder mut T + | |______________________^ `&'holder mut T` implements `PyFunctionArgument<'a, 'holder, '_, false>` + error[E0308]: mismatched types --> tests/ui/invalid_cancel_handle.rs:19:1 | @@ -42,11 +71,11 @@ error[E0277]: `CancelHandle` cannot be used as a Python function argument --> tests/ui/invalid_cancel_handle.rs:24:50 | 24 | async fn missing_cancel_handle_attribute(_param: pyo3::coroutine::CancelHandle) {} - | ^^^^ the trait `PyClass` is not implemented for `CancelHandle` + | ^^^^ the trait `pyo3::PyClass` is not implemented for `CancelHandle` | = note: implement `FromPyObject` to enable using `CancelHandle` as a function argument = note: `Python<'py>` is also a valid argument type to pass the Python token into `#[pyfunction]`s and `#[pymethods]` -help: the trait `PyClass` is implemented for `pyo3::coroutine::Coroutine` +help: the trait `pyo3::PyClass` is implemented for `pyo3::coroutine::Coroutine` --> src/coroutine.rs:29:1 | 29 | #[pyclass(crate = "crate")] @@ -127,7 +156,7 @@ note: required by a bound in `extract_argument` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `extract_argument` = note: this error originates in the attribute macro `pyclass` (in Nightly builds, run with -Z macro-backtrace for more info) -error: aborting due to 8 previous errors +error: aborting due to 9 previous errors Some errors have detailed explanations: E0277, E0308. For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/invalid_pyfunction_argument.rs b/tests/ui/invalid_pyfunction_argument.rs index 5b619e85aed..5f4d61deeb8 100644 --- a/tests/ui/invalid_pyfunction_argument.rs +++ b/tests/ui/invalid_pyfunction_argument.rs @@ -3,9 +3,9 @@ use std::sync::atomic::AtomicPtr; #[pyfunction] fn invalid_pyfunction_argument(arg: AtomicPtr<()>) { -//~^ ERROR: `AtomicPtr<()>` cannot be used as a Python function argument -//~| ERROR: `AtomicPtr<()>` cannot be used as a Python function argument -//~| ERROR: `AtomicPtr<()>` cannot be used as a Python function argument + //~^ ERROR: `AtomicPtr<()>` cannot be used as a Python function argument + //~| ERROR: `AtomicPtr<()>` cannot be used as a Python function argument + //~| ERROR: `AtomicPtr<()>` cannot be used as a Python function argument let _ = arg; } @@ -15,7 +15,7 @@ struct Foo; #[pyfunction] fn skip_from_py_object_without_custom_from_py_object(arg: Foo) { -//~^ ERROR: `Foo` cannot be used as a Python function argument + //~^ ERROR: `Foo` cannot be used as a Python function argument let _ = arg; } diff --git a/tests/ui/invalid_pyfunctions.stderr b/tests/ui/invalid_pyfunctions.stderr index 80a517aa8f5..7c37c66c244 100644 --- a/tests/ui/invalid_pyfunctions.stderr +++ b/tests/ui/invalid_pyfunctions.stderr @@ -53,6 +53,7 @@ error[E0277]: the trait bound `&str: From>` `String` implements `From>` `String` implements `From` + `String` implements `From` = note: required for `BoundRef<'_, '_, pyo3::types::PyModule>` to implement `Into<&str>` error: aborting due to 8 previous errors diff --git a/tests/ui/invalid_pymethod_receiver.stderr b/tests/ui/invalid_pymethod_receiver.stderr index 4e72fb16a06..b6b61019337 100644 --- a/tests/ui/invalid_pymethod_receiver.stderr +++ b/tests/ui/invalid_pymethod_receiver.stderr @@ -6,6 +6,7 @@ error[E0277]: the trait bound `i32: TryFrom>` is not s | = help: the following other types implement trait `From`: `i32` implements `From` + `i32` implements `From>` `i32` implements `From` `i32` implements `From` `i32` implements `From` diff --git a/tests/ui/invalid_result_conversion.stderr b/tests/ui/invalid_result_conversion.stderr index 17361ce0995..d854e2e709b 100644 --- a/tests/ui/invalid_result_conversion.stderr +++ b/tests/ui/invalid_result_conversion.stderr @@ -13,7 +13,7 @@ error[E0277]: the trait bound `PyErr: From` is not satisfied `PyErr` implements `From` `PyErr` implements `From` `PyErr` implements `From>` - and 13 others + and 16 others = note: required for `MyError` to implement `Into` error: aborting due to 1 previous error From ab88ab74ef18f8e858deb5ccb765d1cf814fbdb7 Mon Sep 17 00:00:00 2001 From: David Hewitt Date: Sun, 29 Mar 2026 15:23:27 +0100 Subject: [PATCH 17/21] fix cfg gate on compile error test entry --- tests/test_compile_error.rs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/tests/test_compile_error.rs b/tests/test_compile_error.rs index c3732038bd2..f10f9b261ea 100644 --- a/tests/test_compile_error.rs +++ b/tests/test_compile_error.rs @@ -1,6 +1,9 @@ -#![cfg(feature = "macros")] - -#[cfg(not(target_arch = "wasm32"))] // Not possible to invoke compiler from wasm +#[cfg(all( + // Requires "macros" feature to actually do any meaningful testing + feature = "macros", + // Not possible to invoke compiler from wasm + not(target_arch = "wasm32") +))] fn main() { use std::{env::VarError, path::PathBuf}; @@ -164,5 +167,5 @@ fn main() { run_tests(config).unwrap(); } -#[cfg(target_arch = "wasm32")] +#[cfg(any(not(feature = "macros"), target_arch = "wasm32"))] fn main() {} From 1eeea0a3e09537985fba5270788f0eb4ddd77c6a Mon Sep 17 00:00:00 2001 From: David Hewitt Date: Fri, 17 Apr 2026 08:12:02 +0100 Subject: [PATCH 18/21] temp format fixes --- pyo3-ffi/src/structmember.rs | 6 +++--- src/pyclass/create_type_object.rs | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pyo3-ffi/src/structmember.rs b/pyo3-ffi/src/structmember.rs index 2d9dd5a4a1f..4aa6c24db4f 100644 --- a/pyo3-ffi/src/structmember.rs +++ b/pyo3-ffi/src/structmember.rs @@ -2,6 +2,8 @@ use std::ffi::c_int; pub use crate::PyMemberDef; +#[allow(deprecated)] +pub use crate::_Py_T_OBJECT as T_OBJECT; pub use crate::Py_T_BOOL as T_BOOL; pub use crate::Py_T_BYTE as T_BYTE; pub use crate::Py_T_CHAR as T_CHAR; @@ -19,12 +21,10 @@ pub use crate::Py_T_UINT as T_UINT; pub use crate::Py_T_ULONG as T_ULONG; pub use crate::Py_T_ULONGLONG as T_ULONGLONG; pub use crate::Py_T_USHORT as T_USHORT; -#[allow(deprecated)] -pub use crate::_Py_T_OBJECT as T_OBJECT; -pub use crate::Py_T_PYSSIZET as T_PYSSIZET; #[allow(deprecated)] pub use crate::_Py_T_NONE as T_NONE; +pub use crate::Py_T_PYSSIZET as T_PYSSIZET; /* Flags */ pub use crate::Py_READONLY as READONLY; diff --git a/src/pyclass/create_type_object.rs b/src/pyclass/create_type_object.rs index 9c72a9b4d1a..063b615c8a4 100644 --- a/src/pyclass/create_type_object.rs +++ b/src/pyclass/create_type_object.rs @@ -11,7 +11,7 @@ use crate::{ assign_sequence_item_from_mapping, get_sequence_item_from_mapping, tp_dealloc, tp_dealloc_with_gc, PyClassImpl, PyClassItemsIter, PyObjectOffset, }, - pymethods::{Getter, PyGetterDef, PyMethodDefType, PySetterDef, Setter, _call_clear}, + pymethods::{_call_clear, Getter, PyGetterDef, PyMethodDefType, PySetterDef, Setter}, trampoline::trampoline, }, pycell::impl_::PyClassObjectLayout, From 139507bbb98177b51ddf0716fdaa8ea00f5798fa Mon Sep 17 00:00:00 2001 From: David Hewitt Date: Wed, 29 Apr 2026 20:40:43 +0100 Subject: [PATCH 19/21] additional normalizations --- tests/test_compile_error.rs | 97 ++++++++++- tests/ui/base/src/lib.rs | 2 +- tests/ui/forbid_unsafe.rs | 1 + tests/ui/forbid_unsafe.stderr | 15 -- tests/ui/invalid_cancel_handle.stderr | 132 +++++++-------- tests/ui/invalid_closure.stderr | 8 +- tests/ui/invalid_frozen_pyclass_borrow.stderr | 84 +++++----- tests/ui/invalid_intern_arg.stderr | 4 +- tests/ui/invalid_property_args.stderr | 12 +- tests/ui/invalid_pycallargs.stderr | 14 +- tests/ui/invalid_pyclass_args.stderr | 74 ++++---- tests/ui/invalid_pyclass_init.stderr | 12 +- tests/ui/invalid_pyfunction_argument.stderr | 158 +++++++++--------- tests/ui/invalid_pyfunctions.stderr | 1 - tests/ui/invalid_pymethod_enum.stderr | 40 ++--- tests/ui/missing_intopy.stderr | 14 +- tests/ui/not_send.stderr | 32 ++-- tests/ui/not_send2.stderr | 40 ++--- tests/ui/pyclass_send.stderr | 44 ++--- 19 files changed, 428 insertions(+), 356 deletions(-) delete mode 100644 tests/ui/forbid_unsafe.stderr diff --git a/tests/test_compile_error.rs b/tests/test_compile_error.rs index 858df15af05..85605c53040 100644 --- a/tests/test_compile_error.rs +++ b/tests/test_compile_error.rs @@ -12,14 +12,14 @@ fn main() { let mut config = Config::rustc("tests/ui"); - // Various configurations of of + // Various configurations of UI_TEST environment variable for different CI modes match std::env::var("UI_TEST").as_deref() { // Default is to run the test as normal, erroring if output is not as expected. Err(VarError::NotPresent) => { - config.output_conflict_handling = ui_test::error_on_output_conflict + config.output_conflict_handling = error_on_output_conflict_normalized } // Used to update the output files to match expected output - Ok("bless") => config.output_conflict_handling = ui_test::bless_output_files, + Ok("bless") => config.output_conflict_handling = bless_output_files_normalized, // This mode is useful for exercising coverage of the proc macros, e.g. on the // nightly compiler and MSRV, where the output may differ from expected. Ok("ignore") => { @@ -162,13 +162,13 @@ fn main() { // Some trait implementations which are only emitted with certain // features enabled ( - Regex::new(r"\n\s+`i32` implements `From>`") + Regex::new(r"\n[ \t]*`i32` implements `From>`") .unwrap() .into(), Vec::new(), ), ( - Regex::new(r"\n\s+`String` implements `From`") + Regex::new(r"\n[ \t]*`String` implements `From`") .unwrap() .into(), Vec::new(), @@ -181,5 +181,92 @@ fn main() { run_tests(config).unwrap(); } +/// Strips line:col information from src file references in error messages. +/// +/// e.g. the following block: +/// +/// ``` +/// --> src/impl_/extract_argument.rs:226:8 +/// | +/// 220 | pub fn extract_argument<'a, 'holder, 'py, T, const IMPLEMENTS_FROMPYOBJECT: bool>( +/// | ---------------- required by a bound in this function +/// ... +/// 226 | T: PyFunctionArgument<'a, 'holder, 'py, IMPLEMENTS_FROMPYOBJECT>, +/// | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `extract_argument` +/// = note: required for `CancelHandle` to implement `FromPyObject<'_, '_>` +/// = note: required for `CancelHandle` to implement `pyo3::impl_::extract_argument::PyFunctionArgument<'_, '_, '_, true>` +/// ``` +/// +/// becomes: +/// +/// ``` +/// --> src/impl_/extract_argument.rs +/// | +/// | pub fn extract_argument<'a, 'holder, 'py, T, const IMPLEMENTS_FROMPYOBJECT: bool>( +/// | ---------------- required by a bound in this function +/// ... +/// | T: PyFunctionArgument<'a, 'holder, 'py, IMPLEMENTS_FROMPYOBJECT>, +/// | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `extract_argument` +/// = note: required for `CancelHandle` to implement `FromPyObject<'_, '_>` +/// = note: required for `CancelHandle` to implement `pyo3::impl_::extract_argument::PyFunctionArgument<'_, '_, '_, true>` +/// ``` +/// +/// Regex replacement via `ui_test`'s `normalize_stderr` can't express the transformation +/// we need here, so we write a custom wrapper which modifies the output before passing +/// to `ui_test`'s normal output handling machinery. +#[cfg(all(feature = "macros", not(target_arch = "wasm32")))] +fn normalize_src_blocks(output: &[u8]) -> Vec { + use std::sync::LazyLock; + + use regex::bytes::{Captures, Regex}; + + // Matches the full block which we want to replace. + // + // The first line with the src path is captured, and then all following lines starting with either a line number and `|` or just `...` + // are captured as the "listing". + static SRC_BLOCK: LazyLock = LazyLock::new(|| { + Regex::new( + r"\n[ \t]*--> (src/\S+?):\d+:\d+((?:\n[ \t]*\d*[ \t]*[|=][^\n]*|\n[ \t]*\.\.\.)+)", + ) + .unwrap() + }); + + // Matches a gutter line in the listing (potentially with a line number) + static GUTTER: LazyLock = + LazyLock::new(|| Regex::new(r"\n[ \t]*\d*[ \t]*([|=])").unwrap()); + + SRC_BLOCK + .replace_all(output, |captures: &Captures<'_>| { + // always normalize gutter to two spaces, arrow to one space, + // this leads to best stability + let mut out = b"\n --> ".to_vec(); + out.extend_from_slice(&captures[1]); + let listing = GUTTER.replace_all(&captures[2], b"\n $1"); + out.extend_from_slice(&listing); + out + }) + .into_owned() +} + +#[cfg(all(feature = "macros", not(target_arch = "wasm32")))] +fn error_on_output_conflict_normalized( + path: &std::path::Path, + output: &[u8], + errors: &mut Vec, + config: &ui_test::per_test_config::TestConfig, +) { + ui_test::error_on_output_conflict(path, &normalize_src_blocks(output), errors, config); +} + +#[cfg(all(feature = "macros", not(target_arch = "wasm32")))] +fn bless_output_files_normalized( + path: &std::path::Path, + output: &[u8], + errors: &mut Vec, + config: &ui_test::per_test_config::TestConfig, +) { + ui_test::bless_output_files(path, &normalize_src_blocks(output), errors, config); +} + #[cfg(any(not(feature = "macros"), target_arch = "wasm32"))] fn main() {} diff --git a/tests/ui/base/src/lib.rs b/tests/ui/base/src/lib.rs index 606adc062a2..82f2639650c 100644 --- a/tests/ui/base/src/lib.rs +++ b/tests/ui/base/src/lib.rs @@ -1,2 +1,2 @@ -// Causes `ui-test` to build pyo3 as a dependency of the ui tests +// Causes `ui_test` to build pyo3 as a dependency of the ui tests extern crate pyo3; diff --git a/tests/ui/forbid_unsafe.rs b/tests/ui/forbid_unsafe.rs index 612a50fb213..9487b2b3247 100644 --- a/tests/ui/forbid_unsafe.rs +++ b/tests/ui/forbid_unsafe.rs @@ -28,6 +28,7 @@ mod gh_4394 { pub struct Version; } +#[pymodule] mod from_py_with { use pyo3::prelude::*; use pyo3::types::PyBytes; diff --git a/tests/ui/forbid_unsafe.stderr b/tests/ui/forbid_unsafe.stderr deleted file mode 100644 index 44b9d7456db..00000000000 --- a/tests/ui/forbid_unsafe.stderr +++ /dev/null @@ -1,15 +0,0 @@ -warning: function `bytes_from_py` is never used - --> tests/ui/forbid_unsafe.rs:35:8 - | -35 | fn bytes_from_py(bytes: &Bound<'_, PyAny>) -> PyResult> { - | ^^^^^^^^^^^^^ - | - = note: `#[warn(dead_code)]` (part of `#[warn(unused)]`) on by default - -warning: function `f` is never used - --> tests/ui/forbid_unsafe.rs:40:8 - | -40 | fn f(#[pyo3(from_py_with = bytes_from_py)] _bytes: Vec) {} - | ^ - -warning: 2 warnings emitted diff --git a/tests/ui/invalid_cancel_handle.stderr b/tests/ui/invalid_cancel_handle.stderr index 9ffbff76607..3f53f6543d6 100644 --- a/tests/ui/invalid_cancel_handle.stderr +++ b/tests/ui/invalid_cancel_handle.stderr @@ -31,25 +31,25 @@ error[E0277]: `CancelHandle` cannot be used as a Python function argument = note: implement `FromPyObject` to enable using `CancelHandle` as a function argument = note: `Python<'py>` is also a valid argument type to pass the Python token into `#[pyfunction]`s and `#[pymethods]` help: the following other types implement trait `pyo3::impl_::extract_argument::PyFunctionArgument<'a, 'holder, 'py, IMPLEMENTS_FROMPYOBJECT>` - --> src/impl_/extract_argument.rs:92:1 - | - 92 | / impl<'a, 'holder, 'py, T: 'a + 'py> PyFunctionArgument<'a, 'holder, 'py, false> - 93 | | for &'holder Bound<'py, T> - 94 | | where - 95 | | T: PyTypeCheck, - | |___________________^ `&'holder pyo3::Bound<'py, T>` implements `pyo3::impl_::extract_argument::PyFunctionArgument<'a, 'holder, 'py, false>` + --> src/impl_/extract_argument.rs + | + | / impl<'a, 'holder, 'py, T: 'a + 'py> PyFunctionArgument<'a, 'holder, 'py, false> + | | for &'holder Bound<'py, T> + | | where + | | T: PyTypeCheck, + | |___________________^ `&'holder pyo3::Bound<'py, T>` implements `pyo3::impl_::extract_argument::PyFunctionArgument<'a, 'holder, 'py, false>` ... -113 | / impl<'a, 'holder, 'py, T> PyFunctionArgument<'a, 'holder, 'py, false> for Option -114 | | where -115 | | T: PyFunctionArgument<'a, 'holder, 'py, false>, - | |___________________________________________________^ `Option` implements `pyo3::impl_::extract_argument::PyFunctionArgument<'a, 'holder, 'py, false>` + | / impl<'a, 'holder, 'py, T> PyFunctionArgument<'a, 'holder, 'py, false> for Option + | | where + | | T: PyFunctionArgument<'a, 'holder, 'py, false>, + | |___________________________________________________^ `Option` implements `pyo3::impl_::extract_argument::PyFunctionArgument<'a, 'holder, 'py, false>` ... -175 | impl<'a, 'holder, T: PyClass> PyFunctionArgument<'a, 'holder, '_, false> for &'holder T { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `&'holder T` implements `pyo3::impl_::extract_argument::PyFunctionArgument<'a, 'holder, '_, false>` + | impl<'a, 'holder, T: PyClass> PyFunctionArgument<'a, 'holder, '_, false> for &'holder T { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `&'holder T` implements `pyo3::impl_::extract_argument::PyFunctionArgument<'a, 'holder, '_, false>` ... -188 | / impl<'a, 'holder, T: PyClass> PyFunctionArgument<'a, 'holder, '_, false> -189 | | for &'holder mut T - | |______________________^ `&'holder mut T` implements `pyo3::impl_::extract_argument::PyFunctionArgument<'a, 'holder, '_, false>` + | / impl<'a, 'holder, T: PyClass> PyFunctionArgument<'a, 'holder, '_, false> + | | for &'holder mut T + | |______________________^ `&'holder mut T` implements `pyo3::impl_::extract_argument::PyFunctionArgument<'a, 'holder, '_, false>` error[E0308]: mismatched types --> tests/ui/invalid_cancel_handle.rs:19:1 @@ -76,21 +76,21 @@ error[E0277]: `CancelHandle` cannot be used as a Python function argument = note: implement `FromPyObject` to enable using `CancelHandle` as a function argument = note: `Python<'py>` is also a valid argument type to pass the Python token into `#[pyfunction]`s and `#[pymethods]` help: the trait `pyo3::PyClass` is implemented for `pyo3::coroutine::Coroutine` - --> src/coroutine.rs:29:1 - | - 29 | #[pyclass(crate = "crate")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: required for `CancelHandle` to implement `FromPyObject<'_, '_>` - = note: required for `CancelHandle` to implement `pyo3::impl_::extract_argument::PyFunctionArgument<'_, '_, '_, true>` + --> src/coroutine.rs + | + | #[pyclass(crate = "crate")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: required for `CancelHandle` to implement `FromPyObject<'_, '_>` + = note: required for `CancelHandle` to implement `pyo3::impl_::extract_argument::PyFunctionArgument<'_, '_, '_, true>` note: required by a bound in `pyo3::impl_::extract_argument::extract_argument` - --> src/impl_/extract_argument.rs:226:8 - | -220 | pub fn extract_argument<'a, 'holder, 'py, T, const IMPLEMENTS_FROMPYOBJECT: bool>( - | ---------------- required by a bound in this function + --> src/impl_/extract_argument.rs + | + | pub fn extract_argument<'a, 'holder, 'py, T, const IMPLEMENTS_FROMPYOBJECT: bool>( + | ---------------- required by a bound in this function ... -226 | T: PyFunctionArgument<'a, 'holder, 'py, IMPLEMENTS_FROMPYOBJECT>, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `extract_argument` - = note: this error originates in the attribute macro `pyclass` (in Nightly builds, run with -Z macro-backtrace for more info) + | T: PyFunctionArgument<'a, 'holder, 'py, IMPLEMENTS_FROMPYOBJECT>, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `extract_argument` + = note: this error originates in the attribute macro `pyclass` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: `CancelHandle` cannot be used as a Python function argument --> tests/ui/invalid_cancel_handle.rs:24:50 @@ -101,35 +101,35 @@ error[E0277]: `CancelHandle` cannot be used as a Python function argument = note: implement `FromPyObject` to enable using `CancelHandle` as a function argument = note: `Python<'py>` is also a valid argument type to pass the Python token into `#[pyfunction]`s and `#[pymethods]` help: the following other types implement trait `pyo3::impl_::extract_argument::PyFunctionArgument<'a, 'holder, 'py, IMPLEMENTS_FROMPYOBJECT>` - --> src/impl_/extract_argument.rs:92:1 - | - 92 | / impl<'a, 'holder, 'py, T: 'a + 'py> PyFunctionArgument<'a, 'holder, 'py, false> - 93 | | for &'holder Bound<'py, T> - 94 | | where - 95 | | T: PyTypeCheck, - | |___________________^ `&'holder pyo3::Bound<'py, T>` implements `pyo3::impl_::extract_argument::PyFunctionArgument<'a, 'holder, 'py, false>` + --> src/impl_/extract_argument.rs + | + | / impl<'a, 'holder, 'py, T: 'a + 'py> PyFunctionArgument<'a, 'holder, 'py, false> + | | for &'holder Bound<'py, T> + | | where + | | T: PyTypeCheck, + | |___________________^ `&'holder pyo3::Bound<'py, T>` implements `pyo3::impl_::extract_argument::PyFunctionArgument<'a, 'holder, 'py, false>` ... -113 | / impl<'a, 'holder, 'py, T> PyFunctionArgument<'a, 'holder, 'py, false> for Option -114 | | where -115 | | T: PyFunctionArgument<'a, 'holder, 'py, false>, - | |___________________________________________________^ `Option` implements `pyo3::impl_::extract_argument::PyFunctionArgument<'a, 'holder, 'py, false>` + | / impl<'a, 'holder, 'py, T> PyFunctionArgument<'a, 'holder, 'py, false> for Option + | | where + | | T: PyFunctionArgument<'a, 'holder, 'py, false>, + | |___________________________________________________^ `Option` implements `pyo3::impl_::extract_argument::PyFunctionArgument<'a, 'holder, 'py, false>` ... -175 | impl<'a, 'holder, T: PyClass> PyFunctionArgument<'a, 'holder, '_, false> for &'holder T { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `&'holder T` implements `pyo3::impl_::extract_argument::PyFunctionArgument<'a, 'holder, '_, false>` + | impl<'a, 'holder, T: PyClass> PyFunctionArgument<'a, 'holder, '_, false> for &'holder T { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `&'holder T` implements `pyo3::impl_::extract_argument::PyFunctionArgument<'a, 'holder, '_, false>` ... -188 | / impl<'a, 'holder, T: PyClass> PyFunctionArgument<'a, 'holder, '_, false> -189 | | for &'holder mut T - | |______________________^ `&'holder mut T` implements `pyo3::impl_::extract_argument::PyFunctionArgument<'a, 'holder, '_, false>` - = note: required for `CancelHandle` to implement `FromPyObject<'_, '_>` - = note: required for `CancelHandle` to implement `pyo3::impl_::extract_argument::PyFunctionArgument<'_, '_, '_, true>` + | / impl<'a, 'holder, T: PyClass> PyFunctionArgument<'a, 'holder, '_, false> + | | for &'holder mut T + | |______________________^ `&'holder mut T` implements `pyo3::impl_::extract_argument::PyFunctionArgument<'a, 'holder, '_, false>` + = note: required for `CancelHandle` to implement `FromPyObject<'_, '_>` + = note: required for `CancelHandle` to implement `pyo3::impl_::extract_argument::PyFunctionArgument<'_, '_, '_, true>` note: required by a bound in `pyo3::impl_::extract_argument::extract_argument` - --> src/impl_/extract_argument.rs:226:8 - | -220 | pub fn extract_argument<'a, 'holder, 'py, T, const IMPLEMENTS_FROMPYOBJECT: bool>( - | ---------------- required by a bound in this function + --> src/impl_/extract_argument.rs + | + | pub fn extract_argument<'a, 'holder, 'py, T, const IMPLEMENTS_FROMPYOBJECT: bool>( + | ---------------- required by a bound in this function ... -226 | T: PyFunctionArgument<'a, 'holder, 'py, IMPLEMENTS_FROMPYOBJECT>, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `extract_argument` + | T: PyFunctionArgument<'a, 'holder, 'py, IMPLEMENTS_FROMPYOBJECT>, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `extract_argument` error[E0277]: `CancelHandle` cannot be used as a Python function argument --> tests/ui/invalid_cancel_handle.rs:24:50 @@ -140,21 +140,21 @@ error[E0277]: `CancelHandle` cannot be used as a Python function argument = note: implement `FromPyObject` to enable using `CancelHandle` as a function argument = note: `Python<'py>` is also a valid argument type to pass the Python token into `#[pyfunction]`s and `#[pymethods]` help: the trait `pyo3::impl_::pyclass::ExtractPyClassWithClone` is implemented for `pyo3::coroutine::Coroutine` - --> src/coroutine.rs:29:1 - | - 29 | #[pyclass(crate = "crate")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: required for `CancelHandle` to implement `FromPyObject<'_, '_>` - = note: required for `CancelHandle` to implement `pyo3::impl_::extract_argument::PyFunctionArgument<'_, '_, '_, true>` + --> src/coroutine.rs + | + | #[pyclass(crate = "crate")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: required for `CancelHandle` to implement `FromPyObject<'_, '_>` + = note: required for `CancelHandle` to implement `pyo3::impl_::extract_argument::PyFunctionArgument<'_, '_, '_, true>` note: required by a bound in `pyo3::impl_::extract_argument::extract_argument` - --> src/impl_/extract_argument.rs:226:8 - | -220 | pub fn extract_argument<'a, 'holder, 'py, T, const IMPLEMENTS_FROMPYOBJECT: bool>( - | ---------------- required by a bound in this function + --> src/impl_/extract_argument.rs + | + | pub fn extract_argument<'a, 'holder, 'py, T, const IMPLEMENTS_FROMPYOBJECT: bool>( + | ---------------- required by a bound in this function ... -226 | T: PyFunctionArgument<'a, 'holder, 'py, IMPLEMENTS_FROMPYOBJECT>, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `extract_argument` - = note: this error originates in the attribute macro `pyclass` (in Nightly builds, run with -Z macro-backtrace for more info) + | T: PyFunctionArgument<'a, 'holder, 'py, IMPLEMENTS_FROMPYOBJECT>, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `extract_argument` + = note: this error originates in the attribute macro `pyclass` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 9 previous errors diff --git a/tests/ui/invalid_closure.stderr b/tests/ui/invalid_closure.stderr index 6d82dec4f09..6e499efedde 100644 --- a/tests/ui/invalid_closure.stderr +++ b/tests/ui/invalid_closure.stderr @@ -13,10 +13,10 @@ error[E0597]: `local_data` does not live long enough | - `local_data` dropped here while still borrowed | note: requirement that the value outlives `'static` introduced here - --> src/types/function.rs:85:78 - | -85 | F: Fn(&Bound<'_, PyTuple>, Option<&Bound<'_, PyDict>>) -> R + Send + 'static, - | ^^^^^^^ + --> src/types/function.rs + | + | F: Fn(&Bound<'_, PyTuple>, Option<&Bound<'_, PyDict>>) -> R + Send + 'static, + | ^^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/invalid_frozen_pyclass_borrow.stderr b/tests/ui/invalid_frozen_pyclass_borrow.stderr index 843d4895e84..4b48202e3d5 100644 --- a/tests/ui/invalid_frozen_pyclass_borrow.stderr +++ b/tests/ui/invalid_frozen_pyclass_borrow.stderr @@ -16,11 +16,11 @@ note: expected this to be `pyo3::pyclass::boolean_struct::False` 3 | #[pyclass(frozen)] | ^^^^^^^^^^^^^^^^^^ note: required by a bound in `pyo3::impl_::extract_argument::extract_pyclass_ref_mut` - --> src/impl_/extract_argument.rs:212:56 - | -212 | pub fn extract_pyclass_ref_mut<'a, 'holder, T: PyClass>( - | ^^^^^^^^^^^^^^ required by this bound in `extract_pyclass_ref_mut` - = note: this error originates in the attribute macro `pyclass` (in Nightly builds, run with -Z macro-backtrace for more info) + --> src/impl_/extract_argument.rs + | + | pub fn extract_pyclass_ref_mut<'a, 'holder, T: PyClass>( + | ^^^^^^^^^^^^^^ required by this bound in `extract_pyclass_ref_mut` + = note: this error originates in the attribute macro `pyclass` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0271]: type mismatch resolving `::Frozen == False` --> tests/ui/invalid_frozen_pyclass_borrow.rs:9:1 @@ -34,11 +34,11 @@ note: expected this to be `pyo3::pyclass::boolean_struct::False` 3 | #[pyclass(frozen)] | ^^^^^^^^^^^^^^^^^^ note: required by a bound in `PyClassGuardMut` - --> src/pyclass/guard.rs:600:43 - | -600 | pub struct PyClassGuardMut<'a, T: PyClass> { - | ^^^^^^^^^^^^^^ required by this bound in `PyClassGuardMut` - = note: this error originates in the attribute macro `pymethods` which comes from the expansion of the attribute macro `pyclass` (in Nightly builds, run with -Z macro-backtrace for more info) + --> src/pyclass/guard.rs + | + | pub struct PyClassGuardMut<'a, T: PyClass> { + | ^^^^^^^^^^^^^^ required by this bound in `PyClassGuardMut` + = note: this error originates in the attribute macro `pymethods` which comes from the expansion of the attribute macro `pyclass` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0271]: type mismatch resolving `::Frozen == False` --> tests/ui/invalid_frozen_pyclass_borrow.rs:17:31 @@ -52,14 +52,14 @@ note: expected this to be `pyo3::pyclass::boolean_struct::False` 3 | #[pyclass(frozen)] | ^^^^^^^^^^^^^^^^^^ note: required by a bound in `pyo3::Bound::<'py, T>::borrow_mut` - --> src/instance.rs:590:20 - | -588 | pub fn borrow_mut(&self) -> PyRefMut<'py, T> - | ---------- required by a bound in this associated function -589 | where -590 | T: PyClass, - | ^^^^^^^^^^^^^^ required by this bound in `Bound::<'py, T>::borrow_mut` - = note: this error originates in the attribute macro `pyclass` (in Nightly builds, run with -Z macro-backtrace for more info) + --> src/instance.rs + | + | pub fn borrow_mut(&self) -> PyRefMut<'py, T> + | ---------- required by a bound in this associated function + | where + | T: PyClass, + | ^^^^^^^^^^^^^^ required by this bound in `Bound::<'py, T>::borrow_mut` + = note: this error originates in the attribute macro `pyclass` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0271]: type mismatch resolving `::Frozen == False` --> tests/ui/invalid_frozen_pyclass_borrow.rs:28:33 @@ -73,14 +73,14 @@ note: expected this to be `pyo3::pyclass::boolean_struct::False` 24 | #[pyclass(frozen, extends = MutableBase)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: required by a bound in `pyo3::Bound::<'py, T>::borrow_mut` - --> src/instance.rs:590:20 - | -588 | pub fn borrow_mut(&self) -> PyRefMut<'py, T> - | ---------- required by a bound in this associated function -589 | where -590 | T: PyClass, - | ^^^^^^^^^^^^^^ required by this bound in `Bound::<'py, T>::borrow_mut` - = note: this error originates in the attribute macro `pyclass` (in Nightly builds, run with -Z macro-backtrace for more info) + --> src/instance.rs + | + | pub fn borrow_mut(&self) -> PyRefMut<'py, T> + | ---------- required by a bound in this associated function + | where + | T: PyClass, + | ^^^^^^^^^^^^^^ required by this bound in `Bound::<'py, T>::borrow_mut` + = note: this error originates in the attribute macro `pyclass` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0271]: type mismatch resolving `::Frozen == True` --> tests/ui/invalid_frozen_pyclass_borrow.rs:33:11 @@ -94,14 +94,14 @@ note: expected this to be `pyo3::pyclass::boolean_struct::True` 21 | #[pyclass(subclass)] | ^^^^^^^^^^^^^^^^^^^^ note: required by a bound in `pyo3::Py::::get` - --> src/instance.rs:1712:20 - | -1710 | pub fn get(&self) -> &T - | --- required by a bound in this associated function -1711 | where -1712 | T: PyClass + Sync, - | ^^^^^^^^^^^^^ required by this bound in `Py::::get` - = note: this error originates in the attribute macro `pyclass` (in Nightly builds, run with -Z macro-backtrace for more info) + --> src/instance.rs + | + | pub fn get(&self) -> &T + | --- required by a bound in this associated function + | where + | T: PyClass + Sync, + | ^^^^^^^^^^^^^ required by this bound in `Py::::get` + = note: this error originates in the attribute macro `pyclass` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0271]: type mismatch resolving `::Frozen == True` --> tests/ui/invalid_frozen_pyclass_borrow.rs:38:11 @@ -115,14 +115,14 @@ note: expected this to be `pyo3::pyclass::boolean_struct::True` 21 | #[pyclass(subclass)] | ^^^^^^^^^^^^^^^^^^^^ note: required by a bound in `pyo3::Bound::<'py, T>::get` - --> src/instance.rs:646:20 - | -644 | pub fn get(&self) -> &T - | --- required by a bound in this associated function -645 | where -646 | T: PyClass + Sync, - | ^^^^^^^^^^^^^ required by this bound in `Bound::<'py, T>::get` - = note: this error originates in the attribute macro `pyclass` (in Nightly builds, run with -Z macro-backtrace for more info) + --> src/instance.rs + | + | pub fn get(&self) -> &T + | --- required by a bound in this associated function + | where + | T: PyClass + Sync, + | ^^^^^^^^^^^^^ required by this bound in `Bound::<'py, T>::get` + = note: this error originates in the attribute macro `pyclass` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 7 previous errors diff --git a/tests/ui/invalid_intern_arg.stderr b/tests/ui/invalid_intern_arg.stderr index e2e4f697b42..e684353092d 100644 --- a/tests/ui/invalid_intern_arg.stderr +++ b/tests/ui/invalid_intern_arg.stderr @@ -5,8 +5,8 @@ error[E0435]: attempt to use a non-constant value in a constant | ^^^^ non-constant value | help: consider using `let` instead of `static` - --> src/sync.rs:232:9 - | + --> src/sync.rs + | 232 - static INTERNED: $crate::sync::Interned = $crate::sync::Interned::new($text); 232 + let INTERNED: $crate::sync::Interned = $crate::sync::Interned::new($text); | diff --git a/tests/ui/invalid_property_args.stderr b/tests/ui/invalid_property_args.stderr index 4fae6277280..75b71a530ef 100644 --- a/tests/ui/invalid_property_args.stderr +++ b/tests/ui/invalid_property_args.stderr @@ -66,13 +66,13 @@ error[E0277]: `PhantomData` cannot be converted to a Python object and $N others = note: required for `PhantomData` to implement `for<'py> pyo3::impl_::pyclass::PyO3GetField<'py>` note: required by a bound in `pyo3::impl_::pyclass::PyClassGetterGenerator::::generate` - --> src/impl_/pyclass.rs:1308:26 - | -1304 | pub const fn generate(&self, name: &'static CStr, doc: Option<&'static CStr>) -> PyMethodDefType - | -------- required by a bound in this associated function + --> src/impl_/pyclass.rs + | + | pub const fn generate(&self, name: &'static CStr, doc: Option<&'static CStr>) -> PyMethodDefType + | -------- required by a bound in this associated function ... -1308 | for<'py> FieldT: PyO3GetField<'py>, - | ^^^^^^^^^^^^^^^^^ required by this bound in `PyClassGetterGenerator::::generate` + | for<'py> FieldT: PyO3GetField<'py>, + | ^^^^^^^^^^^^^^^^^ required by this bound in `PyClassGetterGenerator::::generate` error: aborting due to 9 previous errors diff --git a/tests/ui/invalid_pycallargs.stderr b/tests/ui/invalid_pycallargs.stderr index 627e0040579..de1b0fb82f2 100644 --- a/tests/ui/invalid_pycallargs.stderr +++ b/tests/ui/invalid_pycallargs.stderr @@ -20,13 +20,13 @@ error[E0277]: `&str` cannot used as a Python `call` argument &'a (T0, T1, T2, T3, T4, T5, T6, T7, T8) and $N others note: required by a bound in `call1` - --> src/types/any.rs:533:12 - | -531 | fn call1(&self, args: A) -> PyResult> - | ----- required by a bound in this associated function -532 | where -533 | A: PyCallArgs<'py>; - | ^^^^^^^^^^^^^^^ required by this bound in `PyAnyMethods::call1` + --> src/types/any.rs + | + | fn call1(&self, args: A) -> PyResult> + | ----- required by a bound in this associated function + | where + | A: PyCallArgs<'py>; + | ^^^^^^^^^^^^^^^ required by this bound in `PyAnyMethods::call1` help: use a unary tuple instead | 6 | any.call1(("foo",)); diff --git a/tests/ui/invalid_pyclass_args.stderr b/tests/ui/invalid_pyclass_args.stderr index 4b247f4b5be..6b5b34ebb3d 100644 --- a/tests/ui/invalid_pyclass_args.stderr +++ b/tests/ui/invalid_pyclass_args.stderr @@ -444,13 +444,13 @@ error[E0277]: `Box` cannot be used as a Pyt = note: required for `Box` to implement `pyo3::FromPyObject<'_, '_>` = note: required for `Box` to implement `pyo3::impl_::extract_argument::PyFunctionArgument<'_, '_, '_, true>` note: required by a bound in `pyo3::impl_::extract_argument::extract_argument` - --> src/impl_/extract_argument.rs:226:8 - | -220 | pub fn extract_argument<'a, 'holder, 'py, T, const IMPLEMENTS_FROMPYOBJECT: bool>( - | ---------------- required by a bound in this function + --> src/impl_/extract_argument.rs + | + | pub fn extract_argument<'a, 'holder, 'py, T, const IMPLEMENTS_FROMPYOBJECT: bool>( + | ---------------- required by a bound in this function ... -226 | T: PyFunctionArgument<'a, 'holder, 'py, IMPLEMENTS_FROMPYOBJECT>, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `extract_argument` + | T: PyFunctionArgument<'a, 'holder, 'py, IMPLEMENTS_FROMPYOBJECT>, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `extract_argument` error[E0277]: `Box` cannot be used as a Python function argument --> tests/ui/invalid_pyclass_args.rs:248:12 @@ -473,13 +473,13 @@ error[E0277]: `Box` cannot be used as a Pyt = note: required for `Box` to implement `pyo3::FromPyObject<'_, '_>` = note: required for `Box` to implement `pyo3::impl_::extract_argument::PyFunctionArgument<'_, '_, '_, true>` note: required by a bound in `pyo3::impl_::extract_argument::extract_argument` - --> src/impl_/extract_argument.rs:226:8 - | -220 | pub fn extract_argument<'a, 'holder, 'py, T, const IMPLEMENTS_FROMPYOBJECT: bool>( - | ---------------- required by a bound in this function + --> src/impl_/extract_argument.rs + | + | pub fn extract_argument<'a, 'holder, 'py, T, const IMPLEMENTS_FROMPYOBJECT: bool>( + | ---------------- required by a bound in this function ... -226 | T: PyFunctionArgument<'a, 'holder, 'py, IMPLEMENTS_FROMPYOBJECT>, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `extract_argument` + | T: PyFunctionArgument<'a, 'holder, 'py, IMPLEMENTS_FROMPYOBJECT>, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `extract_argument` error[E0277]: the trait bound `dyn std::error::Error + Send + Sync: Clone` is not satisfied --> tests/ui/invalid_pyclass_args.rs:248:12 @@ -488,36 +488,36 @@ error[E0277]: the trait bound `dyn std::error::Error + Send + Sync: Clone` is no | ^^^ the trait `Clone` is not implemented for `dyn std::error::Error + Send + Sync` | help: the following other types implement trait `pyo3::impl_::extract_argument::PyFunctionArgument<'a, 'holder, 'py, IMPLEMENTS_FROMPYOBJECT>` - --> src/impl_/extract_argument.rs:92:1 - | - 92 | / impl<'a, 'holder, 'py, T: 'a + 'py> PyFunctionArgument<'a, 'holder, 'py, false> - 93 | | for &'holder Bound<'py, T> - 94 | | where - 95 | | T: PyTypeCheck, - | |___________________^ `&'holder pyo3::Bound<'py, T>` implements `pyo3::impl_::extract_argument::PyFunctionArgument<'a, 'holder, 'py, false>` + --> src/impl_/extract_argument.rs + | + | / impl<'a, 'holder, 'py, T: 'a + 'py> PyFunctionArgument<'a, 'holder, 'py, false> + | | for &'holder Bound<'py, T> + | | where + | | T: PyTypeCheck, + | |___________________^ `&'holder pyo3::Bound<'py, T>` implements `pyo3::impl_::extract_argument::PyFunctionArgument<'a, 'holder, 'py, false>` ... -113 | / impl<'a, 'holder, 'py, T> PyFunctionArgument<'a, 'holder, 'py, false> for Option -114 | | where -115 | | T: PyFunctionArgument<'a, 'holder, 'py, false>, - | |___________________________________________________^ `Option` implements `pyo3::impl_::extract_argument::PyFunctionArgument<'a, 'holder, 'py, false>` + | / impl<'a, 'holder, 'py, T> PyFunctionArgument<'a, 'holder, 'py, false> for Option + | | where + | | T: PyFunctionArgument<'a, 'holder, 'py, false>, + | |___________________________________________________^ `Option` implements `pyo3::impl_::extract_argument::PyFunctionArgument<'a, 'holder, 'py, false>` ... -175 | impl<'a, 'holder, T: PyClass> PyFunctionArgument<'a, 'holder, '_, false> for &'holder T { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `&'holder T` implements `pyo3::impl_::extract_argument::PyFunctionArgument<'a, 'holder, '_, false>` + | impl<'a, 'holder, T: PyClass> PyFunctionArgument<'a, 'holder, '_, false> for &'holder T { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `&'holder T` implements `pyo3::impl_::extract_argument::PyFunctionArgument<'a, 'holder, '_, false>` ... -188 | / impl<'a, 'holder, T: PyClass> PyFunctionArgument<'a, 'holder, '_, false> -189 | | for &'holder mut T - | |______________________^ `&'holder mut T` implements `pyo3::impl_::extract_argument::PyFunctionArgument<'a, 'holder, '_, false>` - = note: required for `Box` to implement `Clone` - = note: required for `Box` to implement `pyo3::FromPyObject<'_, '_>` - = note: required for `Box` to implement `pyo3::impl_::extract_argument::PyFunctionArgument<'_, '_, '_, true>` + | / impl<'a, 'holder, T: PyClass> PyFunctionArgument<'a, 'holder, '_, false> + | | for &'holder mut T + | |______________________^ `&'holder mut T` implements `pyo3::impl_::extract_argument::PyFunctionArgument<'a, 'holder, '_, false>` + = note: required for `Box` to implement `Clone` + = note: required for `Box` to implement `pyo3::FromPyObject<'_, '_>` + = note: required for `Box` to implement `pyo3::impl_::extract_argument::PyFunctionArgument<'_, '_, '_, true>` note: required by a bound in `pyo3::impl_::extract_argument::extract_argument` - --> src/impl_/extract_argument.rs:226:8 - | -220 | pub fn extract_argument<'a, 'holder, 'py, T, const IMPLEMENTS_FROMPYOBJECT: bool>( - | ---------------- required by a bound in this function + --> src/impl_/extract_argument.rs + | + | pub fn extract_argument<'a, 'holder, 'py, T, const IMPLEMENTS_FROMPYOBJECT: bool>( + | ---------------- required by a bound in this function ... -226 | T: PyFunctionArgument<'a, 'holder, 'py, IMPLEMENTS_FROMPYOBJECT>, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `extract_argument` + | T: PyFunctionArgument<'a, 'holder, 'py, IMPLEMENTS_FROMPYOBJECT>, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `extract_argument` error[E0034]: multiple applicable items in scope --> tests/ui/invalid_pyclass_args.rs:254:1 diff --git a/tests/ui/invalid_pyclass_init.stderr b/tests/ui/invalid_pyclass_init.stderr index 5cd6a18c36f..0a4bafdb4bb 100644 --- a/tests/ui/invalid_pyclass_init.stderr +++ b/tests/ui/invalid_pyclass_init.stderr @@ -5,13 +5,13 @@ error[E0277]: the trait bound `i32: pyo3::impl_::callback::IntoPyCallbackOutput< | ^^^ the trait `pyo3::impl_::callback::IntoPyCallbackOutput<'_, i32>` is not implemented for `i32` | help: the following other types implement trait `pyo3::impl_::callback::IntoPyCallbackOutput<'py, Target>` - --> src/impl_/callback.rs:127:1 - | -127 | impl IntoPyCallbackOutput<'_, ffi::Py_ssize_t> for usize { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `usize` implements `pyo3::impl_::callback::IntoPyCallbackOutput<'_, isize>` + --> src/impl_/callback.rs + | + | impl IntoPyCallbackOutput<'_, ffi::Py_ssize_t> for usize { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `usize` implements `pyo3::impl_::callback::IntoPyCallbackOutput<'_, isize>` ... -143 | impl IntoPyCallbackOutput<'_, usize> for usize { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `usize` implements `pyo3::impl_::callback::IntoPyCallbackOutput<'_, usize>` + | impl IntoPyCallbackOutput<'_, usize> for usize { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `usize` implements `pyo3::impl_::callback::IntoPyCallbackOutput<'_, usize>` error: aborting due to 1 previous error diff --git a/tests/ui/invalid_pyfunction_argument.stderr b/tests/ui/invalid_pyfunction_argument.stderr index 3cb1d94a226..20bcce943ec 100644 --- a/tests/ui/invalid_pyfunction_argument.stderr +++ b/tests/ui/invalid_pyfunction_argument.stderr @@ -14,14 +14,14 @@ help: the trait `PyClass` is implemented for `Foo` = note: required for `AtomicPtr<()>` to implement `FromPyObject<'_, '_>` = note: required for `AtomicPtr<()>` to implement `pyo3::impl_::extract_argument::PyFunctionArgument<'_, '_, '_, true>` note: required by a bound in `pyo3::impl_::extract_argument::extract_argument` - --> src/impl_/extract_argument.rs:226:8 - | -220 | pub fn extract_argument<'a, 'holder, 'py, T, const IMPLEMENTS_FROMPYOBJECT: bool>( - | ---------------- required by a bound in this function + --> src/impl_/extract_argument.rs + | + | pub fn extract_argument<'a, 'holder, 'py, T, const IMPLEMENTS_FROMPYOBJECT: bool>( + | ---------------- required by a bound in this function ... -226 | T: PyFunctionArgument<'a, 'holder, 'py, IMPLEMENTS_FROMPYOBJECT>, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `extract_argument` - = note: this error originates in the attribute macro `pyclass` (in Nightly builds, run with -Z macro-backtrace for more info) + | T: PyFunctionArgument<'a, 'holder, 'py, IMPLEMENTS_FROMPYOBJECT>, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `extract_argument` + = note: this error originates in the attribute macro `pyclass` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: `AtomicPtr<()>` cannot be used as a Python function argument --> tests/ui/invalid_pyfunction_argument.rs:5:37 @@ -32,35 +32,35 @@ error[E0277]: `AtomicPtr<()>` cannot be used as a Python function argument = note: implement `FromPyObject` to enable using `AtomicPtr<()>` as a function argument = note: `Python<'py>` is also a valid argument type to pass the Python token into `#[pyfunction]`s and `#[pymethods]` help: the following other types implement trait `pyo3::impl_::extract_argument::PyFunctionArgument<'a, 'holder, 'py, IMPLEMENTS_FROMPYOBJECT>` - --> src/impl_/extract_argument.rs:92:1 - | - 92 | / impl<'a, 'holder, 'py, T: 'a + 'py> PyFunctionArgument<'a, 'holder, 'py, false> - 93 | | for &'holder Bound<'py, T> - 94 | | where - 95 | | T: PyTypeCheck, - | |___________________^ `&'holder pyo3::Bound<'py, T>` implements `pyo3::impl_::extract_argument::PyFunctionArgument<'a, 'holder, 'py, false>` + --> src/impl_/extract_argument.rs + | + | / impl<'a, 'holder, 'py, T: 'a + 'py> PyFunctionArgument<'a, 'holder, 'py, false> + | | for &'holder Bound<'py, T> + | | where + | | T: PyTypeCheck, + | |___________________^ `&'holder pyo3::Bound<'py, T>` implements `pyo3::impl_::extract_argument::PyFunctionArgument<'a, 'holder, 'py, false>` ... -113 | / impl<'a, 'holder, 'py, T> PyFunctionArgument<'a, 'holder, 'py, false> for Option -114 | | where -115 | | T: PyFunctionArgument<'a, 'holder, 'py, false>, - | |___________________________________________________^ `Option` implements `pyo3::impl_::extract_argument::PyFunctionArgument<'a, 'holder, 'py, false>` + | / impl<'a, 'holder, 'py, T> PyFunctionArgument<'a, 'holder, 'py, false> for Option + | | where + | | T: PyFunctionArgument<'a, 'holder, 'py, false>, + | |___________________________________________________^ `Option` implements `pyo3::impl_::extract_argument::PyFunctionArgument<'a, 'holder, 'py, false>` ... -175 | impl<'a, 'holder, T: PyClass> PyFunctionArgument<'a, 'holder, '_, false> for &'holder T { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `&'holder T` implements `pyo3::impl_::extract_argument::PyFunctionArgument<'a, 'holder, '_, false>` + | impl<'a, 'holder, T: PyClass> PyFunctionArgument<'a, 'holder, '_, false> for &'holder T { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `&'holder T` implements `pyo3::impl_::extract_argument::PyFunctionArgument<'a, 'holder, '_, false>` ... -188 | / impl<'a, 'holder, T: PyClass> PyFunctionArgument<'a, 'holder, '_, false> -189 | | for &'holder mut T - | |______________________^ `&'holder mut T` implements `pyo3::impl_::extract_argument::PyFunctionArgument<'a, 'holder, '_, false>` - = note: required for `AtomicPtr<()>` to implement `FromPyObject<'_, '_>` - = note: required for `AtomicPtr<()>` to implement `pyo3::impl_::extract_argument::PyFunctionArgument<'_, '_, '_, true>` + | / impl<'a, 'holder, T: PyClass> PyFunctionArgument<'a, 'holder, '_, false> + | | for &'holder mut T + | |______________________^ `&'holder mut T` implements `pyo3::impl_::extract_argument::PyFunctionArgument<'a, 'holder, '_, false>` + = note: required for `AtomicPtr<()>` to implement `FromPyObject<'_, '_>` + = note: required for `AtomicPtr<()>` to implement `pyo3::impl_::extract_argument::PyFunctionArgument<'_, '_, '_, true>` note: required by a bound in `pyo3::impl_::extract_argument::extract_argument` - --> src/impl_/extract_argument.rs:226:8 - | -220 | pub fn extract_argument<'a, 'holder, 'py, T, const IMPLEMENTS_FROMPYOBJECT: bool>( - | ---------------- required by a bound in this function + --> src/impl_/extract_argument.rs + | + | pub fn extract_argument<'a, 'holder, 'py, T, const IMPLEMENTS_FROMPYOBJECT: bool>( + | ---------------- required by a bound in this function ... -226 | T: PyFunctionArgument<'a, 'holder, 'py, IMPLEMENTS_FROMPYOBJECT>, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `extract_argument` + | T: PyFunctionArgument<'a, 'holder, 'py, IMPLEMENTS_FROMPYOBJECT>, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `extract_argument` error[E0277]: `AtomicPtr<()>` cannot be used as a Python function argument --> tests/ui/invalid_pyfunction_argument.rs:5:37 @@ -71,35 +71,35 @@ error[E0277]: `AtomicPtr<()>` cannot be used as a Python function argument = note: implement `FromPyObject` to enable using `AtomicPtr<()>` as a function argument = note: `Python<'py>` is also a valid argument type to pass the Python token into `#[pyfunction]`s and `#[pymethods]` help: the following other types implement trait `pyo3::impl_::extract_argument::PyFunctionArgument<'a, 'holder, 'py, IMPLEMENTS_FROMPYOBJECT>` - --> src/impl_/extract_argument.rs:92:1 - | - 92 | / impl<'a, 'holder, 'py, T: 'a + 'py> PyFunctionArgument<'a, 'holder, 'py, false> - 93 | | for &'holder Bound<'py, T> - 94 | | where - 95 | | T: PyTypeCheck, - | |___________________^ `&'holder pyo3::Bound<'py, T>` implements `pyo3::impl_::extract_argument::PyFunctionArgument<'a, 'holder, 'py, false>` + --> src/impl_/extract_argument.rs + | + | / impl<'a, 'holder, 'py, T: 'a + 'py> PyFunctionArgument<'a, 'holder, 'py, false> + | | for &'holder Bound<'py, T> + | | where + | | T: PyTypeCheck, + | |___________________^ `&'holder pyo3::Bound<'py, T>` implements `pyo3::impl_::extract_argument::PyFunctionArgument<'a, 'holder, 'py, false>` ... -113 | / impl<'a, 'holder, 'py, T> PyFunctionArgument<'a, 'holder, 'py, false> for Option -114 | | where -115 | | T: PyFunctionArgument<'a, 'holder, 'py, false>, - | |___________________________________________________^ `Option` implements `pyo3::impl_::extract_argument::PyFunctionArgument<'a, 'holder, 'py, false>` + | / impl<'a, 'holder, 'py, T> PyFunctionArgument<'a, 'holder, 'py, false> for Option + | | where + | | T: PyFunctionArgument<'a, 'holder, 'py, false>, + | |___________________________________________________^ `Option` implements `pyo3::impl_::extract_argument::PyFunctionArgument<'a, 'holder, 'py, false>` ... -175 | impl<'a, 'holder, T: PyClass> PyFunctionArgument<'a, 'holder, '_, false> for &'holder T { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `&'holder T` implements `pyo3::impl_::extract_argument::PyFunctionArgument<'a, 'holder, '_, false>` + | impl<'a, 'holder, T: PyClass> PyFunctionArgument<'a, 'holder, '_, false> for &'holder T { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `&'holder T` implements `pyo3::impl_::extract_argument::PyFunctionArgument<'a, 'holder, '_, false>` ... -188 | / impl<'a, 'holder, T: PyClass> PyFunctionArgument<'a, 'holder, '_, false> -189 | | for &'holder mut T - | |______________________^ `&'holder mut T` implements `pyo3::impl_::extract_argument::PyFunctionArgument<'a, 'holder, '_, false>` - = note: required for `AtomicPtr<()>` to implement `FromPyObject<'_, '_>` - = note: required for `AtomicPtr<()>` to implement `pyo3::impl_::extract_argument::PyFunctionArgument<'_, '_, '_, true>` + | / impl<'a, 'holder, T: PyClass> PyFunctionArgument<'a, 'holder, '_, false> + | | for &'holder mut T + | |______________________^ `&'holder mut T` implements `pyo3::impl_::extract_argument::PyFunctionArgument<'a, 'holder, '_, false>` + = note: required for `AtomicPtr<()>` to implement `FromPyObject<'_, '_>` + = note: required for `AtomicPtr<()>` to implement `pyo3::impl_::extract_argument::PyFunctionArgument<'_, '_, '_, true>` note: required by a bound in `pyo3::impl_::extract_argument::extract_argument` - --> src/impl_/extract_argument.rs:226:8 - | -220 | pub fn extract_argument<'a, 'holder, 'py, T, const IMPLEMENTS_FROMPYOBJECT: bool>( - | ---------------- required by a bound in this function + --> src/impl_/extract_argument.rs + | + | pub fn extract_argument<'a, 'holder, 'py, T, const IMPLEMENTS_FROMPYOBJECT: bool>( + | ---------------- required by a bound in this function ... -226 | T: PyFunctionArgument<'a, 'holder, 'py, IMPLEMENTS_FROMPYOBJECT>, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `extract_argument` + | T: PyFunctionArgument<'a, 'holder, 'py, IMPLEMENTS_FROMPYOBJECT>, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `extract_argument` error[E0277]: `Foo` cannot be used as a Python function argument --> tests/ui/invalid_pyfunction_argument.rs:17:59 @@ -115,35 +115,35 @@ help: the trait `pyo3::impl_::pyclass::ExtractPyClassWithClone` is not implement = note: implement `FromPyObject` to enable using `Foo` as a function argument = note: `Python<'py>` is also a valid argument type to pass the Python token into `#[pyfunction]`s and `#[pymethods]` help: the following other types implement trait `pyo3::impl_::extract_argument::PyFunctionArgument<'a, 'holder, 'py, IMPLEMENTS_FROMPYOBJECT>` - --> src/impl_/extract_argument.rs:92:1 - | - 92 | / impl<'a, 'holder, 'py, T: 'a + 'py> PyFunctionArgument<'a, 'holder, 'py, false> - 93 | | for &'holder Bound<'py, T> - 94 | | where - 95 | | T: PyTypeCheck, - | |___________________^ `&'holder pyo3::Bound<'py, T>` implements `pyo3::impl_::extract_argument::PyFunctionArgument<'a, 'holder, 'py, false>` + --> src/impl_/extract_argument.rs + | + | / impl<'a, 'holder, 'py, T: 'a + 'py> PyFunctionArgument<'a, 'holder, 'py, false> + | | for &'holder Bound<'py, T> + | | where + | | T: PyTypeCheck, + | |___________________^ `&'holder pyo3::Bound<'py, T>` implements `pyo3::impl_::extract_argument::PyFunctionArgument<'a, 'holder, 'py, false>` ... -113 | / impl<'a, 'holder, 'py, T> PyFunctionArgument<'a, 'holder, 'py, false> for Option -114 | | where -115 | | T: PyFunctionArgument<'a, 'holder, 'py, false>, - | |___________________________________________________^ `Option` implements `pyo3::impl_::extract_argument::PyFunctionArgument<'a, 'holder, 'py, false>` + | / impl<'a, 'holder, 'py, T> PyFunctionArgument<'a, 'holder, 'py, false> for Option + | | where + | | T: PyFunctionArgument<'a, 'holder, 'py, false>, + | |___________________________________________________^ `Option` implements `pyo3::impl_::extract_argument::PyFunctionArgument<'a, 'holder, 'py, false>` ... -175 | impl<'a, 'holder, T: PyClass> PyFunctionArgument<'a, 'holder, '_, false> for &'holder T { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `&'holder T` implements `pyo3::impl_::extract_argument::PyFunctionArgument<'a, 'holder, '_, false>` + | impl<'a, 'holder, T: PyClass> PyFunctionArgument<'a, 'holder, '_, false> for &'holder T { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `&'holder T` implements `pyo3::impl_::extract_argument::PyFunctionArgument<'a, 'holder, '_, false>` ... -188 | / impl<'a, 'holder, T: PyClass> PyFunctionArgument<'a, 'holder, '_, false> -189 | | for &'holder mut T - | |______________________^ `&'holder mut T` implements `pyo3::impl_::extract_argument::PyFunctionArgument<'a, 'holder, '_, false>` - = note: required for `Foo` to implement `FromPyObject<'_, '_>` - = note: required for `Foo` to implement `pyo3::impl_::extract_argument::PyFunctionArgument<'_, '_, '_, true>` + | / impl<'a, 'holder, T: PyClass> PyFunctionArgument<'a, 'holder, '_, false> + | | for &'holder mut T + | |______________________^ `&'holder mut T` implements `pyo3::impl_::extract_argument::PyFunctionArgument<'a, 'holder, '_, false>` + = note: required for `Foo` to implement `FromPyObject<'_, '_>` + = note: required for `Foo` to implement `pyo3::impl_::extract_argument::PyFunctionArgument<'_, '_, '_, true>` note: required by a bound in `pyo3::impl_::extract_argument::extract_argument` - --> src/impl_/extract_argument.rs:226:8 - | -220 | pub fn extract_argument<'a, 'holder, 'py, T, const IMPLEMENTS_FROMPYOBJECT: bool>( - | ---------------- required by a bound in this function + --> src/impl_/extract_argument.rs + | + | pub fn extract_argument<'a, 'holder, 'py, T, const IMPLEMENTS_FROMPYOBJECT: bool>( + | ---------------- required by a bound in this function ... -226 | T: PyFunctionArgument<'a, 'holder, 'py, IMPLEMENTS_FROMPYOBJECT>, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `extract_argument` + | T: PyFunctionArgument<'a, 'holder, 'py, IMPLEMENTS_FROMPYOBJECT>, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `extract_argument` error: aborting due to 4 previous errors diff --git a/tests/ui/invalid_pyfunctions.stderr b/tests/ui/invalid_pyfunctions.stderr index b6a8e3fb65f..e383591de60 100644 --- a/tests/ui/invalid_pyfunctions.stderr +++ b/tests/ui/invalid_pyfunctions.stderr @@ -53,7 +53,6 @@ error[E0277]: the trait bound `&str: From<&pyo3::Bound<'_, pyo3::types::PyModule `String` implements `From>` `String` implements `From>` `String` implements `From` - `String` implements `From` = note: required for `&pyo3::Bound<'_, pyo3::types::PyModule>` to implement `Into<&str>` error: aborting due to 8 previous errors diff --git a/tests/ui/invalid_pymethod_enum.stderr b/tests/ui/invalid_pymethod_enum.stderr index e20983046f5..aeaaa240f9d 100644 --- a/tests/ui/invalid_pymethod_enum.stderr +++ b/tests/ui/invalid_pymethod_enum.stderr @@ -10,11 +10,11 @@ note: expected this to be `pyo3::pyclass::boolean_struct::False` 3 | #[pyclass] | ^^^^^^^^^^ note: required by a bound in `pyo3::impl_::extract_argument::extract_pyclass_ref_mut` - --> src/impl_/extract_argument.rs:212:56 - | -212 | pub fn extract_pyclass_ref_mut<'a, 'holder, T: PyClass>( - | ^^^^^^^^^^^^^^ required by this bound in `extract_pyclass_ref_mut` - = note: this error originates in the attribute macro `pyclass` (in Nightly builds, run with -Z macro-backtrace for more info) + --> src/impl_/extract_argument.rs + | + | pub fn extract_pyclass_ref_mut<'a, 'holder, T: PyClass>( + | ^^^^^^^^^^^^^^ required by this bound in `extract_pyclass_ref_mut` + = note: this error originates in the attribute macro `pyclass` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0271]: type mismatch resolving `::Frozen == False` --> tests/ui/invalid_pymethod_enum.rs:9:1 @@ -28,11 +28,11 @@ note: expected this to be `pyo3::pyclass::boolean_struct::False` 3 | #[pyclass] | ^^^^^^^^^^ note: required by a bound in `PyClassGuardMut` - --> src/pyclass/guard.rs:600:43 - | -600 | pub struct PyClassGuardMut<'a, T: PyClass> { - | ^^^^^^^^^^^^^^ required by this bound in `PyClassGuardMut` - = note: this error originates in the attribute macro `pymethods` which comes from the expansion of the attribute macro `pyclass` (in Nightly builds, run with -Z macro-backtrace for more info) + --> src/pyclass/guard.rs + | + | pub struct PyClassGuardMut<'a, T: PyClass> { + | ^^^^^^^^^^^^^^ required by this bound in `PyClassGuardMut` + = note: this error originates in the attribute macro `pymethods` which comes from the expansion of the attribute macro `pyclass` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0271]: type mismatch resolving `::Frozen == False` --> tests/ui/invalid_pymethod_enum.rs:30:24 @@ -46,11 +46,11 @@ note: expected this to be `pyo3::pyclass::boolean_struct::False` 21 | #[pyclass] | ^^^^^^^^^^ note: required by a bound in `pyo3::impl_::extract_argument::extract_pyclass_ref_mut` - --> src/impl_/extract_argument.rs:212:56 - | -212 | pub fn extract_pyclass_ref_mut<'a, 'holder, T: PyClass>( - | ^^^^^^^^^^^^^^ required by this bound in `extract_pyclass_ref_mut` - = note: this error originates in the attribute macro `pyclass` (in Nightly builds, run with -Z macro-backtrace for more info) + --> src/impl_/extract_argument.rs + | + | pub fn extract_pyclass_ref_mut<'a, 'holder, T: PyClass>( + | ^^^^^^^^^^^^^^ required by this bound in `extract_pyclass_ref_mut` + = note: this error originates in the attribute macro `pyclass` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0271]: type mismatch resolving `::Frozen == False` --> tests/ui/invalid_pymethod_enum.rs:27:1 @@ -64,11 +64,11 @@ note: expected this to be `pyo3::pyclass::boolean_struct::False` 21 | #[pyclass] | ^^^^^^^^^^ note: required by a bound in `PyClassGuardMut` - --> src/pyclass/guard.rs:600:43 - | -600 | pub struct PyClassGuardMut<'a, T: PyClass> { - | ^^^^^^^^^^^^^^ required by this bound in `PyClassGuardMut` - = note: this error originates in the attribute macro `pymethods` which comes from the expansion of the attribute macro `pyclass` (in Nightly builds, run with -Z macro-backtrace for more info) + --> src/pyclass/guard.rs + | + | pub struct PyClassGuardMut<'a, T: PyClass> { + | ^^^^^^^^^^^^^^ required by this bound in `PyClassGuardMut` + = note: this error originates in the attribute macro `pymethods` which comes from the expansion of the attribute macro `pyclass` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 4 previous errors diff --git a/tests/ui/missing_intopy.stderr b/tests/ui/missing_intopy.stderr index ae621f44882..b765e4df04e 100644 --- a/tests/ui/missing_intopy.stderr +++ b/tests/ui/missing_intopy.stderr @@ -23,13 +23,13 @@ help: the trait `IntoPyObject<'_>` is not implemented for `Blah` &'a (T0, T1, T2, T3, T4) and $N others note: required by a bound in `pyo3::impl_::wrap::UnknownReturnType::::wrap` - --> src/impl_/wrap.rs:124:12 - | -122 | pub fn wrap<'py>(&self, _: T) -> T - | ---- required by a bound in this associated function -123 | where -124 | T: IntoPyObject<'py>, - | ^^^^^^^^^^^^^^^^^ required by this bound in `UnknownReturnType::::wrap` + --> src/impl_/wrap.rs + | + | pub fn wrap<'py>(&self, _: T) -> T + | ---- required by a bound in this associated function + | where + | T: IntoPyObject<'py>, + | ^^^^^^^^^^^^^^^^^ required by this bound in `UnknownReturnType::::wrap` error[E0599]: no method named `map_err` found for struct `Blah` in the current scope --> tests/ui/missing_intopy.rs:4:14 diff --git a/tests/ui/not_send.stderr b/tests/ui/not_send.stderr index f5f5d271473..d43252da722 100644 --- a/tests/ui/not_send.stderr +++ b/tests/ui/not_send.stderr @@ -13,21 +13,21 @@ note: required because it appears within the type `PhantomData<*mut pyo3::Python 814 | pub struct PhantomData; | ^^^^^^^^^^^ note: required because it appears within the type `pyo3::marker::NotSend` - --> src/marker.rs:358:8 - | -358 | struct NotSend(PhantomData<*mut Python<'static>>); - | ^^^^^^^ + --> src/marker.rs + | + | struct NotSend(PhantomData<*mut Python<'static>>); + | ^^^^^^^ note: required because it appears within the type `PhantomData` ../src/library/core/src/marker.rs:814:12 | 814 | pub struct PhantomData; | ^^^^^^^^^^^ note: required because it appears within the type `pyo3::Python<'_>` - --> src/marker.rs:354:12 - | -354 | pub struct Python<'py>(PhantomData<&'py AttachGuard>, PhantomData); - | ^^^^^^ - = note: required for `&pyo3::Python<'_>` to implement `Send` + --> src/marker.rs + | + | pub struct Python<'py>(PhantomData<&'py AttachGuard>, PhantomData); + | ^^^^^^ + = note: required for `&pyo3::Python<'_>` to implement `Send` note: required because it's used within this closure --> tests/ui/not_send.rs:5:15 | @@ -35,13 +35,13 @@ note: required because it's used within this closure | ^^ = note: required for `{closure@tests/ui/not_send.rs:5:15: 5:17}` to implement `Ungil` note: required by a bound in `pyo3::Python::<'py>::detach` - --> src/marker.rs:560:12 - | -558 | pub fn detach(self, f: F) -> T - | ------ required by a bound in this associated function -559 | where -560 | F: Ungil + FnOnce() -> T, - | ^^^^^ required by this bound in `Python::<'py>::detach` + --> src/marker.rs + | + | pub fn detach(self, f: F) -> T + | ------ required by a bound in this associated function + | where + | F: Ungil + FnOnce() -> T, + | ^^^^^ required by this bound in `Python::<'py>::detach` error: aborting due to 1 previous error diff --git a/tests/ui/not_send2.stderr b/tests/ui/not_send2.stderr index 899a73c479f..7124e0c4852 100644 --- a/tests/ui/not_send2.stderr +++ b/tests/ui/not_send2.stderr @@ -17,26 +17,26 @@ note: required because it appears within the type `PhantomData<*mut pyo3::Python 814 | pub struct PhantomData; | ^^^^^^^^^^^ note: required because it appears within the type `pyo3::marker::NotSend` - --> src/marker.rs:358:8 - | -358 | struct NotSend(PhantomData<*mut Python<'static>>); - | ^^^^^^^ + --> src/marker.rs + | + | struct NotSend(PhantomData<*mut Python<'static>>); + | ^^^^^^^ note: required because it appears within the type `PhantomData` ../src/library/core/src/marker.rs:814:12 | 814 | pub struct PhantomData; | ^^^^^^^^^^^ note: required because it appears within the type `pyo3::Python<'_>` - --> src/marker.rs:354:12 - | -354 | pub struct Python<'py>(PhantomData<&'py AttachGuard>, PhantomData); - | ^^^^^^ + --> src/marker.rs + | + | pub struct Python<'py>(PhantomData<&'py AttachGuard>, PhantomData); + | ^^^^^^ note: required because it appears within the type `pyo3::Bound<'_, PyString>` - --> src/instance.rs:75:12 - | - 75 | pub struct Bound<'py, T>(Python<'py>, ManuallyDrop>); - | ^^^^^ - = note: required for `&pyo3::Bound<'_, PyString>` to implement `Send` + --> src/instance.rs + | + | pub struct Bound<'py, T>(Python<'py>, ManuallyDrop>); + | ^^^^^ + = note: required for `&pyo3::Bound<'_, PyString>` to implement `Send` note: required because it's used within this closure --> tests/ui/not_send2.rs:9:19 | @@ -44,13 +44,13 @@ note: required because it's used within this closure | ^^ = note: required for `{closure@tests/ui/not_send2.rs:9:19: 9:21}` to implement `Ungil` note: required by a bound in `pyo3::Python::<'py>::detach` - --> src/marker.rs:560:12 - | -558 | pub fn detach(self, f: F) -> T - | ------ required by a bound in this associated function -559 | where -560 | F: Ungil + FnOnce() -> T, - | ^^^^^ required by this bound in `Python::<'py>::detach` + --> src/marker.rs + | + | pub fn detach(self, f: F) -> T + | ------ required by a bound in this associated function + | where + | F: Ungil + FnOnce() -> T, + | ^^^^^ required by this bound in `Python::<'py>::detach` error: aborting due to 1 previous error diff --git a/tests/ui/pyclass_send.stderr b/tests/ui/pyclass_send.stderr index 1a87c142f93..351552f0c99 100644 --- a/tests/ui/pyclass_send.stderr +++ b/tests/ui/pyclass_send.stderr @@ -11,12 +11,12 @@ note: required because it appears within the type `NotSyncNotSend` 5 | struct NotSyncNotSend(*mut c_void); | ^^^^^^^^^^^^^^ note: required by a bound in `pyo3::impl_::pyclass::assertions::assert_pyclass_send_sync` - --> src/impl_/pyclass/assertions.rs:6:8 + --> src/impl_/pyclass/assertions.rs | -4 | pub const fn assert_pyclass_send_sync() + | pub const fn assert_pyclass_send_sync() | ------------------------ required by a bound in this function -5 | where -6 | T: Send + Sync, + | where + | T: Send + Sync, | ^^^^ required by this bound in `assert_pyclass_send_sync` error[E0277]: `*mut c_void` cannot be shared between threads safely @@ -32,12 +32,12 @@ note: required because it appears within the type `NotSyncNotSend` 5 | struct NotSyncNotSend(*mut c_void); | ^^^^^^^^^^^^^^ note: required by a bound in `pyo3::impl_::pyclass::assertions::assert_pyclass_send_sync` - --> src/impl_/pyclass/assertions.rs:6:15 + --> src/impl_/pyclass/assertions.rs | -4 | pub const fn assert_pyclass_send_sync() + | pub const fn assert_pyclass_send_sync() | ------------------------ required by a bound in this function -5 | where -6 | T: Send + Sync, + | where + | T: Send + Sync, | ^^^^ required by this bound in `assert_pyclass_send_sync` error[E0277]: `*mut c_void` cannot be shared between threads safely @@ -53,13 +53,13 @@ note: required because it appears within the type `SendNotSync` 10 | struct SendNotSync(*mut c_void); | ^^^^^^^^^^^ note: required by a bound in `pyo3::impl_::pyclass::assertions::assert_pyclass_send_sync` - --> src/impl_/pyclass/assertions.rs:6:15 - | - 4 | pub const fn assert_pyclass_send_sync() - | ------------------------ required by a bound in this function - 5 | where - 6 | T: Send + Sync, - | ^^^^ required by this bound in `assert_pyclass_send_sync` + --> src/impl_/pyclass/assertions.rs + | + | pub const fn assert_pyclass_send_sync() + | ------------------------ required by a bound in this function + | where + | T: Send + Sync, + | ^^^^ required by this bound in `assert_pyclass_send_sync` error[E0277]: `*mut c_void` cannot be sent between threads safely --> tests/ui/pyclass_send.rs:15:8 @@ -74,13 +74,13 @@ note: required because it appears within the type `SyncNotSend` 15 | struct SyncNotSend(*mut c_void); | ^^^^^^^^^^^ note: required by a bound in `pyo3::impl_::pyclass::assertions::assert_pyclass_send_sync` - --> src/impl_/pyclass/assertions.rs:6:8 - | - 4 | pub const fn assert_pyclass_send_sync() - | ------------------------ required by a bound in this function - 5 | where - 6 | T: Send + Sync, - | ^^^^ required by this bound in `assert_pyclass_send_sync` + --> src/impl_/pyclass/assertions.rs + | + | pub const fn assert_pyclass_send_sync() + | ------------------------ required by a bound in this function + | where + | T: Send + Sync, + | ^^^^ required by this bound in `assert_pyclass_send_sync` error: aborting due to 4 previous errors From 2a5beec077a9ec7febca6c8635b0738125f95b95 Mon Sep 17 00:00:00 2001 From: David Hewitt Date: Sat, 2 May 2026 10:33:30 +0100 Subject: [PATCH 20/21] bless changes on 3.10 --- tests/ui/abi3_inheritance.stderr | 48 +++++------------- tests/ui/abi3_nativetype_inheritance.stderr | 56 +++++++-------------- tests/ui/invalid_result_conversion.stderr | 2 +- 3 files changed, 31 insertions(+), 75 deletions(-) diff --git a/tests/ui/abi3_inheritance.stderr b/tests/ui/abi3_inheritance.stderr index 255dd0d1264..ea3f82ce1c9 100644 --- a/tests/ui/abi3_inheritance.stderr +++ b/tests/ui/abi3_inheritance.stderr @@ -1,49 +1,28 @@ error[E0277]: pyclass `PyException` cannot be subclassed - --> tests/ui/abi3_inheritance.rs:4:1 - | -4 | #[pyclass(extends=PyException)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required for `#[pyclass(extends=PyException)]` - | - = help: the trait `pyo3::impl_::pyclass::PyClassBaseType` is not implemented for `PyException` - = note: `PyException` must have `#[pyclass(subclass)]` to be eligible for subclassing - = note: subclassing native types requires Python >= 3.12 when using the `abi3` feature -<<<<<<< HEAD -help: the trait `PyClassBaseType` is implemented for `PyAny` - --> src/types/any.rs:55:1 + --> tests/ui/abi3_inheritance.rs:4:1 | -55 | impl crate::impl_::pyclass::PyClassBaseType for PyAny { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: this error originates in the attribute macro `pyclass` (in Nightly builds, run with -Z macro-backtrace for more info) -======= + 4 | #[pyclass(extends=PyException)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required for `#[pyclass(extends=PyException)]` + | + = help: the trait `pyo3::impl_::pyclass::PyClassBaseType` is not implemented for `PyException` + = note: `PyException` must have `#[pyclass(subclass)]` to be eligible for subclassing + = note: subclassing native types requires Python >= 3.12 when using the `abi3` feature help: the trait `pyo3::impl_::pyclass::PyClassBaseType` is implemented for `PyAny` --> src/types/any.rs | | impl crate::impl_::pyclass::PyClassBaseType for PyAny { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: this error originates in the attribute macro `pyclass` (in Nightly builds, run with -Z macro-backtrace for more info) ->>>>>>> main error[E0277]: pyclass `PyException` cannot be subclassed - --> tests/ui/abi3_inheritance.rs:4:19 - | -4 | #[pyclass(extends=PyException)] - | ^^^^^^^^^^^ required for `#[pyclass(extends=PyException)]` - | - = help: the trait `pyo3::impl_::pyclass::PyClassBaseType` is not implemented for `PyException` - = note: `PyException` must have `#[pyclass(subclass)]` to be eligible for subclassing - = note: subclassing native types requires Python >= 3.12 when using the `abi3` feature -<<<<<<< HEAD -help: the trait `PyClassBaseType` is implemented for `PyAny` - --> src/types/any.rs:55:1 + --> tests/ui/abi3_inheritance.rs:4:19 | - 55 | impl crate::impl_::pyclass::PyClassBaseType for PyAny { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: required by a bound in `PyClassImpl::BaseType` - --> src/impl_/pyclass.rs:184:33 + 4 | #[pyclass(extends=PyException)] + | ^^^^^^^^^^^ required for `#[pyclass(extends=PyException)]` | -184 | type BaseType: PyTypeInfo + PyClassBaseType; - | ^^^^^^^^^^^^^^^ required by this bound in `PyClassImpl::BaseType` -======= + = help: the trait `pyo3::impl_::pyclass::PyClassBaseType` is not implemented for `PyException` + = note: `PyException` must have `#[pyclass(subclass)]` to be eligible for subclassing + = note: subclassing native types requires Python >= 3.12 when using the `abi3` feature help: the trait `pyo3::impl_::pyclass::PyClassBaseType` is implemented for `PyAny` --> src/types/any.rs | @@ -54,7 +33,6 @@ note: required by a bound in `pyo3::impl_::pyclass::PyClassImpl::BaseType` | | type BaseType: PyTypeInfo + PyClassBaseType; | ^^^^^^^^^^^^^^^ required by this bound in `PyClassImpl::BaseType` ->>>>>>> main warning: use of deprecated associated constant `pyo3::impl_::deprecated::HasAutomaticFromPyObject::::MSG`: The `FromPyObject` implementation for `#[pyclass]` types which implement `Clone` is changing to an opt-in option. Use `#[pyclass(from_py_object)]` to opt-in to the `FromPyObject` derive now, or `#[pyclass(skip_from_py_object)]` to skip the `FromPyObject` implementation. --> tests/ui/abi3_inheritance.rs:4:1 diff --git a/tests/ui/abi3_nativetype_inheritance.stderr b/tests/ui/abi3_nativetype_inheritance.stderr index 72d6548fd8e..774c4df2261 100644 --- a/tests/ui/abi3_nativetype_inheritance.stderr +++ b/tests/ui/abi3_nativetype_inheritance.stderr @@ -1,53 +1,28 @@ error[E0277]: pyclass `PyDict` cannot be subclassed - --> tests/ui/abi3_nativetype_inheritance.rs:5:1 - | -5 | #[pyclass(extends=PyDict)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ required for `#[pyclass(extends=PyDict)]` - | - = help: the trait `pyo3::impl_::pyclass::PyClassBaseType` is not implemented for `PyDict` - = note: `PyDict` must have `#[pyclass(subclass)]` to be eligible for subclassing - = note: subclassing native types requires Python >= 3.12 when using the `abi3` feature -<<<<<<< HEAD -help: the trait `PyClassBaseType` is implemented for `PyAny` - --> src/types/any.rs:55:1 + --> tests/ui/abi3_nativetype_inheritance.rs:5:1 | -55 | impl crate::impl_::pyclass::PyClassBaseType for PyAny { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: this error originates in the attribute macro `pyclass` (in Nightly builds, run with -Z macro-backtrace for more info) -======= + 5 | #[pyclass(extends=PyDict)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ required for `#[pyclass(extends=PyDict)]` + | + = help: the trait `pyo3::impl_::pyclass::PyClassBaseType` is not implemented for `PyDict` + = note: `PyDict` must have `#[pyclass(subclass)]` to be eligible for subclassing + = note: subclassing native types requires Python >= 3.12 when using the `abi3` feature help: the trait `pyo3::impl_::pyclass::PyClassBaseType` is implemented for `PyAny` --> src/types/any.rs | | impl crate::impl_::pyclass::PyClassBaseType for PyAny { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: this error originates in the attribute macro `pyclass` (in Nightly builds, run with -Z macro-backtrace for more info) ->>>>>>> main error[E0277]: pyclass `PyDict` cannot be subclassed - --> tests/ui/abi3_nativetype_inheritance.rs:5:19 - | -5 | #[pyclass(extends=PyDict)] - | ^^^^^^ required for `#[pyclass(extends=PyDict)]` - | - = help: the trait `pyo3::impl_::pyclass::PyClassBaseType` is not implemented for `PyDict` - = note: `PyDict` must have `#[pyclass(subclass)]` to be eligible for subclassing - = note: subclassing native types requires Python >= 3.12 when using the `abi3` feature -<<<<<<< HEAD -help: the trait `PyClassBaseType` is implemented for `PyAny` - --> src/types/any.rs:55:1 + --> tests/ui/abi3_nativetype_inheritance.rs:5:19 | - 55 | impl crate::impl_::pyclass::PyClassBaseType for PyAny { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: required by a bound in `PyClassImpl::BaseType` - --> src/impl_/pyclass.rs:184:33 + 5 | #[pyclass(extends=PyDict)] + | ^^^^^^ required for `#[pyclass(extends=PyDict)]` | -184 | type BaseType: PyTypeInfo + PyClassBaseType; - | ^^^^^^^^^^^^^^^ required by this bound in `PyClassImpl::BaseType` - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0277`. -======= + = help: the trait `pyo3::impl_::pyclass::PyClassBaseType` is not implemented for `PyDict` + = note: `PyDict` must have `#[pyclass(subclass)]` to be eligible for subclassing + = note: subclassing native types requires Python >= 3.12 when using the `abi3` feature help: the trait `pyo3::impl_::pyclass::PyClassBaseType` is implemented for `PyAny` --> src/types/any.rs | @@ -58,4 +33,7 @@ note: required by a bound in `pyo3::impl_::pyclass::PyClassImpl::BaseType` | | type BaseType: PyTypeInfo + PyClassBaseType; | ^^^^^^^^^^^^^^^ required by this bound in `PyClassImpl::BaseType` ->>>>>>> main + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/invalid_result_conversion.stderr b/tests/ui/invalid_result_conversion.stderr index 6c046f92f70..3cb6322b53e 100644 --- a/tests/ui/invalid_result_conversion.stderr +++ b/tests/ui/invalid_result_conversion.stderr @@ -8,11 +8,11 @@ error[E0277]: the trait bound `PyErr: From` is not satisfied `PyErr` implements `From` `PyErr` implements `From>` `PyErr` implements `From>` + `PyErr` implements `From` `PyErr` implements `From>` `PyErr` implements `From>` `PyErr` implements `From` `PyErr` implements `From` - `PyErr` implements `From>` and $N others = note: required for `MyError` to implement `Into` From 027d8fbf92a3a0be016f75182acee600206db80b Mon Sep 17 00:00:00 2001 From: David Hewitt Date: Sat, 2 May 2026 10:35:23 +0100 Subject: [PATCH 21/21] bless tests on 3.14 --- tests/ui/invalid_base_class.stderr | 47 +++++------------------------- 1 file changed, 8 insertions(+), 39 deletions(-) diff --git a/tests/ui/invalid_base_class.stderr b/tests/ui/invalid_base_class.stderr index 2e9bd42fd6f..2759ef588fb 100644 --- a/tests/ui/invalid_base_class.stderr +++ b/tests/ui/invalid_base_class.stderr @@ -6,12 +6,7 @@ error[E0277]: pyclass `PyBool` cannot be subclassed | = help: the trait `pyo3::impl_::pyclass::PyClassBaseType` is not implemented for `PyBool` = note: `PyBool` must have `#[pyclass(subclass)]` to be eligible for subclassing -<<<<<<< HEAD - = note: with the `abi3` feature enabled, PyO3 does not support subclassing native types - = help: the following other types implement trait `PyClassBaseType`: -======= = help: the following other types implement trait `pyo3::impl_::pyclass::PyClassBaseType`: ->>>>>>> main PyAny PyArithmeticError PyAssertionError @@ -20,20 +15,18 @@ error[E0277]: pyclass `PyBool` cannot be subclassed PyBaseExceptionGroup PyBlockingIOError PyBrokenPipeError - and 63 others + and $N others = note: this error originates in the attribute macro `pyclass` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: pyclass `PyBool` cannot be subclassed -<<<<<<< HEAD --> tests/ui/invalid_base_class.rs:4:19 | 4 | #[pyclass(extends=PyBool)] | ^^^^^^ required for `#[pyclass(extends=PyBool)]` | - = help: the trait `PyClassBaseType` is not implemented for `PyBool` + = help: the trait `pyo3::impl_::pyclass::PyClassBaseType` is not implemented for `PyBool` = note: `PyBool` must have `#[pyclass(subclass)]` to be eligible for subclassing - = note: with the `abi3` feature enabled, PyO3 does not support subclassing native types - = help: the following other types implement trait `PyClassBaseType`: + = help: the following other types implement trait `pyo3::impl_::pyclass::PyClassBaseType`: PyAny PyArithmeticError PyAssertionError @@ -42,37 +35,13 @@ error[E0277]: pyclass `PyBool` cannot be subclassed PyBaseExceptionGroup PyBlockingIOError PyBrokenPipeError - and 63 others -note: required by a bound in `PyClassImpl::BaseType` - --> src/impl_/pyclass.rs:184:33 - | -184 | type BaseType: PyTypeInfo + PyClassBaseType; - | ^^^^^^^^^^^^^^^ required by this bound in `PyClassImpl::BaseType` - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0277`. -======= - --> tests/ui/invalid_base_class.rs:4:19 - | -4 | #[pyclass(extends=PyBool)] - | ^^^^^^ required for `#[pyclass(extends=PyBool)]` - | - = help: the trait `pyo3::impl_::pyclass::PyClassBaseType` is not implemented for `PyBool` - = note: `PyBool` must have `#[pyclass(subclass)]` to be eligible for subclassing - = help: the following other types implement trait `pyo3::impl_::pyclass::PyClassBaseType`: - PyAny - PyArithmeticError - PyAssertionError - PyAttributeError - PyBaseException - PyBaseExceptionGroup - PyBlockingIOError - PyBrokenPipeError - and $N others + and $N others note: required by a bound in `pyo3::impl_::pyclass::PyClassImpl::BaseType` --> src/impl_/pyclass.rs | | type BaseType: PyTypeInfo + PyClassBaseType; | ^^^^^^^^^^^^^^^ required by this bound in `PyClassImpl::BaseType` ->>>>>>> main + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`.