Path errors caused by copy not implemented

Hello i have tried a bunch of solutions but i cant seem to get around copy not implemented.
(.clone()) Gives same error.

note: the full funciton is bigger. you can find the entire "program" here: GitHub - NicTanghe/winder: Terminal file browser with vim and image support WIndows compatible.

 let temp = location_loc1.parent().unwrap();
 location_loc1.push(&temp);

It looks like your program has a few errors, so let's try to step through them one by one.

First is this one on line 75:

error[E0382]: use of moved value: `location_loc1`
  --> src/main.rs:75:40
   |
37 | async fn print_events(mut selector_loc1:i8, location_loc1: PathBuf) {
   |                                             ------------- move occurs because `location_loc1` has type `std::path::PathBuf`, which does not implement the `Copy` trait
...
75 |                             let test = location_loc1;
   |                                        ^^^^^^^^^^^^^ value used here after move
...
89 |                         printtype(location_loc1,selector_loc1);
   |                                   ------------- value moved here, in previous iteration of loop

We can reduce it down to this:

use std::path::PathBuf;

fn foo(location_loc1: PathBuf) {
    let test = location_loc1;
    println!("{}", location_loc1.display());
}

(playground)

The reason this fails is because you've moved the location_loc1 value into test on line 75 of your code, then try to use it again later on. But when you move the location_loc1 value to another location the original variable is no longer initialized, so trying to use it later on doesn't make sense.

The second error is almost identical to the first:

error[E0382]: borrow of moved value: `location_loc1`
    --> src/main.rs:76:42
     |
37   | async fn print_events(mut selector_loc1:i8, location_loc1: PathBuf) {
     |                                             ------------- move occurs because `location_loc1` has type `std::path::PathBuf`, which does not implement the `Copy` trait
...
75   |                             let test = location_loc1;
     |                                        ------------- value moved here
76   |                             let parent = location_loc1.parent().map(|p| p.to_owned()).unwrap();
     |                                          ^^^^^^^^^^^^^^^^^^^^^^ value borrowed here after move

We can use the same reasoning here. The variable in location_loc1 has been moved into test so the location_loc1 variable no longer contains anything and trying to use it doesn't make sense.

The "which does not implement the Copy trait" bit is because the only time you can continue using a value after it has been assigned somewhere else is when the type implements Copy. The Copy trait is special and tells the compiler that assignment should copy the value's bytes to the new variable and leave the original variable intact.

I'm not sure what you are trying to accomplish here so can't provide the right fix, although you might be able to explicitly make a copy of the path instead of moving it (i.e. let test = location_loc1.clone()).

You also get this error message:

error[E0596]: cannot borrow `location_loc1` as mutable, as it is not declared as mutable
  --> src/main.rs:77:29
   |
37 | async fn print_events(mut selector_loc1:i8, location_loc1: PathBuf) {
   |                                             ------------- help: consider changing this to be mutable: `mut location_loc1`
...
77 |                             location_loc1.push(parent);
   |                             ^^^^^^^^^^^^^ cannot borrow as mutable

That's because the push() method takes &mut self because it is mutating the PathBuf. However you haven't said we are allowed to mutate location_loc1 (by marking it as mut), so calling a method which borrows self as mut isn't allowed.

The compiler even tells you how you can fix the problem: "help: consider changing this to be mutable: mut location_loc1".

Your Down Votes on Stack Exchange

I think what is happening is that you haven't given the right amount of context for people to adequately answer your question.

For example, those two lines alone don't really give me enough information to reproduce your issue, although I could make a pretty good guess based on my experience with similar "copy not implemented" errors. What I mean is that if I copied that into an empty file (or even the body of a main() function) and pointed the compiler at it I would either get a syntax error or the compiler would complain that location_loc1 doesn't exist and I don't know what type it is meant to have.

Similarly, I'm missing crucial information like which precise statement was triggering the error and hints for resolving the issue that the compiler is providing.

People aren't trying to be patronising or difficult here, without a Minimal, Reproducible example it really is hard to help you figure out what caused your problem.

On the other end of the spectrum, giving someone a link to a full repository is too much context. I now need to clone your repository and sift through a 203-line main.rs file in order to figure out what is going wrong. Considering most people are answering questions on the internet in their own time because they want to be nice, you don't want to take advantage of that good will by making them waste half an hour reading your entire program (in reality, most people won't bother and will just leave your question unanswered).

As an aside, I know it's frustrating when people keep proposing solutions which don't work for your situation but try not to be too vocal about other platforms. It's not a good look.

6 Likes

To be frank, this is the type of question that is probably explicitly mentioned in the SO FAQ as not having enough research effort put into it, or at least it is not apparent what you have tried to solve it, since it's about a very basic aspect of the language. You should probably go through an introductory tutorial such as Rust by Example before even considering asking such a question.

2 Likes

Seems because of stress I forgot to add a proper description.

I have already tried all the mentioned fixes and more and none of them work.
The mut was no longer there by accident.

also, clone still returns me the error that

borrow of moved value: location_loc1
value borrowed here after moverustcE0382

main.rs(89, 35): value moved here, in previous iteration of loop

main.rs(37, 44): move occurs because location_loc1 has type std::path::PathBuf, which does not implement the Copy trait

I guess I'm just a bit perplexed by people giving simple solutions that don't fix anything. Which I already tried but forgot to state here.

I'm grateful for the attempt at help, though.

ALso i had a previous version that used strings wich fed paths but that had the issue that it turns some / into \ wich breaks strings.

Ignoring the missing comma in the imports and the missing mut, running cargo check on your repository returns 3 errors. Changing just

- let test = location_loc1;
+ let test = location_loc1.clone();

makes it so cargo check only returns one error. The remaining error is essentially the same as the other two and can be fixed the same way, the change to the let test line is just an example (hence the i.e.).

Well, here's the playground I got by stubbing anything possibly relevant and trimming everything clearly non-relevant. The errors are:

error[E0382]: use of moved value: `location_loc1`
  --> src/main.rs:68:40
   |
50 | async fn print_events(mut selector_loc1:i8, location_loc1: PathBuf) {
   |                                             ------------- move occurs because `location_loc1` has type `PathBuf`, which does not implement the `Copy` trait
...
68 |                             let test = location_loc1;
   |                                        ^^^^^^^^^^^^^ value used here after move
...
78 |                         printtype(location_loc1,selector_loc1);
   |                                   ------------- value moved here, in previous iteration of loop

error[E0382]: borrow of moved value: `location_loc1`
    --> src/main.rs:69:42
     |
50   | async fn print_events(mut selector_loc1:i8, location_loc1: PathBuf) {
     |                                             ------------- move occurs because `location_loc1` has type `PathBuf`, which does not implement the `Copy` trait
...
68   |                             let test = location_loc1;
     |                                        ------------- value moved here
69   |                             let parent = location_loc1.parent().map(|p| p.to_owned()).unwrap();
     |                                          ^^^^^^^^^^^^^^^^^^^^^^ value borrowed here after move
     |
     = note: borrow occurs due to deref coercion to `Path`
note: deref defined here

error[E0596]: cannot borrow `location_loc1` as mutable, as it is not declared as mutable
  --> src/main.rs:70:29
   |
50 | async fn print_events(mut selector_loc1:i8, location_loc1: PathBuf) {
   |                                             ------------- help: consider changing this to be mutable: `mut location_loc1`
...
70 |                             location_loc1.push(parent);
   |                             ^^^^^^^^^^^^^ cannot borrow as mutable

error[E0382]: use of moved value: `location_loc1`
  --> src/main.rs:78:35
   |
50 | async fn print_events(mut selector_loc1:i8, location_loc1: PathBuf) {
   |                                             ------------- move occurs because `location_loc1` has type `PathBuf`, which does not implement the `Copy` trait
...
68 |                             let test = location_loc1;
   |                                        ------------- value moved here
...
78 |                         printtype(location_loc1,selector_loc1);
   |                                   ^^^^^^^^^^^^^ value moved here, in previous iteration of loop

Going from the first:

  • printtype takes ownership of its first argument, so it can't be used afterwards. However, it's not really using the ownership, so you can make it less restrictive by changing loc: PathBuf to loc: &Path. This change, along with the corresponding changes on call sites (compiler will remind you where they are), eliminates both the first and the last error.
  • let test = location_loc1; also moves ownership from the location_loc1. The fix is even simpler: test isn't used, so this assignment can be removed. If in real code test is used, however, you have to either add explicit clone, as suggested above, or rearrange your code so that test only needs a borrow of location_loc1.
  • Finally, the "cannot borrow location_loc1 as mutable" error is fixed just by following the compiler suggestion as-is.

And here's the playground with all fixes applied.

1 Like

The main issues seems to b me not properly updating GitHub because I'm forgot the git commit -m command.

And as I said in the description, it doesn't fix anything that is actually a problem.
Since the issue remains that the copy trait is not implemented.

I appreciate everyone pointing me to obvious mistakes.

But I did come here to get help on other thing then reading the error codes and first google hits.

I did go through rust by example.

The problem is that it's 2 simple and doesn't tell you how to fix the error of copy not implemented even when you use clone.

The issue is that you're trying to copy the thing which cannot be copied, just because of its semantics. And, of course, if you try to clone the thing after it was moved - the error will not go away, since, well, there's nothing to be cloned by this moment.

I was replying to an old answer.
Sorry for blurring out what i think, it's a bit more obvious in real life, but still.
I realize I'm being a complete ass here, which is not fun dealing with.

Indeed Just changing to path buf &PathBuf and fixing some random mistakes seems to make it all compile.

Now there is a whole bunch of other problems but ill mark as solved and spend some time trying to fix the parenting to work as it should.