You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: text/3519-arbitrary-self-types-v2.md
+6-4Lines changed: 6 additions & 4 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -236,17 +236,19 @@ The existing Rust [reference section for method calls describes the algorithm fo
236
236
237
237
The key part of the first page is this:
238
238
239
+
> The first step is to build a list of **candidate receiver types**. Obtain these by repeatedly dereferencing 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. Then, for each candidate `T`, add `&T` and `&mut T` to the list immediately after `T`.
240
+
239
241
> Then, for each candidate type `T`, search for a visible method with a receiver of that type in the following places:
240
242
> -`T`'s inherent methods (methods implemented directly on `T`).
241
243
> Any of the methods provided by a visible trait implemented by `T`.
242
244
243
-
This changes.
245
+
We'll call this second list the **candidate methods**.
244
246
245
-
The list of candidate types is assembled in exactly the same way, but we now search for a visible method with a receiver of that type in _more_ places.
247
+
With this RFC, the candidate receiver types are assembled the same way - nothing changes. But, the **candidate methods** are assembled in a different way. Specifically, instead of iterating the candidate receiver types, we assemble a new list of types by following the chain of `Receiver` implementations. As `Receiver` is implemented for all types that implement `Deref`, this may be the same list or a longer list. Aside from following a different trait, the list is assembled the same way, including the insertion of equivalent reference types.
246
248
247
-
Specifically, instead of using the list of candidate types assembled using the `Deref`trait, we search a list assembled using the `Receiver` trait. As `Receiver`is implemented for all types that implement `Deref`, this is a longer list.
249
+
We then search each type for inherent methods or trait methods in the existing fashion - the only change is that we search a potentially longer list of types.
248
250
249
-
It's particularly important to emphasize that the list of candidate receiver types _does not change_ - that's still assembled using the `Deref` trait just as now. But, a wider set of locations is searched for methods with those receiver types.
251
+
It's particularly important to emphasize also that the list of candidate receiver types _does not change_. But, a wider set of locations is searched for methods with those receiver types.
250
252
251
253
For instance, `Weak<T>` implements `Receiver` but not `Deref`. Imagine you have `let t: Weak<SomeStruct> = /* obtain */; t.some_method();`. We will now search `impl SomeStruct {}` blocks for an implementation of `fn some_method(self: Weak<SomeStruct>)`, `fn some_method(self: &Weak<SomeStruct>)`, etc. The possible self types in the method call expression are unchanged - they're still obtained by searching the `Deref` chain for `t` - but we'll look in more places for methods with those valid `self` types.
0 commit comments