Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Method Resolution & Operator Overload

Method calls are the expressions that look like $receiver.method($args..). Method calls in Rust involve a fair bit of implicit magic: the receiver expression may be referenced and/or dereferenced to get to the right type, and figuring out which methods are available requires trait solving.

Explaining how that works is out of scope for this guide (see the Reference section); whatever the exact process, the result is that we replace each method call with a full-unambiguous function call expression and some expression adjustments:

#![allow(unused)]
fn main() {
let opt = Some(42);
let x: &i32 = opt.as_ref().clone().unwrap();
// desugars to:
let x: &i32 = Option::unwrap(<Option<&i32> as Clone>::clone(&Option::as_ref(&opt)));
}

The <Type as Trait>::method(self, args..) syntax is called UFCS (Uniform Function Call Syntax) and allows specifying exactly what trait method is getting called. Note also how opt got borrowed into &opt in order to match the type required for Option::as_ref.

Aside postfix method calls, a number of operations can be overridden using traits. We desugar such overridden operations into the appropriate method call:

  • a + b -> Add::add(a, b)
  • a += b -> AddAssign::add_assign(&mut a, b)
  • a - b -> Sub::sub(a, b)
  • -a -> Neg::neg(a)
  • a[b] -> Index::index(&a, b)/IndexMut::index_mut(&mut a, b)
  • f(args...) -> Fn::call/FnMut::call_mut/FnOnce::call_once(f, (args...))
  • etc

The non-overriden versions of these operations stay unchanged. For example + on integers is built-in, but on integer references is defined by a trait:

#![allow(unused)]
fn main() {
let x = 1 + 2 + &3;
// becomes
let x = 1 + <i32 as Add<&i32>>::add(2, &3);
}

Note that we don't handle the * operator (overrideable with Deref/DerefMut) here, we'll do it in Deref/DerefMut Desugarings.

At the end of this step every method call and overridden operator use has been turned into a plain function call.