Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Arbitrary self types v2: update reference. #1699

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 21 additions & 1 deletion src/expressions/method-call-expr.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,18 @@ Then, for each candidate `T`, add `&T` and `&mut T` to the list immediately afte

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]`.

Then, for each candidate type `T`, search for a [visible] method with a receiver of that type in the following places:
A second - possible more expansive - list is then made of types where we might
find [visible] methods with a receiver of that type, called the list of
contributing types. To make this list, follow the exact same process,
but this time use the `Receiver` trait
instead of the `Deref` trait for any non-built-in derefences.

There is a blanket implementation of `Receiver` for all `T: Deref`, so in many
cases the lists are identical, but there are rare smart pointers which
may implement `Receiver` without implementing `Deref`, so this second list of
types may be longer than the list of candidate types.

Then, for each contributing type `T`, search for a [visible] method with a receiver of any candidate type in the following places:

1. `T`'s inherent methods (methods implemented directly on `T`).
1. Any of the methods provided by a [visible] trait implemented by `T`.
Expand Down Expand Up @@ -66,6 +77,15 @@ Once a method is looked up, if it can't be called for one (or more) of those rea
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.
These cases require a [disambiguating function call syntax] for method and function invocation.

As well as emitting methods for multiple candidates within a given step,
an additional search may be performed to look for specific cases where an outer
(smart pointer) type may have a method that shadows or overrides a method
on its referent. This process is performed if we are about to return a method
identified by a by-value step; a search is then performed for a matching by-reference
methods deeper along the chain of contributing types with an identical `self` type.
This extra search is also performed if we are about to return a method from
a `&T` pick; error are emitted if a `&mut T` method would be shadowed.

> **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.
>
> The edition used for this purpose is determined by the token representing the method name.
Expand Down
13 changes: 5 additions & 8 deletions src/items/associated-items.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,15 +113,11 @@ well as the usual function call notation.

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

```text
P = &'lt S | &'lt mut S | Box<S> | Rc<S> | Arc<S> | Pin<P>
S = Self | P
```

The `Self` terminal in this grammar denotes a type resolving to the implementing type.
This can also include the contextual type alias `Self`, other type aliases,
or associated type projections resolving to the implementing type.

Expand Down Expand Up @@ -571,6 +567,7 @@ fn main() {
[`Pin<P>`]: ../special-types-and-traits.md#pinp
[`Rc<Self>`]: ../special-types-and-traits.md#rct
[`Sized`]: ../special-types-and-traits.md#sized
[`Receiver`]: ../special-types-and-traits.md#receiver
[traits]: traits.md
[type aliases]: type-aliases.md
[inherent implementations]: implementations.md#inherent-implementations
Expand Down
11 changes: 10 additions & 1 deletion src/special-types-and-traits.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,15 @@ The traits in [`std::ops`] and [`std::cmp`] are used to overload [operators],
## `Deref` and `DerefMut`

As well as overloading the unary `*` operator, [`Deref`] and [`DerefMut`] are
also used in [method resolution] and [deref coercions].
also used in [deref coercions]; see also [`Receiver`] below.

## `Receiver`

[`Receiver`] is used in [method resolution]. It indicates that a type may be
used as a method receiver; that is, the type of a `self` parameter for a
method. There is a blanket implementation of `Receiver` for all `T: Deref`,
so it's rare to implement `Receiver` directly: you'd only normally do this
for smart pointer types which for some reason can't implement `Deref`.

## `Drop`

Expand Down Expand Up @@ -145,6 +153,7 @@ These implicit `Sized` bounds may be relaxed by using the special `?Sized` bound
[`DerefMut`]: std::ops::DerefMut
[`Pin<P>`]: std::pin::Pin
[`Rc<Self>`]: std::rc::Rc
[`Receiver`]: std::ops::Receiver
[`RefUnwindSafe`]: std::panic::RefUnwindSafe
[`Termination`]: std::process::Termination
[`UnwindSafe`]: std::panic::UnwindSafe
Expand Down
Loading