]> git.proxmox.com Git - rustc.git/blame - src/doc/reference/src/expressions/method-call-expr.md
New upstream version 1.52.0~beta.3+dfsg1
[rustc.git] / src / doc / reference / src / expressions / method-call-expr.md
CommitLineData
ea8adc8c
XL
1# Method-call expressions
2
0bf4aa26
XL
3> **<sup>Syntax</sup>**\
4> _MethodCallExpression_ :\
5> &nbsp;&nbsp; [_Expression_] `.` [_PathExprSegment_] `(`[_CallParams_]<sup>?</sup> `)`
6
6a06907d
XL
7A _method call_ consists of an expression (the *receiver*) followed by a single dot, an expression path segment, and a parenthesized expression-list.
8Method calls are resolved to associated [methods] on specific traits, either statically dispatching to a method if the 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/trait-object.md).
ea8adc8c
XL
9
10```rust
11let pi: Result<f32, _> = "3.14".parse();
12let log_pi = pi.unwrap_or(1.0).log(2.72);
13# assert!(1.14 < log_pi && log_pi < 1.15)
14```
15
6a06907d
XL
16When looking up a method call, the receiver may be automatically dereferenced or borrowed in order to call a method.
17This requires a more complex lookup process than for other functions, since there may be a number of possible methods to call.
18The following procedure is used:
2c00a5a8 19
6a06907d
XL
20The first step is to build a list of candidate receiver types.
21Obtain these by repeatedly [dereferencing][dereference] the receiver expression's type, adding each type encountered to the list, then finally attempting an [unsized coercion] at the end, and adding the result type if that is successful.
22Then, for each candidate `T`, add `&T` and `&mut T` to the list immediately after `T`.
2c00a5a8 23
6a06907d 24For instance, if the receiver has type `Box<[i32;2]>`, then the candidate types will be `Box<[i32;2]>`, `&Box<[i32;2]>`, `&mut Box<[i32;2]>`, `[i32; 2]` (by dereferencing), `&[i32; 2]`, `&mut [i32; 2]`, `[i32]` (by unsized coercion), `&[i32]`, and finally `&mut [i32]`.
2c00a5a8 25
6a06907d 26Then, for each candidate type `T`, search for a [visible] method with a receiver of that type in the following places:
ea8adc8c 27
2c00a5a8 281. `T`'s inherent methods (methods implemented directly on `T`).
6a06907d
XL
291. Any of the methods provided by a [visible] trait implemented by `T`.
30 If `T` is a type parameter, methods provided by trait bounds on `T` are looked up first.
31 Then all remaining methods in scope are looked up.
32
33> Note: the lookup is done for each type in order, which can occasionally lead to surprising results.
34> The below code will print "In trait impl!", because `&self` methods are looked up first, the trait method is found before the struct's `&mut self` method is found.
2c00a5a8
XL
35>
36> ```rust
37> struct Foo {}
38>
39> trait Bar {
40> fn bar(&self);
41> }
42>
43> impl Foo {
44> fn bar(&mut self) {
45> println!("In struct impl!")
46> }
47> }
48>
49> impl Bar for Foo {
50> fn bar(&self) {
51> println!("In trait impl!")
52> }
53> }
54>
55> fn main() {
56> let mut f = Foo{};
57> f.bar();
58> }
59> ```
60
6a06907d 61If this results in multiple possible candidates, then it is an error, and the receiver must be [converted][disambiguate call] to an appropriate receiver type to make the method call.
2c00a5a8 62
6a06907d
XL
63This process does not take into account the mutability or lifetime of the receiver, or whether a method is `unsafe`.
64Once a method is looked up, if it can't be called for one (or more) of those reasons, the result is a compiler error.
2c00a5a8 65
6a06907d
XL
66If a step is reached where there is more than one possible method, such as where generic methods or traits are considered the same, then it is a compiler error.
67These cases require a [disambiguating function call syntax] for method and function invocation.
ff7c6d11 68
8faf50e0
XL
69<div class="warning">
70
6a06907d
XL
71***Warning:*** For [trait objects], if there is an inherent method of the same name as a trait method, it will give a compiler error when trying to call the method in a method call expression.
72Instead, you can call the method using [disambiguating function call syntax], in which case it calls the trait method, not the inherent method.
73There is no way to call the inherent method.
74Just don't define inherent methods on trait objects with the same name a trait method and you'll be fine.
8faf50e0
XL
75
76</div>
2c00a5a8 77
416331ca
XL
78[_CallParams_]: call-expr.md
79[_Expression_]: ../expressions.md
80[_PathExprSegment_]: ../paths.md#paths-in-expressions
81[visible]: ../visibility-and-privacy.md
82[trait objects]: ../types/trait-object.md
83[disambiguate call]: call-expr.md#disambiguating-function-calls
84[disambiguating function call syntax]: call-expr.md#disambiguating-function-calls
85[dereference]: operator-expr.md#the-dereference-operator
86[methods]: ../items/associated-items.md#methods
87[unsized coercion]: ../type-coercions.md#unsized-coercions