Skip to content

Commit 3122881

Browse files
author
Alexis Hunt
committed
Further review feedback.
1 parent 87bea5d commit 3122881

File tree

2 files changed

+57
-57
lines changed

2 files changed

+57
-57
lines changed

src/expressions/method-call-expr.md

Lines changed: 45 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,31 @@
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
1211
let pi: Result<f32, _> = "3.14".parse();
1312
let 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`, that expression will
18-
be the `self` parameter. This parameter is special and, unlike with other
19-
parameters to methods or other functions, may be automatically dereferenced or
20-
borrowed in order to call a method. This requires a more complex lookup process,
21-
since there may be a number of possible methods to call. The following procedure
22-
is used:
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:
2320

2421
The first step is to build a list of candidate receiver types. Obtain
25-
these by repeatedly [dereferencing][dereference] the type, adding each type
26-
encountered to the list, then finally attempting an [unsized coercion] at the
27-
end, and adding the result type if that is successful. Then, for each candidate
28-
`T`, add `&T` and `&mut T` to the list immediately after `T`.
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`.
2926

30-
For instance, if `A` is `Box<[i32;2]>`, then the candidate types will be
31-
`Box<[i32;2]>`, `&Box<[i32;2]>`, `&mut Box<[i32;2]>`, `[i32; 2]` (by
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
3229
dereferencing), `&[i32; 2]`, `&mut [i32; 2]`, `[i32]` (by unsized coercion),
3330
`&[i32]`, and finally `&mut [i32]`.
3431

@@ -40,35 +37,35 @@ a receiver of that type in the following places:
4037
is a type parameter, methods provided by trait bounds on `T` are looked up
4138
first. Then all remaining methods in scope are looked up.
4239

43-
Note: the lookup is done for each type in order, which can occasionally lead
44-
to surprising results. The below code will print "In trait impl!", because
45-
`&self` methods are looked up first, the trait method is found before the
46-
struct's `&mut self` method is found.
47-
48-
```rust
49-
struct Foo {}
50-
51-
trait Bar {
52-
fn bar(&self);
53-
}
54-
55-
impl Foo {
56-
fn bar(&mut self) {
57-
println!("In struct impl!")
58-
}
59-
}
60-
61-
impl Bar for Foo {
62-
fn bar(&self) {
63-
println!("In trait impl!")
64-
}
65-
}
66-
67-
fn main() {
68-
let mut f = Foo{};
69-
f.bar();
70-
}
71-
```
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+
> ```
7269
7370
If this results in multiple possible candidates, then it is an error, and the
7471
receiver must be [converted][disambiguate call] to an appropriate receiver type

src/type-coercions.md

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -155,10 +155,10 @@ relate to converting sized types to unsized types, and are permitted in a few
155155
cases where other coercions are not, as described above. They can still happen
156156
anywhere else a coercion can occur.
157157

158-
Two traits, `Unsized` and `CoerceUnsized`, are used to assist in this process
159-
and expose it for library use. The compiler following coercions are built-in
160-
and, if `T` can be coerced to `U` with one of the, then the compiler will
161-
provide an implementation of `Unsized<U>` for `T`:
158+
Two traits, [`Unsize`](Unsize) and [`CoerceUnsized`](CoerceUnsized), are used
159+
to assist in this process and expose it for library use. The compiler following
160+
coercions are built-in and, if `T` can be coerced to `U` with one of the, then
161+
the compiler will provide an implementation of `Unsize<U>` for `T`:
162162

163163
* `[T; n]` to `[T]`.
164164

@@ -167,15 +167,18 @@ provide an implementation of `Unsized<U>` for `T`:
167167

168168
* `Foo<..., T, ...>` to `Foo<..., U, ...>`, when:
169169
* `Foo` is a struct.
170-
* `T` implements `Unsized<U>`.
170+
* `T` implements `Unsize<U>`.
171171
* The last field of `Foo` has a type involving `T`.
172172
* If that field has type `Bar<T>`, then `Bar<T>` implements `Unsized<Bar<U>>`.
173173
* T is not part of the type of any other fields.
174174

175175
Additionally, a type `Foo<T>` can implement `CoerceUnsized<Foo<U>>` when `T`
176-
implements `Unsized<U>` or `CoerceUnsized<Foo<U>>`. This allows it to provide a
176+
implements `Unsize<U>` or `CoerceUnsized<Foo<U>>`. This allows it to provide a
177177
unsized coercion to `Foo<U>`.
178178

179-
Note: While the definition of the unsized coercions and their implementation
180-
has been stabilized, the traits themselves are not yet stable and therefore
181-
can't be used directly in stable Rust.
179+
> Note: While the definition of the unsized coercions and their implementation
180+
> has been stabilized, the traits themselves are not yet stable and therefore
181+
> can't be used directly in stable Rust.
182+
183+
[Unsize]: ../std/marker/trait.Unsize.html
184+
[CoerceUnsized]: ../std/ops/trait.CoerceUnsized.html

0 commit comments

Comments
 (0)