I tried to define fn to_str(&self) -> Option<&str> as a trait method to make a function able to receive &OsStr, OsString, &str or String as a parameter s: impl ToStr.
I defined the following ToStr trait:
use std::ffi::OsString;
trait ToStr {
fn to_str(&self) -> Option<&str>;
}
impl ToStr for OsString {
fn to_str(&self) -> Option<&str> {
// warning: function cannot return without recursing
// self.to_str()
// warning: function cannot return without recursing
// OsString::to_str(self)
// warning: function cannot return without recursing
// Self::to_str(self)
// error[E0404]: expected trait, found struct `OsString`
// <Self as OsString>::to_str(self)
}
}
fn f(s: impl ToStr) {
dbg!(s.to_str());
}
fn main() {
f(OsString::new());
}
How can I resolve the recursion problem? I want to call the to_str method, which is an associated function of OsString.
To be more precise, you want to call to_str on OsStr, not on OsString. (OsString implements Deref<Target = OsStr>, which is probably why you thought that OsString has a .to_str() method). I don't remember the exact procedure by which a .method() call is resolved, but there is a well-defined order in which things are checked... and I assume that the compiler is correctly telling you that calling the trait method takes precedence over dereferencing self and then calling an inherent method.
How about (**self).to_str()? Or maybe just (*self).to_str() is enough, idk, but I know the first one should work.
Under that explanation, T = &OsString is added in step 1. Then, OsString is added in step 2/3, then those steps are repeated and OsStr is added. Later, &OsStr is added in step 5.
The end result is that inherent methods whose self type is &OsString have the highest priority, but trait methods whose self type is &OsString still have priority over any sort of method whose self type is &OsStr.