From 2251c7be26b1c6cc467618e0e8b6d3eb441ab025 Mon Sep 17 00:00:00 2001 From: Johann Hemmann Date: Tue, 15 Aug 2023 11:12:12 +0200 Subject: [PATCH] Document early exit of method candidate search Before it was unclear that Rust does not search through all candidates types, but exits the search as soon as it found a fitting method. --- src/expressions/method-call-expr.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/expressions/method-call-expr.md b/src/expressions/method-call-expr.md index 8a2f68cc3..18ce3b963 100644 --- a/src/expressions/method-call-expr.md +++ b/src/expressions/method-call-expr.md @@ -19,7 +19,7 @@ The following procedure is used: The first step is to build a list of candidate receiver types. Obtain these by repeatedly [dereferencing][dereference] 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`. +Then, for each candidate `T`, add `&T` and `&mut T` to the ordered list immediately after `T`. 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]`. @@ -30,6 +30,8 @@ Then, for each candidate type `T`, search for a [visible] method with a receiver If `T` is a type parameter, methods provided by trait bounds on `T` are looked up first. Then all remaining methods in scope are looked up. +As soon as one candidate type yielded a fitting method, the search process is stopped. + > Note: the lookup is done for each type in order, which can occasionally lead to surprising results. > The below code will print "In trait impl!", because `&self` methods are looked up first, the trait method is found before the struct's `&mut self` method is found. > @@ -58,7 +60,7 @@ Then, for each candidate type `T`, search for a [visible] method with a receiver > } > ``` -If this results in multiple possible candidates, then it is an error, and the receiver must be [converted][disambiguate call] to an appropriate receiver type to make the method call. +If any candidate type results in multiple possible methods, then it is an error, and the receiver must be [converted][disambiguate call] to an appropriate receiver type to make the method call. This process does not take into account the mutability or lifetime of the receiver, or whether a method is `unsafe`. Once a method is looked up, if it can't be called for one (or more) of those reasons, the result is a compiler error.