Skip to content

rustc should suggest borrowing values, when a borrow satisfies the same trait bound as an owned value #102473

@pluiedev

Description

@pluiedev

On the Rust community Discord server, a user reported that functions like std::fs::create_dir_all, that take either PathBufs or &PathBufs thanks to their T: AsRef<Path> bound, do not make clear to the user that the function does not require an owned value.

It is obviously too late to change the signatures on the freestanding functions in std::fs to prevent users from encountering this issue, so we really need to improve the error generated by this issue, which does not mention borrowing the value as a solution.


Given the following code: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=83da9a037a3b29b8f28c341fbb725787

pub fn create_dir_and_return_path() -> std::path::PathBuf {
    let path = std::path::PathBuf::from("haha");
    std::fs::create_dir_all(path).unwrap();
    path
}

The current output is:

Compiling playground v0.0.1 (/playground)
error[[E0382]](https://doc.rust-lang.org/nightly/error-index.html#E0382): use of moved value: `path`
 --> src/lib.rs:4:5
  |
2 |     let path = std::path::PathBuf::from("haha");
  |         ---- move occurs because `path` has type `PathBuf`, which does not implement the `Copy` trait
3 |     std::fs::create_dir_all(path).unwrap();
  |                             ---- value moved here
4 |     path
  |     ^^^^ value used here after move

For more information about this error, try `rustc --explain E0382`.
error: could not compile `playground` due to previous error

Ideally the output should look like:

Compiling playground v0.0.1 (/playground)
error[[E0382]](https://doc.rust-lang.org/nightly/error-index.html#E0382): use of moved value: `path`
 --> src/lib.rs:4:5
  |
2 |     let path = std::path::PathBuf::from("haha");
  |         ---- move occurs because `path` has type `PathBuf`, which does not implement the `Copy` trait
3 |     std::fs::create_dir_all(path).unwrap();
  |                             ---- value moved here
4 |     path
  |     ^^^^ value used here after move
  |
  = help: consider borrowing `path` here:
  |
3 -    std::fs::create_dir_all(path).unwrap();
3 +    std::fs::create_dir_all(&path).unwrap();
  |
  = note: ...so that `path` can remain valid after function call


For more information about this error, try `rustc --explain E0382`.
error: could not compile `playground` due to previous error

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-diagnosticsArea: Messages for errors, warnings, and lintsT-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