Skip to content

Suggest changing receiver of method when used causing move error #159488

Description

@estebank

Code

struct Bag(Vec<i32>);

impl Bag {
    fn total(self) -> i32 {
        self.0.iter().sum()
    }
}

fn main() {
    let bag = Bag(vec![1]);
    println!("{}", bag.total());

    // The diagnostic points out that `self` consumes `bag`, but for a locally
    // defined method it could also mention changing the receiver to `&self` when
    // the method does not need ownership.
    println!("{:?}", bag.0);
    //~^ ERROR borrow of moved value: `bag`
}

Current output

error[E0382]: borrow of moved value: `bag`
  --> $DIR/local-by-value-method-receiver.rs:20:22
   |
LL |     let bag = Bag(vec![1]);
   |         --- move occurs because `bag` has type `Bag`, which does not implement the `Copy` trait
LL |     println!("{}", bag.total());
   |                        ------- `bag` moved due to this method call
...
LL |     println!("{:?}", bag.0);
   |                      ^^^^^ value borrowed here after move
   |
note: `Bag::total` takes ownership of the receiver `self`, which moves `bag`
  --> $DIR/local-by-value-method-receiver.rs:8:14
   |
LL |     fn total(self) -> i32 {
   |              ^^^^

Desired output

error[E0382]: borrow of moved value: `bag`
  --> $DIR/local-by-value-method-receiver.rs:20:22
   |
LL |     let bag = Bag(vec![1]);
   |         --- move occurs because `bag` has type `Bag`, which does not implement the `Copy` trait
LL |     println!("{}", bag.total());
   |                        ------- `bag` moved due to this method call
...
LL |     println!("{:?}", bag.0);
   |                      ^^^^^ value borrowed here after move
   |
note: `Bag::total` takes ownership of the receiver `self`, which moves `bag`
  --> $DIR/local-by-value-method-receiver.rs:8:14
   |
LL |     fn total(self) -> i32 {
   |              ^^^^
help: consider changing `Bag::total` to not consume `Self`
   |
LL |     fn total(&self) -> i32 {
   |              +

Rationale and extra context

We should only provide the suggestion if we've analyzed total to check that it doesn't need to consume Self.

The act is already implied by the current diagnostic.

Other cases

Rust Version

1.97

Anything else?

No response

Metadata

Metadata

Assignees

Labels

A-diagnosticsArea: Messages for errors, warnings, and lintsD-lack-of-suggestionDiagnostics: Adding a (structured) suggestion would increase the quality of the diagnostic.D-papercutDiagnostics: An error or lint that needs small tweaks.P-lowLow priorityT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions