Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't I convert &&mut to &&?

Tags:

rust

This code compiles in C++:

int x = 5;
int *const px = &x;
int *const *const ppx = &px;
int const *const *const cppx = ppx;

So I tried to do the equivalent in Rust:

let mut x: i32 = 5;
let px: &mut i32 = &mut x;
let ppx: &&mut i32 = &px;
let cppx: &&i32 = ppx;

However, this fails to compile:

error[E0308]: mismatched types
 --> src/main.rs:5:23
  |
5 |     let cppx: &&i32 = ppx;
  |               -----   ^^^ types differ in mutability
  |               |
  |               expected due to this
  |
  = note: expected reference `&&i32`
             found reference `&&mut i32`

Why isn't it allowed?

like image 726
vbstb Avatar asked Mar 13 '21 03:03

vbstb


People also ask

Why is my video not converting?

If your video is failing to convert, or unable to play for the entire duration, it's likely that your source file contains corruption. Corruption can be introduced on your hard drive or anywhere along the production process (shooting, editing, exporting).

Why can't I convert to Number in Excel?

On the Tools menu, click Options. In the Options dialog box, click the Error Checking tab. In the Settings section, click to select the Enable background error checking check box. In the Rules section, make sure the Number stored as text rule is selected, and then click OK.

How do you enable convert to Number in Excel?

Convert Text to Numbers Using 'Convert to Number' OptionSelect all the cells that you want to convert from text to numbers. Click on the yellow diamond shape icon that appears at the top right. From the menu that appears, select 'Convert to Number' option.

How do I convert text to numbers?

Select the cells that have numbers stored as text. On the Home tab, click Paste > Paste Special. Click Multiply, and then click OK. Excel multiplies each cell by 1, and in doing so, converts the text to numbers.


1 Answers

So I tried to do the equivalent in Rust:

Careful! C pointers and C++ references are not equivalent to Rust references.

  • int const *x; in C and C++ is a pointer that cannot modify the pointed value. It says nothing about whether the actual value behind the pointer is immutable or not: it is not a pointer to an immutable value! Converting an int *x into that one only restricts what the pointer can do, so it is allowed without a cast. The opposite is not true.

  • &mut i32 in Rust is a mutable reference. If you have one of these, then Rust guarantees that this is the only one that may access the value at this point in time, and that the value itself is mutable. To get such a mutable reference, you had to borrow it at some point. We can convert one of these into an immutable one &i32 because we know we were the only ones, so it is OK to have one immutable one. The opposite is not allowed.

They are similar, and under the hood they end up being an address in memory, but they represent different concepts that give different guarantees.

Why isn't it allowed?

It is, because you are going from mutable to immutable, but you need to be explicit by reborrowing:

let cppx: &&i32 = &&**ppx;

See What's the difference between placing “mut” before a variable name and after the “:”? and https://doc.rust-lang.org/book/ch04-02-references-and-borrowing.html for more information. Rust also has pointer types: *const and *mut.

like image 125
Acorn Avatar answered Sep 20 '22 13:09

Acorn