Remove functions, use same uninit for all field tests
@@ -2172,10 +2172,17 @@ impl CodeGenerator for CompInfo {
let should_skip_field_offset_checks =
is_opaque || too_many_base_vtables;
- let (check_field_offset_decls, check_field_offset_invocs) = if should_skip_field_offset_checks
+ let (uninit_decl, check_field_offset) = if should_skip_field_offset_checks
{
- (vec![], vec![])
+ (None, vec![])
} else {
+ (
+ Some(quote! {
+ // Use a shared MaybeUninit so that rustc with
+ // opt-level=0 doesn't take too much stack
+ // space, see #2218.
+ const UNINIT: ::#prefix::mem::MaybeUninit<#canonical_ident> = ::#prefix::mem::MaybeUninit::uninit();
+ }),
self.fields()
.iter()
.filter_map(|field| match *field {
@@ -2187,41 +2194,32 @@ impl CodeGenerator for CompInfo {
field.offset().map(|offset| {
let field_offset = offset / 8;
let field_name = ctx.rust_ident(name);
- // Put each check in its own function, so
- // that rustc with opt-level=0 doesn't take
- // too much stack space, see #2218.
- let test_fn = Ident::new(&format!("test_field_{}", name), Span::call_site());
- (
quote! {
- fn #test_fn() {
assert_eq!(
unsafe {
- let uninit = ::#prefix::mem::MaybeUninit::<#canonical_ident>::uninit();
- let ptr = uninit.as_ptr();
+ let ptr = UNINIT.as_ptr();
::#prefix::ptr::addr_of!((*ptr).#field_name) as usize - ptr as usize
},
#field_offset,
concat!("Offset of field: ", stringify!(#canonical_ident), "::", stringify!(#field_name))
);
}
- },
- quote! { #test_fn(); }
- )
})
})
- .unzip()
+ .collect()
+ )
};
let item = quote! {
#[test]
fn #fn_name() {
- #( #check_field_offset_decls )*
+ #uninit_decl
assert_eq!(#size_of_expr,
#size,
concat!("Size of: ", stringify!(#canonical_ident)));
#check_struct_align
- #( #check_field_offset_invocs )*
+ #( #check_field_offset )*
}
};
result.push(item);
