Repository: dtolnay/cxx (language: rust)

Issue:
Detect mutable slice in return position of a safe function
The check that detects turning a shared reference into an exclusive reference in a safe signature is not triggering for slice exclusive references, likely because those are represented differently from references to statically sized types in our internal syntax tree.

```rust
#[cxx::bridge]
mod ffi {
    unsafe extern "C++" {
        fn f(x: &i32) -> &mut i32;  // correctly disallowed
        fn g(x: &i32) -> &mut [i32];  // incorrectly allowed
    }
}
```

```console
error[cxxbridge]: &mut return type is not allowed unless there is a &mut argument
  ┌─ src/main.rs:4:9
  │
4 │         fn f(x: &i32) -> &mut i32;
  │         ^^^^^^^^^^^^^^^^^^^^^^^^^^ &mut return type is not allowed unless there is a &mut argument
```


Discussion / hints:

Fix patch:
diff --git a/syntax/check.rs b/syntax/check.rs
index 10025ac27..bab2dec5a 100644
--- a/syntax/check.rs
+++ b/syntax/check.rs
@@ -514,6 +514,7 @@ fn check_mut_return_restriction(cx: &mut Check, efn: &ExternFn) {
 
     match &efn.ret {
         Some(Type::Ref(ty)) if ty.mutable => {}
+        Some(Type::SliceRef(slice)) if slice.mutable => {}
         _ => return,
     }
 


Test patch:
diff --git a/tests/ui/mut_return.rs b/tests/ui/mut_return.rs
index aef3680b9..f30988b8c 100644
--- a/tests/ui/mut_return.rs
+++ b/tests/ui/mut_return.rs
@@ -11,6 +11,7 @@ mod ffi {
         unsafe fn g(t: &Thing) -> Pin<&mut CxxString>;
         fn h(t: Box<Mut>) -> Pin<&mut CxxString>;
         fn i<'a>(t: Box<Mut<'a>>) -> Pin<&'a mut CxxString>;
+        fn j(t: &Thing) -> &mut [u8];
     }
 }
 
diff --git a/tests/ui/mut_return.stderr b/tests/ui/mut_return.stderr
index 5845eb8ae..e33393d85 100644
--- a/tests/ui/mut_return.stderr
+++ b/tests/ui/mut_return.stderr
@@ -3,3 +3,9 @@ error: &mut return type is not allowed unless there is a &mut argument
    |
 10 |         fn f(t: &Thing) -> Pin<&mut CxxString>;
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: &mut return type is not allowed unless there is a &mut argument
+  --> $DIR/mut_return.rs:14:9
+   |
+14 |         fn j(t: &Thing) -> &mut [u8];
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^