Rollup merge of #151954 - Muhtasim-Rasheed:issue-109829-help-message, r=eholk

Add help message suggesting explicit reference cast for From/TryFrom

Closes rust-lang/rust#109829

Improves E0277 diagnostics when a `From` or `TryFrom` implementation is expected, but the provided type is a reference that can be explicitly cast to a type the trait can convert from.
This commit is contained in:
Jonathan Brouwer 2026-02-10 13:00:45 +01:00 committed by GitHub
commit 39bb68119d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 203 additions and 0 deletions

View file

@ -0,0 +1,50 @@
// compile-fail
use std::convert::TryFrom;
use std::path::{Path, PathBuf};
pub struct ToolA(PathBuf);
//~^ HELP the trait `From<&PathBuf>` is not implemented for `ToolA`
impl From<&Path> for ToolA {
//~^ HELP the following other types implement trait `From<T>`
fn from(p: &Path) -> ToolA {
ToolA(p.to_path_buf())
}
}
// Add a different From<T> impl to ensure we suggest the correct cast
impl From<&str> for ToolA {
fn from(s: &str) -> ToolA {
ToolA(PathBuf::from(s))
}
}
pub struct ToolB(PathBuf);
//~^ HELP the trait `From<&PathBuf>` is not implemented for `ToolB`
//~| HELP the trait `From<&PathBuf>` is not implemented for `ToolB`
impl TryFrom<&Path> for ToolB {
//~^ HELP the trait `TryFrom<&PathBuf>` is not implemented for `ToolB`
//~| HELP the trait `TryFrom<&PathBuf>` is not implemented for `ToolB`
type Error = ();
fn try_from(p: &Path) -> Result<ToolB, ()> {
Ok(ToolB(p.to_path_buf()))
}
}
fn main() {
let path = PathBuf::new();
let _ = ToolA::from(&path);
//~^ ERROR the trait bound `ToolA: From<&PathBuf>` is not satisfied
//~| HELP consider casting the `&PathBuf` value to `&Path`
let _ = ToolB::try_from(&path);
//~^ ERROR the trait bound `ToolB: TryFrom<&PathBuf>` is not satisfied
//~| ERROR the trait bound `ToolB: From<&PathBuf>` is not satisfied
//~| HELP consider casting the `&PathBuf` value to `&Path`
//~| HELP consider casting the `&PathBuf` value to `&Path`
//~| HELP for that trait implementation, expected `Path`, found `PathBuf`
//~| HELP for that trait implementation, expected `Path`, found `PathBuf`
}

View file

@ -0,0 +1,68 @@
error[E0277]: the trait bound `ToolA: From<&PathBuf>` is not satisfied
--> $DIR/explicit-reference-cast.rs:40:13
|
LL | let _ = ToolA::from(&path);
| ^^^^^ unsatisfied trait bound
|
= help: consider casting the `&PathBuf` value to `&Path`
help: the trait `From<&PathBuf>` is not implemented for `ToolA`
--> $DIR/explicit-reference-cast.rs:6:1
|
LL | pub struct ToolA(PathBuf);
| ^^^^^^^^^^^^^^^^
help: the following other types implement trait `From<T>`
--> $DIR/explicit-reference-cast.rs:9:1
|
LL | impl From<&Path> for ToolA {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ `ToolA` implements `From<&Path>`
...
LL | impl From<&str> for ToolA {
| ^^^^^^^^^^^^^^^^^^^^^^^^^ `ToolA` implements `From<&str>`
error[E0277]: the trait bound `ToolB: TryFrom<&PathBuf>` is not satisfied
--> $DIR/explicit-reference-cast.rs:43:13
|
LL | let _ = ToolB::try_from(&path);
| ^^^^^ unsatisfied trait bound
|
= help: consider casting the `&PathBuf` value to `&Path`
help: the trait `From<&PathBuf>` is not implemented for `ToolB`
--> $DIR/explicit-reference-cast.rs:23:1
|
LL | pub struct ToolB(PathBuf);
| ^^^^^^^^^^^^^^^^
help: the trait `TryFrom<&PathBuf>` is not implemented for `ToolB`
but trait `TryFrom<&Path>` is implemented for it
--> $DIR/explicit-reference-cast.rs:27:1
|
LL | impl TryFrom<&Path> for ToolB {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= help: for that trait implementation, expected `Path`, found `PathBuf`
= note: required for `&PathBuf` to implement `Into<ToolB>`
= note: required for `ToolB` to implement `TryFrom<&PathBuf>`
error[E0277]: the trait bound `ToolB: From<&PathBuf>` is not satisfied
--> $DIR/explicit-reference-cast.rs:43:13
|
LL | let _ = ToolB::try_from(&path);
| ^^^^^^^^^^^^^^^^^^^^^^ unsatisfied trait bound
|
= help: consider casting the `&PathBuf` value to `&Path`
help: the trait `From<&PathBuf>` is not implemented for `ToolB`
--> $DIR/explicit-reference-cast.rs:23:1
|
LL | pub struct ToolB(PathBuf);
| ^^^^^^^^^^^^^^^^
help: the trait `TryFrom<&PathBuf>` is not implemented for `ToolB`
but trait `TryFrom<&Path>` is implemented for it
--> $DIR/explicit-reference-cast.rs:27:1
|
LL | impl TryFrom<&Path> for ToolB {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= help: for that trait implementation, expected `Path`, found `PathBuf`
= note: required for `&PathBuf` to implement `Into<ToolB>`
= note: required for `ToolB` to implement `TryFrom<&PathBuf>`
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0277`.