Emit a better error for abi3 inheritance (#4185)
* Emit a better error for abi3 inheritance * Update tests/test_compile_error.rs --------- Co-authored-by: David Hewitt <mail@davidhewitt.dev>
This commit is contained in:
parent
1c64a03ea0
commit
fff053bde7
|
@ -140,6 +140,10 @@ pub fn print_feature_cfgs() {
|
||||||
if rustc_minor_version >= 74 {
|
if rustc_minor_version >= 74 {
|
||||||
println!("cargo:rustc-cfg=invalid_from_utf8_lint");
|
println!("cargo:rustc-cfg=invalid_from_utf8_lint");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if rustc_minor_version >= 78 {
|
||||||
|
println!("cargo:rustc-cfg=diagnostic_namespace");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Registers `pyo3`s config names as reachable cfg expressions
|
/// Registers `pyo3`s config names as reachable cfg expressions
|
||||||
|
@ -160,6 +164,7 @@ pub fn print_expected_cfgs() {
|
||||||
println!("cargo:rustc-check-cfg=cfg(invalid_from_utf8_lint)");
|
println!("cargo:rustc-check-cfg=cfg(invalid_from_utf8_lint)");
|
||||||
println!("cargo:rustc-check-cfg=cfg(pyo3_disable_reference_pool)");
|
println!("cargo:rustc-check-cfg=cfg(pyo3_disable_reference_pool)");
|
||||||
println!("cargo:rustc-check-cfg=cfg(pyo3_leak_on_drop_without_reference_pool)");
|
println!("cargo:rustc-check-cfg=cfg(pyo3_leak_on_drop_without_reference_pool)");
|
||||||
|
println!("cargo:rustc-check-cfg=cfg(diagnostic_namespace)");
|
||||||
|
|
||||||
// allow `Py_3_*` cfgs from the minimum supported version up to the
|
// allow `Py_3_*` cfgs from the minimum supported version up to the
|
||||||
// maximum minor version (+1 for development for the next)
|
// maximum minor version (+1 for development for the next)
|
||||||
|
|
|
@ -1102,6 +1102,13 @@ impl<T> PyClassThreadChecker<T> for ThreadCheckerImpl {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Trait denoting that this class is suitable to be used as a base type for PyClass.
|
/// Trait denoting that this class is suitable to be used as a base type for PyClass.
|
||||||
|
|
||||||
|
#[cfg_attr(
|
||||||
|
all(diagnostic_namespace, feature = "abi3"),
|
||||||
|
diagnostic::on_unimplemented(
|
||||||
|
note = "with the `abi3` feature enabled, PyO3 does not support subclassing native types"
|
||||||
|
)
|
||||||
|
)]
|
||||||
pub trait PyClassBaseType: Sized {
|
pub trait PyClassBaseType: Sized {
|
||||||
type LayoutAsBase: PyClassObjectLayout<Self>;
|
type LayoutAsBase: PyClassObjectLayout<Self>;
|
||||||
type BaseNativeType;
|
type BaseNativeType;
|
||||||
|
|
|
@ -64,4 +64,7 @@ fn test_compile_errors() {
|
||||||
#[cfg(any(not(Py_LIMITED_API), Py_3_10))] // to avoid PyFunctionArgument for &str
|
#[cfg(any(not(Py_LIMITED_API), Py_3_10))] // to avoid PyFunctionArgument for &str
|
||||||
t.compile_fail("tests/ui/invalid_cancel_handle.rs");
|
t.compile_fail("tests/ui/invalid_cancel_handle.rs");
|
||||||
t.pass("tests/ui/pymodule_missing_docs.rs");
|
t.pass("tests/ui/pymodule_missing_docs.rs");
|
||||||
|
#[cfg(all(Py_LIMITED_API, not(feature = "experimental-async")))]
|
||||||
|
// output changes with async feature
|
||||||
|
t.compile_fail("tests/ui/abi3_inheritance.rs");
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
use pyo3::exceptions::PyException;
|
||||||
|
use pyo3::prelude::*;
|
||||||
|
|
||||||
|
#[pyclass(extends=PyException)]
|
||||||
|
#[derive(Clone)]
|
||||||
|
struct MyException {
|
||||||
|
code: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
|
@ -0,0 +1,24 @@
|
||||||
|
error[E0277]: the trait bound `PyException: PyClassBaseType` is not satisfied
|
||||||
|
--> tests/ui/abi3_inheritance.rs:4:19
|
||||||
|
|
|
||||||
|
4 | #[pyclass(extends=PyException)]
|
||||||
|
| ^^^^^^^^^^^ the trait `PyClass` is not implemented for `PyException`, which is required by `PyException: PyClassBaseType`
|
||||||
|
|
|
||||||
|
= note: with the `abi3` feature enabled, PyO3 does not support subclassing native types
|
||||||
|
= help: the trait `PyClassBaseType` is implemented for `PyAny`
|
||||||
|
= note: required for `PyException` to implement `PyClassBaseType`
|
||||||
|
note: required by a bound in `PyClassImpl::BaseType`
|
||||||
|
--> src/impl_/pyclass.rs
|
||||||
|
|
|
||||||
|
| type BaseType: PyTypeInfo + PyClassBaseType;
|
||||||
|
| ^^^^^^^^^^^^^^^ required by this bound in `PyClassImpl::BaseType`
|
||||||
|
|
||||||
|
error[E0277]: the trait bound `PyException: PyClass` is not satisfied
|
||||||
|
--> tests/ui/abi3_inheritance.rs:4:1
|
||||||
|
|
|
||||||
|
4 | #[pyclass(extends=PyException)]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `PyClass` is not implemented for `PyException`, which is required by `PyException: PyClassBaseType`
|
||||||
|
|
|
||||||
|
= help: the trait `PyClass` is implemented for `MyException`
|
||||||
|
= note: required for `PyException` to implement `PyClassBaseType`
|
||||||
|
= note: this error originates in the attribute macro `pyclass` (in Nightly builds, run with -Z macro-backtrace for more info)
|
|
@ -4,6 +4,7 @@ error[E0277]: the trait bound `PyDict: PyClassBaseType` is not satisfied
|
||||||
5 | #[pyclass(extends=PyDict)]
|
5 | #[pyclass(extends=PyDict)]
|
||||||
| ^^^^^^ the trait `PyClass` is not implemented for `PyDict`, which is required by `PyDict: PyClassBaseType`
|
| ^^^^^^ the trait `PyClass` is not implemented for `PyDict`, which is required by `PyDict: PyClassBaseType`
|
||||||
|
|
|
|
||||||
|
= note: with the `abi3` feature enabled, PyO3 does not support subclassing native types
|
||||||
= help: the trait `PyClassBaseType` is implemented for `PyAny`
|
= help: the trait `PyClassBaseType` is implemented for `PyAny`
|
||||||
= note: required for `PyDict` to implement `PyClassBaseType`
|
= note: required for `PyDict` to implement `PyClassBaseType`
|
||||||
note: required by a bound in `PyClassImpl::BaseType`
|
note: required by a bound in `PyClassImpl::BaseType`
|
||||||
|
|
Loading…
Reference in New Issue