Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unhelpful .clone() suggestion when moving a mutable reference #127285

Closed
cyrgani opened this issue Jul 3, 2024 · 1 comment · Fixed by #127579
Closed

Unhelpful .clone() suggestion when moving a mutable reference #127285

cyrgani opened this issue Jul 3, 2024 · 1 comment · Fixed by #127579
Assignees
Labels
A-diagnostics Area: Messages for errors, warnings, and lints T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@cyrgani
Copy link
Contributor

cyrgani commented Jul 3, 2024

Code

struct X(u32);

impl X {
    fn f(&mut self) {
        generic(self);
        self.0 += 1;
    }
}

fn generic<T>(_x: T) {}

Current output

error[E0382]: use of moved value: `self`
  --> src/lib.rs:6:9
   |
4  |     fn f(&mut self) {
   |          --------- move occurs because `self` has type `&mut X`, which does not implement the `Copy` trait
5  |         generic(self);
   |                 ---- value moved here
6  |         self.0 += 1;
   |         ^^^^^^^^^^^ value used here after move
   |
note: consider changing this parameter type in function `generic` to borrow instead if owning the value isn't necessary
  --> src/lib.rs:10:19
   |
10 | fn generic<T>(_x: T) {}
   |    -------        ^ this parameter takes ownership of the value
   |    |
   |    in this function
help: consider cloning the value if the performance cost is acceptable
   |
5  |         generic(self).clone();
   |                      ++++++++

For more information about this error, try `rustc --explain E0382`.

Desired output

error[E0382]: use of moved value: `self`
  --> src/lib.rs:6:9
   |
4  |     fn f(&mut self) {
   |          --------- move occurs because `self` has type `&mut X`, which does not implement the `Copy` trait
5  |         generic(self);
   |                 ---- value moved here
6  |         self.0 += 1;
   |         ^^^^^^^^^^^ value used here after move
   |
note: consider changing this parameter type in function `generic` to borrow instead if owning the value isn't necessary
  --> src/lib.rs:10:19
   |
10 | fn generic<T>(_x: T) {}
   |    -------        ^ this parameter takes ownership of the value
   |    |
   |    in this function
help: consider reborrowing `self` instead
   |
5  |         generic(&mut *self);
   |                 ++++++

For more information about this error, try `rustc --explain E0382`.

Rationale and extra context

Cloning the returned value (which is ()) obviously doesn't help. But &mut T does not implement Clone, so changing the suggestion to clone self wouldn't help either. In fact, adding .clone() as suggested right now will error and suggest next:

help: consider cloning the value if the performance cost is acceptable
   |
5  |         generic(self).clone().clone();
   |                      ++++++++

And so on.

Instead, reborrowing self with generic(&mut *self) makes the code compile and should be suggested.

Thanks to bruh791 on the rust community discord server for explaining the problem and solution to me.

Other cases

No response

Rust Version

rustc 1.79.0 (129f3b996 2024-06-10)
binary: rustc
commit-hash: 129f3b9964af4d4a709d1383930ade12dfe7c081
commit-date: 2024-06-10
host: x86_64-unknown-linux-gnu
release: 1.79.0
LLVM version: 18.1.7

Anything else?

Replacing the use of

fn generic<T>(_x: T) {}

with

fn direct(_x: &mut X) {}

compiles even without reborrowing.

@cyrgani cyrgani added A-diagnostics Area: Messages for errors, warnings, and lints T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Jul 3, 2024
@surechen
Copy link
Contributor

surechen commented Jul 4, 2024

@rustbot claim

surechen added a commit to surechen/rust that referenced this issue Jul 10, 2024
…on and it's type is a generic param, it can be reborrowed to avoid moving.

for example:

```rust
struct Y(u32);
// x's type is '& mut Y' and it is used in `fn generic<T>(x: T) {}`.
fn generic<T>(x: T) {}
```

fixes rust-lang#127285
surechen added a commit to surechen/rust that referenced this issue Jul 11, 2024
…on and it's type is a generic param, it can be reborrowed to avoid moving.

for example:

```rust
struct Y(u32);
// x's type is '& mut Y' and it is used in `fn generic<T>(x: T) {}`.
fn generic<T>(x: T) {}
```

fixes rust-lang#127285
surechen added a commit to surechen/rust that referenced this issue Jul 11, 2024
…on and it's type is a generic param, it can be reborrowed to avoid moving.

for example:

```rust
struct Y(u32);
// x's type is '& mut Y' and it is used in `fn generic<T>(x: T) {}`.
fn generic<T>(x: T) {}
```

fixes rust-lang#127285
surechen added a commit to surechen/rust that referenced this issue Jul 11, 2024
…on and it's type is a generic param, it can be reborrowed to avoid moving.

for example:

```rust
struct Y(u32);
// x's type is '& mut Y' and it is used in `fn generic<T>(x: T) {}`.
fn generic<T>(x: T) {}
```

fixes rust-lang#127285
surechen added a commit to surechen/rust that referenced this issue Jul 12, 2024
…on and it's type is a generic param, it can be reborrowed to avoid moving.

for example:

```rust
struct Y(u32);
// x's type is '& mut Y' and it is used in `fn generic<T>(x: T) {}`.
fn generic<T>(x: T) {}
```

fixes rust-lang#127285
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this issue Jul 17, 2024
Solve a error `.clone()` suggestion when moving a mutable reference

If the moved value is a mut reference, it is used in a generic function and it's type is a generic param, suggest it can be reborrowed to avoid moving.

for example:

```rust
struct Y(u32);
// x's type is '& mut Y' and it is used in `fn generic<T>(x: T) {}`.
fn generic<T>(x: T) {}
```

fixes rust-lang#127285
@bors bors closed this as completed in 4821b84 Jul 18, 2024
rust-timer added a commit to rust-lang-ci/rust that referenced this issue Jul 18, 2024
Rollup merge of rust-lang#127579 - surechen:fix_127285, r=lcnr

Solve a error `.clone()` suggestion when moving a mutable reference

If the moved value is a mut reference, it is used in a generic function and it's type is a generic param, suggest it can be reborrowed to avoid moving.

for example:

```rust
struct Y(u32);
// x's type is '& mut Y' and it is used in `fn generic<T>(x: T) {}`.
fn generic<T>(x: T) {}
```

fixes rust-lang#127285
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-diagnostics Area: Messages for errors, warnings, and lints T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants