Allow casting mut array ref to mut ptr

We now allow two new casts:

- mut array reference to mut ptr. Example:

      let mut x: [usize; 2] = [0, 0];
      let p = &mut x as *mut usize;

  We allow casting const array references to const pointers so not
  allowing mut references to mut pointers was inconsistent.

- mut array reference to const ptr. Example:

      let mut x: [usize; 2] = [0, 0];
      let p = &mut x as *const usize;

  This was similarly inconsistent as we allow casting mut references to
  const pointers.

Existing test 'vector-cast-weirdness' updated to test both cases.

Fixes #24151
This commit is contained in:
Ömer Sinan Ağacan 2021-01-28 20:22:33 +03:00
parent 6523b721c3
commit d64b749f2c
4 changed files with 55 additions and 25 deletions

View file

@ -1,7 +1,11 @@
// Issue #14893. Tests that casts from vectors don't behave strangely in the
// presence of the `_` type shorthand notation.
//
// Update: after a change to the way casts are done, we have more type information
// around and so the errors here are no longer exactly the same.
//
// Update: With PR #81479 some of the previously rejected cases are now allowed.
// New test cases added.
struct X {
y: [u8; 2],
@ -12,13 +16,19 @@ fn main() {
// No longer a type mismatch - the `_` can be fully resolved by type inference.
let p1: *const u8 = &x1.y as *const _;
let p1: *mut u8 = &x1.y as *mut _;
//~^ ERROR: casting `&[u8; 2]` as `*mut u8` is invalid
let t1: *const [u8; 2] = &x1.y as *const _;
let t1: *mut [u8; 2] = &x1.y as *mut _;
//~^ ERROR: casting `&[u8; 2]` as `*mut [u8; 2]` is invalid
let h1: *const [u8; 2] = &x1.y as *const [u8; 2];
let t1: *mut [u8; 2] = &x1.y as *mut [u8; 2];
//~^ ERROR: casting `&[u8; 2]` as `*mut [u8; 2]` is invalid
let mut x1 = X { y: [0, 0] };
// This is still an error since we don't allow casts from &mut [T; n] to *mut T.
let p1: *mut u8 = &mut x1.y as *mut _; //~ ERROR casting
let p1: *mut u8 = &mut x1.y as *mut _;
let p2: *const u8 = &mut x1.y as *const _;
let t1: *mut [u8; 2] = &mut x1.y as *mut _;
let h1: *mut [u8; 2] = &mut x1.y as *mut [u8; 2];
}

View file

@ -1,9 +1,21 @@
error[E0606]: casting `&mut [u8; 2]` as `*mut u8` is invalid
--> $DIR/vector-cast-weirdness.rs:21:23
error[E0606]: casting `&[u8; 2]` as `*mut u8` is invalid
--> $DIR/vector-cast-weirdness.rs:19:23
|
LL | let p1: *mut u8 = &mut x1.y as *mut _;
| ^^^^^^^^^^^^^^^^^^^
LL | let p1: *mut u8 = &x1.y as *mut _;
| ^^^^^^^^^^^^^^^
error: aborting due to previous error
error[E0606]: casting `&[u8; 2]` as `*mut [u8; 2]` is invalid
--> $DIR/vector-cast-weirdness.rs:22:28
|
LL | let t1: *mut [u8; 2] = &x1.y as *mut _;
| ^^^^^^^^^^^^^^^
error[E0606]: casting `&[u8; 2]` as `*mut [u8; 2]` is invalid
--> $DIR/vector-cast-weirdness.rs:25:28
|
LL | let t1: *mut [u8; 2] = &x1.y as *mut [u8; 2];
| ^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0606`.