diff --git a/rust/pin-init/internal/src/init.rs b/rust/pin-init/internal/src/init.rs index 1957be83a196..e98182c65447 100644 --- a/rust/pin-init/internal/src/init.rs +++ b/rust/pin-init/internal/src/init.rs @@ -269,18 +269,17 @@ fn expand( }, |(_, err)| Box::new(err), ); - let (has_data_trait, get_data, init_from_closure) = if pinned { + let (get_pin_data, init_from_closure) = if pinned { ( - format_ident!("HasPinData"), - format_ident!("__pin_data"), + Some( + quote_spanned! { path.span().resolved_at(Span::mixed_site()) => + let data = ::pin_init::__internal::HasPinData::__pin_data(data); + }, + ), format_ident!("pin_init_from_closure"), ) } else { - ( - format_ident!("HasInitData"), - format_ident!("__init_data"), - format_ident!("init_from_closure"), - ) + (None, format_ident!("init_from_closure")) }; let init_kind = get_init_kind(rest, dcx); let zeroable_check = match init_kind { @@ -313,11 +312,14 @@ fn assert_zeroable(_: *mut T) Ok(quote_spanned! { Span::mixed_site() => { // Get the data about fields from the supplied type. let data = { - use ::pin_init::__internal::#has_data_trait; + use ::pin_init::__internal::HasInitData; // Can't use `<#path as #has_data_trait>::#get_data`, since the user is able to omit // generics (which need to be present with that syntax). - #path::#get_data() + #path::__init_data() }; + + #get_pin_data + // Ensure that `data` really is of type `data` and help with type inference: let init = data.__make_closure::<_, #error>( move |slot| { diff --git a/rust/pin-init/internal/src/pin_data.rs b/rust/pin-init/internal/src/pin_data.rs index 9fdce1593c7f..982a38ceea93 100644 --- a/rust/pin-init/internal/src/pin_data.rs +++ b/rust/pin-init/internal/src/pin_data.rs @@ -527,7 +527,7 @@ unsafe impl #impl_generics ::pin_init::__internal::HasPinData for #struct_name # type PinData = __ThePinData #ty_generics; #[inline] - fn __pin_data() -> Self::PinData { + fn __pin_data(_: ::pin_init::__internal::InitData) -> Self::PinData { __ThePinData { __phantom: ::pin_init::__internal::PhantomInvariant::new() } } } diff --git a/rust/pin-init/src/__internal.rs b/rust/pin-init/src/__internal.rs index e5f75432fe87..914c4d1a06eb 100644 --- a/rust/pin-init/src/__internal.rs +++ b/rust/pin-init/src/__internal.rs @@ -70,7 +70,7 @@ pub unsafe fn new() -> Self { pub unsafe trait HasPinData { type PinData; - fn __pin_data() -> Self::PinData; + fn __pin_data(_: InitData) -> Self::PinData; } /// This trait is automatically implemented for every type. diff --git a/rust/pin-init/src/lib.rs b/rust/pin-init/src/lib.rs index 4110590348c6..319485dc18ce 100644 --- a/rust/pin-init/src/lib.rs +++ b/rust/pin-init/src/lib.rs @@ -920,7 +920,8 @@ macro_rules! assert_pinned { ($ty:ty, $field:ident, $field_ty:ty, inline) => { // SAFETY: This code is unreachable. let _ = move |ptr: *mut $ty| unsafe { - let data = <$ty as $crate::__internal::HasPinData>::__pin_data(); + let data = <$ty as $crate::__internal::HasInitData>::__init_data(); + let data = $crate::__internal::HasPinData::__pin_data(data); _ = data .$field(ptr) .init($crate::__internal::AlwaysFail::<$field_ty>::new());