Skip to content

Commit cea25a8

Browse files
committed
Arbitrary self types v2: update reference.
1 parent 93b921c commit cea25a8

File tree

3 files changed

+37
-10
lines changed

3 files changed

+37
-10
lines changed

src/expressions/method-call-expr.md

+21-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,18 @@ Then, for each candidate `T`, add `&T` and `&mut T` to the list immediately afte
2323

2424
For 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]`.
2525

26-
Then, for each candidate type `T`, search for a [visible] method with a receiver of that type in the following places:
26+
A second - possible more expansive - list is then made of types where we might
27+
find [visible] methods with a receiver of that type, called the list of
28+
contributing types. To make this list, follow the exact same process,
29+
but this time use the `Receiver` trait
30+
instead of the `Deref` trait for any non-built-in derefences.
31+
32+
There is a blanket implementation of `Receiver` for all `T: Deref`, so in many
33+
cases the lists are identical, but there are rare smart pointers which
34+
may implement `Receiver` without implementing `Deref`, so this second list of
35+
types may be longer than the list of candidate types.
36+
37+
Then, for each contributing type `T`, search for a [visible] method with a receiver of any candidate type in the following places:
2738

2839
1. `T`'s inherent methods (methods implemented directly on `T`).
2940
1. Any of the methods provided by a [visible] trait implemented by `T`.
@@ -66,6 +77,15 @@ Once a method is looked up, if it can't be called for one (or more) of those rea
6677
If 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.
6778
These cases require a [disambiguating function call syntax] for method and function invocation.
6879
80+
As well as emitting methods for multiple candidates within a given step,
81+
an additional search may be performed to look for specific cases where an outer
82+
(smart pointer) type may have a method that shadows or overrides a method
83+
on its referent. This process is performed if we are about to return a method
84+
identified by a by-value step; a search is then performed for a matching by-reference
85+
methods deeper along the chain of contributing types with an identical `self` type.
86+
This extra search is also performed if we are about to return a method from
87+
a `&T` pick; error are emitted if a `&mut T` method would be shadowed.
88+
6989
> **Edition differences**: Before the 2021 edition, during the search for visible methods, if the candidate receiver type is an [array type], methods provided by the standard library [`IntoIterator`] trait are ignored.
7090
>
7191
> The edition used for this purpose is determined by the token representing the method name.

src/items/associated-items.md

+5-8
Original file line numberDiff line numberDiff line change
@@ -110,15 +110,11 @@ well as the usual function call notation.
110110

111111
r[items.associated.fn.method.self-ty]
112112
If the type of the `self` parameter is specified, it is limited to types resolving
113-
to one generated by the following grammar (where `'lt` denotes some arbitrary
114-
lifetime):
113+
to a type implementing the [`Receiver`] trait with a `Target` associated type
114+
matching the implementing type. Typically, this means the type itself, a
115+
reference to it, or a smart pointer referring to it (such as [`Box<Self>`]
116+
or [`Arc<Self>`]).
115117

116-
```text
117-
P = &'lt S | &'lt mut S | Box<S> | Rc<S> | Arc<S> | Pin<P>
118-
S = Self | P
119-
```
120-
121-
The `Self` terminal in this grammar denotes a type resolving to the implementing type.
122118
This can also include the contextual type alias `Self`, other type aliases,
123119
or associated type projections resolving to the implementing type.
124120

@@ -564,6 +560,7 @@ fn main() {
564560
[`Pin<P>`]: ../special-types-and-traits.md#pinp
565561
[`Rc<Self>`]: ../special-types-and-traits.md#rct
566562
[`Sized`]: ../special-types-and-traits.md#sized
563+
[`Receiver`]: ../special-types-and-traits.md#receiver
567564
[traits]: traits.md
568565
[type aliases]: type-aliases.md
569566
[inherent implementations]: implementations.md#inherent-implementations

src/special-types-and-traits.md

+11-1
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,16 @@ r[lang-types.deref]
7373
## `Deref` and `DerefMut`
7474

7575
As well as overloading the unary `*` operator, [`Deref`] and [`DerefMut`] are
76-
also used in [method resolution] and [deref coercions].
76+
also used in [deref coercions]; see also [`Receiver`] below.
77+
78+
r[lang-types.receiver]
79+
## `Receiver`
80+
81+
[`Receiver`] is used in [method resolution]. It indicates that a type may be
82+
used as a method receiver; that is, the type of a `self` parameter for a
83+
method. There is a blanket implementation of `Receiver` for all `T: Deref`,
84+
so it's rare to implement `Receiver` directly: you'd only normally do this
85+
for smart pointer types which for some reason can't implement `Deref`.
7786

7887
r[lang-types.drop]
7988
## `Drop`
@@ -218,6 +227,7 @@ These implicit `Sized` bounds may be relaxed by using the special `?Sized` bound
218227
[`DerefMut`]: std::ops::DerefMut
219228
[`Pin<P>`]: std::pin::Pin
220229
[`Rc<Self>`]: std::rc::Rc
230+
[`Receiver`]: std::ops::Receiver
221231
[`RefUnwindSafe`]: std::panic::RefUnwindSafe
222232
[`Termination`]: std::process::Termination
223233
[`UnwindSafe`]: std::panic::UnwindSafe

0 commit comments

Comments
 (0)