Squashed 'third_party/autocxx/' changes from fdfb26e26..69eb3d8d2

69eb3d8d2 Merge pull request #1353 from EdmundGoodman/main
e0923cfdf Merge pull request #1354 from google/remove-unused-fields
b78edbaf0 Remove redundant fields.
585d5c1cd Add integration tests for functions taking array parameters
2f84e49f2 Merge pull request #1352 from google/clippy-5
efa122b50 More clippy fixes.
4eeeeb873 Further fix.
d6bf45456 Clippy fix.
d223b2f4a Merge pull request #1345 from google/allow-unused
2dcdff106 Merge pull request #1344 from google/missing-headers
5dd9a002d Fix unused import warnings.
f7bcbc75d Merge pull request #1338 from google/dependabot/cargo/rustix-0.37.25
65afd59d0 Add some missing headers.
ce7f49fd6 Merge pull request #1340 from google/fix-ci-probs
c9e274f68 Missing stdints.
2ebe0b557 Bump rustix from 0.37.23 to 0.37.25
6daf52209 Merge pull request #1335 from google/clippy-4
c25b46565 Clippy fix.
e8012a011 Merge pull request #1330 from google/subclass-opaque
2e8430026 Test for #1328.
762dbf397 Merge pull request #1324 from google/clippy5
c8e5e72d5 Merge pull request #1323 from google/fix-1318
354cec9f8 Clippy fixes.
2ef099dca Fix badly named alloc function - fixes #1318
b9550bda7 Merge pull request #1313 from google/bitfieldthing
748119f2c Merge branch 'main' of github.com:google/autocxx into bitfieldthing
366f3f430 Fix test.
a354a5d95 Better diagnostics on why these types are ignored.
b624e9cdc Adding diagnostics about bitfields.
648f47782 Add bitfield test kindly submitted for #1303

git-subtree-dir: third_party/autocxx
git-subtree-split: 69eb3d8d283c5cceb3829b5f200370353de2bd63
Signed-off-by: James Kuszmaul <jabukuszmaul+collab@gmail.com>
Change-Id: If2569977170bda9cda3ab3f3ee9ccbdc099ad9da
diff --git a/Cargo.lock b/Cargo.lock
index a7872e3..4587dcb 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1392,9 +1392,9 @@
 
 [[package]]
 name = "rustix"
-version = "0.37.23"
+version = "0.37.25"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4d69718bf81c6127a49dc64e44a742e8bb9213c0ff8869a22c308f84c1d4ab06"
+checksum = "d4eb579851244c2c03e7c24f501c3432bed80b8f720af1d6e5b0e0f01555a035"
 dependencies = [
  "bitflags 1.3.2",
  "errno",
@@ -1561,7 +1561,7 @@
  "cfg-if",
  "fastrand",
  "redox_syscall",
- "rustix 0.37.23",
+ "rustix 0.37.25",
  "windows-sys",
 ]
 
@@ -1590,7 +1590,7 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "8e6bf6f19e9f8ed8d4048dc22981458ebcf406d67e94cd422e5ecd73d63b3237"
 dependencies = [
- "rustix 0.37.23",
+ "rustix 0.37.25",
  "windows-sys",
 ]
 
diff --git a/engine/src/ast_discoverer.rs b/engine/src/ast_discoverer.rs
index f555419..6be9d8f 100644
--- a/engine/src/ast_discoverer.rs
+++ b/engine/src/ast_discoverer.rs
@@ -672,7 +672,7 @@
             }
         };
         discoveries.search_item(&itm, None).unwrap();
-        assert!(discoveries.extern_rust_funs.get(0).unwrap().sig.ident == "bar");
+        assert!(discoveries.extern_rust_funs.first().unwrap().sig.ident == "bar");
     }
 
     #[test]
@@ -686,7 +686,7 @@
             }
         };
         discoveries.search_item(&itm, None).unwrap();
