Skip to content

Suboptimal diagnostic E0599 on impl AsRef<T> #140178

@JarredAllen

Description

@JarredAllen

Code

pub fn foo(path: impl AsRef<std::path::Path>) {
    let _ = path.join("bar");
}

Current output

error[E0599]: no method named `join` found for type parameter `impl AsRef<std::path::Path>` in the current scope
 --> src/lib.rs:2:18
  |
1 | pub fn foo(path: impl AsRef<std::path::Path>) {
  |                  --------------------------- method `join` not found for this type parameter
2 |     let _ = path.join("bar");
  |                  ^^^^ method not found in `impl AsRef<std::path::Path>`

For more information about this error, try `rustc --explain E0599`.

Desired output

It should suggest `path.as_ref().join(..)` (add in the `.as_ref()`) to make it visible.

Rationale and extra context

I was helping someone else new to Rust, and I suggested that they use Path::join() to append to a path. They initially tried doing that, but then it didn't work because they had the code like the one in the snippet and impl AsRef<Path> doesn't have a .join() method. Iteratively trying things and fixing them on their own, with hints from the rust compiler, they eventually landed on this worse code that does compile:

pub fn foo(path: impl AsRef<std::path::Path> + std::fmt::Display) {
    let _ = format!("{path}/bar");
}

I think they would have found their way to the correct solution if there was any sort of hint that the problem was that they needed to add a .as_ref() call.

More generally, I think this would be good for any impl AsRef<T>, if someone tries to use a method/field on T itself (maybe excluding cases where you either have impl AsRef<T> + AsRef<U> or impl<U: AsRef<T>> SomeTrait for U, I think these diagnostics might not be as helpful in edge-cases like those).

Other cases

Rust Version

the current nightly as hosted on play.rust-lang.org

Anything else?

No response

Metadata

Metadata

Assignees

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