How is it possible that method to_string exists, as the error msg says, but trait bounds were not satisfied, which basically means "some" interface is not implemented for that type.
So which one is it, does the method exists and if so I should be able to use it or the interface is not implemented and thus the method doesn't exist and I cannot use it!!!
Which one is it????
Have to be honest, some of the rust terminology, like bounds not being satisfied is so alien to most of the not even programmers, but people in general that I'm really struggling why the well known terminology, ie "interface" wasn't used in the first place. Just to be different? Silly argument.
error[E0599]: the method to_string exists for struct PathBuf, but its trait bounds were not satisfied
--> src/fm_table.rs:359:72
|
359 | *rc_current_path.borrow_mut() = path_t.clone().to_string();
| ^^^^^^^^^
|
::: .rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/path.rs:1156:1
|
1156 | pub struct PathBuf {
| ------------------
| |
| doesn't satisfy PathBuf: ToString
| doesn't satisfy PathBuf: std::fmt::Display
PathBuf doesn't have a .to_string() method as a path doesn't need to be UTF-8 while a String must be. Are you sure you want to turn it into a String? If this is only for showing the path to the user you can use .display() which does a lossy conversion to UTF-8.
It is a bit misleading. The .to_string() method exists on the ToString trait. There is a blanked implementation of ToString, but only for types implementing Display. I believe rustc thinks it needs to use this blanket implementation and then complains that the Display bound isn't satisfied for PathBuf.
The reason for the error message is that the standard library has the following snippet (simplified a bit):
impl<T: fmt::Display> ToString for T {
fn to_string(&self) -> String {
...
}
}
which is short-hand for
impl<T> ToString for T
where
T: fmt::Display
{
fn to_string(&self) -> String {
...
}
}
The <T> part makes this generic, making it apply to all types. The parts after the where is then the list of bounds (requirements) for the impl block, and only types that satisfy all of the trait bounds are actually affected. This kind of impl block is called a blanket impl.
The error appears because PathBuf is part of "all types" — it just doesn't satisfy the trait bound that PathBuf must implement Display. You're going to get this error on any type that does not implement Display.
The error message is trying to be helpful by explaining why the blanket impl does not apply here.
I wonder if that error message could be improved to something like "the method to_string doesn't exist for struct PathBuf", then in a note/help section explain "the method to_string would exist for struct PathBuf, but the following trait bounds were not satisfied: doesn't satisfy PathBuf: ToString doesn't satisfy PathBuf: std::fmt::Display".
Could we also get rid of that fugly "trait bounds" and call it for what it is: an interface?
The interface X is not implemented for type T sounds normal.
Trait bounds X are not satisfied for type T sounds at best confusing.
I actually every time read about trait bounds not being satisfied, translate it in my head to iface not being implemented.
Yes it would. That's my main peeve with interfaces being called traits in rust. Is there any other language that doesn't call interface interface but some forced, just to be different and awkward word?
Rust traits are not entirely the same as, say, Java interfaces. The only other language I know of which has an exact equivalent to Rust traits is Haskell, which calls them type classes.
There's Scala, but their traits are actually just interfaces.
Well, they are in some ways more powerful. See e.g. the Default trait. You can not implement anything like that in Java. See also the Send/Sync traits, which don't even have any methods.