-        assert!(discoveries.extern_rust_funs.get(0).unwrap().sig.ident == "bar");
+        assert!(discoveries.extern_rust_funs.first().unwrap().sig.ident == "bar");
     }
 
     #[test]
@@ -702,7 +702,7 @@
         assert!(
             discoveries
                 .extern_rust_types
-                .get(0)
+                .first()
                 .unwrap()
                 .get_final_ident()
                 == "Bar"
diff --git a/engine/src/conversion/analysis/allocators.rs b/engine/src/conversion/analysis/allocators.rs
index da25a77..aab637c 100644
--- a/engine/src/conversion/analysis/allocators.rs
+++ b/engine/src/conversion/analysis/allocators.rs
@@ -101,11 +101,11 @@
 }
 
 pub(crate) fn get_alloc_name(ty_name: &QualifiedName) -> QualifiedName {
-    get_name(ty_name, "alloc")
+    get_name(ty_name, "autocxx_alloc")
 }
 
 pub(crate) fn get_free_name(ty_name: &QualifiedName) -> QualifiedName {
-    get_name(ty_name, "free")
+    get_name(ty_name, "autocxx_free")
 }
 
 fn get_name(ty_name: &QualifiedName, label: &str) -> QualifiedName {
diff --git a/engine/src/conversion/analysis/depth_first.rs b/engine/src/conversion/analysis/depth_first.rs
index baadbd7..3c6241b 100644
--- a/engine/src/conversion/analysis/depth_first.rs
+++ b/engine/src/conversion/analysis/depth_first.rs
@@ -44,7 +44,7 @@
     type Item = &'a T;
 
     fn next(&mut self) -> Option<Self::Item> {
-        let first_candidate = self.queue.get(0).map(|api| api.name());
+        let first_candidate = self.queue.front().map(|api| api.name());
         while let Some(candidate) = self.queue.pop_front() {
             if !candidate
                 .field_and_base_deps()
@@ -54,7 +54,7 @@
                 return Some(candidate);
             }
             self.queue.push_back(candidate);
-            if self.queue.get(0).map(|api| api.name()) == first_candidate {
+            if self.queue.front().map(|api| api.name()) == first_candidate {
                 panic!(
                     "Failed to find a candidate; there must be a circular dependency. Queue is {}",
                     self.queue
diff --git a/engine/src/conversion/analysis/fun/mod.rs b/engine/src/conversion/analysis/fun/mod.rs
index 415e40a..dc953ad 100644
--- a/engine/src/conversion/analysis/fun/mod.rs
+++ b/engine/src/conversion/analysis/fun/mod.rs
@@ -80,7 +80,7 @@
 
 #[derive(Clone, Debug)]
 pub(crate) enum MethodKind {
-    Normal(ReceiverMutability),
+    Normal,
     Constructor { is_default: bool },
     Static,
     Virtual(ReceiverMutability),
@@ -964,7 +964,7 @@
                     let receiver_mutability =
                         receiver_mutability.expect("Failed to find receiver details");
                     match fun.virtualness {
-                        Virtualness::None => MethodKind::Normal(receiver_mutability),
+                        Virtualness::None => MethodKind::Normal,
                         Virtualness::Virtual => MethodKind::Virtual(receiver_mutability),
                         Virtualness::PureVirtual => MethodKind::PureVirtual(receiver_mutability),
                     }
@@ -1152,7 +1152,7 @@
                     ref impl_for,
                     method_kind:
                         MethodKind::Constructor { .. }
-                        | MethodKind::Normal(..)
+                        | MethodKind::Normal
                         | MethodKind::PureVirtual(..)
                         | MethodKind::Virtual(..),
                     ..
diff --git a/engine/src/conversion/analysis/pod/byvalue_checker.rs b/engine/src/conversion/analysis/pod/byvalue_checker.rs
index 6e2e9b9..d0c828e 100644
--- a/engine/src/conversion/analysis/pod/byvalue_checker.rs
+++ b/engine/src/conversion/analysis/pod/byvalue_checker.rs
@@ -158,6 +158,12 @@
                     ));
                     break;
                 }
+                None if ty_id.get_final_item() == "__BindgenBitfieldUnit" => {
+                    field_safety_problem = PodState::UnsafeToBePod(format!(
+                        "Type {tyname} could not be POD because it is a bitfield"
+                    ));
+                    break;
+                }
                 None => {
                     field_safety_problem = PodState::UnsafeToBePod(format!(
                         "Type {tyname} could not be POD because its dependent type {ty_id} isn't known"
diff --git a/engine/src/conversion/analysis/type_converter.rs b/engine/src/conversion/analysis/type_converter.rs
index 63f7ae9..99cd61d 100644
--- a/engine/src/conversion/analysis/type_converter.rs
+++ b/engine/src/conversion/analysis/type_converter.rs
@@ -251,7 +251,7 @@
                             let i = make_ident(s);
                             parse_quote! { #i }
                         })
-                        .chain(typ.path.segments.into_iter())
+                        .chain(typ.path.segments)
                         .collect();
                 }
             }
diff --git a/engine/src/conversion/codegen_rs/mod.rs b/engine/src/conversion/codegen_rs/mod.rs
index abab612..ee56169 100644
--- a/engine/src/conversion/codegen_rs/mod.rs
+++ b/engine/src/conversion/codegen_rs/mod.rs
@@ -1130,6 +1130,7 @@
         let segs =
             Self::find_output_mod_root(name.get_namespace()).chain(name.get_bindgen_path_idents());
         Item::Use(parse_quote! {
+            #[allow(unused_imports)]
             pub use #(#segs)::*;
         })
     }
diff --git a/engine/src/conversion/mod.rs b/engine/src/conversion/mod.rs
index 61d7d6d..fa24d4d 100644
--- a/engine/src/conversion/mod.rs
+++ b/engine/src/conversion/mod.rs
@@ -114,7 +114,7 @@
             None => Err(ConvertError::NoContent),
             Some((_, items)) => {
                 // Parse the bindgen mod.
-                let items_to_process = items.drain(..).collect();
+                let items_to_process = std::mem::take(items);
                 let parser = ParseBindgen::new(self.config);
                 let apis = parser.parse_items(items_to_process, source_file_contents)?;
                 Self::dump_apis("parsing", &apis);
diff --git a/engine/src/known_types.rs b/engine/src/known_types.rs
index 10199fb..573be4e 100644
--- a/engine/src/known_types.rs
+++ b/engine/src/known_types.rs
@@ -12,7 +12,7 @@
 use once_cell::sync::OnceCell;
 use syn::{parse_quote, TypePath};
 
-//// The behavior of the type.
+/// The behavior of the type.
 #[derive(Debug)]
 enum Behavior {
     CxxContainerPtr,
diff --git a/engine/src/parse_file.rs b/engine/src/parse_file.rs
index 16ea625..9dd620c 100644
--- a/engine/src/parse_file.rs
+++ b/engine/src/parse_file.rs
@@ -21,7 +21,7 @@
 use std::{io::Read, path::PathBuf};
 use std::{panic::UnwindSafe, path::Path, rc::Rc};
 use syn::spanned::Spanned;
-use syn::{token::Brace, Item, ItemMod};
+use syn::Item;
 use thiserror::Error;
 
 /// Errors which may occur when parsing a Rust source file to discover
@@ -119,7 +119,7 @@
                     Segment::Cxx(CxxBridge::from(itm))
                 }
                 Item::Mod(itm) => {
-                    if let Some((brace, items)) = itm.content {
+                    if let Some((_, items)) = itm.content {
                         let mut mod_state = State {
                             auto_allowlist: self.auto_allowlist,
                             ..Default::default()
@@ -137,18 +137,9 @@
                         }
                         self.extra_superclasses.extend(mod_state.extra_superclasses);
                         self.discoveries.extend(mod_state.discoveries);
-                        Segment::Mod(
-                            mod_state.results,
-                            (
-                                brace,
-                                ItemMod {
-                                    content: None,
-                                    ..itm
-                                },
-                            ),
-                        )
+                        Segment::Mod(mod_state.results)
                     } else {
-                        Segment::Other(Item::Mod(itm))
+                        Segment::Other
                     }
                 }
                 Item::Struct(ref its) => {
@@ -189,13 +180,13 @@
                     self.discoveries
                         .search_item(&item, mod_path)
                         .map_err(ParseError::Discovery)?;
-                    Segment::Other(item)
+                    Segment::Other
                 }
                 _ => {
                     self.discoveries
                         .search_item(&item, mod_path)
                         .map_err(ParseError::Discovery)?;
-                    Segment::Other(item)
+                    Segment::Other
                 }
             };
             self.results.push(result);
@@ -283,8 +274,8 @@
 enum Segment {
     Autocxx(IncludeCppEngine),
     Cxx(CxxBridge),
-    Mod(Vec<Segment>, (Brace, ItemMod)),
-    Other(Item),
+    Mod(Vec<Segment>),
+    Other,
 }
 
 pub trait CppBuildable {
@@ -303,7 +294,7 @@
                 .flat_map(|s| -> Box<dyn Iterator<Item = &IncludeCppEngine>> {
                     match s {
                         Segment::Autocxx(includecpp) => Box::new(std::iter::once(includecpp)),
-                        Segment::Mod(segments, _) => Box::new(do_get_autocxxes(segments)),
+                        Segment::Mod(segments) => Box::new(do_get_autocxxes(segments)),
                         _ => Box::new(std::iter::empty()),
                     }
                 })
@@ -331,7 +322,7 @@
                         Segment::Cxx(cxxbridge) => {
                             Box::new(std::iter::once(cxxbridge as &dyn CppBuildable))
                         }
-                        Segment::Mod(segments, _) => Box::new(do_get_cpp_buildables(segments)),
+                        Segment::Mod(segments) => Box::new(do_get_cpp_buildables(segments)),
                         _ => Box::new(std::iter::empty()),
                     }
                 })
@@ -349,7 +340,7 @@
                 .flat_map(|s| -> Box<dyn Iterator<Item = &mut IncludeCppEngine>> {
                     match s {
                         Segment::Autocxx(includecpp) => Box::new(std::iter::once(includecpp)),
-                        Segment::Mod(segments, _) => Box::new(do_get_autocxxes_mut(segments)),
+                        Segment::Mod(segments) => Box::new(do_get_autocxxes_mut(segments)),
                         _ => Box::new(std::iter::empty()),
                     }
                 })
@@ -368,7 +359,7 @@
                 .flat_map(|s| -> Box<dyn Iterator<Item = &PathBuf>> {
                     match s {
                         Segment::Autocxx(includecpp) => Box::new(includecpp.include_dirs()),
-                        Segment::Mod(segments, _) => Box::new(do_get_include_dirs(segments)),
+                        Segment::Mod(segments) => Box::new(do_get_include_dirs(segments)),
                         _ => Box::new(std::iter::empty()),
                     }
                 })
diff --git a/engine/src/types.rs b/engine/src/types.rs
index f7eaae0..3afbf9d 100644
--- a/engine/src/types.rs
+++ b/engine/src/types.rs
@@ -236,6 +236,10 @@
 /// cxx.
 #[derive(Error, Clone, Debug)]
 pub enum InvalidIdentError {
+    #[error("Union are not supported by autocxx (and their bindgen names have __ so are not acceptable to cxx)")]
+    Union,
+    #[error("Bitfields are not supported by autocxx (and their bindgen names have __ so are not acceptable to cxx)")]
+    Bitfield,
     #[error("Names containing __ are reserved by C++ so not acceptable to cxx")]
     TooManyUnderscores,
     #[error("bindgen decided to call this type _bindgen_ty_N because it couldn't deduce the correct name for it. That means we can't generate C++ bindings to it.")]
@@ -251,7 +255,12 @@
 /// where code will be output as part of the `#[cxx::bridge]` mod.
 pub fn validate_ident_ok_for_cxx(id: &str) -> Result<(), InvalidIdentError> {
     validate_ident_ok_for_rust(id)?;
-    if id.contains("__") {
+    // Provide a couple of more specific diagnostics if we can.
+    if id.starts_with("__BindgenBitfieldUnit") {
+        Err(InvalidIdentError::Bitfield)
+    } else if id.starts_with("__BindgenUnionField") {
+        Err(InvalidIdentError::Union)
+    } else if id.contains("__") {
         Err(InvalidIdentError::TooManyUnderscores)
     } else if id.starts_with("_bindgen_ty_") {
         Err(InvalidIdentError::BindgenTy)
diff --git a/integration-tests/src/lib.rs b/integration-tests/src/lib.rs
index 2335ee5..02d672f 100644
--- a/integration-tests/src/lib.rs
+++ b/integration-tests/src/lib.rs
@@ -459,7 +459,7 @@
     let generated_rs_files = build_results.1;
 
     if let Some(code_checker) = &rust_code_checker {
-        let mut file = File::open(generated_rs_files.get(0).ok_or(TestError::NoRs)?)
+        let mut file = File::open(generated_rs_files.first().ok_or(TestError::NoRs)?)
             .map_err(TestError::RsFileOpen)?;
         let mut content = String::new();
         file.read_to_string(&mut content)
diff --git a/integration-tests/tests/cpprefs_test.rs b/integration-tests/tests/cpprefs_test.rs
index 9cc6d39..820e67a 100644
--- a/integration-tests/tests/cpprefs_test.rs
+++ b/integration-tests/tests/cpprefs_test.rs
@@ -52,6 +52,7 @@
         indoc! {"
         #include <string>
         #include <sstream>
+        #include <cstdint>
 
         class Goat {
             public:
@@ -80,6 +81,7 @@
         indoc! {"
         #include <string>
         #include <sstream>
+        #include <cstdint>
 
         class Goat {
             public:
diff --git a/integration-tests/tests/integration_test.rs b/integration-tests/tests/integration_test.rs
index ec2b1e7..0939cae 100644
--- a/integration-tests/tests/integration_test.rs
+++ b/integration-tests/tests/integration_test.rs
@@ -4490,6 +4490,7 @@
 fn test_typedef_to_std() {
     let hdr = indoc! {"
         #include <string>
+        #include <cstdint>
         typedef std::string my_string;
         inline uint32_t take_str(my_string a) {
             return a.size();
@@ -4523,6 +4524,7 @@
 fn test_typedef_in_pod_struct() {
     let hdr = indoc! {"
         #include <string>
+        #include <cstdint>
         typedef uint32_t my_int;
         struct A {
             my_int a;
@@ -4544,6 +4546,7 @@
 fn test_cint_in_pod_struct() {
     let hdr = indoc! {"
         #include <string>
+        #include <cstdint>
         struct A {
             int a;
         };
@@ -4613,6 +4616,7 @@
 fn test_typedef_to_std_in_struct() {
     let hdr = indoc! {"
         #include <string>
+        #include <cstdint>
         typedef std::string my_string;
         struct A {
             my_string a;
@@ -4998,6 +5002,43 @@
 }
 
 #[test]
+fn test_take_struct_built_array_in_function() {
+    let hdr = indoc! {"
+    #include <cstdint>
+    struct data {
+        char a[4];
+    };
+    uint32_t take_array(char a[4]) {
+        return a[0] + a[2];
+    }
+    "};
+    let rs = quote! {
+        let mut c = ffi::data { a: [ 10, 20, 30, 40 ] };
+        unsafe {
+            assert_eq!(ffi::take_array(c.a.as_mut_ptr()), 40);
+        }
+    };
+    run_test("", hdr, rs, &["take_array"], &["data"]);
+}
+
+#[test]
+fn test_take_array_in_function() {
+    let hdr = indoc! {"
+    #include <cstdint>
+    uint32_t take_array(char a[4]) {
+        return a[0] + a[2];
+    }
+    "};
+    let rs = quote! {
+        let mut a: [i8; 4] = [ 10, 20, 30, 40 ];
+        unsafe {
+            assert_eq!(ffi::take_array(a.as_mut_ptr()), 40);
+        }
+    };
+    run_test("", hdr, rs, &["take_array"], &[]);
+}
+
+#[test]
 fn test_union_ignored() {
     let hdr = indoc! {"
     #include <cstdint>
@@ -7772,6 +7813,58 @@
 }
 
 #[test]
+fn test_pv_subclass_opaque_param() {
+    let hdr = indoc! {"
+    #include <cstdint>
+
+    typedef uint32_t MyUnsupportedType[4];
+
+    struct MySupportedType {
+        uint32_t a;
+    };
+
+    class MySuperType {
+    public:
+        virtual void foo(const MyUnsupportedType* foo, const MySupportedType* bar) const = 0;
+        virtual ~MySuperType() = default;
+    };
+    "};
+    run_test_ex(
+        "",
+        hdr,
+        quote! {
+            MySubType::new_rust_owned(MySubType { a: 3, cpp_peer: Default::default() });
+        },
+        quote! {
+            subclass!("MySuperType",MySubType)
+            extern_cpp_opaque_type!("MyUnsupportedType", crate::ffi2::MyUnsupportedType)
+        },
+        None,
+        None,
+        Some(quote! {
+
+            #[cxx::bridge]
+            pub mod ffi2 {
+                unsafe extern "C++" {
+                    include!("input.h");
+                    type MyUnsupportedType;
+                }
+            }
+            use autocxx::subclass::CppSubclass;
+            use ffi::MySuperType_methods;
+            #[autocxx::subclass::subclass]
+            pub struct MySubType {
+                a: u32
+            }
+            impl MySuperType_methods for MySubType {
+                unsafe fn foo(&self, _foo: *const ffi2::MyUnsupportedType, _bar: *const ffi::MySupportedType) {
+                }
+            }
+        }),
+    );
+}
+
+#[test]
 fn test_pv_subclass_return() {
     let hdr = indoc! {"
     #include <cstdint>
@@ -12241,6 +12334,58 @@
     run_test("", hdr, rs, &["A"], &[]);
 }
 
+#[test]
+fn test_badly_named_alloc() {
+    let hdr = indoc! {"
+        #include <stdarg.h>
+        class A {
+        public:
+            void alloc();
+        };
+    "};
+    let rs = quote! {};
+    run_test("", hdr, rs, &["A"], &[]);
+}
+
+#[test]
+fn test_cpp_union_pod() {
+    let hdr = indoc! {"
+        typedef unsigned long long UInt64_t;
+        struct ManagedPtr_t_;
+        typedef struct ManagedPtr_t_ ManagedPtr_t;
+        
+        typedef int (*ManagedPtr_ManagerFunction_t)(
+                ManagedPtr_t *managedPtr,
+                const ManagedPtr_t *srcPtr,
+                int operation);
+        
+        typedef union {
+            int intValue;
+            void *ptr;
+        } ManagedPtr_t_data_;
+        
+        struct ManagedPtr_t_ {
+            void *pointer;
+            ManagedPtr_t_data_ userData[4];
+            ManagedPtr_ManagerFunction_t manager;
+        };
+        
+        typedef struct CorrelationId_t_ {
+            unsigned int size : 8;
+            unsigned int valueType : 4;
+            unsigned int classId : 16;
+            unsigned int reserved : 4;
+        
+            union {
+                UInt64_t intValue;
+                ManagedPtr_t ptrValue;
+            } value;
+        } CorrelationId_t;
+    "};
+    run_test("", hdr, quote! {}, &["CorrelationId_t_"], &[]);
+    run_test_expect_fail("", hdr, quote! {}, &[], &["CorrelationId_t_"]);
+}
+
 // Yet to test:
 // - Ifdef
 // - Out param pointers