Repository: rust
Issue: Diagnostic for mismatched pointers type could be improved
Labels: C-enhancement,A-diagnostics,T-compiler

The following snippet is build with Rust 1.38.0: https://rust.godbolt.org/z/NGTGo-
<details>
<summary>snippet</summary>

```rust
mod unique {
    type HANDLE = *mut ::std::os::raw::c_void;
    type PHANDLE = *mut HANDLE;
    fn foo(token: PHANDLE) {}

    fn bar() {
        let token: HANDLE = ::std::ptr::null_mut();
        foo(token as *mut _);
        foo(&mut token);
        foo(&token);
        foo(token);
    }
}

mod shared {
    type HANDLE = *const ::std::os::raw::c_void;
    type PHANDLE = *const HANDLE;
    fn foo(token: PHANDLE) {}

    fn bar() {
        let token: HANDLE = ::std::ptr::null_mut();
        foo(token as *const _);
        foo(&mut token);
        foo(&token);
        foo(token);
    }
}

mod unique_mut {
    type HANDLE = *mut ::std::os::raw::c_void;
    type PHANDLE = *mut HANDLE;
    fn foo(token: PHANDLE) {}

    fn bar() {
        let mut token: HANDLE = ::std::ptr::null_mut();
        foo(token as *mut _);
        foo(&mut token);
        foo(&token);
        foo(token);
    }
}
```
</details>
The compiler outputs:
<details>
<summary>rustc's output</summary>

```rust
error[E0308]: mismatched types
  --> src/lib.rs:10:13
   |
10 |         foo(&token);
   |             ^^^^^^ types differ in mutability
   |
   = note: expected type `*mut *mut std::ffi::c_void`
              found type `&*mut std::ffi::c_void`

error[E0308]: mismatched types
  --> src/lib.rs:11:13
   |
11 |         foo(token);
   |             ^^^^^ expected *-ptr, found enum `std::ffi::c_void`
   |
   = note: expected type `*mut *mut std::ffi::c_void`
              found type `*mut std::ffi::c_void`

error[E0308]: mismatched types
  --> src/lib.rs:25:13
   |
25 |         foo(token);
   |             ^^^^^ expected *-ptr, found enum `std::ffi::c_void`
   |
   = note: expected type `*const *const std::ffi::c_void`
              found type `*const std::ffi::c_void`

error[E0308]: mismatched types
  --> src/lib.rs:38:13
   |
38 |         foo(&token);
   |             ^^^^^^ types differ in mutability
   |
   = note: expected type `*mut *mut std::ffi::c_void`
              found type `&*mut std::ffi::c_void`

error[E0308]: mismatched types
  --> src/lib.rs:39:13
   |
39 |         foo(token);
   |             ^^^^^ expected *-ptr, found enum `std::ffi::c_void`
   |
   = note: expected type `*mut *mut std::ffi::c_void`
              found type `*mut std::ffi::c_void`

error: aborting due to 5 previous errors
```
</details>

I'm a beginner in Rust's FFI. So my questions may seems silly.

1. In module `unique`, line 8: we mutually borrow `token`, but `token` is never defined
with `let mut` syntax. Is this accepted?

2. Same question but for module `shared`, line 23.

3. Can we suggest borrowing with appropriate mutability  in `foo(token)` lines?

   For example:
   ```rust
   error[E0308]: mismatched types
     --> src/lib.rs:10:13
      |
   10 |         foo(&token);
      |             ^^^^^^ types differ in mutability
      |
      = note: expected type `*mut *mut std::ffi::c_void`
                 found type `&*mut std::ffi::c_void`
        try: `&mut token`

   error[E0308]: mismatched types
     --> src/lib.rs:11:13
      |
   11 |         foo(token);
      |             ^^^^^ expected *-ptr, found enum `std::ffi::c_void`
      |
      = note: expected type `*mut *mut std::ffi::c_void`
                 found type `*mut std::ffi::c_void`
        try: `&mut token`
   ```