Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Discuss unambiguous function call syntax #45

Merged
merged 3 commits into from
May 26, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 76 additions & 0 deletions src/expressions.md
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,10 @@ exact `self`-type of the left-hand-side is known, or dynamically dispatching if
the left-hand-side expression is an indirect [trait
object](types.html#trait-objects).

The compiler sometimes cannot infer to which function or method a given call
refers. These cases require a [more specific syntax.](#disambiguating-function-calls)
for method and function invocation.

## Field expressions

A _field expression_ consists of an expression followed by a single dot and an
Expand Down Expand Up @@ -544,6 +548,78 @@ let x: i32 = add(1i32, 2i32);
let pi: Result<f32, _> = "3.14".parse();
```

### Disambiguating Function Calls

Rust treats all function calls as sugar for a more explicit, fully-qualified
syntax. Upon compilation, Rust will desugar all function calls into the explicit
form. Rust may sometimes require you to qualify function calls with trait,
depending on the ambiguity of a call in light of in-scope items.

> **Note**: In the past, the Rust community used the terms "Unambiguous
> Function Call Syntax", "Universal Function Call Syntax", or "UFCS", in
> documentation, issues, RFCs, and other community writings. However, the term
> lacks descriptive power and potentially confuses the issue at hand. We mention
> it here for searchability's sake.

Several situations often occur which result in ambiguities about the receiver or
referent of method or associated function calls. These situations may include:

* Multiple in-scope traits define methods with the same name for the same types
* Auto-`deref` is undesirable; for example, distinguishing between methods on a
smart pointer itself and the pointer's referent
* Methods which take no arguments, like `default()`, and return properties of a
type, like `size_of()`

To resolve the ambiguity, the programmer may refer to their desired method or
function using more specific paths, types, or traits.

For example,

```rust
trait Pretty {
fn print(&self);
}

trait Ugly {
fn print(&self);
}

struct Foo;
impl Pretty for Foo {
fn print(&self) {}
}

struct Bar;
impl Pretty for Bar {
fn print(&self) {}
}
impl Ugly for Bar{
fn print(&self) {}
}

fn main() {
let f = Foo;
let b = Bar;

// we can do this because we only have one item called `print` for `Foo`s
f.print();
// more explicit, and, in the case of `Foo`, not necessary
Foo::print(&f);
// if you're not into the whole brevity thing
<Foo as Pretty>::print(&f);

// b.print(); // Error: multiple 'print' found
// Bar::print(&b); // Still an error: multiple `print` found

// necessary because of in-scope items defining `print`
<Bar as Pretty>::print(&b);
}
```

Refer to [RFC 132] for further details and motivations.

[RFC 132]: https://github.com/rust-lang/rfcs/blob/master/text/0132-ufcs.md

## Lambda expressions

A _lambda expression_ (sometimes called an "anonymous function expression")
Expand Down
1 change: 0 additions & 1 deletion src/undocumented.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ to shrink!
specified.
- [Flexible target specification] - Some---but not all---flags are documented
in [Conditional compilation]
- [Unambiguous function call syntax]
- [Require parentheses for chained comparisons]
- [Integer overflow not `unsafe`] - documented with a reference to the RFC, but
requires further details
Expand Down