What types are allowed for `self` in methods?

A method tipically has

fn my_method(self, ...)

but there are some traits that has these:

fn poll_read(
    self: Pin<&mut Self>,
    cx: &mut Context<'_>,
    buf: &mut tokio::io::ReadBuf<'_>
) -> Poll<std::io::Result<()>> {

I couldn't find anywhere the rules for what is allowed. For example, I can do a method for Arc<Self> like this:

use std::sync::Arc;

struct A{
    u: u8
}

impl A{
    fn my_method(self: Arc<Self>) -> u8{
        self.u
    }
}

but what are the limits?

2 Likes
struct S;

impl S {
    pub fn f(self: usize) {}
}

The code above fails to compile with the error below:

error[E0307]: invalid `self` parameter type: usize
 --> src/lib.rs:4:20
  |
4 |     pub fn f(self: usize) {}
  |                    ^^^^^
  |
  = note: type of `self` must be `Self` or a type that dereferences to it
  = help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)

I didn't know either, so I pretty much just asked the compiler. I love rustc so much :slight_smile:

2 Likes

https://doc.rust-lang.org/stable/reference/items/associated-items.html?highlight=self#methods

// Examples of methods implemented on struct `Example`.
struct Example;
type Alias = Example;
trait Trait { type Output; }
impl Trait for Example { type Output = Example; }
impl Example {
    fn by_value(self: Self) {}
    fn by_ref(self: &Self) {}
    fn by_ref_mut(self: &mut Self) {}
    fn by_box(self: Box<Self>) {}
    fn by_rc(self: Rc<Self>) {}
    fn by_arc(self: Arc<Self>) {}
    fn by_pin(self: Pin<&Self>) {}
    fn explicit_type(self: Arc<Example>) {}
    fn with_lifetime<'a>(self: &'a Self) {}
    fn nested<'a>(self: &mut &'a Arc<Rc<Box<Alias>>>) {}
    fn via_projection(self: <Example as Trait>::Output) {}
}
5 Likes

What is via_projection() and what is it used for? I've never seen it so far.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.