Redeclaring self as mut in method

This is just a style question, but it's bugged me for years so I wanted to see if anyone else had any ideas. It concerns methods that take ownership of instances of Self.

pub fn some_func(self) -> Self

I notice in the core, and std APIs I haven't seen any of them take mut self:

pub fn some_func(mut self) -> Self

That led me to conclude that explicitly specifying mut in the method signature when taking ownership is somehow ugly. Leaking implementation details unnecessarily. After all, it's taking ownership so the method can mutate it if it wants to.

So, I've always done this:

pub fn some_func(self) -> Self {
    let mut input_self = self;
    ...
    input_self
}

But it's always bugged me that I couldn't just do this:

pub fn some_func(self) -> Self {
    let mut self = self;
}

Does this bug anyone else, or am I crazy? And more to the point, what do other people do?

Thanks!

There's some recent discussion here:

2 Likes

rustdoc doesn't show the mut in documentation, precisely because it is an implementation detail.

7 Likes

FWIW, the generally used synonym for self when you need to rebind it is this.

2 Likes

:exploding_head:

I didn't realize. I was basing my aversion on the lack of mut in the docs. But there could have been mut in the code all along.

How long has this been the case? I certainly remember that it did a while back.

That's what I recalled too, but it has been quite awhile apparently. I have no idea how comprehensive the signature normalization is.

Rust trivia night material: The pattern of your arguments is not always an implementation detail per se, as it can affect your API (unintentionally).

2 Likes

I don't think this example showing that the pattern affects the API. The code compiles just as well if the destructuring into let (_i, mut x) = arg; is done locally. Also, all it shows is how the pattern being used determines whether the implementation compiles at all, whereas an example of something affecting the API would need two function implementations to compile, but the callers to behave differently or compile vs. not compile.

3 Likes

Oops, my memory got it backwards, thanks.

Huh, that's way longer than I thought. I don't care enough to bisect what release it changed in :person_shrugging: