mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
rust: pin-init: add diagnostic attribute for PinInit and Init
Give a slightly more useful error message when these traits are not
implemented.
Before this change:
error[E0277]: the trait bound `impl pin_init::PinInit<Bar>: Init<Bar, _>` is not satisfied
--> tests/ui/compile-fail/init/invalid_init.rs:19:16
|
19 | bar <- Bar::new(),
| -------^^^^^^^^^^
| | |
| | the trait `Init<Bar, _>` is not implemented for `impl pin_init::PinInit<Bar>`
| required by a bound introduced by this call
After this change:
error[E0277]: `impl pin_init::PinInit<Bar>` cannot be used to movably initialize `Bar` with error `_`
--> tests/ui/compile-fail/init/invalid_init.rs:19:16
|
19 | bar <- Bar::new(),
| -------^^^^^^^^^^
| | |
| | the trait `Init<Bar, _>` is not implemented for `impl pin_init::PinInit<Bar>`
| required by a bound introduced by this call
|
= note: if your type implements `PinInit` but not `Init`, you might be forgetting a `#[pin]` annotation on fields
Ideally, we would generate differnet message when `PinInit` is implemented
but not `Init`; that is not feasible with today's
`diagnostics::on_unimplemented` attribute. However, the added note is worth
it because in `init!()` is more rarely used compared to `pin_init!()`; in
most cases `Init` being unimplemented is the result of missing `#[pin]`.
Link: https://patch.msgid.link/20260923-dev-pin-data-diag-v1-5-e4d7193569e5@garyguo.net
Signed-off-by: Gary Guo <gary@garyguo.net>
This commit is contained in:
parent
6f78441c58
commit
666b3e7cfa
|
|
@ -966,6 +966,9 @@ macro_rules! assert_pinned {
|
|||
#[cfg_attr(not(kernel), doc = "[`Arc<T>`]: alloc::alloc::sync::Arc")]
|
||||
#[cfg_attr(not(kernel), doc = "[`Box<T>`]: alloc::alloc::boxed::Box")]
|
||||
#[must_use = "An initializer must be used in order to create its value."]
|
||||
#[diagnostic::on_unimplemented(
|
||||
message = "`{Self}` cannot be used to initialize `{T}` with error `{E}`"
|
||||
)]
|
||||
pub unsafe trait PinInit<T: ?Sized, E = Infallible>: Sized {
|
||||
/// Alias of [`PinInit::__init`].
|
||||
///
|
||||
|
|
@ -1100,6 +1103,11 @@ unsafe fn __init(self, slot: *mut T) -> Result<(), E> {
|
|||
#[cfg_attr(not(kernel), doc = "[`Arc<T>`]: alloc::alloc::sync::Arc")]
|
||||
#[cfg_attr(not(kernel), doc = "[`Box<T>`]: alloc::alloc::boxed::Box")]
|
||||
#[must_use = "An initializer must be used in order to create its value."]
|
||||
#[diagnostic::on_unimplemented(
|
||||
message = "`{Self}` cannot be used to movably initialize `{T}` with error `{E}`",
|
||||
note = "if your type implements `PinInit` but not `Init`, \
|
||||
you might be forgetting a `#[pin]` annotation on fields"
|
||||
)]
|
||||
pub unsafe trait Init<T: ?Sized, E = Infallible>: PinInit<T, E> {
|
||||
/// First initializes the value using `self` then calls the function `f` with the initialized
|
||||
/// value.
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user