| The `self` parameter in a method has an invalid "receiver type". | |
| Erroneous code example: | |
| ```compile_fail,E0307 | |
| struct Foo; | |
| struct Bar; | |
| trait Trait { | |
| fn foo(&self); | |
| } | |
| impl Trait for Foo { | |
| fn foo(self: &Bar) {} | |
| } | |
| ``` | |
| Methods take a special first parameter, of which there are three variants: | |
| `self`, `&self`, and `&mut self`. These are syntactic sugar for | |
| `self: Self`, `self: &Self`, and `self: &mut Self` respectively. | |
| ``` | |
| # struct Foo; | |
| trait Trait { | |
| fn foo(&self); | |
| // ^^^^^ `self` here is a reference to the receiver object | |
| } | |
| impl Trait for Foo { | |
| fn foo(&self) {} | |
| // ^^^^^ the receiver type is `&Foo` | |
| } | |
| ``` | |
| The type `Self` acts as an alias to the type of the current trait | |
| implementer, or "receiver type". Besides the already mentioned `Self`, | |
| `&Self` and `&mut Self` valid receiver types, the following are also valid: | |
| `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, and `self: Pin<P>` | |
| (where P is one of the previous types except `Self`). Note that `Self` can | |
| also be the underlying implementing type, like `Foo` in the following | |
| example: | |
| ``` | |
| # struct Foo; | |
| # trait Trait { | |
| # fn foo(&self); | |
| # } | |
| impl Trait for Foo { | |
| fn foo(self: &Foo) {} | |
| } | |
| ``` | |
| This error will be emitted by the compiler when using an invalid receiver type, | |
| like in the following example: | |
| ```compile_fail,E0307 | |
| # struct Foo; | |
| # struct Bar; | |
| # trait Trait { | |
| # fn foo(&self); | |
| # } | |
| impl Trait for Foo { | |
| fn foo(self: &Bar) {} | |
| } | |
| ``` | |
| The nightly feature [Arbitrary self types][AST] extends the accepted | |
| set of receiver types to also include any type that implements the | |
| `Receiver` trait and can follow its chain of `Target` types to `Self`. | |
| There's a blanket implementation of `Receiver` for `T: Deref`, so any | |
| type which dereferences to `Self` can be used. | |
| ``` | |
| #![feature(arbitrary_self_types)] | |
| struct Foo; | |
| struct Bar; | |
| // Because you can dereference `Bar` into `Foo`... | |
| impl std::ops::Deref for Bar { | |
| type Target = Foo; | |
| fn deref(&self) -> &Foo { | |
| &Foo | |
| } | |
| } | |
| impl Foo { | |
| fn foo(self: Bar) {} | |
| // ^^^^^^^^^ ...it can be used as the receiver type | |
| } | |
| ``` | |
| [AST]: https://doc.rust-lang.org/unstable-book/language-features/arbitrary-self-types.html |