lotsoftools

Understanding Rust Error E0389: Cannot Assign to Data in a `&` Reference

Introduction to Rust Error E0389

In Rust, error E0389 occurs when attempting to mutate data using a non-mutable reference. Although this error code is no longer emitted by the compiler, it is still important to understand the concepts and issues surrounding it. In this article, we will explore error E0389 with code examples and discuss how to fix it.

The Error E0389 Code Example

Let's examine the erroneous code example provided by the official Rust documentation:

struct FancyNum {
    num: u8,
}

fn main() {
    let mut fancy = FancyNum{ num: 5 };
    let fancy_ref = &(&mut fancy);
    fancy_ref.num = 6; // error: cannot assign to data in a `&` reference
    println!("{}", fancy_ref.num);
}

In this example, &mut fancy is mutable, but &(&mut fancy) is not. There can be multiple references of type &(&mut T) that point to the same value, so they must be immutable to prevent multiple mutable references to the same value.

How to Fix Rust Error E0389

There are two ways to fix error E0389: either remove the outer reference or make the outer reference mutable.

Option 1: Removing the Outer Reference

Here's the corrected code with the outer reference removed:

struct FancyNum {
    num: u8,
}

fn main() {
    let mut fancy = FancyNum{ num: 5 };

    let fancy_ref = &mut fancy;
    // `fancy_ref` is now &mut FancyNum, rather than &(&mut FancyNum)

    fancy_ref.num = 6; // No error!

    println!("{}", fancy_ref.num);
}

By removing the outer reference, we can now successfully mutate the value without encountering error E0389.

Option 2: Making the Outer Reference Mutable

Alternatively, you can make the outer reference mutable as shown in this example:

struct FancyNum {
    num: u8,
}

fn main() {
    let mut fancy = FancyNum{ num: 5 };

    let fancy_ref = &mut (&mut fancy);
    // `fancy_ref` is now &mut(&mut FancyNum), rather than &(&mut FancyNum)

    fancy_ref.num = 6; // No error!

    println!("{}", fancy_ref.num);
}

Making the outer reference mutable allows for successful data mutation while avoiding error E0389.

Conclusion

In this article, we have explored Rust error E0389, which occurs when attempting to mutate data using a non-mutable reference. We have examined the erroneous code example provided by the official Rust documentation and discussed two ways to fix the issue. Understanding error E0389 and its solutions will help you write more efficient and error-free Rust code.