> For the complete documentation index, see [llms.txt](https://a.b.cr/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://a.b.cr/notebook/language/rust/reference/understanding-and-mut-and-mut-reference.md).

# 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)
