Universal Function Call Syntax

Sometimes, functions can have the same names. Consider this code:

fn main() { trait Foo { fn f(&self); } trait Bar { fn f(&self); } struct Baz; impl Foo for Baz { fn f(&self) { println!("Baz’s impl of Foo"); } } impl Bar for Baz { fn f(&self) { println!("Baz’s impl of Bar"); } } let b = Baz; }
trait Foo {
    fn f(&self);
}

trait Bar {
    fn f(&self);
}

struct Baz;

impl Foo for Baz {
    fn f(&self) { println!("Baz’s impl of Foo"); }
}

impl Bar for Baz {
    fn f(&self) { println!("Baz’s impl of Bar"); }
}

let b = Baz;

If we were to try to call b.f()`b.f()`, we’d get an error:

error: multiple applicable methods in scope [E0034]
b.f();
  ^~~
note: candidate #1 is defined in an impl of the trait `main::Foo` for the type
`main::Baz`
    fn f(&self) { println!("Baz’s impl of Foo"); }
    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
note: candidate #2 is defined in an impl of the trait `main::Bar` for the type
`main::Baz`
    fn f(&self) { println!("Baz’s impl of Bar"); }
    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

We need a way to disambiguate which method we need. This feature is called ‘universal function call syntax’, and it looks like this:

fn main() { trait Foo { fn f(&self); } trait Bar { fn f(&self); } struct Baz; impl Foo for Baz { fn f(&self) { println!("Baz’s impl of Foo"); } } impl Bar for Baz { fn f(&self) { println!("Baz’s impl of Bar"); } } let b = Baz; Foo::f(&b); Bar::f(&b); }
Foo::f(&b);
Bar::f(&b);

Let’s break it down.

fn main() { Foo:: Bar:: }
Foo::
Bar::

These halves of the invocation are the types of the two traits: Foo`Fooand` and Bar`Bar`. This is what ends up actually doing the disambiguation between the two: Rust calls the one from the trait name you use.

fn main() { f(&b) }
f(&b)

When we call a method like b.f()`b.f()using [method syntax][methodsyntax], Rust will automatically borrow` using method syntax, Rust will automatically borrow b`bif` if f()`f()takes` takes &self`&self. In this case, Rust will not, and so we need to pass an explicit`. In this case, Rust will not, and so we need to pass an explicit &b`&b`.

Angle-bracket Form

The form of UFCS we just talked about:

fn main() { Trait::method(args); }
Trait::method(args);

Is a short-hand. There’s an expanded form of this that’s needed in some situations:

fn main() { <Type as Trait>::method(args); }
<Type as Trait>::method(args);

The <>::`<>::syntax is a means of providing a type hint. The type goes inside the` syntax is a means of providing a type hint. The type goes inside the <>`<>s. In this case, the type is`s. In this case, the type is Type as Trait`Type as Trait, indicating that we want`, indicating that we want Trait`Trait’s version of`’s version of method`methodto be called here. The` to be called here. The as Trait`as Trait` part is optional if it’s not ambiguous. Same with the angle brackets, hence the shorter form.

Here’s an example of using the longer form.

fn main() { trait Foo { fn clone(&self); } #[derive(Clone)] struct Bar; impl Foo for Bar { fn clone(&self) { println!("Making a clone of Bar"); <Bar as Clone>::clone(self); } } }
trait Foo {
    fn clone(&self);
}

#[derive(Clone)]
struct Bar;

impl Foo for Bar {
    fn clone(&self) {
        println!("Making a clone of Bar");

        <Bar as Clone>::clone(self);
    }
}

This will call the Clone`Clonetrait’s` trait’s clone()`clone()method, rather than` method, rather than Foo`Foo`’s.