Files
sousa-gecko/third_party/rust/bindgen/codegen/impl_partialeq.rs
T
Emilio Cobos Álvarez b50f83948d Bug 1985509 - Update bindgen to fix overaligned types on x86. r=nika,supply-chain-reviewers,profiler-reviewers,canaltinova
Bindgen historically represented 8-byte aligned types with u64. That's
borked in x86 where u64 is 4-byte aligned.

I fixed this in upstream bindgen
(https://github.com/rust-lang/rust-bindgen/pull/3280), so update it.

There are a few changes needed:

 * https://github.com/mozilla/neqo/pull/2913 to deal with the now
   properly aligned type.

 * Similar change (less fun because transmute, but still sound) in the
   macos crash reporter. I could try to generate a bit easier to use
   bindings for 8-byte 8-byte-aligned blobs, but this would do.

 * Some opaque additions in layout/style/ServoBindings.toml and the
   profiler bindings. This is unrelated to the opaque change, but
   fallout from other bindgen improvements. In particular, layout tests
   now run at compile time, so this uncovered some layout mismatches on
   platforms where we don't run rusttests on CI.

Differential Revision: https://phabricator.services.mozilla.com/D262840
2025-08-28 21:18:57 +00:00

115 lines
3.5 KiB
Rust

use crate::ir::comp::{CompInfo, CompKind, Field, FieldMethods};
use crate::ir::context::BindgenContext;
use crate::ir::item::{IsOpaque, Item};
use crate::ir::ty::TypeKind;
/// Generate a manual implementation of `PartialEq` trait for the
/// specified compound type.
pub(crate) fn gen_partialeq_impl(
ctx: &BindgenContext,
comp_info: &CompInfo,
item: &Item,
ty_for_impl: &proc_macro2::TokenStream,
) -> Option<proc_macro2::TokenStream> {
let mut tokens = vec![];
if item.is_opaque(ctx, &()) {
tokens.push(quote! {
&self._bindgen_opaque_blob[..] == &other._bindgen_opaque_blob[..]
});
} else if comp_info.kind() == CompKind::Union {
assert!(!ctx.options().untagged_union);
tokens.push(quote! {
&self.bindgen_union_field[..] == &other.bindgen_union_field[..]
});
} else {
for base in comp_info.base_members() {
if !base.requires_storage(ctx) {
continue;
}
let ty_item = ctx.resolve_item(base.ty);
let field_name = &base.field_name;
tokens.push(gen_field(ctx, ty_item, field_name));
}
for field in comp_info.fields() {
match *field {
Field::DataMember(ref fd) => {
let ty_item = ctx.resolve_item(fd.ty());
let name = fd.name().unwrap();
tokens.push(gen_field(ctx, ty_item, name));
}
Field::Bitfields(ref bu) => {
for bitfield in bu.bitfields() {
if bitfield.name().is_some() {
let getter_name = bitfield.getter_name();
let name_ident = ctx.rust_ident_raw(getter_name);
tokens.push(quote! {
self.#name_ident () == other.#name_ident ()
});
}
}
}
}
}
}
Some(quote! {
fn eq(&self, other: & #ty_for_impl) -> bool {
#( #tokens )&&*
}
})
}
fn gen_field(
ctx: &BindgenContext,
ty_item: &Item,
name: &str,
) -> proc_macro2::TokenStream {
fn quote_equals(
name_ident: &proc_macro2::Ident,
) -> proc_macro2::TokenStream {
quote! { self.#name_ident == other.#name_ident }
}
let name_ident = ctx.rust_ident(name);
let ty = ty_item.expect_type();
match *ty.kind() {
TypeKind::Void |
TypeKind::NullPtr |
TypeKind::Int(..) |
TypeKind::Complex(..) |
TypeKind::Float(..) |
TypeKind::Enum(..) |
TypeKind::TypeParam |
TypeKind::UnresolvedTypeRef(..) |
TypeKind::Reference(..) |
TypeKind::ObjCInterface(..) |
TypeKind::ObjCId |
TypeKind::ObjCSel |
TypeKind::Comp(..) |
TypeKind::Pointer(_) |
TypeKind::Function(..) |
TypeKind::Array(..) |
TypeKind::TemplateInstantiation(..) |
TypeKind::Opaque => quote_equals(&name_ident),
TypeKind::Vector(_, len) => {
let self_ids = 0..len;
let other_ids = 0..len;
quote! {
#(self.#self_ids == other.#other_ids &&)* true
}
}
TypeKind::ResolvedTypeRef(t) |
TypeKind::TemplateAlias(t, _) |
TypeKind::Alias(t) |
TypeKind::BlockPointer(t) => {
let inner_item = ctx.resolve_item(t);
gen_field(ctx, inner_item, name)
}
}
}