# Understanding \&mut \&mut Reference

## Problem Statement

I followed [a Solana tutorial](https://github.com/figment-networks/learn-web3-dapp) and had some trouble understanding the following code:

```rust
greeting_account.serialize(&mut &mut account.data.borrow_mut()[..])?;
```

where `greeting_account` is a struct and `.serialize()` is a method derived from [BorshSerialize](https://docs.rs/borsh/latest/borsh/ser/trait.BorshSerialize.html).

One other thing to note is that `account` is an [AccountInfo](https://docs.rs/solana-program/1.8.1/solana_program/account_info/struct.AccountInfo.html) struct from the [solana\_program](https://docs.rs/solana-program/1.10.8/solana_program) crate and `data` has to type: `Rc<RefCell<&'a mut [u8]>>`

The magic with double `&mut` and `[..]` make me, a Rust newbie, really feel scared.&#x20;

This problem has troubled me for a long time, making me care neither for food nor drink, and now I want to beat fear and try to understand this sentence.

## Resolution

First of all, let me google it, and fortunately, I found the most relevant answer just on the top of the result: [Trouble understanding \&mut \&mut reference](https://stackoverflow.com/questions/69670357/trouble-understanding-mut-mut-reference).

Let me split the problem into the following:

1. Why should we add `[..]`?
2. Why double `&mut`?

The code in the tutorial is very long and deep, if you don't want to clone the code, the following code *(which has the same effect as the code in the tutorial I think...)* is simplified for you to understand:

```rust
use borsh::maybestd::io::Write; // Simply add 'borsh = "0.9.1"' to Cargo.toml
use std::cell::RefCell;
use std::rc::Rc;

struct Node<'a> {
    value: Rc<RefCell<&'a mut [u8]>>,
}

fn ref_mut<T: Write>(x: &mut T) -> &mut T {
    x
}

fn main() {
    let mut v: [u8; 3] = [1, 2, 3];
    let node = Node {
        value: Rc::new(RefCell::new(&mut v)),
    };
    println!("{:?}", ref_mut(&mut &mut node.value.borrow_mut()[..]));
}
```

where `value` in the struct `Node` has the same type as the `data` in `account`, and the function `ref_mut` has the same receiver as the function `serialize`.

### Why should we add `[..]`?

{% hint style="info" %}
Most of this part is referenced from the top answer in [Trouble understanding \&mut \&mut reference](https://stackoverflow.com/a/69674104).
{% endhint %}

If we want to know the secret of the double `&mut`, we may go through the `[..]` first.

When we look at the [documentation about certain cases of indexing](https://doc.rust-lang.org/std/ops/trait.IndexMut.html), we see, that

```rust
node.value.borrow_mut()[..]
```

is sugar for

```rust
*(node.value.borrow_mut().index_mut(..))
```

Why is that a valid expression?

`..` is a shorthand for [`RangeFull`](https://doc.rust-lang.org/std/ops/struct.RangeFull.html).

`RangeFull` has an implementation for [`SliceIndex<[u8]>`](https://doc.rust-lang.org/std/ops/struct.RangeFull.html#impl-SliceIndex%3C%5BT%5D%3E).

With this [blanket implementation](https://doc.rust-lang.org/std/ops/trait.IndexMut.html#impl-IndexMut%3CI%3E-1), we get a `IndexMut<RangeFull> for [u8]`, which provides

```rust
fn index_mut(&mut [u8], index: RangeFull) -> &mut [u8]
```

### Why double `&mut`?

The double `&mut` really bothered me for a while, since the common case may only have one in it.

After I made it clear, I found it is actually a simple problem of type. Let's go back to the code above again, and locate the line of code which we have a problem with:

```rust
println!("{:?}", ref_mut(&mut &mut node.value.borrow_mut()[..]));
```

In this line, we pass `&mut &mut node.value.borrow_mut()[..]` as a parameter into the function named `ref_mut`:

```rust
fn ref_mut<T: Write>(x: &mut T) -> &mut T {
    x
}
```

As [Trait Bound Syntax](https://doc.rust-lang.org/book/ch10-02-traits.html#trait-bound-syntax) says:

> The `impl Trait` syntax works for straightforward cases but is actually syntax sugar for a longer form, which is called a *trait bound*; it looks like this:
>
> ```rust
> pub fn notify<T: Summary>(item: &T) {
>     println!("Breaking news! {}", item.summarize());
> }
> ```
>
> This longer form is equivalent to the example in the previous section but is more verbose. We place trait bounds with the declaration of the generic type parameter after a colon and inside angle brackets.

so the type `T` we input to `ref_mut` should implement `Write`, which is the same as the `Write` in the problem, since the definition of the trait Write is very long, so let's go to the definition of the main method (`write` for a writer) in it:

```rust
#[stable(feature = "rust1", since = "1.0.0")]
#[doc(notable_trait)]
#[cfg_attr(not(test), rustc_diagnostic_item = "IoWrite")]
pub trait Write {
    // -- snip --
    #[stable(feature = "rust1", since = "1.0.0")]
    fn write(&mut self, buf: &[u8]) -> Result<usize>;
    // -- snip --
}
```

According to the method, the instance of `Write` should be a mutable reference of an array with `u8` type.

Now let's push it backwords, in order to satisfy the bound `Write`, the generic type in `ref_mut` has to be `&mut [u8]`, and we remove the generic type in `ref_mut` temporarily, which simply replaces T with `&mut [u8]`, besides, add some suitable lifetime parameters:

```rust
fn ref_mut<'a>(x: &'a mut &'a mut [u8]) -> &'a mut &'a mut [u8] {
    x
}
```

From now on, the problem is simple for everyone, we have a function that receives one parameter with the type: `&mut &mut [u8]`.

Here are the types of every part of `&mut &mut node.value.borrow_mut()[..]`:

* `node.value.borrow_mut()` has `RefMut<&mut [u8]>`
* `node.value.borrow_mut()[..]` has `[u8]`
* `&mut node.value.borrow_mut()[..]` has `&mut [u8]`
* `&mut &mut node.value.borrow_mut()[..]` has `&mut &mut [u8]`

To keep track of the actual writing position, we need a mutable reference to the mutable reference, and the input should have double `&mut` now.

Now the [auto dereferencing](https://doc.rust-lang.org/reference/expressions/method-call-expr.html) kicks in.

```rust
node.value.borrow_mut().index_mut(..)
```

And `RefMut<&mut [u8]>` implements [`DerefMut`](https://doc.rust-lang.org/std/ops/trait.DerefMut.html#impl-DerefMut-4) which have `Deref<Target = &mut [u8]>` as a super trait.

And `&mut [u8]` implements `DerefMut` with `Deref<Target = [u8]>` as a super trait.

As mentioned in the [reference](https://doc.rust-lang.org/reference/expressions/method-call-expr.html), the compiler will now take the receiver expression and dereference it repeatedly, so it gets a list of candidate types. It also adds for each type resulting from a dereference of the reference type and the mutable reference type to the list of candidate types. From these candidate types, it selects one providing the method to call.

1. `RefMut<&mut [u8]>` using `node.value.borrow_mut()`
2. `&RefMut<&mut [u8]>`
3. `&mut RefMut<&mut [u8]>`
4. `&mut [u8]` using `*node.value.borrow_mut().deref_mut()` (means dereferenced from `RefMut<&mut [u8]>`)
5. `&&mut [u8]`
6. `&mut &mut [u8]`
7. `[u8]` using `*(*node.value.borrow_mut().deref_mut())` (now dereferenced from `&mut [u8]`)
8. `&[u8]`
9. `&mut [u8]`

(In 7. we are dereferencing a pointer type `&mut [u8]` so no `DerefMut` the Trait is used.)

The first (and only) type in this list provides an `index_mut()` method is `&mut [u8]`, via the `IndexMut<FullRange>` implementation for `[u8]`, so `&mut [u8]` is selected as receiver type. The return type of `index_mut()` is `&mut [u8]` as well.

So now, we hopefully understand, the type of `*(node.value.borrow_mut().index_mut(..))` is `[u8]`.

Thanks to the discussion of dereferencing, `node.value.borrow_mut()` can also be dereferenced with `*`. Since `node.value` has type `RefMut<&mut [u8]>`, it will be `&mut [u8]` after dereferencing, which can get the actual value simply. Finally after adding one more `&mut`, we can also match the type the function needed:

```rust
println!("{:?}", ref_mut(&mut *node.value.borrow_mut()));
```

## Conclusion

It may be confused if you are familiar with the `*` and `&` operator in C++ when you just step into the reference in Rust. Since they are two different things, we should avoid using C++ references to think about Rust references.

According to the question [Why do references need to be explicitly dereferenced](https://users.rust-lang.org/t/solved-why-do-references-need-to-be-explicitly-dereferenced/7770), these words reminded me:

> So I’d treat `&` types in Rust like you would `*` types in C/C++, while keeping in mind the following points.
>
> 1. A Rust `&` type is stored as a pointer, sometimes with a length and other information (see below responses).
> 2. When you call `foo.bar()`, or access `foo.bar`, rust will automatically dereference foo if it has a type of `&Foo`.
> 3. There is a trait called `Deref` that some smart pointer types implement, to change how the \* operator works.

## Reference

1. [Solana Tutorial 101](https://learn.figment.io/pathways/solana-pathway)
2. [Borsh, binary serializer for security-critical projects](https://borsh.io/)
3. [Carte borsh](https://docs.rs/borsh/latest/borsh/)
4. [The base library for all Solana on-chain Rust programs](https://docs.rs/solana-program/1.10.8/solana_program/)
5. [Trouble understanding \&mut \&mut reference](https://stackoverflow.com/questions/69670357/trouble-understanding-mut-mut-reference)
6. [Trait Bound Syntax](https://doc.rust-lang.org/book/ch10-02-traits.html#trait-bound-syntax)
7. [Documentation about certain cases of indexing](https://doc.rust-lang.org/std/ops/trait.IndexMut.html)
8. [RangeFull](https://doc.rust-lang.org/std/ops/struct.RangeFull.html)
9. [SliceIndex<\[u8\]>](https://doc.rust-lang.org/std/ops/struct.RangeFull.html#impl-SliceIndex%3C%5BT%5D%3E)
10. [Blanket implementation](https://doc.rust-lang.org/std/ops/trait.IndexMut.html#impl-IndexMut%3CI%3E-1)
11. [Why do references need to be explicitly dereferenced?](https://users.rust-lang.org/t/solved-why-do-references-need-to-be-explicitly-dereferenced/7770)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://a.b.cr/notebook/language/rust/reference/understanding-and-mut-and-mut-reference.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
