Skip to content

Commit 13111ef

Browse files
committed
internal: pin_data: use closure for handle_field
`handle_field` is currently a function, which precludes it from referencing things in the scope of the parent function. Given that it's only called once, inline its contents to the closure that invokes it instead, so it can directly reference `struct_name` without having to pass in as argument. Signed-off-by: Gary Guo <gary@garyguo.net>
1 parent 41ed491 commit 13111ef

4 files changed

Lines changed: 84 additions & 88 deletions

File tree

internal/src/pin_data.rs

Lines changed: 70 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -336,7 +336,7 @@ fn generate_projections(
336336

337337
fn generate_the_pin_data(
338338
vis: &Visibility,
339-
ident: &Ident,
339+
struct_name: &Ident,
340340
generics: &Generics,
341341
fields: &[(bool, &Field)],
342342
) -> TokenStream {
@@ -347,78 +347,74 @@ fn generate_the_pin_data(
347347
// not structurally pinned, then it can be initialized via `Init`.
348348
//
349349
// The functions are `unsafe` to prevent accidentally calling them.
350-
fn handle_field(
351-
Field {
352-
vis,
353-
ident,
354-
ty,
355-
attrs,
356-
..
357-
}: &Field,
358-
struct_ident: &Ident,
359-
pinned: bool,
360-
) -> TokenStream {
361-
let ident = ident
362-
.as_ref()
363-
.expect("only structs with named fields are supported");
364-
let project_ident = format_ident!("__project_{ident}");
365-
let (init_ty, init_fn, project_ty, project_body, pin_safety) = if pinned {
366-
(
367-
quote!(PinInit),
368-
quote!(__pinned_init),
369-
quote!(::core::pin::Pin<&'__slot mut #ty>),
370-
// SAFETY: this field is structurally pinned.
371-
quote!(unsafe { ::core::pin::Pin::new_unchecked(slot) }),
372-
quote!(
373-
/// - `slot` will not move until it is dropped, i.e. it will be pinned.
374-
),
375-
)
376-
} else {
377-
(
378-
quote!(Init),
379-
quote!(__init),
380-
quote!(&'__slot mut #ty),
381-
quote!(slot),
382-
quote!(),
383-
)
384-
};
385-
let slot_safety = format!(
386-
" `slot` points at the field `{ident}` inside of `{struct_ident}`, which is pinned.",
387-
);
388-
quote! {
389-
/// # Safety
390-
///
391-
/// - `slot` is a valid pointer to uninitialized memory.
392-
/// - the caller does not touch `slot` when `Err` is returned, they are only permitted
393-
/// to deallocate.
394-
#pin_safety
395-
#(#attrs)*
396-
#vis unsafe fn #ident<E>(
397-
self,
398-
slot: *mut #ty,
399-
init: impl ::pin_init::#init_ty<#ty, E>,
400-
) -> ::core::result::Result<(), E> {
401-
// SAFETY: this function has the same safety requirements as the __init function
402-
// called below.
403-
unsafe { ::pin_init::#init_ty::#init_fn(init, slot) }
404-
}
405-
406-
/// # Safety
407-
///
408-
#[doc = #slot_safety]
409-
#(#attrs)*
410-
#vis unsafe fn #project_ident<'__slot>(
411-
self,
412-
slot: &'__slot mut #ty,
413-
) -> #project_ty {
414-
#project_body
415-
}
416-
}
417-
}
418-
419350
let field_accessors = fields
420351
.iter()
421-
.map(|(pinned, field)| handle_field(field, ident, *pinned))
352+
.map(|(pinned, field)| {
353+
let Field {
354+
vis,
355+
ident,
356+
ty,
357+
attrs,
358+
..
359+
} = field;
360+
361+
let field_name = ident
362+
.as_ref()
363+
.expect("only structs with named fields are supported");
364+
let project_ident = format_ident!("__project_{field_name}");
365+
let (init_ty, init_fn, project_ty, project_body, pin_safety) = if *pinned {
366+
(
367+
quote!(PinInit),
368+
quote!(__pinned_init),
369+
quote!(::core::pin::Pin<&'__slot mut #ty>),
370+
// SAFETY: this field is structurally pinned.
371+
quote!(unsafe { ::core::pin::Pin::new_unchecked(slot) }),
372+
quote!(
373+
/// - `slot` will not move until it is dropped, i.e. it will be pinned.
374+
),
375+
)
376+
} else {
377+
(
378+
quote!(Init),
379+
quote!(__init),
380+
quote!(&'__slot mut #ty),
381+
quote!(slot),
382+
quote!(),
383+
)
384+
};
385+
let slot_safety = format!(
386+
" `slot` points at the field `{field_name}` inside of `{struct_name}`, which is pinned.",
387+
);
388+
quote! {
389+
/// # Safety
390+
///
391+
/// - `slot` is a valid pointer to uninitialized memory.
392+
/// - the caller does not touch `slot` when `Err` is returned, they are only
393+
/// permitted to deallocate.
394+
#pin_safety
395+
#(#attrs)*
396+
#vis unsafe fn #field_name<E>(
397+
self,
398+
slot: *mut #ty,
399+
init: impl ::pin_init::#init_ty<#ty, E>,
400+
) -> ::core::result::Result<(), E> {
401+
// SAFETY: this function has the same safety requirements as the __init function
402+
// called below.
403+
unsafe { ::pin_init::#init_ty::#init_fn(init, slot) }
404+
}
405+
406+
/// # Safety
407+
///
408+
#[doc = #slot_safety]
409+
#(#attrs)*
410+
#vis unsafe fn #project_ident<'__slot>(
411+
self,
412+
slot: &'__slot mut #ty,
413+
) -> #project_ty {
414+
#project_body
415+
}
416+
}
417+
})
422418
.collect::<TokenStream>();
423419
quote! {
424420
// We declare this struct which will host all of the projection function for our type. It
@@ -428,7 +424,7 @@ fn generate_the_pin_data(
428424
#whr
429425
{
430426
__phantom: ::core::marker::PhantomData<
431-
fn(#ident #ty_generics) -> #ident #ty_generics
427+
fn(#struct_name #ty_generics) -> #struct_name #ty_generics
432428
>,
433429
}
434430

@@ -452,7 +448,7 @@ fn generate_the_pin_data(
452448

453449
// SAFETY: We have added the correct projection functions above to `__ThePinData` and
454450
// we also use the least restrictive generics possible.
455-
unsafe impl #impl_generics ::pin_init::__internal::HasPinData for #ident #ty_generics
451+
unsafe impl #impl_generics ::pin_init::__internal::HasPinData for #struct_name #ty_generics
456452
#whr
457453
{
458454
type PinData = __ThePinData #ty_generics;
@@ -466,7 +462,7 @@ fn generate_the_pin_data(
466462
unsafe impl #impl_generics ::pin_init::__internal::PinData for __ThePinData #ty_generics
467463
#whr
468464
{
469-
type Datee = #ident #ty_generics;
465+
type Datee = #struct_name #ty_generics;
470466
}
471467
}
472468
}

tests/ui/expand/many_generics.expanded.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,8 @@ const _: () = {
8787
/// # Safety
8888
///
8989
/// - `slot` is a valid pointer to uninitialized memory.
90-
/// - the caller does not touch `slot` when `Err` is returned, they are only permitted
91-
/// to deallocate.
90+
/// - the caller does not touch `slot` when `Err` is returned, they are only
91+
/// permitted to deallocate.
9292
unsafe fn array<E>(
9393
self,
9494
slot: *mut [u8; 1024 * 1024],
@@ -108,8 +108,8 @@ const _: () = {
108108
/// # Safety
109109
///
110110
/// - `slot` is a valid pointer to uninitialized memory.
111-
/// - the caller does not touch `slot` when `Err` is returned, they are only permitted
112-
/// to deallocate.
111+
/// - the caller does not touch `slot` when `Err` is returned, they are only
112+
/// permitted to deallocate.
113113
unsafe fn r<E>(
114114
self,
115115
slot: *mut &'b mut [&'a mut T; SIZE],
@@ -129,8 +129,8 @@ const _: () = {
129129
/// # Safety
130130
///
131131
/// - `slot` is a valid pointer to uninitialized memory.
132-
/// - the caller does not touch `slot` when `Err` is returned, they are only permitted
133-
/// to deallocate.
132+
/// - the caller does not touch `slot` when `Err` is returned, they are only
133+
/// permitted to deallocate.
134134
/// - `slot` will not move until it is dropped, i.e. it will be pinned.
135135
unsafe fn _pin<E>(
136136
self,

tests/ui/expand/pin-data.expanded.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,8 @@ const _: () = {
4949
/// # Safety
5050
///
5151
/// - `slot` is a valid pointer to uninitialized memory.
52-
/// - the caller does not touch `slot` when `Err` is returned, they are only permitted
53-
/// to deallocate.
52+
/// - the caller does not touch `slot` when `Err` is returned, they are only
53+
/// permitted to deallocate.
5454
unsafe fn array<E>(
5555
self,
5656
slot: *mut [u8; 1024 * 1024],
@@ -70,8 +70,8 @@ const _: () = {
7070
/// # Safety
7171
///
7272
/// - `slot` is a valid pointer to uninitialized memory.
73-
/// - the caller does not touch `slot` when `Err` is returned, they are only permitted
74-
/// to deallocate.
73+
/// - the caller does not touch `slot` when `Err` is returned, they are only
74+
/// permitted to deallocate.
7575
/// - `slot` will not move until it is dropped, i.e. it will be pinned.
7676
unsafe fn _pin<E>(
7777
self,

tests/ui/expand/pinned_drop.expanded.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,8 @@ const _: () = {
4949
/// # Safety
5050
///
5151
/// - `slot` is a valid pointer to uninitialized memory.
52-
/// - the caller does not touch `slot` when `Err` is returned, they are only permitted
53-
/// to deallocate.
52+
/// - the caller does not touch `slot` when `Err` is returned, they are only
53+
/// permitted to deallocate.
5454
unsafe fn array<E>(
5555
self,
5656
slot: *mut [u8; 1024 * 1024],
@@ -70,8 +70,8 @@ const _: () = {
7070
/// # Safety
7171
///
7272
/// - `slot` is a valid pointer to uninitialized memory.
73-
/// - the caller does not touch `slot` when `Err` is returned, they are only permitted
74-
/// to deallocate.
73+
/// - the caller does not touch `slot` when `Err` is returned, they are only
74+
/// permitted to deallocate.
7575
/// - `slot` will not move until it is dropped, i.e. it will be pinned.
7676
unsafe fn _pin<E>(
7777
self,

0 commit comments

Comments
 (0)