Add getters for `no_unique_address` fields, and use them in a test.

PiperOrigin-RevId: 428594290
diff --git a/rs_bindings_from_cc/src_code_gen.rs b/rs_bindings_from_cc/src_code_gen.rs
index 889ba5a..2f10a0d 100644
--- a/rs_bindings_from_cc/src_code_gen.rs
+++ b/rs_bindings_from_cc/src_code_gen.rs
@@ -780,6 +780,7 @@
             quote! {}
         };
 
+    let no_unique_address_accessors = cc_struct_no_unique_address_impl(record, ir)?;
     let base_class_into = cc_struct_upcast_impl(record, ir)?;
 
     let record_tokens = quote! {
@@ -792,6 +793,8 @@
             #empty_struct_placeholder_field
         }
 
+        #no_unique_address_accessors
+
         #base_class_into
 
         #unpin_impl
@@ -1418,6 +1421,36 @@
     }
 }
 
+// Returns the accessor functions for no_unique_address member variables.
+fn cc_struct_no_unique_address_impl(record: &Record, ir: &IR) -> Result<TokenStream> {
+    let mut fields = vec![];
+    let mut types = vec![];
+    for field in &record.fields {
+        if field.access != AccessSpecifier::Public || !field.is_no_unique_address {
+            continue;
+        }
+        fields.push(make_rs_ident(&field.identifier.identifier));
+        types.push(format_rs_type(&field.type_.rs_type, ir, &HashMap::new()).with_context(
+            || format!("Failed to format type for field {:?} on record {:?}", field, record),
+        )?)
+    }
+
+    if fields.is_empty() {
+        return Ok(quote! {});
+    }
+
+    let ident = make_rs_ident(&record.identifier.identifier);
+    Ok(quote! {
+        impl #ident {
+            #(
+                pub fn #fields(&self) -> &#types {
+                    unsafe {&* (&self.#fields as *const _ as *const #types)}
+                }
+            )*
+        }
+    })
+}
+
 /// Returns the implementation of base class conversions, for converting a type
 /// to its unambiguous public base classes.
 ///
@@ -2198,6 +2231,15 @@
                     field2: [std::mem::MaybeUninit<u8>; 2],
                     pub z: i16,
                 }
+
+                impl Struct {
+                    pub fn field1(&self) -> &Field1 {
+                        unsafe {&* (&self.field1 as *const _ as *const Field1)}
+                    }
+                    pub fn field2(&self) -> &Field2 {
+                        unsafe {&* (&self.field2 as *const _ as *const Field2)}
+                    }
+                }
             }
         );
         Ok(())
diff --git a/rs_bindings_from_cc/test/struct/no_unique_address/no_unique_address.h b/rs_bindings_from_cc/test/struct/no_unique_address/no_unique_address.h
new file mode 100644
index 0000000..4ed5081
--- /dev/null
+++ b/rs_bindings_from_cc/test/struct/no_unique_address/no_unique_address.h
@@ -0,0 +1,17 @@
+// Part of the Crubit project, under the Apache License v2.0 with LLVM
+// Exceptions. See /LICENSE for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+
+#ifndef CRUBIT_RS_BINDINGS_FROM_CC_TEST_STRUCT_NO_UNIQUE_ADDRESS_NO_UNIQUE_ADDRESS_H_
+#define CRUBIT_RS_BINDINGS_FROM_CC_TEST_STRUCT_NO_UNIQUE_ADDRESS_NO_UNIQUE_ADDRESS_H_
+#pragma clang lifetime_elision
+
+struct Struct final {
+  static Struct Make(int f1, char f2) { return Struct{f1, f2}; }
+  // Nobody would ever use a no_unique_address int/char field, this is just
+  // enough to test that the transmute is correct.
+  [[no_unique_address]] int field1 = 1;
+  [[no_unique_address]] char field2 = 2;
+};
+
+#endif  // CRUBIT_RS_BINDINGS_FROM_CC_TEST_STRUCT_NO_UNIQUE_ADDRESS_NO_UNIQUE_ADDRESS_H_
diff --git a/rs_bindings_from_cc/test/struct/no_unique_address/no_unique_address_test.rs b/rs_bindings_from_cc/test/struct/no_unique_address/no_unique_address_test.rs
new file mode 100644
index 0000000..eeccd58
--- /dev/null
+++ b/rs_bindings_from_cc/test/struct/no_unique_address/no_unique_address_test.rs
@@ -0,0 +1,15 @@
+// Part of the Crubit project, under the Apache License v2.0 with LLVM
+// Exceptions. See /LICENSE for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+
+#[cfg(test)]
+mod tests {
+    use no_unique_address::*;
+
+    #[test]
+    fn test_get() {
+        let s = Struct::Make(1, 2);
+        assert_eq!(s.field1(), &1);
+        assert_eq!(s.field2(), &2);
+    }
+}