Skip to content

Commit e0ae072

Browse files
committed
rewrite the initializer macros using syn
Rewrite the initializer macros `[pin_]init!` using `syn`. No functional changes intended aside from improved error messages on syntactic and semantical errors. For example if one forgets to use `<-` with an initializer (and instead uses `:`): impl Bar { fn new() -> impl PinInit<Self> { ... } } impl Foo { fn new() -> impl PinInit<Self> { pin_init!(Self { bar: Bar::new() }) } } Then the declarative macro would report: error[E0308]: mismatched types --> tests/ui/compile-fail/init/colon_instead_of_arrow.rs:21:9 | 14 | fn new() -> impl PinInit<Self> { | ------------------ the found opaque type ... 21 | pin_init!(Self { bar: Bar::new() }) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | | expected `Bar`, found opaque type | arguments to this function are incorrect | = note: expected struct `Bar` found opaque type `impl pin_init::PinInit<Bar>` note: function defined here --> $RUST/core/src/ptr/mod.rs | | pub const unsafe fn write<T>(dst: *mut T, src: T) { | ^^^^^ = note: this error originates in the macro `$crate::__init_internal` which comes from the expansion of the macro `pin_init` (in Nightly builds, run with -Z macro-backtrace for more info) And the new error is: error[E0308]: mismatched types --> tests/ui/compile-fail/init/colon_instead_of_arrow.rs:21:31 | 14 | fn new() -> impl PinInit<Self> { | ------------------ the found opaque type ... 21 | pin_init!(Self { bar: Bar::new() }) | --- ^^^^^^^^^^ expected `Bar`, found opaque type | | | arguments to this function are incorrect | = note: expected struct `Bar` found opaque type `impl pin_init::PinInit<Bar>` note: function defined here --> $RUST/core/src/ptr/mod.rs | | pub const unsafe fn write<T>(dst: *mut T, src: T) { | ^^^^^ Importantly, this error gives much more accurate span locations, pointing to the offending field, rather than the entire macro invocation. Signed-off-by: Benno Lossin <[email protected]>
1 parent ed15061 commit e0ae072

22 files changed

+527
-1193
lines changed

internal/src/init.rs

Lines changed: 433 additions & 0 deletions
Large diffs are not rendered by default.

internal/src/lib.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
use proc_macro::TokenStream;
1414
use syn::parse_macro_input;
1515

16+
mod init;
1617
mod pin_data;
1718
mod pinned_drop;
1819
mod zeroable;
@@ -44,3 +45,23 @@ pub fn derive_zeroable(input: TokenStream) -> TokenStream {
4445
pub fn maybe_derive_zeroable(input: TokenStream) -> TokenStream {
4546
zeroable::maybe_derive(parse_macro_input!(input as _)).into()
4647
}
48+
49+
#[proc_macro]
50+
pub fn init(input: TokenStream) -> TokenStream {
51+
init::expand(
52+
parse_macro_input!(input as _),
53+
Some("::core::convert::Infallible"),
54+
false,
55+
)
56+
.into()
57+
}
58+
59+
#[proc_macro]
60+
pub fn pin_init(input: TokenStream) -> TokenStream {
61+
init::expand(
62+
parse_macro_input!(input as _),
63+
Some("::core::convert::Infallible"),
64+
true,
65+
)
66+
.into()
67+
}

internal/src/pin_data.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,7 @@ fn generate_projections(
315315
});
316316
quote! {
317317
#[allow(dead_code)]
318+
#[doc(hidden)]
318319
#vis struct #projection #generics {
319320
#(#fields_decl)*
320321
___pin_phantom_data: ::core::marker::PhantomData<&'__pin mut ()>,
@@ -330,6 +331,7 @@ fn generate_projections(
330331
///
331332
/// These fields are **not** structurally pinned:
332333
#(#not_structurally_pinned_fields_docs)*
334+
#[inline]
333335
#vis fn project<'__pin>(
334336
self: ::core::pin::Pin<&'__pin mut Self>,
335337
) -> #projection #ty_gen {
@@ -394,7 +396,7 @@ fn generate_the_pin_data(
394396
quote!(__init),
395397
quote!(&'__slot mut #ty),
396398
quote!(slot),
397-
quote!(#[doc = ""]),
399+
quote!(),
398400
)
399401
};
400402
let slot_safety = format!(

src/lib.rs

Lines changed: 2 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -297,8 +297,6 @@ extern crate self as pin_init;
297297

298298
#[doc(hidden)]
299299
pub mod __internal;
300-
#[doc(hidden)]
301-
pub mod macros;
302300

303301
#[cfg(any(feature = "std", feature = "alloc"))]
304302
mod alloc;
@@ -781,32 +779,7 @@ macro_rules! stack_try_pin_init {
781779
/// ```
782780
///
783781
/// [`NonNull<Self>`]: core::ptr::NonNull
784-
// For a detailed example of how this macro works, see the module documentation of the hidden
785-
// module `macros` inside of `macros.rs`.
786-
#[macro_export]
787-
macro_rules! pin_init {
788-
($(&$this:ident in)? $t:ident $(::<$($generics:ty),* $(,)?>)? {
789-
$($fields:tt)*
790-
}) => {
791-
$crate::pin_init!($(&$this in)? $t $(::<$($generics),*>)? {
792-
$($fields)*
793-
}? ::core::convert::Infallible)
794-
};
795-
($(&$this:ident in)? $t:ident $(::<$($generics:ty),* $(,)?>)? {
796-
$($fields:tt)*
797-
}? $err:ty) => {
798-
$crate::__init_internal!(
799-
@this($($this)?),
800-
@typ($t $(::<$($generics),*>)? ),
801-
@fields($($fields)*),
802-
@error($err),
803-
@data(PinData, use_data),
804-
@has_data(HasPinData, __pin_data),
805-
@construct_closure(pin_init_from_closure),
806-
@munch_fields($($fields)*),
807-
)
808-
}
809-
}
782+
pub use pin_init_internal::pin_init;
810783

811784
/// Construct an in-place, fallible initializer for `struct`s.
812785
///
@@ -844,32 +817,7 @@ macro_rules! pin_init {
844817
/// }
845818
/// # let _ = Box::init(BigBuf::new());
846819
/// ```
847-
// For a detailed example of how this macro works, see the module documentation of the hidden
848-
// module `macros` inside of `macros.rs`.
849-
#[macro_export]
850-
macro_rules! init {
851-
($(&$this:ident in)? $t:ident $(::<$($generics:ty),* $(,)?>)? {
852-
$($fields:tt)*
853-
}) => {
854-
$crate::init!($(&$this in)? $t $(::<$($generics),*>)? {
855-
$($fields)*
856-
}? ::core::convert::Infallible)
857-
};
858-
($(&$this:ident in)? $t:ident $(::<$($generics:ty),* $(,)?>)? {
859-
$($fields:tt)*
860-
}? $err:ty) => {
861-
$crate::__init_internal!(
862-
@this($($this)?),
863-
@typ($t $(::<$($generics),*>)?),
864-
@fields($($fields)*),
865-
@error($err),
866-
@data(InitData, /*no use_data*/),
867-
@has_data(HasInitData, __init_data),
868-
@construct_closure(init_from_closure),
869-
@munch_fields($($fields)*),
870-
)
871-
}
872-
}
820+
pub use pin_init_internal::init;
873821

874822
/// Asserts that a field on a struct using `#[pin_data]` is marked with `#[pin]` ie. that it is
875823
/// structurally pinned.

0 commit comments

Comments
 (0)