Skip to content

Commit a40f8a7

Browse files
committed
remove try_ versions of the initializer macros
The `try_[pin_]init!` versions of the initializer macros are superfluous. Instead of forcing the user to always write an error in `try_[pin_]init!` and not allowing one in `[pin_]init!`, combine them into `[pin_]init!` that defaults the error to `core::convert::Infallible`, but also allows to specify a custom one. Projects using pin-init still can provide their own defaulting initializers using the `try_` prefix. Signed-off-by: Benno Lossin <lossin@kernel.org>
1 parent 252dc48 commit a40f8a7

14 files changed

+48
-135
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ struct DriverData {
135135

136136
impl DriverData {
137137
fn new() -> impl PinInit<Self, Error> {
138-
try_pin_init!(Self {
138+
pin_init!(Self {
139139
status <- CMutex::new(0),
140140
buffer: Box::init(pin_init::init_zeroed())?,
141141
}? Error)

examples/linked_list.rs

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66

77
use core::{
88
cell::Cell,
9-
convert::Infallible,
109
marker::PhantomPinned,
1110
pin::Pin,
1211
ptr::{self, NonNull},
@@ -31,31 +30,31 @@ pub struct ListHead {
3130

3231
impl ListHead {
3332
#[inline]
34-
pub fn new() -> impl PinInit<Self, Infallible> {
35-
try_pin_init!(&this in Self {
33+
pub fn new() -> impl PinInit<Self> {
34+
pin_init!(&this in Self {
3635
next: unsafe { Link::new_unchecked(this) },
3736
prev: unsafe { Link::new_unchecked(this) },
3837
pin: PhantomPinned,
39-
}? Infallible)
38+
})
4039
}
4140

4241
#[inline]
4342
#[allow(dead_code)]
44-
pub fn insert_next(list: &ListHead) -> impl PinInit<Self, Infallible> + '_ {
45-
try_pin_init!(&this in Self {
43+
pub fn insert_next(list: &ListHead) -> impl PinInit<Self> + '_ {
44+
pin_init!(&this in Self {
4645
prev: list.next.prev().replace(unsafe { Link::new_unchecked(this)}),
4746
next: list.next.replace(unsafe { Link::new_unchecked(this)}),
4847
pin: PhantomPinned,
49-
}? Infallible)
48+
})
5049
}
5150

5251
#[inline]
53-
pub fn insert_prev(list: &ListHead) -> impl PinInit<Self, Infallible> + '_ {
54-
try_pin_init!(&this in Self {
52+
pub fn insert_prev(list: &ListHead) -> impl PinInit<Self> + '_ {
53+
pin_init!(&this in Self {
5554
next: list.prev.next().replace(unsafe { Link::new_unchecked(this)}),
5655
prev: list.prev.replace(unsafe { Link::new_unchecked(this)}),
5756
pin: PhantomPinned,
58-
}? Infallible)
57+
})
5958
}
6059

6160
#[inline]

examples/pthread_mutex.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -98,11 +98,11 @@ mod pthread_mtx {
9898
// SAFETY: mutex has been initialized
9999
unsafe { pin_init_from_closure(init) }
100100
}
101-
try_pin_init!(Self {
102-
data: UnsafeCell::new(data),
103-
raw <- init_raw(),
104-
pin: PhantomPinned,
105-
}? Error)
101+
pin_init!(Self {
102+
data: UnsafeCell::new(data),
103+
raw <- init_raw(),
104+
pin: PhantomPinned,
105+
}? Error)
106106
}
107107

108108
#[allow(dead_code)]

src/lib.rs

Lines changed: 12 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@
146146
//!
147147
//! impl DriverData {
148148
//! fn new() -> impl PinInit<Self, Error> {
149-
//! try_pin_init!(Self {
149+
//! pin_init!(Self {
150150
//! status <- CMutex::new(0),
151151
//! buffer: Box::init(pin_init::init_zeroed())?,
152152
//! }? Error)
@@ -528,7 +528,7 @@ macro_rules! stack_pin_init {
528528
/// x: u32,
529529
/// }
530530
///
531-
/// stack_try_pin_init!(let foo: Foo = try_pin_init!(Foo {
531+
/// stack_try_pin_init!(let foo: Foo = pin_init!(Foo {
532532
/// a <- CMutex::new(42),
533533
/// b: Box::try_new(Bar {
534534
/// x: 64,
@@ -555,7 +555,7 @@ macro_rules! stack_pin_init {
555555
/// x: u32,
556556
/// }
557557
///
558-
/// stack_try_pin_init!(let foo: Foo =? try_pin_init!(Foo {
558+
/// stack_try_pin_init!(let foo: Foo =? pin_init!(Foo {
559559
/// a <- CMutex::new(42),
560560
/// b: Box::try_new(Bar {
561561
/// x: 64,
@@ -584,10 +584,10 @@ macro_rules! stack_try_pin_init {
584584
};
585585
}
586586

587-
/// Construct an in-place, pinned initializer for `struct`s.
587+
/// Construct an in-place, fallible pinned initializer for `struct`s.
588588
///
589-
/// This macro defaults the error to [`Infallible`]. If you need a different error, then use
590-
/// [`try_pin_init!`].
589+
/// The error type defaults to [`Infallible`]; if you need a different one, write `? Error` at the
590+
/// end, after the struct initializer.
591591
///
592592
/// The syntax is almost identical to that of a normal `struct` initializer:
593593
///
@@ -783,54 +783,10 @@ macro_rules! pin_init {
783783
($(&$this:ident in)? $t:ident $(::<$($generics:ty),* $(,)?>)? {
784784
$($fields:tt)*
785785
}) => {
786-
$crate::try_pin_init!($(&$this in)? $t $(::<$($generics),*>)? {
786+
$crate::pin_init!($(&$this in)? $t $(::<$($generics),*>)? {
787787
$($fields)*
788788
}? ::core::convert::Infallible)
789789
};
790-
}
791-
792-
/// Construct an in-place, fallible pinned initializer for `struct`s.
793-
///
794-
/// If the initialization can complete without error (or [`Infallible`]), then use [`pin_init!`].
795-
///
796-
/// You can use the `?` operator or use `return Err(err)` inside the initializer to stop
797-
/// initialization and return the error.
798-
///
799-
/// IMPORTANT: if you have `unsafe` code inside of the initializer you have to ensure that when
800-
/// initialization fails, the memory can be safely deallocated without any further modifications.
801-
///
802-
/// The syntax is identical to [`pin_init!`] with the following exception: you must append `? $type`
803-
/// after the `struct` initializer to specify the error type you want to use.
804-
///
805-
/// # Examples
806-
///
807-
/// ```rust
808-
/// # #![feature(allocator_api)]
809-
/// # #[path = "../examples/error.rs"] mod error; use error::Error;
810-
/// use pin_init::{pin_data, try_pin_init, PinInit, InPlaceInit, init_zeroed};
811-
///
812-
/// #[pin_data]
813-
/// struct BigBuf {
814-
/// big: Box<[u8; 1024 * 1024 * 1024]>,
815-
/// small: [u8; 1024 * 1024],
816-
/// ptr: *mut u8,
817-
/// }
818-
///
819-
/// impl BigBuf {
820-
/// fn new() -> impl PinInit<Self, Error> {
821-
/// try_pin_init!(Self {
822-
/// big: Box::init(init_zeroed())?,
823-
/// small: [0; 1024 * 1024],
824-
/// ptr: core::ptr::null_mut(),
825-
/// }? Error)
826-
/// }
827-
/// }
828-
/// # let _ = Box::pin_init(BigBuf::new());
829-
/// ```
830-
// For a detailed example of how this macro works, see the module documentation of the hidden
831-
// module `macros` inside of `macros.rs`.
832-
#[macro_export]
833-
macro_rules! try_pin_init {
834790
($(&$this:ident in)? $t:ident $(::<$($generics:ty),* $(,)?>)? {
835791
$($fields:tt)*
836792
}? $err:ty) => {
@@ -847,10 +803,10 @@ macro_rules! try_pin_init {
847803
}
848804
}
849805

850-
/// Construct an in-place initializer for `struct`s.
806+
/// Construct an in-place, fallible initializer for `struct`s.
851807
///
852-
/// This macro defaults the error to [`Infallible`]. If you need a different error, then use
853-
/// [`try_init!`].
808+
/// This macro defaults the error to [`Infallible`]; if you need a different one, write `? Error`
809+
/// at the end, after the struct initializer.
854810
///
855811
/// The syntax is identical to [`pin_init!`] and its safety caveats also apply:
856812
/// - `unsafe` code must guarantee either full initialization or return an error and allow
@@ -890,52 +846,10 @@ macro_rules! init {
890846
($(&$this:ident in)? $t:ident $(::<$($generics:ty),* $(,)?>)? {
891847
$($fields:tt)*
892848
}) => {
893-
$crate::try_init!($(&$this in)? $t $(::<$($generics),*>)? {
849+
$crate::init!($(&$this in)? $t $(::<$($generics),*>)? {
894850
$($fields)*
895851
}? ::core::convert::Infallible)
896-
}
897-
}
898-
899-
/// Construct an in-place fallible initializer for `struct`s.
900-
///
901-
/// If the initialization can complete without error (or [`Infallible`]), then use
902-
/// [`init!`].
903-
///
904-
/// The syntax is identical to [`try_pin_init!`]. You need to specify a custom error
905-
/// via `? $type` after the `struct` initializer.
906-
/// The safety caveats from [`try_pin_init!`] also apply:
907-
/// - `unsafe` code must guarantee either full initialization or return an error and allow
908-
/// deallocation of the memory.
909-
/// - the fields are initialized in the order given in the initializer.
910-
/// - no references to fields are allowed to be created inside of the initializer.
911-
///
912-
/// # Examples
913-
///
914-
/// ```rust
915-
/// # #![feature(allocator_api)]
916-
/// # use core::alloc::AllocError;
917-
/// # use pin_init::InPlaceInit;
918-
/// use pin_init::{try_init, Init, init_zeroed};
919-
///
920-
/// struct BigBuf {
921-
/// big: Box<[u8; 1024 * 1024 * 1024]>,
922-
/// small: [u8; 1024 * 1024],
923-
/// }
924-
///
925-
/// impl BigBuf {
926-
/// fn new() -> impl Init<Self, AllocError> {
927-
/// try_init!(Self {
928-
/// big: Box::init(init_zeroed())?,
929-
/// small: [0; 1024 * 1024],
930-
/// }? AllocError)
931-
/// }
932-
/// }
933-
/// # let _ = Box::init(BigBuf::new());
934-
/// ```
935-
// For a detailed example of how this macro works, see the module documentation of the hidden
936-
// module `macros` inside of `macros.rs`.
937-
#[macro_export]
938-
macro_rules! try_init {
852+
};
939853
($(&$this:ident in)? $t:ident $(::<$($generics:ty),* $(,)?>)? {
940854
$($fields:tt)*
941855
}? $err:ty) => {

tests/ring_buf.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ pub struct EvenU64 {
166166
impl EvenU64 {
167167
#[allow(clippy::manual_is_multiple_of)]
168168
pub fn new2(value: u64) -> impl Init<Self, Error> {
169-
try_init!(Self {
169+
init!(Self {
170170
info: "Hello world!".to_owned(),
171171
data: if value % 2 == 0 {
172172
value
@@ -178,7 +178,7 @@ impl EvenU64 {
178178

179179
#[allow(clippy::manual_is_multiple_of)]
180180
pub fn new(value: u64) -> impl Init<Self, ()> {
181-
try_init!(Self {
181+
init!(Self {
182182
info: "Hello world!".to_owned(),
183183
data: if value % 2 == 0 {
184184
value

tests/ui/compile-fail/init/missing_error_type.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,5 @@ struct Foo {
55
}
66

77
fn main() {
8-
let _ = try_init!(Foo { x: Box::new(0)? }?);
8+
let _ = init!(Foo { x: Box::new(0)? }?);
99
}

tests/ui/compile-fail/init/missing_error_type.stderr

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
error: unexpected end of macro invocation
2-
--> tests/ui/compile-fail/init/missing_error_type.rs:8:47
2+
--> tests/ui/compile-fail/init/missing_error_type.rs:8:43
33
|
4-
8 | let _ = try_init!(Foo { x: Box::new(0)? }?);
5-
| ^ missing tokens in macro arguments
4+
8 | let _ = init!(Foo { x: Box::new(0)? }?);
5+
| ^ missing tokens in macro arguments
66
|
77
note: while trying to match meta-variable `$err:ty`
88
--> src/lib.rs

tests/ui/compile-fail/init/missing_field.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ struct Foo {
99

1010
fn main() {
1111
let _foo = pin_init!(Foo { a: 0 });
12-
let _foo = try_pin_init!(Foo { a: 0 }? ::std::convert::Infallible);
12+
let _foo = pin_init!(Foo { a: 0 }? ::std::convert::Infallible);
1313
let _foo = init!(Foo { a: 0 });
14-
let _foo = try_init!(Foo { a: 0 }? ::std::convert::Infallible);
14+
let _foo = init!(Foo { a: 0 }? ::std::convert::Infallible);
1515
}

tests/ui/compile-fail/init/missing_field.stderr

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@ error[E0063]: missing field `b` in initializer of `Foo`
55
| ^^^ missing `b`
66

77
error[E0063]: missing field `b` in initializer of `Foo`
8-
--> tests/ui/compile-fail/init/missing_field.rs:12:30
8+
--> tests/ui/compile-fail/init/missing_field.rs:12:26
99
|
10-
12 | let _foo = try_pin_init!(Foo { a: 0 }? ::std::convert::Infallible);
11-
| ^^^ missing `b`
10+
12 | let _foo = pin_init!(Foo { a: 0 }? ::std::convert::Infallible);
11+
| ^^^ missing `b`
1212

1313
error[E0063]: missing field `b` in initializer of `Foo`
1414
--> tests/ui/compile-fail/init/missing_field.rs:13:22
@@ -17,7 +17,7 @@ error[E0063]: missing field `b` in initializer of `Foo`
1717
| ^^^ missing `b`
1818

1919
error[E0063]: missing field `b` in initializer of `Foo`
20-
--> tests/ui/compile-fail/init/missing_field.rs:14:26
20+
--> tests/ui/compile-fail/init/missing_field.rs:14:22
2121
|
22-
14 | let _foo = try_init!(Foo { a: 0 }? ::std::convert::Infallible);
23-
| ^^^ missing `b`
22+
14 | let _foo = init!(Foo { a: 0 }? ::std::convert::Infallible);
23+
| ^^^ missing `b`

tests/ui/compile-fail/init/missing_pin_data.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,4 @@ error[E0599]: no associated item named `__pin_data` found for struct `Foo` in th
1010
= help: items from traits can only be used if the trait is implemented and in scope
1111
= note: the following trait defines an item `__pin_data`, perhaps you need to implement it:
1212
candidate #1: `HasPinData`
13-
= note: this error originates in the macro `$crate::try_pin_init` which comes from the expansion of the macro `pin_init` (in Nightly builds, run with -Z macro-backtrace for more info)
13+
= note: this error originates in the macro `$crate::pin_init` which comes from the expansion of the macro `pin_init` (in Nightly builds, run with -Z macro-backtrace for more info)

0 commit comments

Comments
 (0)