Skip to content

Suggest cloning Arc/Rc #104232

Description

@ibraheemdev
fn main() {
    let x = Arc::new(1);
    foo(x);
    bar(x);
}

fn foo(_: Arc<usize>) {}
fn bar(_: Arc<usize>) {}
error[[E0382]](https://doc.rust-lang.org/stable/error-index.html#E0382): use of moved value: `x`
 --> src/main.rs:6:9
  |
4 |     let x = Arc::new(1);
  |         - move occurs because `x` has type `std::sync::Arc<usize>`, which does not implement the `Copy` trait
5 |     foo(x);
  |         - value moved here
6 |     bar(x);
  |         ^ value used here after move

The help message could mention that Arc implements Clone. We don't usually suggest cloning values in diagnostics, but for Arc/Rc we probably should.

Another common case (this one is probably harder to suggest a fix for):

fn main() {
    let x = Arc::new(1);
    for _ in 0..4 {
        std::thread::spawn(move || {
            println!("{}", x);
        });
    }
}
error[[E0382]](https://doc.rust-lang.org/stable/error-index.html#E0382): use of moved value: `x`
 --> src/main.rs:6:28
  |
4 |     let x = Arc::new(1);
  |         - move occurs because `x` has type `std::sync::Arc<i32>`, which does not implement the `Copy` trait
5 |     for _ in 0..4 {
6 |         std::thread::spawn(move || {
  |                            ^^^^^^^ value moved into closure here, in previous iteration of loop
7 |             println!("{}", x);
  |                            - use occurs due to use in closure

Activity

  1. added
    A-diagnosticsArea: Messages for errors, warnings, and lints
    T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.
    on Nov 10, 2022
  2. chenyukang commented on Nov 10, 2022

    @chenyukang
    Member

    @rustbot claim

  3. estebank commented on Nov 11, 2022

    @estebank
    Contributor

    @chenyukang make sure to account for Rc as well! :)

  4. chenyukang commented on Nov 24, 2022

    @chenyukang
    Member

    This is covered by #103908, could be closed now.

  5. estebank commented on Nov 24, 2022

    @estebank
    Contributor

    @chenyukang oh! Great to hear, sorry for making you waste your time :-/

    There are a couple of improvements I would like to make on top of that merged PR though, which you might be interested in doing: I would like to customize the message depending on the type size (if smaller than lets say a KB do not talk about perf cost), whether the type implements Drop (to mention that the drop guard might change what is being done) and special case Arc and Rc and tell people to clone without any equivocation. We might want to use this ticket to track that work?

  6. estebank commented on Jan 13, 2023

    @estebank
    Contributor

    Triage: The first case is now handled, but the second case isn't.

  7. added
    D-newcomer-roadblockDiagnostics: Confusing error or lint; hard to understand for new users.
    D-terseDiagnostics: An error or lint that doesn't give enough information about the problem at hand.
    on Jan 13, 2023
  8. added a commit that references this issue on May 1, 2024
    0e39707
  9. estebank commented on May 1, 2024

    @estebank
    Contributor

    Current output:

    error[E0382]: use of moved value: `x`
     --> src/main.rs:5:9
      |
    3 |     let x = Arc::new(1);
      |         - move occurs because `x` has type `Arc<usize>`, which does not implement the `Copy` trait
    4 |     foo(x);
      |         - value moved here
    5 |     bar(x);
      |         ^ value used here after move
      |
    note: consider changing this parameter type in function `foo` to borrow instead if owning the value isn't necessary
     --> src/main.rs:8:11
      |
    8 | fn foo(_: Arc<usize>) {}
      |    ---    ^^^^^^^^^^ this parameter takes ownership of the value
      |    |
      |    in this function
    help: clone the value to increment its reference count
      |
    4 |     foo(x.clone());
      |          ++++++++
    
    error[E0382]: use of moved value: `x`
     --> src/main.rs:5:28
      |
    3 |     let x = Arc::new(1);
      |         - move occurs because `x` has type `Arc<i32>`, which does not implement the `Copy` trait
    4 |     for _ in 0..4 {
      |     ------------- inside of this loop
    5 |         std::thread::spawn(move || {
      |                            ^^^^^^^ value moved into closure here, in previous iteration of loop
    6 |             println!("{}", x);
      |                            - use occurs due to use in closure
    

    After #124595, the output will be

    error[E0382]: use of moved value: `qwer`
     --> f203.rs:5:28
      |
    3 |     let qwer = Arc::new(1);
      |         ---- move occurs because `qwer` has type `Arc<i32>`, which does not implement the `Copy` trait
    4 |     for _ in 0..4 {
      |     ------------- inside of this loop
    5 |         std::thread::spawn(move || {
      |                            ^^^^^^^ value moved into closure here, in previous iteration of loop
    6 |             println!("{}", qwer);
      |                            ---- use occurs due to use in closure
      |
    help: clone the value before moving it into the closure
      |
    5 ~         let value = qwer.clone();
    6 ~         std::thread::spawn(move || {
    7 ~             println!("{}", value);
      |
    
  10. added 2 commits that reference this issue on May 1, 2024
    63051c3
    d695130
  11. added a commit that references this issue on Jun 24, 2025
    63dd473
  12. added a commit that references this issue on Jun 26, 2025
    f24d64a
  13. added 2 commits that reference this issue on Jun 26, 2025
    53cd91d
    aa8ba54
  14. added a commit that references this issue on Jun 26, 2025
    8cddd10
  15. added a commit that references this issue on Jun 27, 2025
    f3e6cd0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

A-diagnosticsArea: Messages for errors, warnings, and lintsD-newcomer-roadblockDiagnostics: Confusing error or lint; hard to understand for new users.D-terseDiagnostics: An error or lint that doesn't give enough information about the problem at hand.T-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