d33tah
d33tah

Reputation: 11561

Why can't I pass a String from env::Args to Path::new?

Consider the following example:

use std::env;
use std::path::Path;

fn main() {
    let args: Vec<_> = env::args().collect();
    let out_path: String = args[2];
    let _path = Path::new(out_path);
}

Here's the error I'm getting while compiling:

error[E0308]: mismatched types
 --> main.rs:8:27
  |
8 |     let _path = Path::new(out_path);
  |                           ^^^^^^^^
  |                           |
  |                           expected reference, found struct `std::string::String`
  |                           help: consider borrowing here: `&out_path`
  |
  = note: expected type `&_`
             found type `std::string::String`

Now if I follow compiler's suggestion, I get this:

error[E0507]: cannot move out of indexed content
 --> main.rs:7:28
  |
7 |     let out_path: String = args[2];
  |                            ^^^^^^^
  |                            |
  |                            cannot move out of indexed content
  |                            help: consider using a reference instead: `&args[2]`

error: aborting due to previous error

Which, after applying the suggestion, leads me to the previous error:

error[E0308]: mismatched types
 --> main.rs:7:28
  |
7 |     let out_path: String = &args[2];
  |                            ^^^^^^^^
  |                            |
  |                            expected struct `std::string::String`, found reference
  |                            help: consider removing the borrow: `args[2]`
  |
  = note: expected type `std::string::String`
             found type `&std::string::String`

How can I understand the situation and solve the problem?

Upvotes: 0

Views: 227

Answers (1)

ljedrz
ljedrz

Reputation: 22173

This was indeed an unfortunate sequence of suggestions (use a reference > remove that reference), but this was caused by the manual type ascription related to out_path.

You want a string slice, not an owned String:

let out_path: &str = &args[2];

This fits both the restriction of args (you can't move out of indexed content) and the requirements of Path::new, which requires a reference.

As for your comment, a clone() "fixes" the cannot move out of indexed content error because it doesn't require a move from the args vector - it copies an element from it instead. This fix is of course inferior to just borrowing it, which also works with Path::new.

Upvotes: 5

Related Questions