Repository: google/autocxx (rust)

Issue:
Trait bound error from autocxx bindings
## Expected Behavior
It compiles.

## Actual Behavior
```
error[E0277]: the trait bound `root::GraphicElement: VectorElement` is not satisfied
  --> /home/lofty/nextpnr/common/route/awooter/target/debug/build/awooter-a283d7034f88f2ba/out/autocxx-build-dir/rs/autocxx-ffi-default-gen.rs:1:45716
   |
1  | ...am < root :: DecalId >) -> cxx :: UniquePtr < cxx :: CxxVector < root :: GraphicElement > > { let mut space0 = autocxx :: ValueParamHa...
   |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `VectorElement` is not implemented for `root::GraphicElement`
   |
   = help: the following other types implement trait `VectorElement`:
             CxxString
             f32
             f64
             i16
             i32
             i64
             i8
             isize
           and 30 others
   = note: required because of the requirements on the impl of `UniquePtrTarget` for `CxxVector<root::GraphicElement>`
note: required by a bound in `UniquePtr`
  --> /home/lofty/.cargo/registry/src/github.com-1ecc6299db9ec823/cxx-1.0.78/src/unique_ptr.rs:17:8
   |
17 |     T: UniquePtrTarget,
   |        ^^^^^^^^^^^^^^^ required by this bound in `UniquePtr`

error[E0277]: the trait bound `root::GraphicElement: VectorElement` is not satisfied
  --> /home/lofty/nextpnr/common/route/awooter/target/debug/build/awooter-a283d7034f88f2ba/out/autocxx-build-dir/rs/autocxx-ffi-default-gen.rs:1:116522
   |
1  | ...calId) -> UniquePtr < CxxVector < GraphicElement > > ; pub unsafe fn getBelDecal_autocxx_wrapper (autocxx_gen_this : & Arch , bel : Be...
   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `VectorElement` is not implemented for `root::GraphicElement`
   |
   = help: the following other types implement trait `VectorElement`:
             CxxString
             f32
             f64
             i16
             i32
             i64
             i8
             isize
           and 30 others
   = note: required because of the requirements on the impl of `UniquePtrTarget` for `CxxVector<root::GraphicElement>`
note: required by a bound in `UniquePtr`
  --> /home/lofty/.cargo/registry/src/github.com-1ecc6299db9ec823/cxx-1.0.78/src/unique_ptr.rs:17:8
   |
17 |     T: UniquePtrTarget,
   |        ^^^^^^^^^^^^^^^ required by this bound in `UniquePtr`
```

## Steps to Reproduce the Problem

As mentioned in #1167, here's the [repro.zip](https://github.com/google/autocxx/files/9830276/repro.zip).

## Specifications

- Version: `rustc 1.65.0-nightly (2befdefdd 2022-08-06)` (perhaps I should update it)
- Platform: `x86_64-unknown-linux-gnu` (under WSL2)

Pull request:
Fix movability of structs with enum fields
Fixes #1170.

Patch:
diff --git a/engine/src/conversion/analysis/deps.rs b/engine/src/conversion/analysis/deps.rs
index b75addf8..a8519f2f 100644
--- a/engine/src/conversion/analysis/deps.rs
+++ b/engine/src/conversion/analysis/deps.rs
@@ -37,13 +37,9 @@ impl HasDependencies for Api<FnPrePhase1> {
                 ..
             } => Box::new(old_tyname.iter().chain(deps.iter())),
             Api::Struct {
-                analysis:
-                    PodAnalysis {
-                        kind: TypeKind::Pod,
-                        bases,
-                        field_deps,
-                        ..
-                    },
+                analysis: PodAnalysis {
+                    bases, field_deps, ..
+                },
                 ..
             } => Box::new(field_deps.iter().chain(bases.iter())),
             Api::Function { analysis, .. } => Box::new(analysis.deps.iter()),
diff --git a/engine/src/conversion/analysis/fun/implicit_constructors.rs b/engine/src/conversion/analysis/fun/implicit_constructors.rs
index a1bd7178..da8f44eb 100644
--- a/engine/src/conversion/analysis/fun/implicit_constructors.rs
+++ b/engine/src/conversion/analysis/fun/implicit_constructors.rs
@@ -177,6 +177,13 @@ pub(super) fn find_constructors_present(
     apis: &ApiVec<FnPrePhase1>,
 ) -> HashMap<QualifiedName, ItemsFound> {
     let (explicits, unknown_types) = find_explicit_items(apis);
+    let enums: HashSet<QualifiedName> = apis
+        .iter()
+        .filter_map(|api| match api {
+            Api::Enum { name, .. } => Some(name.name.clone()),
+            _ => None,
+        })
+        .collect();
 
     // These contain all the classes we've seen so far with the relevant properties on their
     // constructors of each kind. We iterate via [`depth_first`], so analyzing later classes
@@ -211,7 +218,17 @@ pub(super) fn find_constructors_present(
                 })
             };
             let get_items_found = |qn: &QualifiedName| -> Option<ItemsFound> {
-                if let Some(constructor_details) = known_types().get_constructor_details(qn) {
+                if enums.contains(qn) {
+                    Some(ItemsFound {
+                        default_constructor: SpecialMemberFound::NotPresent,
+                        destructor: SpecialMemberFound::Implicit,
+                        const_copy_constructor: SpecialMemberFound::Implicit,
+                        non_const_copy_constructor: SpecialMemberFound::NotPresent,
+                        move_constructor: SpecialMemberFound::Implicit,
+                        name: Some(name.clone()),
+                    })
+                } else if let Some(constructor_details) = known_types().get_constructor_details(qn)
+                {
                     Some(known_type_items_found(constructor_details))
                 } else {
                     all_items_found.get(qn).cloned()


Test patch:
diff --git a/integration-tests/tests/integration_test.rs b/integration-tests/tests/integration_test.rs
index bc425951..b6ec6ed8 100644
--- a/integration-tests/tests/integration_test.rs
+++ b/integration-tests/tests/integration_test.rs
@@ -11285,6 +11285,16 @@ fn test_typedef_to_ns_enum() {
     run_generate_all_test(hdr);
 }
 
+#[test]
+fn test_enum_in_ns() {
+    let hdr = indoc! {"
+        namespace a {
+        enum b {};
+        } // namespace
+    "};
+    run_test("", hdr, quote! {}, &["a::b"], &[]);
+}
+
 #[test]
 fn test_typedef_unsupported_type_pub() {
     let hdr = indoc! {"
@@ -11701,6 +11711,20 @@ fn test_issue_1143() {
     run_test("", hdr, quote! {}, &["mapnik::Map"], &[]);
 }
 
+#[test]
+fn test_issue_1170() {
+    let hdr = indoc! {
+        "#include <vector>
+        struct a {
+            enum b {} c;
+        } Loc;
+        struct Arch {
+            std::vector<a> d();
+        } DeterministicRNG;"
+    };
+    run_test("", hdr, quote! {}, &["Arch"], &[]);
+}
+
 // Yet to test:
 // - Ifdef
 // - Out param pointers