Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit d378b7b

Browse files
committedMar 19, 2024
Update with review comments
1 parent a1161e3 commit d378b7b

File tree

2 files changed

+130
-113
lines changed

2 files changed

+130
-113
lines changed
 

‎bindgen/codegen/mod.rs

+130-112
Original file line numberDiff line numberDiff line change
@@ -1675,7 +1675,7 @@ impl<'a> FieldCodegen<'a> for BitfieldUnit {
16751675
accessor_kind: FieldAccessorKind,
16761676
parent: &CompInfo,
16771677
parent_item: &Item,
1678-
_last_field: bool,
1678+
last_field: bool,
16791679
result: &mut CodegenResult,
16801680
struct_layout: &mut StructLayoutTracker,
16811681
fields: &mut F,
@@ -1757,7 +1757,7 @@ impl<'a> FieldCodegen<'a> for BitfieldUnit {
17571757
accessor_kind,
17581758
parent,
17591759
parent_item,
1760-
idx == bfields.len() - 1,
1760+
last_field && idx == bfields.len() - 1,
17611761
result,
17621762
struct_layout,
17631763
fields,
@@ -2549,116 +2549,13 @@ impl CodeGenerator for CompInfo {
25492549
}
25502550

25512551
if needs_flexarray_impl {
2552-
let prefix = ctx.trait_prefix();
2553-
2554-
let flex_array =
2555-
flex_inner_ty.as_ref().map(|ty| quote! { [ #ty ] });
2556-
2557-
let dst_ty_for_impl = quote! {
2558-
#canonical_ident < #( #generic_param_names , )* #flex_array >
2559-
2560-
};
2561-
let sized_ty_for_impl = quote! {
2562-
#canonical_ident < #( #generic_param_names , )* [ #flex_inner_ty; 0 ] >
2563-
};
2564-
2565-
let layout = if ctx.options().rust_features().layout_for_ptr {
2566-
quote! {
2567-
pub fn layout(len: usize) -> ::#prefix::alloc::Layout {
2568-
// SAFETY: Null pointers are OK if we don't deref them
2569-
unsafe {
2570-
let p: *const Self = ::#prefix::ptr::from_raw_parts(::#prefix::ptr::null(), len);
2571-
::#prefix::alloc::Layout::for_value_raw(p)
2572-
}
2573-
}
2574-
}
2575-
} else {
2576-
quote!()
2577-
};
2578-
2579-
let (from_ptr_dst, from_ptr_sized) = if ctx
2580-
.options()
2581-
.rust_features()
2582-
.ptr_metadata
2583-
{
2584-
(
2585-
quote! {
2586-
pub fn fixed(&self) -> (& #sized_ty_for_impl, usize) {
2587-
unsafe {
2588-
let (ptr, len) = (self as *const Self).to_raw_parts();
2589-
(&*(ptr as *const #sized_ty_for_impl), len)
2590-
}
2591-
}
2592-
2593-
pub fn fixed_mut(&mut self) -> (&mut #sized_ty_for_impl, usize) {
2594-
unsafe {
2595-
let (ptr, len) = (self as *mut Self).to_raw_parts();
2596-
(&mut *(ptr as *mut #sized_ty_for_impl), len)
2597-
2598-
}
2599-
}
2600-
},
2601-
quote! {
2602-
/// Convert a sized prefix to an unsized structure with the given length.
2603-
///
2604-
/// SAFETY: Underlying storage is initialized up to at least `len` elements.
2605-
pub unsafe fn flex_ref(&self, len: usize) -> &#dst_ty_for_impl {
2606-
// SAFETY: Reference is always valid as pointer. Caller is guaranteeing `len`.
2607-
unsafe { Self::flex_ptr(self, len) }
2608-
}
2609-
2610-
/// Convert a mutable sized prefix to an unsized structure with the given length.
2611-
///
2612-
/// SAFETY: Underlying storage is initialized up to at least `len` elements.
2613-
pub unsafe fn flex_mut_ref(&mut self, len: usize) -> &mut #dst_ty_for_impl {
2614-
// SAFETY: Reference is always valid as pointer. Caller is guaranteeing `len`.
2615-
unsafe { Self::flex_ptr_mut(self, len).assume_init() }
2616-
}
2617-
2618-
/// Construct DST variant from a pointer and a size.
2619-
///
2620-
/// NOTE: lifetime of returned reference is not tied to any underlying storage.
2621-
/// SAFETY: `ptr` is valid. Underlying storage is fully initialized up to at least `len` elements.
2622-
pub unsafe fn flex_ptr<'unbounded>(ptr: *const Self, len: usize) -> &'unbounded #dst_ty_for_impl {
2623-
unsafe { &*::#prefix::ptr::from_raw_parts(ptr as *const (), len) }
2624-
}
2625-
2626-
/// Construct mutable DST variant from a pointer and a
2627-
/// size. The returned `&mut` reference is initialized
2628-
/// pointing to memory referenced by `ptr`, but there's
2629-
/// no requirement that that memory be initialized.
2630-
///
2631-
/// NOTE: lifetime of returned reference is not tied to any underlying storage.
2632-
/// SAFETY: `ptr` is valid. Underlying storage has space for at least `len` elements.
2633-
pub unsafe fn flex_ptr_mut<'unbounded>(
2634-
ptr: *mut Self,
2635-
len: usize,
2636-
) -> ::#prefix::mem::MaybeUninit<&'unbounded mut #dst_ty_for_impl> {
2637-
unsafe {
2638-
// Initialize reference without ever exposing it, as its possibly uninitialized
2639-
let mut uninit = ::#prefix::mem::MaybeUninit::<&mut #dst_ty_for_impl>::uninit();
2640-
(uninit.as_mut_ptr() as *mut *mut #dst_ty_for_impl)
2641-
.write(::#prefix::ptr::from_raw_parts_mut(ptr as *mut (), len));
2642-
2643-
uninit
2644-
}
2645-
}
2646-
},
2647-
)
2648-
} else {
2649-
(quote!(), quote!())
2650-
};
2651-
2652-
result.push(quote! {
2653-
impl #impl_generics_labels #dst_ty_for_impl {
2654-
#layout
2655-
#from_ptr_dst
2656-
}
2657-
2658-
impl #impl_generics_labels #sized_ty_for_impl {
2659-
#from_ptr_sized
2660-
}
2661-
});
2552+
result.push(self.generate_flexarray(
2553+
ctx,
2554+
&canonical_ident,
2555+
flex_inner_ty,
2556+
&*generic_param_names,
2557+
&impl_generics_labels,
2558+
));
26622559
}
26632560

26642561
if needs_default_impl {
@@ -2745,6 +2642,127 @@ impl CodeGenerator for CompInfo {
27452642
}
27462643
}
27472644

2645+
impl CompInfo {
2646+
fn generate_flexarray(
2647+
&self,
2648+
ctx: &BindgenContext,
2649+
canonical_ident: &Ident,
2650+
flex_inner_ty: Option<proc_macro2::TokenStream>,
2651+
generic_param_names: &[Ident],
2652+
impl_generics_labels: &proc_macro2::TokenStream,
2653+
) -> proc_macro2::TokenStream {
2654+
let prefix = ctx.trait_prefix();
2655+
2656+
let flex_array = flex_inner_ty.as_ref().map(|ty| quote! { [ #ty ] });
2657+
2658+
let dst_ty_for_impl = quote! {
2659+
#canonical_ident < #( #generic_param_names , )* #flex_array >
2660+
2661+
};
2662+
let sized_ty_for_impl = quote! {
2663+
#canonical_ident < #( #generic_param_names , )* [ #flex_inner_ty; 0 ] >
2664+
};
2665+
2666+
let layout = if ctx.options().rust_features().layout_for_ptr {
2667+
quote! {
2668+
pub fn layout(len: usize) -> ::#prefix::alloc::Layout {
2669+
// SAFETY: Null pointers are OK if we don't deref them
2670+
unsafe {
2671+
let p: *const Self = ::#prefix::ptr::from_raw_parts(::#prefix::ptr::null(), len);
2672+
::#prefix::alloc::Layout::for_value_raw(p)
2673+
}
2674+
}
2675+
}
2676+
} else {
2677+
quote!()
2678+
};
2679+
2680+
let (from_ptr_dst, from_ptr_sized) = if ctx
2681+
.options()
2682+
.rust_features()
2683+
.ptr_metadata
2684+
{
2685+
(
2686+
quote! {
2687+
pub fn fixed(&self) -> (& #sized_ty_for_impl, usize) {
2688+
unsafe {
2689+
let (ptr, len) = (self as *const Self).to_raw_parts();
2690+
(&*(ptr as *const #sized_ty_for_impl), len)
2691+
}
2692+
}
2693+
2694+
pub fn fixed_mut(&mut self) -> (&mut #sized_ty_for_impl, usize) {
2695+
unsafe {
2696+
let (ptr, len) = (self as *mut Self).to_raw_parts();
2697+
(&mut *(ptr as *mut #sized_ty_for_impl), len)
2698+
2699+
}
2700+
}
2701+
},
2702+
quote! {
2703+
/// Convert a sized prefix to an unsized structure with the given length.
2704+
///
2705+
/// SAFETY: Underlying storage is initialized up to at least `len` elements.
2706+
pub unsafe fn flex_ref(&self, len: usize) -> &#dst_ty_for_impl {
2707+
// SAFETY: Reference is always valid as pointer. Caller is guaranteeing `len`.
2708+
unsafe { Self::flex_ptr(self, len) }
2709+
}
2710+
2711+
/// Convert a mutable sized prefix to an unsized structure with the given length.
2712+
///
2713+
/// SAFETY: Underlying storage is initialized up to at least `len` elements.
2714+
pub unsafe fn flex_mut_ref(&mut self, len: usize) -> &mut #dst_ty_for_impl {
2715+
// SAFETY: Reference is always valid as pointer. Caller is guaranteeing `len`.
2716+
unsafe { Self::flex_ptr_mut(self, len).assume_init() }
2717+
}
2718+
2719+
/// Construct DST variant from a pointer and a size.
2720+
///
2721+
/// NOTE: lifetime of returned reference is not tied to any underlying storage.
2722+
/// SAFETY: `ptr` is valid. Underlying storage is fully initialized up to at least `len` elements.
2723+
pub unsafe fn flex_ptr<'unbounded>(ptr: *const Self, len: usize) -> &'unbounded #dst_ty_for_impl {
2724+
unsafe { &*::#prefix::ptr::from_raw_parts(ptr as *const (), len) }
2725+
}
2726+
2727+
/// Construct mutable DST variant from a pointer and a
2728+
/// size. The returned `&mut` reference is initialized
2729+
/// pointing to memory referenced by `ptr`, but there's
2730+
/// no requirement that that memory be initialized.
2731+
///
2732+
/// NOTE: lifetime of returned reference is not tied to any underlying storage.
2733+
/// SAFETY: `ptr` is valid. Underlying storage has space for at least `len` elements.
2734+
pub unsafe fn flex_ptr_mut<'unbounded>(
2735+
ptr: *mut Self,
2736+
len: usize,
2737+
) -> ::#prefix::mem::MaybeUninit<&'unbounded mut #dst_ty_for_impl> {
2738+
unsafe {
2739+
// Initialize reference without ever exposing it, as its possibly uninitialized
2740+
let mut uninit = ::#prefix::mem::MaybeUninit::<&mut #dst_ty_for_impl>::uninit();
2741+
(uninit.as_mut_ptr() as *mut *mut #dst_ty_for_impl)
2742+
.write(::#prefix::ptr::from_raw_parts_mut(ptr as *mut (), len));
2743+
2744+
uninit
2745+
}
2746+
}
2747+
},
2748+
)
2749+
} else {
2750+
(quote!(), quote!())
2751+
};
2752+
2753+
quote! {
2754+
impl #impl_generics_labels #dst_ty_for_impl {
2755+
#layout
2756+
#from_ptr_dst
2757+
}
2758+
2759+
impl #impl_generics_labels #sized_ty_for_impl {
2760+
#from_ptr_sized
2761+
}
2762+
}
2763+
}
2764+
}
2765+
27482766
impl Method {
27492767
fn codegen_method(
27502768
&self,

‎bindgen/ir/comp.rs

-1
Original file line numberDiff line numberDiff line change
@@ -834,7 +834,6 @@ impl CompFields {
834834
CompFields::Error => return None, // panic?
835835
};
836836

837-
// XXX correct with padding on end?
838837
match fields.last() {
839838
None | Some(Field::Bitfields(..)) => None,
840839
Some(Field::DataMember(FieldData { ty, .. })) => ctx

0 commit comments

Comments
 (0)