diff --git a/src/expressions.md b/src/expressions.md index df79faba7..d89d29cb8 100644 --- a/src/expressions.md +++ b/src/expressions.md @@ -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 @@ -544,6 +548,78 @@ let x: i32 = add(1i32, 2i32); let pi: Result = "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 + ::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` + ::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") diff --git a/src/undocumented.md b/src/undocumented.md index c3ae24788..72a546127 100644 --- a/src/undocumented.md +++ b/src/undocumented.md @@ -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