Repository: mozilla/cbindgen (language: rust)

Issue:
Implement mangling for arrays
input.rs:

```rs
#[repr(C)]
pub struct MyStruct<T> {
    field: T
}

#[no_mangle]
pub extern "C" fn my_function(x: MyStruct<[u8; 4]>) {}
```

`cbindgen --lang c input.rs`:

```c
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>

typedef struct MyStruct__________u8__________4 {
  uint8_t field[4];
} MyStruct__________u8__________4;

void my_function(struct MyStruct__________u8__________4 x);
```


Discussion / hints:

Fix patch:
diff --git a/src/bindgen/mangle.rs b/src/bindgen/mangle.rs
index 52c3be93..5f7fa096 100644
--- a/src/bindgen/mangle.rs
+++ b/src/bindgen/mangle.rs
@@ -27,6 +27,8 @@ enum Separator {
     BeginFn,
     BetweenFnArg,
     EndFn,
+    BeginArray,
+    BetweenArray,
 }
 
 struct Mangler<'a> {
@@ -128,12 +130,11 @@ impl<'a> Mangler<'a> {
                     self.push(Separator::EndFn);
                 }
             }
-            Type::Array(..) => {
-                unimplemented!(
-                    "Unable to mangle generic parameter {:?} for '{}'",
-                    ty,
-                    self.input
-                );
+            Type::Array(ref ty, ref len) => {
+                self.push(Separator::BeginArray);
+                self.append_mangled_type(ty, false);
+                self.push(Separator::BetweenArray);
+                self.append_mangled_argument(&GenericArgument::Const(len.clone()), last);
             }
         }
     }


