Repository: rust-lang/rust-bindgen (rust)

Issue:
Constant array treated as mutable pointer
### Input C/C++ Header

```C++
typedef struct {
    int field;
} strct;

typedef strct typ[1];

void function(const typ a, const strct *b);
```

### Actual Results

```rust
pub type typ = [strct; 1usize];
extern "C" {
    pub fn function(a: *mut strct, b: *const strct);
}
```

### Expected Results
```rust
pub type typ = [strct; 1usize];
extern "C" {
    pub fn function(a: *const strct, b: *const strct);
}
```


Pull request description:
Fix const array issue
Fix #2683. Fairly hacky fix right now, but it doesn't seem to break any tests.

Patch:
diff --git a/bindgen/codegen/mod.rs b/bindgen/codegen/mod.rs
index 339c2fe5..b126a847 100644
--- a/bindgen/codegen/mod.rs
+++ b/bindgen/codegen/mod.rs
@@ -5285,7 +5285,8 @@ pub(crate) mod utils {
                 } else {
                     t.to_rust_ty_or_opaque(ctx, &())
                 };
-                stream.to_ptr(ctx.resolve_type(t).is_const())
+                stream
+                    .to_ptr(ctx.resolve_type(t).is_const() || arg_ty.is_const())
             }
             TypeKind::Pointer(inner) => {
                 let inner = ctx.resolve_item(inner);


Test patch:
diff --git a/bindgen-tests/tests/expectations/tests/const_array_typedef.rs b/bindgen-tests/tests/expectations/tests/const_array_typedef.rs
new file mode 100644
index 00000000..9222e525
--- /dev/null
+++ b/bindgen-tests/tests/expectations/tests/const_array_typedef.rs
@@ -0,0 +1,42 @@
+#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)]
+#[repr(C)]
+#[derive(Debug, Default, Copy, Clone)]
+pub struct strct {
+    pub field: ::std::os::raw::c_int,
+}
+#[test]
+fn bindgen_test_layout_strct() {
+    const UNINIT: ::std::mem::MaybeUninit<strct> = ::std::mem::MaybeUninit::uninit();
+    let ptr = UNINIT.as_ptr();
+    assert_eq!(
+        ::std::mem::size_of::<strct>(),
+        4usize,
+        concat!("Size of: ", stringify!(strct)),
+    );
+    assert_eq!(
+        ::std::mem::align_of::<strct>(),
+        4usize,
+        concat!("Alignment of ", stringify!(strct)),
+    );
+    assert_eq!(
+        unsafe { ::std::ptr::addr_of!((*ptr).field) as usize - ptr as usize },
+        0usize,
+        concat!("Offset of field: ", stringify!(strct), "::", stringify!(field)),
+    );
+}
+pub type typ = [strct; 1usize];
+extern "C" {
+    pub static mut w: typ;
+}
+extern "C" {
+    pub static mut x: *mut strct;
+}
+extern "C" {
+    pub static y: typ;
+}
+extern "C" {
+    pub static mut z: *const strct;
+}
+extern "C" {
+    pub fn function(a: *const strct, b: *const strct);
+}
diff --git a/bindgen-tests/tests/headers/const_array_typedef.h b/bindgen-tests/tests/headers/const_array_typedef.h
new file mode 100644
index 00000000..e5379c97
--- /dev/null
+++ b/bindgen-tests/tests/headers/const_array_typedef.h
@@ -0,0 +1,13 @@
+typedef struct {
+    int field;
+} strct;
+
+typedef strct typ[1];
+
+extern typ w;
+extern strct *x;
+
+extern const typ y;
+extern const strct *z;
+
+void function(const typ a, const strct *b);