Understanding Rust Error E0307: Invalid Receiver Type
An Overview of Rust Error E0307
Rust Error E0307 occurs when the self parameter in a method has an invalid receiver type. Rust methods have a special first parameter called self, which can have three variants: self, &self, and &mut self. These variants simplify syntax for self: Self, self: &Self, and self: &mut Self, respectively.
Examples of Valid Receiver Types
In addition to the mentioned Self, &Self, and &mut Self, other valid receiver types include self: Box<Self>, self: Rc<Self>, self: Arc<Self>, and self: Pin<P> (where P is one of the previous types except Self). Here are some examples. Valid receiver type example: struct Foo; trait Trait { fn foo(&self); } impl Trait for Foo { fn foo(&self) {} } The receiver type here is `&Foo`. 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) {} }
Causes of Rust Error E0307
This error is emitted when using an invalid receiver type. For example: struct Foo; struct Bar; trait Trait { fn foo(&self); } impl Trait for Foo { fn foo(self: &Bar) {} } Here, the receiver type in the method implementation is &Bar, which is invalid because the Trait is implemented for Foo, not Bar.
Arbitrary Self Types Feature
The nightly feature `Arbitrary self types` extends the set of accepted receiver types to include any type that can dereference to Self. This feature allows more flexibility when defining a receiver type. Example with arbitrary_self_types feature: #![feature(arbitrary_self_types)] struct Foo; struct Bar; impl std::ops::Deref for Bar { type Target = Foo; fn deref(&self) -> &Foo { &Foo } } impl Foo { fn foo(self: Bar) {} } This code compiles because Bar can be dereferenced into Foo.