Test patch:
diff --git a/tests/expectations/generic_pointer.c b/tests/expectations/generic_pointer.c
index 35d430d6..d117ab5b 100644
--- a/tests/expectations/generic_pointer.c
+++ b/tests/expectations/generic_pointer.c
@@ -9,4 +9,10 @@ typedef struct {
 
 typedef Foo_____u8 Boo;
 
+typedef struct {
+  uint8_t a[4];
+} Foo__________u8__________4;
+
 void root(Boo x);
+
+void my_function(Foo__________u8__________4 x);
diff --git a/tests/expectations/generic_pointer.compat.c b/tests/expectations/generic_pointer.compat.c
index d5f3ac9c..e294fb47 100644
--- a/tests/expectations/generic_pointer.compat.c
+++ b/tests/expectations/generic_pointer.compat.c
@@ -9,12 +9,18 @@ typedef struct {
 
 typedef Foo_____u8 Boo;
 
+typedef struct {
+  uint8_t a[4];
+} Foo__________u8__________4;
+
 #ifdef __cplusplus
 extern "C" {
 #endif // __cplusplus
 
 void root(Boo x);
 
+void my_function(Foo__________u8__________4 x);
+
 #ifdef __cplusplus
 }  // extern "C"
 #endif  // __cplusplus
diff --git a/tests/expectations/generic_pointer.cpp b/tests/expectations/generic_pointer.cpp
index 8b505147..60f11d9e 100644
--- a/tests/expectations/generic_pointer.cpp
+++ b/tests/expectations/generic_pointer.cpp
@@ -15,4 +15,6 @@ extern "C" {
 
 void root(Boo x);
 
+void my_function(Foo<uint8_t[4]> x);
+
 }  // extern "C"
diff --git a/tests/expectations/generic_pointer.pyx b/tests/expectations/generic_pointer.pyx
index 4d4e36b7..87b04087 100644
--- a/tests/expectations/generic_pointer.pyx
+++ b/tests/expectations/generic_pointer.pyx
@@ -11,4 +11,9 @@ cdef extern from *:
 
   ctypedef Foo_____u8 Boo;
 
+  ctypedef struct Foo__________u8__________4:
+    uint8_t a[4];
+
   void root(Boo x);
+
+  void my_function(Foo__________u8__________4 x);
diff --git a/tests/expectations/generic_pointer_both.c b/tests/expectations/generic_pointer_both.c
index ac51021e..76766754 100644
--- a/tests/expectations/generic_pointer_both.c
+++ b/tests/expectations/generic_pointer_both.c
@@ -9,4 +9,10 @@ typedef struct Foo_____u8 {
 
 typedef struct Foo_____u8 Boo;
 
+typedef struct Foo__________u8__________4 {
+  uint8_t a[4];
+} Foo__________u8__________4;
+
 void root(Boo x);
+
+void my_function(struct Foo__________u8__________4 x);
diff --git a/tests/expectations/generic_pointer_both.compat.c b/tests/expectations/generic_pointer_both.compat.c
index 5b2981c7..39e0ea31 100644
--- a/tests/expectations/generic_pointer_both.compat.c
+++ b/tests/expectations/generic_pointer_both.compat.c
@@ -9,12 +9,18 @@ typedef struct Foo_____u8 {
 
 typedef struct Foo_____u8 Boo;
 
+typedef struct Foo__________u8__________4 {
+  uint8_t a[4];
+} Foo__________u8__________4;
+
 #ifdef __cplusplus
 extern "C" {
 #endif // __cplusplus
 
 void root(Boo x);
 
+void my_function(struct Foo__________u8__________4 x);
+
 #ifdef __cplusplus
 }  // extern "C"
 #endif  // __cplusplus
diff --git a/tests/expectations/generic_pointer_tag.c b/tests/expectations/generic_pointer_tag.c
index 9c2ea9dc..57825ca3 100644
--- a/tests/expectations/generic_pointer_tag.c
+++ b/tests/expectations/generic_pointer_tag.c
@@ -9,4 +9,10 @@ struct Foo_____u8 {
 
 typedef struct Foo_____u8 Boo;
 
+struct Foo__________u8__________4 {
+  uint8_t a[4];
+};
+
 void root(Boo x);
+
+void my_function(struct Foo__________u8__________4 x);
diff --git a/tests/expectations/generic_pointer_tag.compat.c b/tests/expectations/generic_pointer_tag.compat.c
index 07dee152..dd31fcc1 100644
--- a/tests/expectations/generic_pointer_tag.compat.c
+++ b/tests/expectations/generic_pointer_tag.compat.c
@@ -9,12 +9,18 @@ struct Foo_____u8 {
 
 typedef struct Foo_____u8 Boo;
 
+struct Foo__________u8__________4 {
+  uint8_t a[4];
+};
+
 #ifdef __cplusplus
 extern "C" {
 #endif // __cplusplus
 
 void root(Boo x);
 
+void my_function(struct Foo__________u8__________4 x);
+
 #ifdef __cplusplus
 }  // extern "C"
 #endif  // __cplusplus
diff --git a/tests/expectations/generic_pointer_tag.pyx b/tests/expectations/generic_pointer_tag.pyx
index 0f541a1a..56fb5521 100644
--- a/tests/expectations/generic_pointer_tag.pyx
+++ b/tests/expectations/generic_pointer_tag.pyx
@@ -11,4 +11,9 @@ cdef extern from *:
 
   ctypedef Foo_____u8 Boo;
 
+  cdef struct Foo__________u8__________4:
+    uint8_t a[4];
+
   void root(Boo x);
+
+  void my_function(Foo__________u8__________4 x);
diff --git a/tests/rust/generic_pointer.rs b/tests/rust/generic_pointer.rs
index 1167c76b..828bdc10 100644
--- a/tests/rust/generic_pointer.rs
+++ b/tests/rust/generic_pointer.rs
@@ -9,3 +9,6 @@ pub type Boo = Foo<*mut u8>;
 pub extern "C" fn root(
     x: Boo,
 ) { }
+
+#[no_mangle]
+pub extern "C" fn my_function(x: Foo<[u8; 4]>) {}