rust-lang / rust-lang/rust

Mutable reference prevents value from being moved to its current address

Open
#127,206 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

C-discussion
Dominant language
Rust
Stars
119k
Forks
16.1k
PR merge metrics
PR metrics pending

Description

I tried this code:

fn main() {}

pub struct Structer {
    pub stringy: Vec<String>,
}

impl Structer {
    pub fn extend_stringy(&mut self) {
        self.stringy = self
            .stringy
            .into_iter()
            .map(|stringy| stringy + "extension")
            .collect::<Vec<String>>();
    }
}

I expected this:

self
    .stringy
    .into_iter()
    .map(|stringy| stringy + "extension")
    .collect::<Vec<String>>();

to be assigned to self.stringy, because the value is moved into the same location from where it came.

Instead, I got this error message:

cannot move out of `self.stringy` which is behind a mutable reference
move occurs because `self.stringy` has type `std::vec::Vec<std::string::String>`, which does not implement the `Copy` traitrustc[Click for full compiler diagnostic](rust-analyzer-diagnostics-view:/diagnostic%20message%20%5B0%5D?0#file%3A%2F%2F%2Fhome%2Famir%2Fsrc%2Fnice%2Fsrc%2Fmain.rs)
main.rs(11, 14): `self.stringy` moved due to this method call
collect.rs(344, 18): `std::iter::IntoIterator::into_iter` takes ownership of the receiver `self`, which moves `self.stringy`
main.rs(9, 24): you can `clone` the value and consume it, but this might not be your desired behavior: `<std::vec::Vec<std::string::String> as Clone>::clone(&`, `)`
main.rs(10, 21): consider cloning the value if the performance cost is acceptable: `.clone()`
Meta

rustc --version --verbose:

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
Backtrace

error[E0507]: cannot move out of `self.stringy` which is behind a mutable reference
   --> src/main.rs:9:24
    |
9   |           self.stringy = self
    |  ________________________^
10  | |             .stringy
    | |____________________^ move occurs because `self.stringy` has type `Vec<String>`, which does not implement the `Copy` trait
11  |               .into_iter()
    |                ----------- `self.stringy` moved due to this method call
    |
note: `into_iter` takes ownership of the receiver `self`, which moves `self.stringy`
   --> /home/amir/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/iter/traits/collect.rs:344:18
    |
344 |     fn into_iter(self) -> Self::IntoIter;
    |                  ^^^^
help: you can `clone` the value and consume it, but this might not be your desired behavior
    |
9   ~         self.stringy = <Vec<String> as Clone>::clone(&self
10  ~             .stringy)
    |
help: consider cloning the value if the performance cost is acceptable
    |
10  |             .stringy.clone()
    |                     ++++++++

For more information about this error, try `rustc --explain E0507`.
error: could not compile `nice` (bin "nice") due to 1 previous error

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce the diagnostic from the reported main.rs example with the stated rustc version, then read the ownership and move-checking behavior involved in assigning through &mut self. The issue is asking whether this same-field transformation should be accepted; completion would require an agreed language or compiler behavior and corresponding regression coverage.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
compilers
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.