11# Method-call expressions
22
3- A _ method call_ consists of an expression followed by a single dot, an
4- [ identifier] , and a parenthesized expression-list. Method
5- calls are resolved to methods on specific traits, either statically dispatching
6- to a method if the exact ` self ` -type of the left-hand-side is known, or
7- dynamically dispatching if the left-hand-side expression is an indirect [ trait
8- object] ( types.html#trait-objects ) . Method call expressions will automatically
9- take a shared or mutable borrow of the receiver if needed.
3+ A _ method call_ consists of an expression (the * receiver* ) followed by a single
4+ dot, an [ identifier] , and a parenthesized expression-list. Method calls are
5+ resolved to methods on specific traits, either statically dispatching to a
6+ method if the exact ` self ` -type of the left-hand-side is known, or dynamically
7+ dispatching if the left-hand-side expression is an indirect [ trait
8+ object] ( types.html#trait-objects ) .
109
1110``` rust
1211let pi : Result <f32 , _ > = " 3.14" . parse ();
1312let log_pi = pi . unwrap_or (1.0 ). log (2.72 );
1413# assert! (1.14 < log_pi && log_pi < 1.15 )
1514```
1615
17- When resolving method calls on an expression of type ` A ` , Rust will use the
18- following order, only looking at methods that are [ visible] . If the type of ` A `
19- is a type parameter or ` Self ` in a trait definitition then steps 2-4 first
20- consider traits from bounds on the type paramter, then the traits that are in
21- scope. For other types, only the traits that are in scope are considered.
16+ When looking up a method call, the receiver may be automatically dereferenced or
17+ borrowed in order to call a method. This requires a more complex lookup process
18+ than for other functions, since there may be a number of possible methods to
19+ call. The following procedure is used:
2220
23- 1 . Inherent methods, with receiver of type ` A ` , ` &A ` , ` &mut A ` .
24- 1 . Trait methods with receiver of type ` A ` .
25- 1 . Trait methods with receiver of type ` &A ` .
26- 1 . Trait methods with receiver of type ` &mut A ` .
27- 1 . If it's possible, Rust will then repeat steps 1-5 with
28- ` <A as std::ops::Deref>::Target ` , and insert a dereference operator.
29- 1 . If ` A ` is now an [ array] type, then repeat steps 1-4 with the corresponding
30- slice type.
21+ The first step is to build a list of candidate receiver types. Obtain
22+ these by repeatedly [ dereferencing] [ dereference ] the receiver expression's type,
23+ adding each type encountered to the list, then finally attempting an [ unsized
24+ coercion] at the end, and adding the result type if that is successful. Then,
25+ for each candidate ` T ` , add ` &T ` and ` &mut T ` to the list immediately after ` T ` .
3126
32- Note: In steps 1-4, the receiver is used, not the type of ` Self ` nor the
33- type of ` A ` . For example:
27+ For instance, if the receiver has type ` Box<[i32;2]> ` , then the candidate types
28+ will be ` Box<[i32;2]> ` , ` &Box<[i32;2]> ` , ` &mut Box<[i32;2]> ` , ` [i32; 2] ` (by
29+ dereferencing), ` &[i32; 2] ` , ` &mut [i32; 2] ` , ` [i32] ` (by unsized coercion),
30+ ` &[i32] ` , and finally ` &mut [i32] ` .
3431
35- ``` rust,ignore
36- // `Self` is `&A`, receiver is `&A`.
37- impl<'a> Trait for &'a A {
38- fn method(self) {}
39- }
40- // If `A` is `&B`, then `Self` is `B` and the receiver is `A`.
41- impl B {
42- fn method(&self) {}
43- }
44- ```
32+ Then, for each candidate type ` T ` , search for a [ visible] method with
33+ a receiver of that type in the following places:
34+
35+ 1 . ` T ` 's inherent methods (methods implemented directly on ` T ` ).
36+ 1 . Any of the methods provided by a [ visible] trait implemented by ` T ` . If ` T `
37+ is a type parameter, methods provided by trait bounds on ` T ` are looked up
38+ first. Then all remaining methods in scope are looked up.
39+
40+ > Note: the lookup is done for each type in order, which can occasionally lead
41+ > to surprising results. The below code will print "In trait impl!", because
42+ > ` &self ` methods are looked up first, the trait method is found before the
43+ > struct's ` &mut self ` method is found.
44+ >
45+ > ``` rust
46+ > struct Foo {}
47+ >
48+ > trait Bar {
49+ > fn bar (& self );
50+ > }
51+ >
52+ > impl Foo {
53+ > fn bar (& mut self ) {
54+ > println! (" In struct impl!" )
55+ > }
56+ > }
57+ >
58+ > impl Bar for Foo {
59+ > fn bar (& self ) {
60+ > println! (" In trait impl!" )
61+ > }
62+ > }
63+ >
64+ > fn main () {
65+ > let mut f = Foo {};
66+ > f . bar ();
67+ > }
68+ > ```
69+
70+ If this results in multiple possible candidates , then it is an error , and the
71+ receiver must be [converted ][disambiguate call ] to an appropriate receiver type
72+ to make the method call .
4573
46- Another note: this process does not use the mutability or lifetime of the
47- receiver, or whether ` unsafe ` methods can currently be called to resolve
48- methods. These constraints instead lead to compiler errors.
74+ This process does not take into account the mutability or lifetime of the
75+ receiver , or whether a method is `unsafe `. Once a method is looked up , if it
76+ can 't be called for one (or more ) of those reasons , the result is a compiler
77+ error .
4978
5079If a step is reached where there is more than one possible method , such as where
5180generic methods or traits are considered the same , then it is a compiler
@@ -64,4 +93,5 @@ and function invocation.
6493[visible ]: visibility - and - privacy . html
6594[array ]: types . html#array - and - slice - types
6695[trait objects ]: types . html#trait - objects
67- [ disambiguating function call syntax ] : expressions/call-expr.html#disambiguating-function-calls
96+ [disambiguate call ]: expressions / call - expr . html#disambiguating - function - calls
97+ [dereference ]: expressions / operator - expr . html#the - dereference - operator
0 commit comments