Skip to the content.

Autodereferencing and autoborrowing

Autodereferencing and autoborrowing are two important conveniences in Rust’s type system and method resolution that make code easier to write and read. Let’s break them down carefully:


🔍 1. Autodereferencing

Definition: When you use . syntax to call a method (like v.method()), Rust automatically inserts dereference operations (*) as needed to find the method definition.

Why?

To allow types like Box<T>, Rc<T>, or any type that implements Deref<Target = T> to be treated transparently, so you don’t have to manually write (*v).method().


Example:

use std::ops::Deref;

struct MyBox<T>(T);

impl<T> Deref for MyBox<T> {
    type Target = T;

    fn deref(&self) -> &Self::Target {
        &self.0
    }
}

impl String {
    fn shout(&self) {
        println!("{}!!!", self.to_uppercase());
    }
}

fn main() {
    let my_box = MyBox(String::from("hello"));

    // Here: my_box.shout()
    // Rust:
    // 1. Looks for shout() on MyBox<String> -> not found
    // 2. Autoderef: *my_box -> String
    // 3. Looks for shout() on String -> found

    my_box.shout();
}

Behind the scenes:

(*my_box).shout();

But Rust’s autoderef spares you the explicit * calls.


🔍 2. Autoborrowing

Definition: When calling a method, Rust automatically borrows the receiver (self), if the method signature expects &self or &mut self.


Example:

struct MyStruct;

impl MyStruct {
    fn greet(&self) {
        println!("Hello!");
    }
}

fn main() {
    let s = MyStruct;

    // s.greet() implicitly borrows s as &s
    s.greet();
}

Behind the scenes:

(&s).greet();

This is known as autoborrow.


🔄 Putting It Together

When you call a method:

v.method()

Rust does the following (in order):

✅ 1. Check if v has the method.
✅ 2. If not, autoderef v repeatedly (call Deref::deref) until it finds a type with the method.
✅ 3. Once it finds the method, it checks the method’s self type (self, &self, or &mut self), and autoborrows v as needed.


Summary Table

Concept Action Example
Autoderef Automatically dereferences values using Deref v.method() -> (*v).method()
Autoborrow Automatically borrows values to match &self or &mut self v.method() -> (&v).method()

When doesn’t it happen?

🚫 Autoderef happens only for method calls (dot syntax), not for functions like some_func(v) — that’s why sometimes you have to manually call &v or *v.